Fix rest of PR 13054.
authorBen Pfaff <blp@gnu.org>
Tue, 17 May 2005 05:46:39 +0000 (05:46 +0000)
committerBen Pfaff <blp@gnu.org>
Tue, 17 May 2005 05:46:39 +0000 (05:46 +0000)
13 files changed:
src/ChangeLog
src/aggregate.c
src/data-list.c
src/data-out.c
src/dictionary.c
src/format.c
src/format.def
src/format.h
src/get.c
src/list.q
src/matrix-data.c
src/sfm-read.c
src/tab.c

index 9039838edb3287d4bd821aaddea9dc73feaae287..c111507a4fe43d6c06970cbb0a092ec2528a1519 100644 (file)
@@ -1,6 +1,36 @@
-Sun May 15 23:38:10 2005  Ben Pfaff  <blp@gnu.org>
+Mon May 16 22:34:06 2005  Ben Pfaff  <blp@gnu.org>
 
        Fix rest of PR 13054.
+
+       * format.def: Fix EDATE, SDATE, ADATE, JDATE, QYR, MOYR, WKYR,
+       DATETIME, TIME system/portable file values.
+
+Mon May 16 22:31:15 2005  Ben Pfaff  <blp@gnu.org>
+
+       * data-list.c: (parse_free) Use make_input_format().
+       
+       * data-out.c: (num_to_string) Use make_output_format().
+
+       * dictionary.c: (dict_create_var) Ditto.
+
+       * format.c: (global var f8_2) New var.
+       (make_input_format) New function.
+       (make_output_format) New function.
+
+       * get.c: (cmd_match_files) Use make_output_format().
+
+       * list.q: (cmd_list) Ditto.
+
+       * matrix-data.c: Ditto.
+
+       * sfm-read.c: (parse_format_spec) Check output specifier
+       thoroughly.
+
+       * tab.c: (tab_float) Use make_output_format().
+
+Sun May 15 23:38:10 2005  Ben Pfaff  <blp@gnu.org>
+
+       Fix more of PR 13054.
        
        * format.def: FMT_A should allow 255-character output.  FMT_AHEX
        should allow 510-character input and output.
