Parameter estimate matched with appropriate variable during estimation
[pspp] / src / print.c
index d8f4d77040834a375d9fa31bdb16734b99137abc..a42c82d5bca3e4da742cd5fdc70d819e07e470be 100644 (file)
@@ -14,8 +14,8 @@
 
    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. */
 
 /* FIXME: seems like a lot of code duplication with data-list.c. */
 
@@ -35,6 +35,9 @@
 #include "tab.h"
 #include "var.h"
 
+#include "gettext.h"
+#define _(msgid) gettext (msgid)
+
 /* Describes what to do when an output field is encountered. */
 enum
   {
@@ -246,8 +249,8 @@ struct fmt_list
 static struct
   {
     struct variable **v;               /* variable list */
-    int nv;                    /* number of variables in list */
-    int cv;                    /* number of variables from list used up so far
+    size_t nv;                 /* number of variables in list */
+    size_t cv;                 /* number of variables from list used up so far
                                   by the FORTRAN-like format specifiers */
 
     int recno;                 /* current 1-based record number */
@@ -287,7 +290,7 @@ parse_specs (void)
          int prev_recno = fx.recno;
 
          fx.recno++;
-         if (token == T_NUM)
+         if (lex_is_number ())
            {
              if (!lex_force_int ())
                return 0;
@@ -349,7 +352,7 @@ parse_string_argument (void)
   lex_get ();
 
   /* Parse the included column range. */
-  if (token == T_NUM)
+  if (lex_is_number ())
     {
       /* Width of column range in characters. */
       int c_len;
@@ -360,7 +363,7 @@ parse_string_argument (void)
       /* 1-based index of last column in range. */
       int lc;
 
-      if (!lex_integer_p () || lex_integer () <= 0)
+      if (!lex_is_integer () || lex_integer () <= 0)
        {
          msg (SE, _("%g is not a valid column location."), tokval);
          goto fail;
@@ -371,7 +374,7 @@ parse_string_argument (void)
       lex_negative_to_dash ();
       if (lex_match ('-'))
        {
-         if (!lex_integer_p ())
+         if (!lex_is_integer ())
            {
              msg (SE, _("Column location expected following `%d-'."),
                   fx.spec.fc + 1);
@@ -434,7 +437,7 @@ parse_variable_argument (void)
   if (!parse_variables (default_dict, &fx.v, &fx.nv, PV_DUPLICATE))
     return 0;
 
-  if (token == T_NUM)
+  if (lex_is_number ())
     {
       if (!fixed_parse_compatible ())
        goto fail;
@@ -449,7 +452,7 @@ parse_variable_argument (void)
   else
     {
       /* User wants dictionary format specifiers. */
-      int i;
+      size_t i;
 
       lex_match ('*');
       for (i = 0; i < fx.nv; i++)
@@ -478,13 +481,28 @@ fail:
   return 0;
 }
 
+/* Verifies that FORMAT doesn't need a variable wider than WIDTH.
+   Returns true iff that is the case. */
+static bool
+check_string_width (const struct fmt_spec *format, const struct variable *v) 
+{
+  if (get_format_var_width (format) > v->width)
+    {
+      msg (SE, _("Variable %s has width %d so it cannot be output "
+                 "as format %s."),
+           v->name, v->width, fmt_to_string (format));
+      return false;
+    }
+  return true;
+}
+
 /* Parses a column specification for parse_specs(). */
 static int
 fixed_parse_compatible (void)
 {
-  int dividend;
+  int individual_var_width;
   int type;
-  int i;
+  size_t i;
 
   type = fx.v[0]->type;
   for (i = 1; i < fx.nv; i++)
@@ -553,7 +571,7 @@ fixed_parse_compatible (void)
       else
        fx.spec.u.v.f.type = FMT_F;
 
-      if (token == T_NUM)
+      if (lex_is_number ())
        {
          if (!lex_force_int ())
            return 0;
@@ -592,40 +610,28 @@ fixed_parse_compatible (void)
 
   if ((fx.lc - fx.fc + 1) % fx.nv)
     {
-      msg (SE, _("The %d columns %d-%d can't be evenly divided into %d "
-                "fields."), fx.lc - fx.fc + 1, fx.fc + 1, fx.lc + 1, fx.nv);
+      msg (SE, _("The %d columns %d-%d can't be evenly divided into %u "
+                "fields."),
+           fx.lc - fx.fc + 1, fx.fc + 1, fx.lc + 1, (unsigned) fx.nv);
       return 0;
     }
 
-  dividend = (fx.lc - fx.fc + 1) / fx.nv;
-  fx.spec.u.v.f.w = dividend;
-  if (!check_output_specifier (&fx.spec.u.v.f, 1))
+  individual_var_width = (fx.lc - fx.fc + 1) / fx.nv;
+  fx.spec.u.v.f.w = individual_var_width;
+  if (!check_output_specifier (&fx.spec.u.v.f, true)
+      || !check_specifier_type (&fx.spec.u.v.f, type, true))
     return 0;
-  if ((type == ALPHA) ^ (formats[fx.spec.u.v.f.type].cat & FCAT_STRING))
-    {
-      msg (SE, _("%s variables cannot be displayed with format %s."),
-          type == ALPHA ? _("String") : _("Numeric"),
-          fmt_to_string (&fx.spec.u.v.f));
-      return 0;
-    }
-
-  /* Check that, for string variables, the user didn't specify a width
-     longer than an actual string width. */
   if (type == ALPHA)
     {
-      /* Minimum width of all the string variables specified. */
-      int min_len = fx.v[0]->width;
-
-      for (i = 1; i < fx.nv; i++)
-       min_len = min (min_len, fx.v[i]->width);
-      if (!check_string_specifier (&fx.spec.u.v.f, min_len))
-       return 0;
+      for (i = 0; i < fx.nv; i++)
+        if (!check_string_width (&fx.spec.u.v.f, fx.v[i]))
+          return false;
     }
 
   fx.spec.type = PRT_VAR;
   for (i = 0; i < fx.nv; i++)
     {
-      fx.spec.fc = fx.fc + dividend * i;
+      fx.spec.fc = fx.fc + individual_var_width * i;
       fx.spec.u.v.v = fx.v[i];
       append_var_spec (&fx.spec);
     }
@@ -688,15 +694,10 @@ dump_fmt_list (struct fmt_list * f)
              }
 
            v = fx.v[fx.cv++];
-           if ((v->type == ALPHA) ^ (formats[f->f.type].cat & FCAT_STRING))
-             {
-               msg (SE, _("Display format %s may not be used with a "
-                          "%s variable."), fmt_to_string (&f->f),
-                    v->type == ALPHA ? _("string") : _("numeric"));
-               return 0;
-             }
-           if (!check_string_specifier (&f->f, v->width))
-             return 0;
+            if (!check_output_specifier (&f->f, true)
+                || !check_specifier_type (&f->f, v->type, true)
+                || !check_string_width (&f->f, v))
+              return false;
 
            fx.spec.type = PRT_VAR;
            fx.spec.u.v.v = v;
@@ -727,9 +728,9 @@ fixed_parse_fortran (void)
       else
        head = fl = xmalloc (sizeof *fl);
 
-      if (token == T_NUM)
+      if (lex_is_number ())
        {
-         if (!lex_integer_p ())
+         if (!lex_is_integer ())
            goto fail;
          fl->count = lex_integer ();
          lex_get ();