Encapsulated lexer and updated calling functions accordingly.
[pspp-builds.git] / src / language / stats / examine.q
index 14981e884e0469ae3c2ab080904684cc13ca7608..3aa9e4f080a0a8a1f40b125257c2c7334fbf7550 100644 (file)
@@ -19,51 +19,54 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 02110-1301, USA. */
 
 #include <config.h>
+
 #include <gsl/gsl_cdf.h>
-#include "message.h"
+#include <libpspp/message.h>
+#include <math.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <math.h>
-#include "alloc.h"
-#include "str.h"
-#include "case.h"
-#include "dictionary.h"
-#include "command.h"
-#include "compiler.h"
-#include "lexer.h"
-#include "message.h"
-#include "magic.h"
-#include "misc.h"
-#include "table.h"
-#include "manager.h"
-#include "value-labels.h"
-#include "variable.h"
-#include "procedure.h"
-#include "hash.h"
-#include "casefile.h"
-#include "factor-stats.h"
-#include "moments.h"
-#include "percentiles.h"
-#include "box-whisker.h"
-#include "cartesian.h"
+
+#include <data/case.h>
+#include <data/casefile.h>
+#include <data/dictionary.h>
+#include <data/procedure.h>
+#include <data/value-labels.h>
+#include <data/variable.h>
+#include <language/command.h>
+#include <language/dictionary/split-file.h>
+#include <language/lexer/lexer.h>
+#include <libpspp/alloc.h>
+#include <libpspp/compiler.h>
+#include <libpspp/hash.h>
+#include <libpspp/magic.h>
+#include <libpspp/message.h>
+#include <libpspp/misc.h>
+#include <libpspp/str.h>
+#include <math/factor-stats.h>
+#include <math/moments.h>
+#include <math/percentiles.h>
+#include <output/charts/box-whisker.h>
+#include <output/charts/cartesian.h>
+#include <output/manager.h>
+#include <output/table.h>
 
 #include "gettext.h"
 #define _(msgid) gettext (msgid)
 #define N_(msgid) msgid
 
 /* (headers) */
-#include "chart.h"
-#include "plot-hist.h"
-#include "plot-chart.h"
+#include <output/chart.h>
+#include <output/charts/plot-hist.h>
+#include <output/charts/plot-chart.h>
 
 /* (specification)
    "EXAMINE" (xmn_):
    *^variables=custom;
    +total=custom;
    +nototal=custom;
-   +missing=miss:pairwise/!listwise,
-   rep:report/!noreport,
-   incl:include/!exclude;
+   missing=miss:pairwise/!listwise,
+           rep:report/!noreport,
+           incl:include/!exclude;
    +compare=cmp:variables/!groups;
    +percentiles=custom;
    +id=var;
@@ -107,7 +110,7 @@ static struct factor *factors=0;
 static struct metrics *totals=0;
 
 /* Parse the clause specifying the factors */
-static int examine_parse_independent_vars(struct cmd_examine *cmd);
+static int examine_parse_independent_vars (struct lexer *lexer, const struct dictionary *dict, struct cmd_examine *cmd);
 
 
 