index 7f34309c5354da7cdcc31f4c1d7ccb12ecead7a5..47c60f344c53fbbd660d28903695c2f2170dfad2 100644 (file)
@@ -522,7 +522,6 @@ parse_aggregate_functions (struct agr_proc *agr)
          /* Create the target variable in the aggregate
              dictionary. */
          {
-            static const struct fmt_spec f8_2 = {FMT_F, 8, 2};
            struct variable *destvar;
            
            v->function = func_index;
index a6a68dc687942f5964afada2b132a3dd42d94c15..66fab631ea23032a0e52d87d4724869236475edb 100644 (file)
@@ -848,10 +848,8 @@ parse_free (struct dls_var_spec **first, struct dls_var_spec **last)
       else
        {
          lex_match ('*');
-         input.type = FMT_F;
-         input.w = 8;
-         input.d = 0;
-         output = get_format();
+          input = make_input_format (FMT_F, 8, 0);
+         output = get_format ();
        }
 
       if (input.type == FMT_A || input.type == FMT_AHEX)
index 6439b607045f18e5566deec8a438b9197f88d03e..5fce84f6c433b1075db40d5af774ec98eaedfca0 100644 (file)
@@ -193,10 +193,7 @@ data_out (char *s, const struct fmt_spec *fp, const union value *v)
 void
 num_to_string (double v, char *s, int w, int d)
 {
-  struct fmt_spec f;
-  f.type = FMT_F;
-  f.w = w;
-  f.d = d;
+  struct fmt_spec f = make_output_format (FMT_F, w, d);
   convert_F (s, &f, v);
 }
 \f
index 0fd59e1172113cd1f8754b82c3b08a48d5072943..6fbd5dfa575783efe2447225682fc6cbe1c055c6 100644 (file)
@@ -279,20 +279,14 @@ dict_create_var (struct dictionary *d, const char *name, int width)
   v->miss_type = MISSING_NONE;
   if (v->type == NUMERIC)
     {
-      v->print.type = FMT_F;
-      v->print.w = 8;
-      v->print.d = 2;
-
+      v->print = f8_2;
       v->alignment = ALIGN_RIGHT;
       v->display_width = 8;
       v->measure = MEASURE_SCALE;
     }
   else
     {
-      v->print.type = FMT_A;
-      v->print.w = v->width;
-      v->print.d = 0;
-
+      v->print = make_output_format (FMT_A, v->width, 0);
       v->alignment = ALIGN_LEFT;
       v->display_width = 8;
       v->measure = MEASURE_NOMINAL;
index 87be7b08430bfffddbc6ddbbcdd537927604fdfe..5e06ab2291e43ff4f40efcaeb2fbae4bcfe2a569 100644 (file)
@@ -37,6 +37,9 @@ struct fmt_desc formats[FMT_NUMBER_OF_FORMATS + 1] =
   {"",         -1, -1,  -1, -1,   -1, 0000, -1, -1},
 };
 
+/* Common formats. */
+const struct fmt_spec f8_2 = {FMT_F, 8, 2};
+
 /* Parses the alphabetic prefix of the current token as a format
    specifier name.  Returns the corresponding format specifier
    type if successful, or -1 on failure.  If ALLOW_XT is zero,
@@ -442,3 +445,29 @@ translate_fmt (int spss)
       return type;
   return -1;
 }
+
+/* Returns an input format specification with type TYPE, width W,
+   and D decimals. */
+struct fmt_spec
+make_input_format (int type, int w, int d) 
+{
+  struct fmt_spec f;
+  f.type = type;
+  f.w = w;
+  f.d = d;
+  assert (check_input_specifier (&f, 0));
+  return f;
+}
+
+/* Returns an output format specification with type TYPE, width
+   W, and D decimals. */
+struct fmt_spec
+make_output_format (int type, int w, int d)
+{
+  struct fmt_spec f;
+  f.type = type;
+  f.w = w;
+  f.d = d;
+  assert (check_output_specifier (&f, 0));
+  return f;
+}
index e6f1725ba9d4168adeea8f6c4375991d61936862..0dfc21c08bd386efffb5c1551ddaec4c10418c92 100644 (file)
@@ -45,15 +45,15 @@ DEFFMT (FMT_CCE,      "CCE",       2, -1,  -1,  1,   40, 0020, FMT_CCE, 37)
                                                                     
 /* Date/time formats. */                                            
 DEFFMT (FMT_DATE,        "DATE",      1,  9,  40,  9,   40, 0001, FMT_DATE, 20)
-DEFFMT (FMT_EDATE,       "EDATE",     1,  8,  40,  8,   40, 0001, FMT_EDATE, 23)
-DEFFMT (FMT_SDATE,       "SDATE",     1,  8,  40,  8,   40, 0001, FMT_SDATE, 24)
-DEFFMT (FMT_ADATE,       "ADATE",     1,  8,  40,  8,   40, 0001, FMT_ADATE, 29)
-DEFFMT (FMT_JDATE,       "JDATE",     1,  5,  40,  5,   40, 0001, FMT_JDATE, 28)
-DEFFMT (FMT_QYR,         "QYR",       1,  4,  40,  6,   40, 0001, FMT_QYR, 30)
-DEFFMT (FMT_MOYR,        "MOYR",      1,  6,  40,  6,   40, 0001, FMT_MOYR, 22)
-DEFFMT (FMT_WKYR,        "WKYR",      1,  6,  40,  8,   40, 0001, FMT_WKYR, 21)
-DEFFMT (FMT_DATETIME,    "DATETIME",  2, 17,  40, 17,   40, 0001, FMT_DATETIME, 38)
-DEFFMT (FMT_TIME,        "TIME",      2,  5,  40,  5,   40, 0001, FMT_TIME, 39)
+DEFFMT (FMT_EDATE,       "EDATE",     1,  8,  40,  8,   40, 0001, FMT_EDATE, 38)
+DEFFMT (FMT_SDATE,       "SDATE",     1,  8,  40,  8,   40, 0001, FMT_SDATE, 39)
+DEFFMT (FMT_ADATE,       "ADATE",     1,  8,  40,  8,   40, 0001, FMT_ADATE, 23)
+DEFFMT (FMT_JDATE,       "JDATE",     1,  5,  40,  5,   40, 0001, FMT_JDATE, 24)
+DEFFMT (FMT_QYR,         "QYR",       1,  4,  40,  6,   40, 0001, FMT_QYR, 29)
+DEFFMT (FMT_MOYR,        "MOYR",      1,  6,  40,  6,   40, 0001, FMT_MOYR, 28)
+DEFFMT (FMT_WKYR,        "WKYR",      1,  6,  40,  8,   40, 0001, FMT_WKYR, 30)
+DEFFMT (FMT_DATETIME,    "DATETIME",  2, 17,  40, 17,   40, 0001, FMT_DATETIME, 22)
+DEFFMT (FMT_TIME,        "TIME",      2,  5,  40,  5,   40, 0001, FMT_TIME, 21)
 DEFFMT (FMT_DTIME,       "DTIME",     2, 11,  40,  8,   40, 0001, FMT_DTIME, 25)
 DEFFMT (FMT_WKDAY,       "WKDAY",     1,  2,  40,  2,   40, 0001, FMT_WKDAY, 26)
 DEFFMT (FMT_MONTH,       "MONTH",     1,  3,  40,  3,   40, 0001, FMT_MONTH, 27)
index f1a11a1fa8ffc8ef3d2e06579ddec693f8fde006..da33f5f3abf323a973628c3297256b9ff068c45f 100644 (file)
@@ -104,6 +104,9 @@ enum fmt_parse_flags
     FMTP_SUPPRESS_ERRORS = 002          /* 1=Do not emit error messages. */
   };
 
+/* Common formats. */
+extern const struct fmt_spec f8_2;      /* F8.2. */
+
 int parse_format_specifier (struct fmt_spec *input, enum fmt_parse_flags);
 int parse_format_specifier_name (const char **cp, enum fmt_parse_flags);
 int check_input_specifier (const struct fmt_spec *spec, int emit_error);
@@ -119,5 +122,7 @@ int translate_fmt (int spss);
 void data_out (char *s, const struct fmt_spec *fp, const union value *v);
 char *fmt_to_string (const struct fmt_spec *);
 void num_to_string (double v, char *s, int w, int d);
+struct fmt_spec make_input_format (int type, int w, int d);
+struct fmt_spec make_output_format (int type, int w, int d);
 
 #endif /* !format_h */
index 5ec84482d05c792d5588ea9e19b0453102bb74cd..3300ae6457d717c6b3d14eabd0753d676b9f6b1c 100644 (file)
--- a/src/get.c
+++ b/src/get.c
@@ -977,8 +977,6 @@ cmd_match_files (void)
   for (iter = mtf.head; iter != NULL; iter = iter->next) 
     if (iter->in_name != NULL)
       {
-        static const struct fmt_spec f1_0 = {FMT_F, 1, 0};
-        
         iter->in_var = dict_create_var (mtf.dict, iter->in_name, 0);
         if (iter->in_var == NULL)
           {
@@ -987,7 +985,8 @@ cmd_match_files (void)
                  iter->in_var);
             goto error;
           }
