added automake.mk files in src/language
[pspp] / src / list.q
index 45046a026d21731a6dd70f4c8ef6d668d84e4f2c..c2f3cd61e3e95b3bae92cd6cab2e5bceb6cbe358 100644 (file)
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-   02111-1307, USA. */
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA. */
 
-/* AIX requires this to be the first thing in the file.  */
 #include <config.h>
-#if __GNUC__
-#define alloca __builtin_alloca
-#else
-#if HAVE_ALLOCA_H
-#include <alloca.h>
-#else
-#ifdef _AIX
-#pragma alloca
-#else
-#ifndef alloca                 /* predefined by HP cc +Olibcalls */
-char *alloca ();
-#endif
-#endif
-#endif
-#endif
-
-#include <assert.h>
+#include "error.h"
 #include <stdio.h>
 #include <stdlib.h>
 #include "alloc.h"
+#include "case.h"
 #include "command.h"
+#include "dictionary.h"
 #include "lexer.h"
 #include "error.h"
 #include "magic.h"
 #include "misc.h"
 #include "htmlP.h"
 #include "output.h"
+#include "size_max.h"
 #include "som.h"
+#include "tab.h"
 #include "var.h"
 #include "vfm.h"
 #include "format.h"
 
-#undef DEBUGGING
-/*#define DEBUGGING 1*/
-#include "debug-print.h"
+#include "gettext.h"
+#define _(msgid) gettext (msgid)
 
-#if DEBUGGING
-static void debug_print (void);
-#endif
+/* (headers) */
+
+#include "debug-print.h"
 
 /* (specification)
    list (lst_):
@@ -74,8 +60,8 @@ static void debug_print (void);
 struct list_ext
   {
     int type;          /* 0=Values and labels fit across the page. */
-    int n_vertical;    /* Number of labels to list vertically. */
-    int header_rows;   /* Number of header rows. */
+    size_t n_vertical; /* Number of labels to list vertically. */
+    size_t header_rows;        /* Number of header rows. */
     char **header;     /* The header itself. */
   };
 
@@ -83,26 +69,26 @@ struct list_ext
 static struct cmd_list cmd;
 
 /* Current case number. */
-static int case_num;
+static int case_idx;
 
 /* Line buffer. */
 static char *line_buf;
 
 /* TTY-style output functions. */
-static int n_lines_remaining (struct outp_driver *d);
-static int n_chars_width (struct outp_driver *d);
+static unsigned n_lines_remaining (struct outp_driver *d);
+static unsigned n_chars_width (struct outp_driver *d);
 static void write_line (struct outp_driver *d, char *s);
 
 /* Other functions. */
-static int list_cases (struct ccase *);
+static int list_cases (struct ccase *, void *);
 static void determine_layout (void);
 static void clean_up (void);
 static void write_header (struct outp_driver *);
-static void write_all_headers (void);
+static void write_all_headers (void *);
 
 /* Returns the number of text lines that can fit on the remainder of
    the page. */