@@ -148,7 +151,8 @@ void box_plot_variables(const struct factor *fctr,
 
 
 /* Per Split function */
-static bool run_examine(const struct casefile *cf, void *cmd_);
+static bool run_examine (const struct ccase *,
+                        const struct casefile *cf, void *cmd_, const struct dataset *);
 
 static void output_examine(void);
 
@@ -187,14 +191,14 @@ static short sbc_percentile;
 
 
 int
-cmd_examine(void)
+cmd_examine (struct lexer *lexer, struct dataset *ds)
 {
   bool ok;
 
   subc_list_double_create(&percentile_list);
   percentile_algorithm = PC_HAVERAGE;
 
-  if ( !parse_examine(&cmd) )
+  if ( !parse_examine (lexer, ds, &cmd, NULL) )
     return CMD_FAILURE;
 
   /* If /MISSING=INCLUDE is set, then user missing values are ignored */
@@ -218,7 +222,7 @@ cmd_examine(void)
       subc_list_double_push(&percentile_list, 75);
     }
 
-  ok = multipass_procedure_with_splits (run_examine, &cmd);
+  ok = multipass_procedure_with_splits (ds, run_examine, &cmd);
 
   if ( totals ) 
     {
@@ -275,6 +279,12 @@ output_examine(void)
       if ( cmd.sbc_plot) 
        {
          int v;
+         if ( cmd.a_plot[XMN_PLT_STEMLEAF] ) 
+           msg (SW, _("%s is not currently supported."), "STEMLEAF");
+
+         if ( cmd.a_plot[XMN_PLT_SPREADLEVEL] ) 
+           msg (SW, _("%s is not currently supported."), "SPREADLEVEL");
+
          if ( cmd.a_plot[XMN_PLT_NPPLOT] ) 
            {
              for ( v = 0 ; v < n_dependent_vars; ++v ) 
@@ -285,12 +295,13 @@ output_examine(void)
            {
              if ( cmd.cmp == XMN_GROUPS ) 
                {
-                 box_plot_group(0, dependent_vars, n_dependent_vars, 
-                                cmd.v_id);
+                 box_plot_group (0, (const struct variable **) dependent_vars,
+                                  n_dependent_vars, cmd.v_id);
                }
              else
-               box_plot_variables(0, dependent_vars, n_dependent_vars,
-                                  cmd.v_id);
+               box_plot_variables (0,
+                                    (const struct variable **) dependent_vars,
+                                    n_dependent_vars, cmd.v_id);
            }
 
          if ( cmd.a_plot[XMN_PLT_HISTOGRAM] ) 
@@ -342,11 +353,13 @@ output_examine(void)
          if ( cmd.a_plot[XMN_PLT_BOXPLOT] )
            {
              if ( cmd.cmp == XMN_VARIABLES ) 
-               box_plot_variables(fctr, dependent_vars, n_dependent_vars, 
-                                  cmd.v_id);
+               box_plot_variables (fctr,
+                                    (const struct variable **) dependent_vars,
+                                    n_dependent_vars, cmd.v_id);
              else
-               box_plot_group(fctr, dependent_vars, n_dependent_vars, 
-                              cmd.v_id);
+               box_plot_group (fctr,
+                                (const struct variable **) dependent_vars,
+                                n_dependent_vars, cmd.v_id);
            }
 
          for ( v = 0 ; v < n_dependent_vars; ++v )
@@ -416,54 +429,55 @@ list_to_ptile_hash(const subc_list_double *l)
 
 /* Parse the PERCENTILES subcommand */
 static int
-xmn_custom_percentiles(struct cmd_examine *p UNUSED)
+xmn_custom_percentiles(struct lexer *lexer, struct dataset *ds UNUSED, 
+                      struct cmd_examine *p UNUSED, void *aux UNUSED)
 {
   sbc_percentile = 1;
 
-  lex_match('=');
+  lex_match (lexer, '=');
 
-  lex_match('(');
+  lex_match (lexer, '(');
 
-  while ( lex_is_number() ) 
+  while ( lex_is_number (lexer) ) 
     {
-      subc_list_double_push(&percentile_list,lex_number());
+      subc_list_double_push (&percentile_list, lex_number (lexer));
 
-      lex_get();
+      lex_get (lexer);
 
-      lex_match(',') ;
+      lex_match (lexer, ',') ;
     }
-  lex_match(')');
+  lex_match (lexer, ')');
 
-  lex_match('=');
+  lex_match (lexer, '=');
 
-  if ( lex_match_id("HAVERAGE"))
+  if ( lex_match_id (lexer, "HAVERAGE"))
     percentile_algorithm = PC_HAVERAGE; 
 
-  else if ( lex_match_id("WAVERAGE"))
+  else if ( lex_match_id (lexer, "WAVERAGE"))
     percentile_algorithm = PC_WAVERAGE; 
 
-  else if ( lex_match_id("ROUND"))
+  else if ( lex_match_id (lexer, "ROUND"))
     percentile_algorithm = PC_ROUND;
 
-  else if ( lex_match_id("EMPIRICAL"))
+  else if ( lex_match_id (lexer, "EMPIRICAL"))
     percentile_algorithm = PC_EMPIRICAL;
 
-  else if ( lex_match_id("AEMPIRICAL"))
+  else if ( lex_match_id (lexer, "AEMPIRICAL"))
     percentile_algorithm = PC_AEMPIRICAL; 
 
-  else if ( lex_match_id("NONE"))
+  else if ( lex_match_id (lexer, "NONE"))
     percentile_algorithm = PC_NONE; 
 
 
   if ( 0 == subc_list_double_count(&percentile_list))
     {
-      subc_list_double_push(&percentile_list, 5);
-      subc_list_double_push(&percentile_list, 10);
-      subc_list_double_push(&percentile_list, 25);
-      subc_list_double_push(&percentile_list, 50);
-      subc_list_double_push(&percentile_list, 75);
-      subc_list_double_push(&percentile_list, 90);
-      subc_list_double_push(&percentile_list, 95);
+      subc_list_double_push (&percentile_list, 5);
+      subc_list_double_push (&percentile_list, 10);
+      subc_list_double_push (&percentile_list, 25);
+      subc_list_double_push (&percentile_list, 50);
+      subc_list_double_push (&percentile_list, 75);
+      subc_list_double_push (&percentile_list, 90);
+      subc_list_double_push (&percentile_list, 95);
     }
 
   return 1;
@@ -471,7 +485,7 @@ xmn_custom_percentiles(struct cmd_examine *p UNUSED)
 
 /* TOTAL and NOTOTAL are simple, mutually exclusive flags */
 static int
-xmn_custom_total(struct cmd_examine *p)
+xmn_custom_total (struct lexer *lexer UNUSED, struct dataset *ds UNUSED, struct cmd_examine *p, void *aux UNUSED)
 {
   if ( p->sbc_nototal ) 
     {
@@ -483,7 +497,8 @@ xmn_custom_total(struct cmd_examine *p)
 }
 
 static int
-xmn_custom_nototal(struct cmd_examine *p)
+xmn_custom_nototal (struct lexer *lexer UNUSED, struct dataset *ds UNUSED, 
+                   struct cmd_examine *p, void *aux UNUSED)
 {
   if ( p->sbc_total ) 
     {
@@ -499,17 +514,18 @@ xmn_custom_nototal(struct cmd_examine *p)
 /* Parser for the variables sub command  
    Returns 1 on success */
 static int
-xmn_custom_variables(struct cmd_examine *cmd )
+xmn_custom_variables (struct lexer *lexer, struct dataset *ds, struct cmd_examine *cmd, void *aux UNUSED)
 {
-  lex_match('=');
+  const struct dictionary *dict = dataset_dict (ds);
+  lex_match (lexer, '=');
 
-  if ((token != T_ID || dict_lookup_var (default_dict, tokid) == NULL)
-      && token != T_ALL)
+  if ((lex_token (lexer) != T_ID || dict_lookup_var (dict, lex_tokid (lexer)) == NULL)
+      && lex_token (lexer) != T_ALL)
     {
       return 2;
     }
   
-  if (!parse_variables (default_dict, &dependent_vars, &n_dependent_vars,
+  if (!parse_variables (lexer, dict, &dependent_vars, &n_dependent_vars,
                        PV_NO_DUPLICATE | PV_NUMERIC | PV_NO_SCRATCH) )
     {
       free (dependent_vars);
@@ -520,10 +536,10 @@ xmn_custom_variables(struct cmd_examine *cmd )
 
   totals = xnmalloc (n_dependent_vars, sizeof *totals);
 
-  if ( lex_match(T_BY))
+  if ( lex_match (lexer, T_BY))
     {
       int success ; 
-      success =  examine_parse_independent_vars(cmd);
+      success =  examine_parse_independent_vars (lexer, dict, cmd);
       if ( success != 1 ) {
         free (dependent_vars);
        free (totals) ; 
@@ -538,35 +554,35 @@ xmn_custom_variables(struct cmd_examine *cmd )
 
 /* Parse the clause specifying the factors */
 static int
-examine_parse_independent_vars(struct cmd_examine *cmd)
+examine_parse_independent_vars (struct lexer *lexer, const struct dictionary *dict, struct cmd_examine *cmd)
 {
   int success;
   struct factor *sf = xmalloc (sizeof *sf);
 
-  if ((token != T_ID || dict_lookup_var (default_dict, tokid) == NULL)
-      && token != T_ALL)
+  if ((lex_token (lexer) != T_ID || dict_lookup_var (dict, lex_tokid (lexer)) == NULL)
+      && lex_token (lexer) != T_ALL)
     {
       free ( sf ) ;
       return 2;
     }
 
 
-  sf->indep_var[0] = parse_variable();
+  sf->indep_var[0] = parse_variable (lexer, dict);
   sf->indep_var[1] = 0;
 
-  if ( token == T_BY ) 
+  if ( lex_token (lexer) == T_BY ) 
     {
 
-      lex_match(T_BY);
+      lex_match (lexer, T_BY);
 
-      if ((token != T_ID || dict_lookup_var (default_dict, tokid) == NULL)
-         && token != T_ALL)
+      if ((lex_token (lexer) != T_ID || dict_lookup_var (dict, lex_tokid (lexer)) == NULL)
+         && lex_token (lexer) != T_ALL)
        {
          free ( sf ) ;
          return 2;
        }
 
-      sf->indep_var[1] = parse_variable();
+      sf->indep_var[1] = parse_variable (lexer, dict);
 
     }
 
@@ -580,12 +596,12 @@ examine_parse_independent_vars(struct cmd_examine *cmd)
   sf->next = factors;
   factors = sf;
   
-  lex_match(',');
+  lex_match (lexer, ',');
 
-  if ( token == '.' || token == '/' ) 
+  if ( lex_token (lexer) == '.' || lex_token (lexer) == '/' ) 
     return 1;
 
-  success =  examine_parse_independent_vars(cmd);
+  success =  examine_parse_independent_vars (lexer, dict, cmd);
   
   if ( success != 1 ) 
     free ( sf ) ; 
@@ -611,7 +627,7 @@ void populate_summary(struct tab_table *t, int col, int row,
 
 
 
-static int bad_weight_warn = 1;
+static bool bad_weight_warn = true;
 
 
 /* Perform calculations for the sub factors */
@@ -671,17 +687,23 @@ factor_calc(struct ccase *c, int case_no, double weight, int case_missing)
 }
 
 static bool 
-run_examine(const struct casefile *cf, void *cmd_ )
+run_examine(const struct ccase *first, const struct casefile *cf, 
+           void *cmd_, const struct dataset *ds)
 {
+  struct dictionary *dict = dataset_dict (ds);
   struct casereader *r;
   struct ccase c;
   int v;
 
   const struct cmd_examine *cmd = (struct cmd_examine *) cmd_;
 
+  struct factor *fctr;
+
+  output_split_file_values (ds, first);
+
   /* Make sure we haven't got rubbish left over from a 
      previous split */
-  struct factor *fctr = factors;
+  fctr = factors;
   while (fctr) 
     {
       struct factor *next = fctr->next;
@@ -693,12 +715,10 @@ run_examine(const struct casefile *cf, void *cmd_ )
       fctr = next;
     }
 
-
-
   for ( v = 0 ; v < n_dependent_vars ; ++v ) 
     metrics_precalc(&totals[v]);
 
-  for(r = casefile_get_reader (cf);
+  for(r = casefile_get_reader (cf, NULL);
       casereader_read (r, &c) ;
       case_destroy (&c) ) 
     {
@@ -706,7 +726,7 @@ run_examine(const struct casefile *cf, void *cmd_ )
       const int case_no = casereader_cnum(r);
 
       const double weight = 
-       dict_get_case_weight(default_dict, &c, &bad_weight_warn);
+       dict_get_case_weight(dict, &c, &bad_weight_warn);
 
       if ( cmd->miss == XMN_LISTWISE ) 
        {
@@ -914,7 +934,7 @@ show_summary(struct variable **dependent_var, int n_dep_var,
   tab_vline (tbl, TAL_2, heading_columns, 0, n_rows - 1);
 
 
-  tab_title (tbl, 0, _("Case Processing Summary"));
+  tab_title (tbl, _("Case Processing Summary"));
   
 
   tab_joint_text(tbl, heading_columns, 0, 
@@ -1120,7 +1140,7 @@ show_extremes(struct variable **dependent_var, int n_dep_var,
 
   tab_hline (tbl, TAL_2, 0, n_cols - 1, heading_rows );
 
-  tab_title (tbl, 0, _("Extreme Values"));
+  tab_title (tbl, _("Extreme Values"));
 
   tab_vline (tbl, TAL_2, n_cols - 2, 0, n_rows -1);
   tab_vline (tbl, TAL_1, n_cols - 1, 0, n_rows -1);
@@ -1369,7 +1389,7 @@ show_descriptives(struct variable **dependent_var,
   tab_text (tbl, n_cols - 2, 0, TAB_CENTER | TAT_TITLE, _("Statistic"));
   tab_text (tbl, n_cols - 1, 0, TAB_CENTER | TAT_TITLE, _("Std. Error"));
 
-  tab_title (tbl, 0, _("Descriptives"));
+  tab_title (tbl, _("Descriptives"));
 
 
   for ( i = 0 ; i < n_dep_var ; ++i ) 
@@ -1957,7 +1977,7 @@ show_percentiles(struct variable **dependent_var,
   tab_vline (tbl, TAL_2, n_heading_columns, 0, n_rows - 1);
 
 
-  tab_title (tbl, 0, _("Percentiles"));
+  tab_title (tbl, _("Percentiles"));
 
 
   tab_hline (tbl, TAL_1, n_heading_columns, n_cols - 1, 1 );