-        iter->in_var->print = iter->in_var->write = f1_0;
+        iter->in_var->print = iter->in_var->write
+          = make_output_format (FMT_F, 1, 0);
       }
     
   /* MATCH FILES performs an n-way merge on all its input files.
index 3add8de152e8bd9ef05744ab26020eb3df15e107..97f5372d02584e96bdcf77867ce470e45c7f592a 100644 (file)
@@ -204,9 +204,9 @@ 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++;
index 776dfa5b1c5908bfe21d8fd21583e83f23d01039..d3cde3e68a9896076afa9b1b9b3c8c1271c0553a 100644 (file)
@@ -884,9 +884,7 @@ static int
          di.e = token->string + token->length;
          di.v = (union value *) &token->number;
          di.f1 = first_column;
-         di.format.type = FMT_F;
-         di.format.w = token->length;
-         di.format.d = 0;
+         di.format = make_output_format (FMT_F, token->length, 0);
 
          if (!data_in (&di))
            return 0;
index 23abde90ff1e57c0e14a04d11a5fdbc72a47e463..c036739b596bccc469afe24b3385254d2618c24c 100644 (file)
@@ -974,27 +974,32 @@ error:
 /* Translates the format spec from sysfile format to internal
    format. */
 static int
-parse_format_spec (struct sfm_reader *r, int32 s, struct fmt_spec *v, struct variable *vv)
+parse_format_spec (struct sfm_reader *r, int32 s,
+                   struct fmt_spec *f, struct variable *v)
 {
-  v->type = translate_fmt ((s >> 16) & 0xff);
-  if (v->type == -1)
+  f->type = translate_fmt ((s >> 16) & 0xff);
+  if (f->type == -1)
     lose ((ME, _("%s: Bad format specifier byte (%d)."),
           handle_get_filename (r->fh), (s >> 16) & 0xff));
-  v->w = (s >> 8) & 0xff;
-  v->d = s & 0xff;
+  f->w = (s >> 8) & 0xff;
+  f->d = s & 0xff;
 
-  /* FIXME?  Should verify the resulting specifier more thoroughly. */
-
-  if (v->type == -1)
-    lose ((ME, _("%s: Bad format specifier byte (%d)."),
-          handle_get_filename (r->fh), (s >> 16) & 0xff));
-  if ((vv->type == ALPHA) ^ ((formats[v->type].cat & FCAT_STRING) != 0))
+  if ((v->type == ALPHA) ^ ((formats[f->type].cat & FCAT_STRING) != 0))
     lose ((ME, _("%s: %s variable %s has %s format specifier %s."),
           handle_get_filename (r->fh),
-           vv->type == ALPHA ? _("String") : _("Numeric"),
-          vv->name,
-          formats[v->type].cat & FCAT_STRING ? _("string") : _("numeric"),
-          formats[v->type].name));
+           v->type == ALPHA ? _("String") : _("Numeric"),
+          v->name,
+          formats[f->type].cat & FCAT_STRING ? _("string") : _("numeric"),
+          formats[f->type].name));
+
+  if (!check_output_specifier (f, false)
+      || !check_specifier_width (f, v->width, false)) 
+    {
+      msg (ME, _("%s variable %s has invalid format specifier %s."),
+           v->type == NUMERIC ? _("Numeric") : _("String"),
+           v->name, fmt_to_string (f));
+      *f = v->type == NUMERIC ? f8_2 : make_output_format (FMT_A, v->width, 0);
+    }
   return 1;
 
 error:
index 6005ec9cc72f16eee02b9ceaa02ce185effef118..9f6a9c3554b1512fa7aa4860c1313d061996ff87 100644 (file)
--- a/src/tab.c
+++ b/src/tab.c
@@ -607,9 +607,7 @@ tab_float (struct tab_table *table, int c, int r, unsigned char opt,
   assert (r >= 0);
   assert (r < table->nr);
 
-  f.type = FMT_F;
-  f.w = w;
-  f.d = d;
+  f = make_output_format (FMT_F, w, d);
   
 #if GLOBAL_DEBUGGING
   if (c + table->col_ofs < 0 || r + table->row_ofs < 0