-static inline int
+static inline unsigned
 n_lines_remaining (struct outp_driver *d)
 {
   int diff;
@@ -113,7 +99,7 @@ n_lines_remaining (struct outp_driver *d)
 
 /* Returns the number of fixed-width character that can fit across the
    page. */
-static inline int
+static inline unsigned
 n_chars_width (struct outp_driver *d)
 {
   return d->width / d->fixed_width;
@@ -142,7 +128,6 @@ cmd_list (void)
 {
   struct variable casenum_var;
 
-  lex_match_id ("LIST");
   if (!parse_list (&cmd))
     return CMD_FAILURE;
   
@@ -154,8 +139,8 @@ cmd_list (void)
   if (cmd.last == NOT_LONG)
     cmd.last = LONG_MAX;
   if (!cmd.sbc_variables)
-    fill_all_vars (&cmd.v_variables, &cmd.n_variables,
-                  FV_NO_SYSTEM | FV_NO_SCRATCH);
+    dict_get_vars (default_dict, &cmd.v_variables, &cmd.n_variables,
+                  (1u << DC_SYSTEM) | (1u << DC_SCRATCH));
   if (cmd.n_variables == 0)
     {
       msg (SE, _("No variables specified."));
@@ -194,23 +179,21 @@ cmd_list (void)
   /* Weighting variable. */
   if (cmd.weight == LST_WEIGHT)
     {
-      update_weighting (&default_dict);
-      if (default_dict.weight_index != -1)
+      if (dict_get_weight (default_dict) != NULL)
        {
-         int i;
+         size_t i;
 
          for (i = 0; i < cmd.n_variables; i++)
-           if (cmd.v_variables[i]->index == default_dict.weight_index)
+           if (cmd.v_variables[i] == dict_get_weight (default_dict))
              break;
          if (i >= cmd.n_variables)
            {
              /* Add the weight variable to the end of the variable list. */
              cmd.n_variables++;
-             cmd.v_variables = xrealloc (cmd.v_variables,
-                                         (cmd.n_variables
-                                          * sizeof *cmd.v_variables));
+             cmd.v_variables = xnrealloc (cmd.v_variables, cmd.n_variables,
+                                           sizeof *cmd.v_variables);
              cmd.v_variables[cmd.n_variables - 1]
-               = default_dict.var[default_dict.weight_index];
+                = dict_get_weight (default_dict);
            }
        }
       else
@@ -224,28 +207,23 @@ cmd_list (void)
       strcpy (casenum_var.name, "Case#");
       casenum_var.type = NUMERIC;
       casenum_var.fv = -1;
-      casenum_var.print.type = FMT_F;
-      casenum_var.print.w = (cmd.last == LONG_MAX ? 5 : intlog10 (cmd.last));
-      casenum_var.print.d = 0;
+      casenum_var.print = make_output_format (FMT_F,
+                                              (cmd.last == LONG_MAX
+                                               ? 5 : intlog10 (cmd.last)), 0);
 
       /* Add the weight variable at the beginning of the variable list. */
       cmd.n_variables++;
-      cmd.v_variables = xrealloc (cmd.v_variables,
-                                 cmd.n_variables * sizeof *cmd.v_variables);
+      cmd.v_variables = xnrealloc (cmd.v_variables,
+                                   cmd.n_variables, sizeof *cmd.v_variables);
       memmove (&cmd.v_variables[1], &cmd.v_variables[0],
               (cmd.n_variables - 1) * sizeof *cmd.v_variables);
       cmd.v_variables[0] = &casenum_var;
     }
 
-#if DEBUGGING
-  /* Print out command. */
-  debug_print ();
-#endif
-
   determine_layout ();
 
-  case_num = 0;
-  procedure (write_all_headers, list_cases, NULL);
+  case_idx = 0;
+  procedure_with_splits (write_all_headers, list_cases, NULL, NULL);
   free (line_buf);
 
   clean_up ();
@@ -256,7 +234,7 @@ cmd_list (void)
 /* Writes headers to all devices.  This is done at the beginning of
    each SPLIT FILE group. */
 static void
-write_all_headers (void)
+write_all_headers (void *aux UNUSED)
 {
   struct outp_driver *d;
 
@@ -271,7 +249,7 @@ write_all_headers (void)
        {
          struct html_driver_ext *x = d->ext;
   
-         assert (d->driver_open && d->page_open);
+         assert (d->driver_open);
          if (x->sequence_no == 0 && !d->class->open_page (d))
            {
              msg (ME, _("Cannot open first page on HTML device %s."),
@@ -282,7 +260,7 @@ write_all_headers (void)
          fputs ("<TABLE BORDER=1>\n  <TR>\n", x->file.file);
          
          {
-           int i;
+           size_t i;
 
            for (i = 0; i < cmd.n_variables; i++)
              fprintf (x->file.file, "    <TH><I><B>%s</B></I></TH>\n",
@@ -315,10 +293,11 @@ write_header (struct outp_driver *d)
   /* Design the header. */
   if (!prc->header)
     {
-      int i, x;
-
+      size_t i;
+      size_t x;
+      
       /* Allocate, initialize header. */
-      prc->header = xmalloc (sizeof (char *) * prc->header_rows);
+      prc->header = xnmalloc (prc->header_rows, sizeof *prc->header);
       {
        int w = n_chars_width (d);
        for (i = 0; i < prc->header_rows; i++)
@@ -332,11 +311,11 @@ write_header (struct outp_driver *d)
       for (i = x = 0; i < prc->n_vertical; i++)
        {
          struct variable *v = cmd.v_variables[i];
-         int j;
+         size_t j;
 
          memset (&prc->header[prc->header_rows - 1][x], '-', v->print.w);
          x += v->print.w - 1;
-         for (j = 0; j < (int) strlen (v->name); j++)
+         for (j = 0; j < strlen (v->name); j++)
            prc->header[strlen (v->name) - j - 1][x] = v->name[j];
          x += 2;
        }
@@ -368,13 +347,14 @@ write_header (struct outp_driver *d)
     }
 
   /* Write out the header, in back-to-front order except for the last line. */
-  {
-    int i;
-    
-    for (i = prc->header_rows - 2; i >= 0; i--)
-      write_line (d, prc->header[i]);
-    write_line (d, prc->header[prc->header_rows - 1]);
-  }
+  if (prc->header_rows >= 2) 
+    {
+      size_t i;
+        
+      for (i = prc->header_rows - 1; i-- != 0; )
+        write_line (d, prc->header[i]); 
+    }
+  write_line (d, prc->header[prc->header_rows - 1]);
 }
       
   
@@ -388,7 +368,7 @@ clean_up (void)
     if (d->class->special == 0)
       {
        struct list_ext *prc = d->prc;
-       int i;
+       size_t i;
 
        if (prc->header)
          {
@@ -532,10 +512,11 @@ determine_layout (void)
   
   for (d = outp_drivers (NULL); d; d = outp_drivers (d))
     {
-      int column;      /* Current column. */
+      size_t column;   /* Current column. */
       int width;       /* Accumulated width. */
+      int height;       /* Height of vertical names. */
       int max_width;   /* Page width. */
-      
+
       struct list_ext *prc;
 
       if (d->class == &html_class)
@@ -568,19 +549,24 @@ determine_layout (void)
        }
 
       /* Try layout #2. */
-      for (width = cmd.n_variables - 1, column = 0;
+      for (width = cmd.n_variables - 1, height = 0, column = 0;
           column < cmd.n_variables && width <= max_width;
-          column++)
-         width += cmd.v_variables[column]->print.w;
+          column++) 
+        {
+          struct variable *v = cmd.v_variables[column];
+          width += v->print.w;
+          if (strlen (v->name) > height)
+            height = strlen (v->name);
+        }
       
       /* If it fit then we need to determine how many labels can be
          written horizontally. */
-      if (width <= max_width)
+      if (width <= max_width && height <= SHORT_NAME_LEN)
        {
 #ifndef NDEBUG
-         prc->n_vertical = -1;
+         prc->n_vertical = SIZE_MAX;
 #endif
-         for (column = cmd.n_variables - 1; column >= 0; column--)
+         for (column = cmd.n_variables; column-- != 0; )
            {
              struct variable *v = cmd.v_variables[column];
              int trial_width = (width - v->print.w
@@ -593,7 +579,7 @@ determine_layout (void)
                }
              width = trial_width;
            }
-         assert(prc->n_vertical != -1);
+         assert (prc->n_vertical != SIZE_MAX);
 
          prc->n_vertical = cmd.n_variables;
          /* Finally determine the length of the headers. */
@@ -601,7 +587,7 @@ determine_layout (void)
               column < prc->n_vertical;
               column++)
            prc->header_rows = max (prc->header_rows,
-                                   (int) strlen (cmd.v_variables[column]->name));
+                                   strlen (cmd.v_variables[column]->name));
          prc->header_rows++;
 
          d->class->text_set_font_by_name (d, "FIXED");
@@ -622,13 +608,13 @@ determine_layout (void)
 }
 
 static int
-list_cases (struct ccase *c)
+list_cases (struct ccase *c, void *aux UNUSED)
 {
   struct outp_driver *d;
   
-  case_num++;
-  if (case_num < cmd.first || case_num > cmd.last
-      || (cmd.step != 1 && (case_num - cmd.first) % cmd.step))
+  case_idx++;
+  if (case_idx < cmd.first || case_idx > cmd.last
+      || (cmd.step != 1 && (case_idx - cmd.first) % cmd.step))
     return 1;
 
   for (d = outp_drivers (NULL); d; d = outp_drivers (d))
@@ -673,19 +659,15 @@ list_cases (struct ccase *c)
                memset(&line_buf[x], ' ', width - v->print.w);
                x += width - v->print.w;
              }
-         
-           {
-             union value value;
-           
-             if (formats[v->print.type].cat & FCAT_STRING)
-               value.c = c->data[v->fv].s;
-             else if (v->fv == -1)
-               value.f = case_num;
-             else
-               value.f = c->data[v->fv].f;
-               
-             data_out (&line_buf[x], &v->print, &value);
-           }
+
+            if ((formats[v->print.type].cat & FCAT_STRING) || v->fv != -1)
+             data_out (&line_buf[x], &v->print, case_data (c, v->fv));
+            else 
+              {
+                union value case_idx_value;
+                case_idx_value.f = case_idx;
+                data_out (&line_buf[x], &v->print, &case_idx_value); 
+              }
            x += v->print.w;
          
            line_buf[x++] = ' ';
@@ -710,17 +692,16 @@ list_cases (struct ccase *c)
        for (column = 0; column < cmd.n_variables; column++)
          {
            struct variable *v = cmd.v_variables[column];
-           union value value;
            char buf[41];
            
-           if (formats[v->print.type].cat & FCAT_STRING)
-             value.c = c->data[v->fv].s;
-           else if (v->fv == -1)
-             value.f = case_num;
-           else
-             value.f = c->data[v->fv].f;
-               
-           data_out (buf, &v->print, &value);
+            if ((formats[v->print.type].cat & FCAT_STRING) || v->fv != -1)
+             data_out (buf, &v->print, case_data (c, v->fv));
+            else 
+              {
+                union value case_idx_value;
+                case_idx_value.f = case_idx;
+                data_out (buf, &v->print, &case_idx_value); 
+              }
            buf[v->print.w] = 0;
 
            fprintf (x->file.file, "    <TD ALIGN=RIGHT>%s</TD>\n",
@@ -734,45 +715,6 @@ list_cases (struct ccase *c)
 
   return 1;
 }
-\f
-/* Debugging output. */
-
-#if DEBUGGING
-/* Prints out the command as parsed by cmd_list(). */
-static void
-debug_print (void)
-{
-  int i;
-
-  puts ("LIST");
-  printf ("  VARIABLES=");
-  for (i = 0; i < cmd.n_variables; i++)
-    {
-      if (i)
-       putc (' ', stdout);
-      fputs (cmd.v_variables[i]->name, stdout);
-    }
-
-  printf ("\n  /CASES=FROM %ld TO %ld BY %ld\n", first, last, step);
-
-  fputs ("  /FORMAT=", stdout);
-  if (numbering == NUMBERED)
-    fputs ("NUMBERED", stdout);
-  else
-    fputs ("UNNUMBERED", stdout);
-  putc (' ', stdout);
-  if (wrap == WRAP)
-    fputs ("WRAP", stdout);
-  else
-    fputs ("SINGLE", stdout);
-  putc (' ', stdout);
-  if (weight == WEIGHT)
-    fputs ("WEIGHT", stdout);
-  else
-    fputs ("NOWEIGHT", stdout);
-  puts (".");
-}
-#endif /* DEBUGGING */
 
 /* 
    Local Variables: