/[pspp]/pspp/src/format.c
ViewVC logotype

Diff of /pspp/src/format.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.8 by blp, Tue Mar 1 08:16:15 2005 UTC revision 1.9 by blp, Sat Mar 12 01:08:33 2005 UTC
# Line 26  Line 26 
26  #include "lexer.h"  #include "lexer.h"
27  #include "misc.h"  #include "misc.h"
28  #include "str.h"  #include "str.h"
29    #include "var.h"
30    
31  #define DEFFMT(LABEL, NAME, N_ARGS, IMIN_W, IMAX_W, OMIN_W, OMAX_W, CAT, \  #define DEFFMT(LABEL, NAME, N_ARGS, IMIN_W, IMAX_W, OMIN_W, OMAX_W, CAT, \
32                 OUTPUT, SPSS_FMT) \                 OUTPUT, SPSS_FMT) \
# Line 111  fmt_to_string (const struct fmt_spec *f) Line 112  fmt_to_string (const struct fmt_spec *f)
112    return buf;    return buf;
113  }  }
114    
115    /* Does checks in common betwen check_input_specifier() and
116       check_output_specifier() and returns true if so.  Otherwise,
117       emits an error message (if EMIT_ERROR is nonzero) and returns
118       false. */
119    static bool
120    check_common_specifier (const struct fmt_spec *spec, bool emit_error)
121    {
122      struct fmt_desc *f = &formats[spec->type];
123      char *str = fmt_to_string (spec);
124    
125      if ((f->cat & FCAT_EVEN_WIDTH) && spec->w % 2)
126        {
127          if (emit_error)
128            msg (SE, _("Format %s specifies an odd width %d, but "
129                       "format %s requires an even width."),
130                 str, spec->w, f->name, f->Imin_w, f->Imax_w);
131          return false;
132        }
133      if (f->n_args > 1 && (spec->d < 0 || spec->d > 16))
134        {
135          if (emit_error)
136            msg (SE, _("Format %s specifies a bad number of "
137                       "implied decimal places %d.  Input format %s allows "
138                       "up to 16 implied decimal places."), str, spec->d, f->name);
139          return false;
140        }
141      return true;
142    }
143    
144  /* Checks whether SPEC is valid as an input format and returns  /* Checks whether SPEC is valid as an input format and returns
145     nonzero if so.  Otherwise, emits an error message (if     nonzero if so.  Otherwise, emits an error message (if
146     EMIT_ERROR is nonzero) and returns zero. */     EMIT_ERROR is nonzero) and returns zero. */
147  int  int
148  check_input_specifier (const struct fmt_spec *spec, int emit_error)  check_input_specifier (const struct fmt_spec *spec, int emit_error)
149  {  {
150    struct fmt_desc *f;    struct fmt_desc *f = &formats[spec->type];
151    char *str;    char *str = fmt_to_string (spec);
152    
153    f = &formats[spec->type];    if (!check_common_specifier (spec, emit_error))
154    str = fmt_to_string (spec);      return false;
155    if (spec->type == FMT_X)    if (spec->type == FMT_X)
156      return 1;      return 1;
157    if (f->cat & FCAT_OUTPUT_ONLY)    if (f->cat & FCAT_OUTPUT_ONLY)
# Line 138  check_input_specifier (const struct fmt_ Line 168  check_input_specifier (const struct fmt_
168               str, spec->w, f->name, f->Imin_w, f->Imax_w);               str, spec->w, f->name, f->Imin_w, f->Imax_w);
169        return 0;        return 0;
170      }      }
   if ((f->cat & FCAT_EVEN_WIDTH) && spec->w % 2)  
     {  
       if (emit_error)  
         msg (SE, _("Input format %s specifies an odd width %d, but "  
                    "format %s requires an even width between %d and "  
                    "%d."), str, spec->w, f->name, f->Imin_w, f->Imax_w);  
       return 0;  
     }  
   if (f->n_args > 1 && (spec->d < 0 || spec->d > 16))  
     {  
       if (emit_error)  
         msg (SE, _("Input format %s specifies a bad number of "  
                    "implied decimal places %d.  Input format %s allows "  
                    "up to 16 implied decimal places."), str, spec->d, f->name);  
       return 0;  
     }  
