First step in making struct variable opaque: the boring mechanical
[pspp-builds.git] / src / data / variable.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 "variable.h"
22 #include <libpspp/assertion.h>
23 #include <libpspp/message.h>
24 #include <stdlib.h>
25 #include <libpspp/alloc.h>
26 #include <libpspp/compiler.h>
27 #include "dictionary.h"
28 #include <libpspp/hash.h>
29 #include "identifier.h"
30 #include <libpspp/misc.h>
31 #include <libpspp/str.h>
32 #include "value-labels.h"
33
34 #include "minmax.h"
35
36 #include "gettext.h"
37 #define _(msgid) gettext (msgid)
38
39 /* Returns true if VAR_TYPE is a valid variable type. */
40 bool
41 var_type_is_valid (enum var_type var_type) 
42 {
43   return var_type == NUMERIC || var_type == ALPHA;
44 }
45
46 /* Returns an adjective describing the given variable TYPE,
47    suitable for use in phrases like "numeric variable". */
48 const char *
49 var_type_adj (enum var_type type) 
50 {
51   return type == NUMERIC ? _("numeric") : _("string");
52 }
53
54 /* Returns a noun describing a value of the given variable TYPE,
55    suitable for use in phrases like "a number". */
56 const char *
57 var_type_noun (enum var_type type) 
58 {
59   return type == NUMERIC ? _("number") : _("string");
60 }
61 \f
62 /* Returns true if M is a valid variable measurement level,
63    false otherwise. */
64 bool
65 measure_is_valid (enum measure m)
66 {
67   return m == MEASURE_NOMINAL || m == MEASURE_ORDINAL || m == MEASURE_SCALE;
68 }
69
70 /* Returns true if A is a valid alignment,
71    false otherwise. */
72 bool
73 alignment_is_valid (enum alignment a)
74 {
75   return a == ALIGN_LEFT || a == ALIGN_RIGHT || a == ALIGN_CENTRE;
76 }
77 \f
78 /* Assign auxiliary data AUX to variable V, which must not
79    already have auxiliary data.  Before V's auxiliary data is
80    cleared, AUX_DTOR(V) will be called. */
81 void *
82 var_attach_aux (struct variable *v,
83                 void *aux, void (*aux_dtor) (struct variable *)) 
84 {
85   assert (v->aux == NULL);
86   assert (aux != NULL);
87   v->aux = aux;
88   v->aux_dtor = aux_dtor;
89   return aux;
90 }
91
92 /* Remove auxiliary data, if any, from V, and returns it, without
93    calling any associated destructor. */
94 void *
95 var_detach_aux (struct variable *v) 
96 {
97   void *aux = v->aux;
98   assert (aux != NULL);
99   v->aux = NULL;
100   return aux;
101 }
102
103 /* Clears auxiliary data, if any, from V, and calls any
104    associated destructor. */
105 void
106 var_clear_aux (struct variable *v) 
107 {
108   assert (v != NULL);
109   if (v->aux != NULL) 
110     {
111       if (v->aux_dtor != NULL)
112         v->aux_dtor (v);
113       v->aux = NULL;
114     }
115 }
116
117 /* This function is appropriate for use an auxiliary data
118    destructor (passed as AUX_DTOR to var_attach_aux()) for the
119    case where the auxiliary data should be passed to free(). */
120 void
121 var_dtor_free (struct variable *v) 
122 {
123   free (v->aux);
124 }
125
126 /* Compares A and B, which both have the given WIDTH, and returns
127    a strcmp()-type result. */
128 int
129 compare_values (const union value *a, const union value *b, int width) 
130 {
131   if (width == 0) 
132     return a->f < b->f ? -1 : a->f > b->f;
133   else
134     return memcmp (a->s, b->s, MIN(MAX_SHORT_STRING, width));
135 }
136
137 /* Create a hash of v */
138 unsigned 
139 hash_value(const union value  *v, int width)
140 {
141   unsigned id_hash;
142
143   if ( 0 == width ) 
144     id_hash = hsh_hash_double (v->f);
145   else
146     id_hash = hsh_hash_bytes (v->s, MIN(MAX_SHORT_STRING, width));
147
148   return id_hash;
149 }
150 \f
151 /* Return variable V's name. */
152 const char *
153 var_get_name (const struct variable *v) 
154 {
155   return v->name;
156 }
157
158 /* Sets V's name to NAME. */
159 void
160 var_set_name (struct variable *v, const char *name) 
161 {
162   assert (name[0] != '\0');
163   assert (lex_id_to_token (ss_cstr (name)) == T_ID);
164
165   str_copy_trunc (v->name, sizeof v->name, name);
166 }
167
168 /* Returns true if NAME is an acceptable name for a variable,
169    false otherwise.  If ISSUE_ERROR is true, issues an
170    explanatory error message on failure. */
171 bool
172 var_is_valid_name (const char *name, bool issue_error) 
173 {
174   bool plausible;
175   size_t length, i;
176   
177   assert (name != NULL);
178
179   /* Note that strlen returns number of BYTES, not the number of 
180      CHARACTERS */
181   length = strlen (name);
182
183   plausible = var_is_plausible_name(name, issue_error);
184
185   if ( ! plausible ) 
186     return false;
187
188
189   if (!lex_is_id1 (name[0]))
190     {
191       if (issue_error)
192         msg (SE, _("Character `%c' (in %s), may not appear "
193                    "as the first character in a variable name."),
194              name[0], name);
195       return false;
196     }
197
198
199   for (i = 0; i < length; i++)
200     {
201     if (!lex_is_idn (name[i])) 
202       {
203         if (issue_error)
204           msg (SE, _("Character `%c' (in %s) may not appear in "
205                      "a variable name."),
206                name[i], name);
207         return false;
208       }
209     }
210
211   return true;
212 }
213
214 /* 
215    Returns true if NAME is an plausible name for a variable,
216    false otherwise.  If ISSUE_ERROR is true, issues an
217    explanatory error message on failure. 
218    This function makes no use of LC_CTYPE.
219 */
220 bool
221 var_is_plausible_name (const char *name, bool issue_error) 
222 {
223   size_t length;
224   
225   assert (name != NULL);
226
227   /* Note that strlen returns number of BYTES, not the number of 
228      CHARACTERS */
229   length = strlen (name);
230   if (length < 1) 
231     {
232       if (issue_error)
233         msg (SE, _("Variable name cannot be empty string."));
234       return false;
235     }
236   else if (length > LONG_NAME_LEN) 
237     {
238       if (issue_error)
239         msg (SE, _("Variable name %s exceeds %d-character limit."),
240              name, (int) LONG_NAME_LEN);
241       return false;
242     }
243
244   if (lex_id_to_token (ss_cstr (name)) != T_ID) 
245     {
246       if (issue_error)
247         msg (SE, _("`%s' may not be used as a variable name because it "
248                    "is a reserved word."), name);
249       return false;
250     }
251
252   return true;
253 }
254
255 /* A hsh_compare_func that orders variables A and B by their
256    names. */
257 int
258 compare_var_names (const void *a_, const void *b_, const void *aux UNUSED) 
259 {
260   const struct variable *a = a_;
261   const struct variable *b = b_;
262
263   return strcasecmp (var_get_name (a), var_get_name (b));
264 }
265
266 /* A hsh_hash_func that hashes variable V based on its name. */
267 unsigned
268 hash_var_name (const void *v_, const void *aux UNUSED) 
269 {
270   const struct variable *v = v_;
271
272   return hsh_hash_case_string (var_get_name (v));
273 }
274
275 /* A hsh_compare_func that orders pointers to variables A and B
276    by their names. */
277 int
278 compare_var_ptr_names (const void *a_, const void *b_, const void *aux UNUSED) 
279 {
280   struct variable *const *a = a_;
281   struct variable *const *b = b_;
282
283   return strcasecmp (var_get_name (*a), var_get_name (*b));
284 }
285
286 /* A hsh_hash_func that hashes pointer to variable V based on its
287    name. */
288 unsigned
289 hash_var_ptr_name (const void *v_, const void *aux UNUSED) 
290 {
291   struct variable *const *v = v_;
292
293   return hsh_hash_case_string (var_get_name (*v));
294 }
295 \f
296 /* Returns the type of a variable with the given WIDTH. */
297 static enum var_type
298 width_to_type (int width) 
299 {
300   return width == 0 ? NUMERIC : ALPHA;
301 }
302
303 /* Returns the type of variable V. */
304 enum var_type
305 var_get_type (const struct variable *v) 
306 {
307   return width_to_type (v->width);
308 }
309
310 /* Returns the width of variable V. */
311 int
312 var_get_width (const struct variable *v) 
313 {
314   return v->width;
315 }
316
317 /* Sets the width of V to WIDTH. */
318 void
319 var_set_width (struct variable *v, int new_width) 
320 {
321   enum var_type new_type = width_to_type (new_width);
322   
323   if (mv_is_resizable (&v->miss, new_width))
324     mv_resize (&v->miss, new_width);
325   else
326     mv_init (&v->miss, new_width);
327
328   if (v->val_labs != NULL) 
329     {
330       if (val_labs_can_set_width (v->val_labs, new_width))
331         val_labs_set_width (v->val_labs, new_width);
332       else 
333         {
334           val_labs_destroy (v->val_labs);
335           v->val_labs = NULL;
336         }
337     }
338   
339   if (var_get_type (v) != new_type) 
340     {
341       v->print = (new_type == NUMERIC
342                   ? fmt_for_output (FMT_F, 8, 2)
343                   : fmt_for_output (FMT_A, new_width, 0));
344       v->write = v->print;
345     }
346   else if (new_type == ALPHA) 
347     {
348       v->print.w = v->print.type == FMT_AHEX ? new_width * 2 : new_width;
349       v->write.w = v->write.type == FMT_AHEX ? new_width * 2 : new_width;
350     }
351
352   v->width = new_width;
353 }
354
355 /* Returns true if variable V is numeric, false otherwise. */
356 bool
357 var_is_numeric (const struct variable *v) 
358 {
359   return var_get_type (v) == NUMERIC;
360 }
361
362 /* Returns true if variable V is a string variable, false
363    otherwise. */
364 bool
365 var_is_alpha (const struct variable *v) 
366 {
367   return var_get_type (v) == ALPHA;
368 }
369
370 /* Returns true if variable V is a short string variable, false
371    otherwise. */
372 bool
373 var_is_short_string (const struct variable *v) 
374 {
375   return v->width > 0 && v->width <= MAX_SHORT_STRING;
376 }
377
378 /* Returns true if variable V is a long string variable, false
379    otherwise. */
380 bool
381 var_is_long_string (const struct variable *v) 
382 {
383   return v->width > MAX_SHORT_STRING;
384 }
385
386 /* Returns true if variable V is a very long string variable,
387    false otherwise. */
388 bool
389 var_is_very_long_string (const struct variable *v) 
390 {
391   return v->width > MAX_LONG_STRING;
392 }
393
394 /* Returns variable V's missing values. */
395 const struct missing_values *
396 var_get_missing_values (const struct variable *v) 
397 {
398   return &v->miss;
399 }
400
401 /* Sets variable V's missing values to MISS, which must be of the
402    correct width. */
403 void
404 var_set_missing_values (struct variable *v, const struct missing_values *miss)
405 {
406   if (miss != NULL) 
407     {
408       assert (v->width == mv_get_width (miss));
409       mv_copy (&v->miss, miss);
410     }
411   else
412     mv_init (&v->miss, v->width);
413 }
414
415 /* Sets variable V to have no user-missing values. */
416 void
417 var_clear_missing_values (struct variable *v) 
418 {
419   var_set_missing_values (v, NULL);
420 }
421
422 /* Returns true if V has any user-missing values,
423    false otherwise. */
424 bool
425 var_has_missing_values (const struct variable *v) 
426 {
427   return !mv_is_empty (&v->miss);
428 }
429
430 /* Returns true if VALUE is system missing or user-missing value
431    for V, false otherwise. */
432 bool
433 var_is_value_missing (const struct variable *v, const union value *value) 
434 {
435   return mv_is_value_missing (&v->miss, value);
436 }
437
438 /* Returns true if D is system missing or a missing value in V,
439    false otherwise.
440    V must be a numeric variable. */
441 bool
442 var_is_num_missing (const struct variable *v, double d) 
443 {
444   return mv_is_num_missing (&v->miss, d);
445 }
446
447 /* Returns true if S[] is a missing value for V, false otherwise.
448    S[] must contain exactly as many characters as V's width.
449    V must be a string variable. */
450 bool
451 var_is_str_missing (const struct variable *v, const char s[]) 
452 {
453   return mv_is_str_missing (&v->miss, s);
454 }
455
456 /* Returns true if VALUE is a missing value for V, false
457    otherwise. */
458 bool
459 var_is_value_user_missing (const struct variable *v, const union value *value) 
460 {
461   return mv_is_value_user_missing (&v->miss, value);
462 }
463
464 /* Returns true if D is a user-missing value for V, false
465    otherwise.  V must be a numeric variable. */
466 bool
467 var_is_num_user_missing (const struct variable *v, double d) 
468 {
469   return mv_is_num_user_missing (&v->miss, d);
470 }
471
472 /* Returns true if S[] is a missing value for V, false otherwise.
473    V must be a string variable. 
474    S[] must contain exactly as many characters as V's width. */
475 bool
476 var_is_str_user_missing (const struct variable *v, const char s[]) 
477 {
478   return mv_is_str_user_missing (&v->miss, s);
479 }
480
481 /* Returns true if V is a numeric variable and VALUE is the
482    system missing value. */
483 bool
484 var_is_value_system_missing (const struct variable *v,
485                              const union value *value) 
486 {
487   return mv_is_value_system_missing (&v->miss, value);
488 }
489 \f
490 /* Print and write formats. */
491
492 /* Returns V's print format specification. */
493 const struct fmt_spec *
494 var_get_print_format (const struct variable *v) 
495 {
496   return &v->print;
497 }
498
499 /* Sets V's print format specification to PRINT, which must be a
500    valid format specification for outputting a variable of V's
501    width. */
502 void
503 var_set_print_format (struct variable *v, const struct fmt_spec *print) 
504 {
505   assert (fmt_check_width_compat (print, v->width));
506   v->print = *print;
507 }
508
509 /* Returns V's write format specification. */
510 const struct fmt_spec *
511 var_get_write_format (const struct variable *v) 
512 {
513   return &v->write;
514 }
515
516 /* Sets V's write format specification to WRITE, which must be a
517    valid format specification for outputting a variable of V's
518    width. */
519 void
520 var_set_write_format (struct variable *v, const struct fmt_spec *write) 
521 {
522   assert (fmt_check_width_compat (write, v->width));
523   v->write = *write;
524 }
525
526 /* Sets V's print and write format specifications to FORMAT,
527    which must be a valid format specification for outputting a
528    variable of V's width. */
529 void
530 var_set_both_formats (struct variable *v, const struct fmt_spec *format) 
531 {
532   var_set_print_format (v, format);
533   var_set_write_format (v, format);
534 }
535 \f
536 /* Returns V's variable label, or a null pointer if it has none. */
537 const char *
538 var_get_label (const struct variable *v) 
539 {
540   return v->label;
541 }
542
543 /* Sets V's variable label to LABEL, stripping off leading and
544    trailing white space and truncating to 255 characters.
545    If LABEL is a null pointer or if LABEL is an empty string
546    (after stripping white space), then V's variable label (if
547    any) is removed. */
548 void
549 var_set_label (struct variable *v, const char *label) 
550 {
551   free (v->label);
552   v->label = NULL;
553
554   if (label != NULL) 
555     {
556       struct substring s = ss_cstr (label);
557       ss_trim (&s, ss_cstr (CC_SPACES));
558       ss_truncate (&s, 255);
559       if (!ss_is_empty (s)) 
560         v->label = ss_xstrdup (s);
561     }
562 }
563
564 /* Removes any variable label from V. */
565 void
566 var_clear_label (struct variable *v) 
567 {
568   var_set_label (v, NULL);
569 }
570
571 /* Returns true if V has a variable V,
572    false otherwise. */
573 bool
574 var_has_label (const struct variable *v) 
575 {
576   return v->label != NULL;
577 }
578 \f
579 /* Returns V's measurement level. */
580 enum measure
581 var_get_measure (const struct variable *v) 
582 {
583   return v->measure;
584 }
585
586 /* Sets V's measurement level to MEASURE. */
587 void
588 var_set_measure (struct variable *v, enum measure measure) 
589 {
590   assert (measure_is_valid (measure));
591   v->measure = measure;
592 }
593
594 /* Returns V's display width, which applies only to GUIs. */
595 int
596 var_get_display_width (const struct variable *v) 
597 {
598   return v->display_width;
599 }
600
601 /* Sets V's display width to DISPLAY_WIDTH. */
602 void
603 var_set_display_width (struct variable *v, int display_width) 
604 {
605   v->display_width = display_width;
606 }
607
608 /* Returns V's display alignment, which applies only to GUIs. */
609 enum alignment
610 var_get_alignment (const struct variable *v) 
611 {
612   return v->alignment;
613 }
614
615 /* Sets V's display alignment to ALIGNMENT. */
616 void
617 var_set_alignment (struct variable *v, enum alignment alignment) 
618 {
619   assert (alignment_is_valid (alignment));
620   v->alignment = alignment;
621 }
622 \f
623 /* Returns the number of "union value"s need to store a value of
624    variable V. */
625 size_t
626 var_get_value_cnt (const struct variable *v) 
627 {
628   return v->width == 0 ? 1 : DIV_RND_UP (v->width, MAX_SHORT_STRING);
629 }
630
631 /* Return whether variable V's values should be preserved from
632    case to case. */
633 bool
634 var_get_leave (const struct variable *v) 
635 {
636   return v->leave;
637 }
638 \f
639 /* Returns V's short name, if it has one, or a null pointer
640    otherwise.
641
642    Short names are used only for system and portable file input
643    and output.  They are upper-case only, not necessarily unique,
644    and limited to SHORT_NAME_LEN characters (plus a null
645    terminator).  Any variable may have no short name, indicated
646    by returning a null pointer. */
647 const char *
648 var_get_short_name (const struct variable *v) 
649 {
650   return v->short_name[0] != '\0' ? v->short_name : NULL;
651 }
652
653 /* Sets V's short_name to SHORT_NAME, truncating it to
654    SHORT_NAME_LEN characters and converting it to uppercase in
655    the process.  Specifying a null pointer for SHORT_NAME clears
656    the variable's short name. */
657 void
658 var_set_short_name (struct variable *v, const char *short_name) 
659 {
660   assert (v != NULL);
661   assert (short_name == NULL || var_is_plausible_name (short_name, false));
662
663   if (short_name != NULL) 
664     {
665       str_copy_trunc (v->short_name, sizeof v->short_name, short_name);
666       str_uppercase (v->short_name); 
667     }
668   else
669     v->short_name[0] = '\0';
670 }
671
672 /* Clears V's short name. */
673 void
674 var_clear_short_name (struct variable *v) 
675 {
676   assert (v != NULL);
677
678   v->short_name[0] = '\0';
679 }
680
681 /* Sets V's short name to BASE, followed by a suffix of the form
682    _A, _B, _C, ..., _AA, _AB, etc. according to the value of
683    SUFFIX_NUMBER.  Truncates BASE as necessary to fit. */
684 void
685 var_set_short_name_suffix (struct variable *v, const char *base,
686                            int suffix_number)
687 {
688   char suffix[SHORT_NAME_LEN + 1];
689   char short_name[SHORT_NAME_LEN + 1];
690   char *start, *end;
691   int len, ofs;
692
693   assert (v != NULL);
694   assert (suffix_number >= 0);
695
696   /* Set base name. */
697   var_set_short_name (v, base);
698
699   /* Compose suffix. */
700   start = end = suffix + sizeof suffix - 1;
701   *end = '\0';
702   do 
703     {
704       *--start = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"[suffix_number % 26];
705       if (start <= suffix + 1)
706         msg (SE, _("Variable suffix too large."));
707       suffix_number /= 26;
708     }
709   while (suffix_number > 0);
710   *--start = '_';
711
712   /* Append suffix to V's short name. */
713   str_copy_trunc (short_name, sizeof short_name, base);
714   len = end - start;
715   if (len + strlen (short_name) > SHORT_NAME_LEN)
716     ofs = SHORT_NAME_LEN - len;
717   else
718     ofs = strlen (short_name);
719   strcpy (short_name + ofs, start);
720
721   /* Set name. */
722   var_set_short_name (v, short_name);
723 }
724
725
726 /* Returns the dictionary class corresponding to a variable named
727    NAME. */
728 enum dict_class
729 dict_class_from_id (const char *name) 
730 {
731   assert (name != NULL);
732
733   switch (name[0]) 
734     {
735     default:
736       return DC_ORDINARY;
737     case '$':
738       return DC_SYSTEM;
739     case '#':
740       return DC_SCRATCH;
741     }
742 }
743
744 /* Returns the name of dictionary class DICT_CLASS. */
745 const char *
746 dict_class_to_name (enum dict_class dict_class) 
747 {
748   switch (dict_class) 
749     {
750     case DC_ORDINARY:
751       return _("ordinary");
752     case DC_SYSTEM:
753       return _("system");
754     case DC_SCRATCH:
755       return _("scratch");
756     default:
757       NOT_REACHED ();
758     }
759 }
760
761 /* Return the number of bytes used when writing case_data for a variable 
762    of WIDTH */
763 int
764 width_to_bytes(int width)
765 {
766   assert (width >= 0);
767
768   if ( width == 0 ) 
769     return MAX_SHORT_STRING ;
770   else if (width <= MAX_LONG_STRING) 
771     return ROUND_UP (width, MAX_SHORT_STRING);
772   else 
773     {
774       int chunks = width / EFFECTIVE_LONG_STRING_LENGTH ;
775       int remainder = width % EFFECTIVE_LONG_STRING_LENGTH ;
776       int bytes = remainder + (chunks * (MAX_LONG_STRING + 1) );
777       return ROUND_UP (bytes, MAX_SHORT_STRING); 
778     }
779 }
780
781