checkin of 0.3.0
[pspp-builds.git] / src / formats.c
1 /* PSPP - computes sample statistics.
2    Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
3    Written by Ben Pfaff <blp@gnu.org>.
4
5    This program is free software; you can redistribute it and/or
6    modify it under the terms of the GNU General Public License as
7    published by the Free Software Foundation; either version 2 of the
8    License, or (at your option) any later version.
9
10    This program is distributed in the hope that it will be useful, but
11    WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    General Public License for more details.
14
15    You should have received a copy of the GNU General Public License
16    along with this program; if not, write to the Free Software
17    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
18    02111-1307, USA. */
19
20 #include <config.h>
21 #include <limits.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include "command.h"
25 #include "error.h"
26 #include "lexer.h"
27 #include "misc.h"
28 #include "str.h"
29 #include "var.h"
30
31 #undef DEBUGGING
32 /*#define DEBUGGING 1*/
33 #include "debug-print.h"
34
35 #if DEBUGGING
36 static void debug_print (void);
37 #endif
38
39 enum
40   {
41     FORMATS_PRINT = 001,
42     FORMATS_WRITE = 002
43   };
44
45 static int internal_cmd_formats (int);
46
47 int
48 cmd_print_formats (void)
49 {
50   lex_match_id ("FORMATS");
51   return internal_cmd_formats (FORMATS_PRINT);
52 }
53
54 int
55 cmd_write_formats (void)
56 {
57   lex_match_id ("FORMATS");
58   return internal_cmd_formats (FORMATS_WRITE);
59 }
60
61 int
62 cmd_formats (void)
63 {
64   lex_match_id ("FORMATS");
65   return internal_cmd_formats (FORMATS_PRINT | FORMATS_WRITE);
66 }
67
68 int
69 internal_cmd_formats (int which)
70 {
71   /* Variables. */
72   struct variable **v;
73   int cv;
74
75   /* Format to set the variables to. */
76   struct fmt_spec f;
77
78   /* Numeric or string. */
79   int type;
80
81   /* Counter. */
82   int i;
83
84   for (;;)
85     {
86       if (token == '.')
87         break;
88
89       if (!parse_variables (NULL, &v, &cv, PV_SAME_TYPE))
90         return CMD_PART_SUCCESS_MAYBE;
91       type = v[0]->type;
92
93       if (!lex_match ('('))
94         {
95           msg (SE, _("`(' expected after variable list"));
96           goto fail;
97         }
98       if (!parse_format_specifier (&f, 0) || !check_output_specifier (&f))
99         goto fail;
100
101       /* Catch type mismatch errors. */
102       if ((type == ALPHA) ^ (0 != (formats[f.type].cat & FCAT_STRING)))
103         {
104           msg (SE, _("Format %s may not be assigned to a %s variable."),
105                fmt_to_string (&f), type == NUMERIC ? _("numeric") : _("string"));
106           goto fail;
107         }
108
109       /* This is an additional check for string variables.  We can't
110          let the user specify an A8 format for a string variable with
111          width 4. */
112       if (type == ALPHA)
113         {
114           /* Shortest string so far. */
115           int min_len = INT_MAX;
116
117           for (i = 0; i < cv; i++)
118             min_len = min (min_len, v[i]->width);
119           if (!check_string_specifier (&f, min_len))
120             goto fail;
121         }
122
123       if (!lex_match (')'))
124         {
125           msg (SE, _("`)' expected after output format."));
126           goto fail;
127         }
128
129       for (i = 0; i < cv; i++)
130         {
131           if (which & FORMATS_PRINT)
132             v[i]->print = f;
133           if (which & FORMATS_WRITE)
134             v[i]->write = f;
135         }
136       free (v);
137       v = NULL;
138     }
139 #if DEBUGGING
140   debug_print ();
141 #endif
142   return CMD_SUCCESS;
143
144 fail:
145   free (v);
146   return CMD_PART_SUCCESS_MAYBE;
147 }
148
149 #if DEBUGGING
150 static void
151 debug_print (void)
152 {
153   int i;
154
155   printf (_("Formats:\n"));
156   printf (_("  Name      Print         Write\n"));
157   printf ("  --------  ------------  ------------\n");
158   for (i = 0; i < default_dict.nvar; i++)
159     {
160       struct variable *v = default_dict.var[i];
161       printf ("  %-8s  %-12s", v->name, fmt_to_string (&v->print));
162       printf ("  %-12s\n", fmt_to_string (&v->write));
163     }
164 }
165 #endif /* DEBUGGING */