171    return 1;    return 1;
172  }  }
173    
# Line 163  check_input_specifier (const struct fmt_ Line 177  check_input_specifier (const struct fmt_
177  int  int
178  check_output_specifier (const struct fmt_spec *spec, int emit_error)  check_output_specifier (const struct fmt_spec *spec, int emit_error)
179  {  {
180    struct fmt_desc *f;    struct fmt_desc *f = &formats[spec->type];
181    char *str;    char *str = fmt_to_string (spec);
182    
183    f = &formats[spec->type];    if (!check_common_specifier (spec, emit_error))
184    str = fmt_to_string (spec);      return false;
185    if (spec->type == FMT_X)    if (spec->type == FMT_X)
186      return 1;      return 1;
187    if (spec->w < f->Omin_w || spec->w > f->Omax_w)    if (spec->w < f->Omin_w || spec->w > f->Omax_w)
# Line 190  check_output_specifier (const struct fmt Line 204  check_output_specifier (const struct fmt
204               f->Omin_w + 1 + spec->d, spec->d, str);               f->Omin_w + 1 + spec->d, spec->d, str);
205        return 0;        return 0;
206      }      }
207    if ((f->cat & FCAT_EVEN_WIDTH) && spec->w % 2)    return 1;
208      {  }
209        if (emit_error)  
210          msg (SE, _("Output format %s specifies an odd width %d, but "  /* Checks that FORMAT is appropriate for a variable of the given
211                     "output format %s requires an even width between %d and "     TYPE and returns true if so.  Otherwise returns false and (if
212                     "%d."), str, spec->w, f->name, f->Omin_w, f->Omax_w);     EMIT_ERROR is true) emits an error message. */
213        return 0;  bool
214      }  check_specifier_type (const struct fmt_spec *format,
215    if (f->n_args > 1 && (spec->d < 0 || spec->d > 16))                        int type, bool emit_error)
216    {
217      const struct fmt_desc *f = &formats[format->type];
218      assert (type == NUMERIC || type == ALPHA);
219      if ((type == ALPHA) != ((f->cat & FCAT_STRING) != 0))
220      {      {
221        if (emit_error)        if (emit_error)
222          msg (SE, _("Output format %s specifies a bad number of "          msg (SE, _("%s variables are not compatible with %s format %s."),
223                     "implied decimal places %d.  Output format %s allows "               type == ALPHA ? _("String") : _("Numeric"),
224                     "a number of implied decimal places between 1 "               type == ALPHA ? _("numeric") : _("string"),
225                     "and 16."), str, spec->d, f->name);               fmt_to_string (format));
226        return 0;        return false;
227      }      }
228    return 1;    return true;
229  }  }
230      
231  /* If a string variable has width W, you can't display it with a  /* Checks that FORMAT is appropriate for a variable of the given
232     format specifier with a required width MIN_LEN>W. */     WIDTH and returns true if so.  Otherwise returns false and (if
233  int     EMIT_ERROR is true) emits an error message. */
234  check_string_specifier (const struct fmt_spec *f, int min_len)  bool
235    check_specifier_width (const struct fmt_spec *format,
236                           int width, bool emit_error)
237  {  {
238    if ((f->type == FMT_A && min_len > f->w)    if (!check_specifier_type (format, width != 0 ? ALPHA : NUMERIC, emit_error))
239        || (f->type == FMT_AHEX && min_len * 2 > f->w))      return false;
240      if (get_format_var_width (format) != width)
241      {      {
242        msg (SE, _("Can't display a string variable of width %d with "        if (emit_error)
243                   "format specifier %s."), min_len, fmt_to_string (f));          msg (SE, _("String variable with width %d not compatible with "
244        return 0;                     "format %s."),
245                 width, fmt_to_string (format));
246          return false;
247      }      }
248    return 1;    return true;
249  }  }
250    
251  /* Converts input format specifier INPUT into output format  /* Converts input format specifier INPUT into output format
# Line 387  int Line 410  int
410  get_format_var_width (const struct fmt_spec *spec)  get_format_var_width (const struct fmt_spec *spec)
411  {  {
412    if (spec->type == FMT_AHEX)    if (spec->type == FMT_AHEX)
413      return spec->w * 2;      return spec->w / 2;
414    else if (spec->type == FMT_A)    else if (spec->type == FMT_A)
415      return spec->w;      return spec->w;
416    else    else

Legend:
Removed from v.1.8  
changed lines
  Added in v.1.9

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26