Adopt use of gnulib for portability.
[pspp-builds.git] / src / vars-atr.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., 51 Franklin Street, Fifth Floor, Boston, MA
18    02110-1301, USA. */
19
20 #include <config.h>
21 #include "var.h"
22 #include "error.h"
23 #include <stdlib.h>
24 #include "alloc.h"
25 #include "command.h"
26 #include "dictionary.h"
27 #include "do-ifP.h"
28 #include "expressions/public.h"
29 #include "file-handle.h"
30 #include "hash.h"
31 #include "lexer.h"
32 #include "misc.h"
33 #include "str.h"
34 #include "value-labels.h"
35 #include "vfm.h"
36
37 #include "gettext.h"
38 #define _(msgid) gettext (msgid)
39
40 #include "debug-print.h"
41
42 /* Assign auxiliary data AUX to variable V, which must not
43    already have auxiliary data.  Before V's auxiliary data is
44    cleared, AUX_DTOR(V) will be called. */
45 void *
46 var_attach_aux (struct variable *v,
47                 void *aux, void (*aux_dtor) (struct variable *)) 
48 {
49   assert (v->aux == NULL);
50   assert (aux != NULL);
51   v->aux = aux;
52   v->aux_dtor = aux_dtor;
53   return aux;
54 }
55
56 /* Remove auxiliary data, if any, from V, and returns it, without
57    calling any associated destructor. */
58 void *
59 var_detach_aux (struct variable *v) 
60 {
61   void *aux = v->aux;
62   assert (aux != NULL);
63   v->aux = NULL;
64   return aux;
65 }
66
67 /* Clears auxiliary data, if any, from V, and calls any
68    associated destructor. */
69 void
70 var_clear_aux (struct variable *v) 
71 {
72   assert (v != NULL);
73   if (v->aux != NULL) 
74     {
75       if (v->aux_dtor != NULL)
76         v->aux_dtor (v);
77       v->aux = NULL;
78     }
79 }
80
81 /* This function is appropriate for use an auxiliary data
82    destructor (passed as AUX_DTOR to var_attach_aux()) for the
83    case where the auxiliary data should be passed to free(). */
84 void
85 var_dtor_free (struct variable *v) 
86 {
87   free (v->aux);
88 }
89
90 /* Compares A and B, which both have the given WIDTH, and returns
91    a strcmp()-type result. */
92 int
93 compare_values (const union value *a, const union value *b, int width) 
94 {
95   if (width == 0) 
96     return a->f < b->f ? -1 : a->f > b->f;
97   else
98     return memcmp (a->s, b->s, min(MAX_SHORT_STRING, width));
99 }
100
101 /* Create a hash of v */
102 unsigned 
103 hash_value(const union value  *v, int width)
104 {
105   unsigned id_hash;
106
107   if ( 0 == width ) 
108     id_hash = hsh_hash_double (v->f);
109   else
110     id_hash = hsh_hash_bytes (v->s, min(MAX_SHORT_STRING, width));
111
112   return id_hash;
113 }
114
115
116
117 /* Discards all the current state in preparation for a data-input
118    command like DATA LIST or GET. */
119 void
120 discard_variables (void)
121 {
122   dict_clear (default_dict);
123   default_handle = NULL;
124
125   n_lag = 0;
126   
127   if (vfm_source != NULL)
128     {
129       free_case_source (vfm_source);
130       vfm_source = NULL;
131     }
132
133   cancel_transformations ();
134
135   ctl_stack = NULL;
136
137   expr_free (process_if_expr);
138   process_if_expr = NULL;
139
140   cancel_temporary ();
141
142   pgm_state = STATE_INIT;
143 }
144
145 /* Return nonzero only if X is a user-missing value for numeric
146    variable V. */
147 inline int
148 is_num_user_missing (double x, const struct variable *v)
149 {
150   switch (v->miss_type)
151     {
152     case MISSING_NONE:
153       return 0;
154     case MISSING_1:
155       return x == v->missing[0].f;
156     case MISSING_2:
157       return x == v->missing[0].f || x == v->missing[1].f;
158     case MISSING_3:
159       return (x == v->missing[0].f || x == v->missing[1].f
160               || x == v->missing[2].f);
161     case MISSING_RANGE:
162       return x >= v->missing[0].f && x <= v->missing[1].f;
163     case MISSING_LOW:
164       return x <= v->missing[0].f;
165     case MISSING_HIGH:
166       return x >= v->missing[0].f;
167     case MISSING_RANGE_1:
168       return ((x >= v->missing[0].f && x <= v->missing[1].f)
169               || x == v->missing[2].f);
170     case MISSING_LOW_1:
171       return x <= v->missing[0].f || x == v->missing[1].f;
172     case MISSING_HIGH_1:
173       return x >= v->missing[0].f || x == v->missing[1].f;
174     default:
175       assert (0);
176     }
177   abort ();
178 }
179
180 /* Return nonzero only if string S is a user-missing variable for
181    string variable V. */
182 inline int
183 is_str_user_missing (const unsigned char s[], const struct variable *v)
184 {
185   /* FIXME: should these be memcmp()? */
186   switch (v->miss_type)
187     {
188     case MISSING_NONE:
189       return 0;
190     case MISSING_1:
191       return !strncmp (s, v->missing[0].s, v->width);
192     case MISSING_2:
193       return (!strncmp (s, v->missing[0].s, v->width)
194               || !strncmp (s, v->missing[1].s, v->width));
195     case MISSING_3:
196       return (!strncmp (s, v->missing[0].s, v->width)
197               || !strncmp (s, v->missing[1].s, v->width)
198               || !strncmp (s, v->missing[2].s, v->width));
199     default:
200       assert (0);
201     }
202   abort ();
203 }
204
205 /* Return nonzero only if value VAL is system-missing for variable
206    V. */
207 int
208 is_system_missing (const union value *val, const struct variable *v)
209 {
210   return v->type == NUMERIC && val->f == SYSMIS;
211 }
212
213 /* Return nonzero only if value VAL is system- or user-missing for
214    variable V. */
215 int
216 is_missing (const union value *val, const struct variable *v)
217 {
218   switch (v->type)
219     {
220     case NUMERIC:
221       if (val->f == SYSMIS)
222         return 1;
223       return is_num_user_missing (val->f, v);
224     case ALPHA:
225       return is_str_user_missing (val->s, v);
226     default:
227       assert (0);
228     }
229   abort ();
230 }
231
232 /* Return nonzero only if value VAL is user-missing for variable V. */
233 int
234 is_user_missing (const union value *val, const struct variable *v)
235 {
236   switch (v->type)
237     {
238     case NUMERIC:
239       return is_num_user_missing (val->f, v);
240     case ALPHA:
241       return is_str_user_missing (val->s, v);
242     default:
243       assert (0);
244     }
245   abort ();
246 }
247 \f
248 /* Returns true if NAME is an acceptable name for a variable,
249    false otherwise.  If ISSUE_ERROR is true, issues an
250    explanatory error message on failure. */
251 bool
252 var_is_valid_name (const char *name, bool issue_error) 
253 {
254   size_t length, i;
255   
256   assert (name != NULL);
257
258   length = strlen (name);
259   if (length < 1) 
260     {
261       if (issue_error)
262         msg (SE, _("Variable name cannot be empty string."));
263       return false;
264     }
265   else if (length > LONG_NAME_LEN) 
266     {
267       if (issue_error)
268         msg (SE, _("Variable name %s exceeds %d-character limit."),
269              name, (int) LONG_NAME_LEN);
270       return false;
271     }
272
273   for (i = 0; i < length; i++)
274     if (!CHAR_IS_IDN (name[i])) 
275       {
276         if (issue_error)
277           msg (SE, _("Character `%c' (in %s) may not appear in "
278                      "a variable name."),
279                name[i], name);
280         return false;
281       }
282         
283   if (!CHAR_IS_ID1 (name[0]))
284     {
285       if (issue_error)
286         msg (SE, _("Character `%c' (in %s), may not appear "
287                    "as the first character in a variable name."),
288              name[0], name);
289       return false;
290     }
291
292   if (lex_id_to_token (name, strlen (name)) != T_ID) 
293     {
294       if (issue_error)
295         msg (SE, _("%s may not be used as a variable name because it "
296                    "is a reserved word."), name);
297       return false;
298     }
299
300   return true;
301 }
302
303 /* A hsh_compare_func that orders variables A and B by their
304    names. */
305 int
306 compare_var_names (const void *a_, const void *b_, void *foo UNUSED) 
307 {
308   const struct variable *a = a_;
309   const struct variable *b = b_;
310
311   return strcasecmp (a->name, b->name);
312 }
313
314 /* A hsh_hash_func that hashes variable V based on its name. */
315 unsigned
316 hash_var_name (const void *v_, void *foo UNUSED) 
317 {
318   const struct variable *v = v_;
319
320   return hsh_hash_case_string (v->name);
321 }
322
323 /* A hsh_compare_func that orders pointers to variables A and B
324    by their names. */
325 int
326 compare_var_ptr_names (const void *a_, const void *b_, void *foo UNUSED) 
327 {
328   struct variable *const *a = a_;
329   struct variable *const *b = b_;
330
331   return strcasecmp ((*a)->name, (*b)->name);
332 }
333
334 /* A hsh_hash_func that hashes pointer to variable V based on its
335    name. */
336 unsigned
337 hash_var_ptr_name (const void *v_, void *foo UNUSED) 
338 {
339   struct variable *const *v = v_;
340
341   return hsh_hash_case_string ((*v)->name);
342 }
343 \f
344 /* Sets V's short_name to SHORT_NAME, truncating it to
345    SHORT_NAME_LEN characters and converting it to uppercase in
346    the process. */
347 void
348 var_set_short_name (struct variable *v, const char *short_name) 
349 {
350   assert (v != NULL);
351   assert (short_name[0] == '\0' || var_is_valid_name (short_name, false));
352   
353   str_copy_trunc (v->short_name, sizeof v->short_name, short_name);
354   str_uppercase (v->short_name);
355 }
356
357 /* Clears V's short name. */
358 void
359 var_clear_short_name (struct variable *v) 
360 {
361   assert (v != NULL);
362
363   v->short_name[0] = '\0';
364 }
365
366 /* Sets V's short name to BASE, followed by a suffix of the form
367    _A, _B, _C, ..., _AA, _AB, etc. according to the value of
368    SUFFIX.  Truncates BASE as necessary to fit. */
369 void
370 var_set_short_name_suffix (struct variable *v, const char *base, int suffix)
371 {
372   char string[SHORT_NAME_LEN + 1];
373   char *start, *end;
374   int len, ofs;
375
376   assert (v != NULL);
377   assert (suffix >= 0);
378   assert (strlen (v->short_name) > 0);
379
380   /* Set base name. */
381   var_set_short_name (v, base);
382
383   /* Compose suffix_string. */
384   start = end = string + sizeof string - 1;
385   *end = '\0';
386   do 
387     {
388       *--start = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"[suffix % 26];
389       if (start <= string + 1)
390         msg (SE, _("Variable suffix too large."));
391       suffix /= 26;
392     }
393   while (suffix > 0);
394   *--start = '_';
395
396   /* Append suffix_string to V's short name. */
397   len = end - start;
398   if (len + strlen (v->short_name) > SHORT_NAME_LEN)
399     ofs = SHORT_NAME_LEN - len;
400   else
401     ofs = strlen (v->short_name);
402   strcpy (v->short_name + ofs, start);
403 }