Added the ability to resize string variables from the GUI. Thanks to
[pspp-builds.git] / src / data / variable.c
1 /* PSPP - a program for statistical analysis.
2    Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc.
3
4    This program is free software: you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation, either version 3 of the License, or
7    (at your option) any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program.  If not, see <http://www.gnu.org/licenses/>. */
16
17 #include <config.h>
18 #include "variable.h"
19
20 #include <stdlib.h>
21
22
23 #include "category.h"
24 #include "data-out.h"
25 #include "format.h"
26 #include "dictionary.h"
27 #include "identifier.h"
28 #include "missing-values.h"
29 #include "value-labels.h"
30 #include "vardict.h"
31
32 #include <libpspp/misc.h>
33 #include <libpspp/alloc.h>
34 #include <libpspp/assertion.h>
35 #include <libpspp/compiler.h>
36 #include <libpspp/hash.h>
37 #include <libpspp/message.h>
38 #include <libpspp/str.h>
39
40 #include "gettext.h"
41 #define _(msgid) gettext (msgid)
42
43 /* A variable. */
44 struct variable
45   {
46     /* Dictionary information. */
47     char name[LONG_NAME_LEN + 1]; /* Variable name.  Mixed case. */
48     int width;                  /* 0 for numeric, otherwise string width. */
49     struct missing_values miss; /* Missing values. */
50     struct fmt_spec print;      /* Default format for PRINT. */
51     struct fmt_spec write;      /* Default format for WRITE. */
52     struct val_labs *val_labs;  /* Value labels. */
53     char *label;                /* Variable label. */
54
55     /* GUI information. */
56     enum measure measure;       /* Nominal, ordinal, or continuous. */
57     int display_width;          /* Width of data editor column. */
58     enum alignment alignment;   /* Alignment of data in GUI. */
59
60     /* Case information. */
61     bool leave;                 /* Leave value from case to case? */
62
63     /* Data for use by containing dictionary. */
64     struct vardict_info vardict;
65
66     /* Short name, used only for system and portable file input
67        and output.  Upper case only. Short names are not necessarily
68        unique.  Any variable may have no short name, indicated by an
69        empty string. */
70     char short_name[SHORT_NAME_LEN + 1];
71
72     /* Each command may use these fields as needed. */
73     void *aux;
74     void (*aux_dtor) (struct variable *);
75
76     /* Values of a categorical variable.  Procedures need
77        vectors with binary entries, so any variable of type ALPHA will
78        have its values stored here. */
79     struct cat_vals *obs_vals;
80   };
81
82 /* Returns true if VAR_TYPE is a valid variable type. */
83 bool
84 var_type_is_valid (enum var_type var_type)
85 {
86   return var_type == VAR_NUMERIC || var_type == VAR_STRING;
87 }
88
89 /* Returns the variable type for the given width. */
90 enum var_type
91 var_type_from_width (int width)
92 {
93   return width != 0 ? VAR_STRING : VAR_NUMERIC;
94 }
95 \f
96 /* Creates and returns a new variable with the given NAME and
97    WIDTH and other fields initialized to default values.  The
98    variable is not added to a dictionary; for that, use
99    dict_create_var instead. */
100 struct variable *
101 var_create (const char *name, int width)
102 {
103   struct variable *v;
104
105   assert (width >= 0 && width <= MAX_STRING);
106
107   v = xmalloc (sizeof *v);
108   v->vardict.dict_index = v->vardict.case_index = -1;
109   var_set_name (v, name);
110   v->width = width;
111   mv_init (&v->miss, width);
112   v->leave = var_must_leave (v);
113   if (var_is_numeric (v))
114     {
115       v->print = fmt_for_output (FMT_F, 8, 2);
116       v->alignment = ALIGN_RIGHT;
117       v->display_width = 8;
118       v->measure = MEASURE_SCALE;
119     }
120   else
121     {
122       v->print = fmt_for_output (FMT_A, var_get_width (v), 0);
123       v->alignment = ALIGN_LEFT;
124       v->display_width = 8;
125       v->measure = MEASURE_NOMINAL;
126     }
127   v->write = v->print;
128   v->val_labs = NULL;
129   v->label = NULL;
130   var_clear_short_name (v);
131   v->aux = NULL;
132   v->aux_dtor = NULL;
133   v->obs_vals = NULL;
134
135   return v;
136 }
137
138 /* Creates and returns a clone of OLD_VAR.  Most properties of
139    the new variable are copied from OLD_VAR, except:
140
141     - The variable's short name is not copied, because there is
142       no reason to give a new variable with potentially a new
143       name the same short name.
144
145     - The new variable is not added to OLD_VAR's dictionary by
146       default.  Use dict_clone_var, instead, to do that.
147
148     - Auxiliary data and obs_vals are not copied. */
149 struct variable *
150 var_clone (const struct variable *old_var)
151 {
152   struct variable *new_var = var_create (var_get_name (old_var),
153                                          var_get_width (old_var));
154
155   var_set_missing_values (new_var, var_get_missing_values (old_var));
156   var_set_print_format (new_var, var_get_print_format (old_var));
157   var_set_write_format (new_var, var_get_write_format (old_var));
158   var_set_value_labels (new_var, var_get_value_labels (old_var));
159   var_set_label (new_var, var_get_label (old_var));
160   var_set_measure (new_var, var_get_measure (old_var));
161   var_set_display_width (new_var, var_get_display_width (old_var));
162   var_set_alignment (new_var, var_get_alignment (old_var));
163   var_set_leave (new_var, var_get_leave (old_var));
164
165   return new_var;
166 }
167
168 /* Destroys variable V.
169    V must not belong to a dictionary.  If it does, use
170    dict_delete_var instead. */
171 void
172 var_destroy (struct variable *v)
173 {
174   if (v != NULL)
175     {
176       assert (!var_has_vardict (v));
177       cat_stored_values_destroy (v->obs_vals);
178       var_clear_aux (v);
179       val_labs_destroy (v->val_labs);
180       var_clear_label (v);
181       free (v);
182     }
183 }
184 \f
185 /* Variable names. */
186
187 /* Return variable V's name. */
188 const char *
189 var_get_name (const struct variable *v)
190 {
191   return v->name;
192 }
193
194 /* Sets V's name to NAME.
195    Do not use this function for a variable in a dictionary.  Use
196    dict_rename_var instead. */
197 void
198 var_set_name (struct variable *v, const char *name)
199 {
200   assert (v->vardict.dict_index == -1);
201   assert (var_is_plausible_name (name, false));
202
203   str_copy_trunc (v->name, sizeof v->name, name);
204   dict_var_changed (v);
205 }
206
207 /* Returns true if NAME is an acceptable name for a variable,
208    false otherwise.  If ISSUE_ERROR is true, issues an
209    explanatory error message on failure. */
210 bool
211 var_is_valid_name (const char *name, bool issue_error)
212 {
213   bool plausible;
214   size_t length, i;
215
216   assert (name != NULL);
217
218   /* Note that strlen returns number of BYTES, not the number of
219      CHARACTERS */
220   length = strlen (name);
221
222   plausible = var_is_plausible_name(name, issue_error);
223
224   if ( ! plausible )
225     return false;
226
227
228   if (!lex_is_id1 (name[0]))
229     {
230       if (issue_error)
231         msg (SE, _("Character `%c' (in %s) may not appear "
232                    "as the first character in a variable name."),
233              name[0], name);
234       return false;
235     }
236
237
238   for (i = 0; i < length; i++)
239     {
240     if (!lex_is_idn (name[i]))
241       {
242         if (issue_error)
243           msg (SE, _("Character `%c' (in %s) may not appear in "
244                      "a variable name."),
245                name[i], name);
246         return false;
247       }
248     }
249
250   return true;
251 }
252
253 /* Returns true if NAME is an plausible name for a variable,
254    false otherwise.  If ISSUE_ERROR is true, issues an
255    explanatory error message on failure.
256    This function makes no use of LC_CTYPE.
257 */
258 bool
259 var_is_plausible_name (const char *name, bool issue_error)
260 {
261   size_t length;
262
263   assert (name != NULL);
264
265   /* Note that strlen returns number of BYTES, not the number of
266      CHARACTERS */
267   length = strlen (name);
268   if (length < 1)
269     {
270       if (issue_error)
271         msg (SE, _("Variable name cannot be empty string."));
272       return false;
273     }
274   else if (length > LONG_NAME_LEN)
275     {
276       if (issue_error)
277         msg (SE, _("Variable name %s exceeds %d-character limit."),
278              name, (int) LONG_NAME_LEN);
279       return false;
280     }
281
282   if (lex_id_to_token (ss_cstr (name)) != T_ID)
283     {
284       if (issue_error)
285         msg (SE, _("`%s' may not be used as a variable name because it "
286                    "is a reserved word."), name);
287       return false;
288     }
289
290   return true;
291 }
292
293 /* A hsh_compare_func that orders variables A and B by their
294    names. */
295 int
296 compare_vars_by_name (const void *a_, const void *b_, const void *aux UNUSED)
297 {
298   const struct variable *a = a_;
299   const struct variable *b = b_;
300
301   return strcasecmp (a->name, b->name);
302 }
303
304 /* A hsh_hash_func that hashes variable V based on its name. */
305 unsigned
306 hash_var_by_name (const void *v_, const void *aux UNUSED)
307 {
308   const struct variable *v = v_;
309
310   return hsh_hash_case_string (v->name);
311 }
312
313 /* A hsh_compare_func that orders pointers to variables A and B
314    by their names. */
315 int
316 compare_var_ptrs_by_name (const void *a_, const void *b_,
317                           const void *aux UNUSED)
318 {
319   struct variable *const *a = a_;
320   struct variable *const *b = b_;
321
322   return strcasecmp (var_get_name (*a), var_get_name (*b));
323 }
324
325 /* A hsh_hash_func that hashes pointer to variable V based on its
326    name. */
327 unsigned
328 hash_var_ptr_by_name (const void *v_, const void *aux UNUSED)
329 {
330   struct variable *const *v = v_;
331
332   return hsh_hash_case_string (var_get_name (*v));
333 }
334 \f
335 /* Returns the type of variable V. */
336 enum var_type
337 var_get_type (const struct variable *v)
338 {
339   return var_type_from_width (v->width);
340 }
341
342 /* Returns the width of variable V. */
343 int
344 var_get_width (const struct variable *v)
345 {
346   return v->width;
347 }
348
349 /* Sets the width of V to WIDTH. */
350 void
351 var_set_width (struct variable *v, int new_width)
352 {
353   const int old_width = v->width;
354   enum var_type new_type = var_type_from_width (new_width);
355
356   if (mv_is_resizable (&v->miss, new_width))
357     mv_resize (&v->miss, new_width);
358   else
359     mv_init (&v->miss, new_width);
360
361   if (v->val_labs != NULL)
362     {
363       if (val_labs_can_set_width (v->val_labs, new_width))
364         val_labs_set_width (v->val_labs, new_width);
365       else
366         {
367           val_labs_destroy (v->val_labs);
368           v->val_labs = NULL;
369         }
370     }
371
372   if (var_get_type (v) != new_type)
373     {
374       v->print = (new_type == VAR_NUMERIC
375                   ? fmt_for_output (FMT_F, 8, 2)
376                   : fmt_for_output (FMT_A, new_width, 0));
377       v->write = v->print;
378     }
379   else if (new_type == VAR_STRING)
380     {
381       v->print.w = v->print.type == FMT_AHEX ? new_width * 2 : new_width;
382       v->write.w = v->write.type == FMT_AHEX ? new_width * 2 : new_width;
383     }
384
385   v->width = new_width;
386
387   {
388     const int old_val_count = value_cnt_from_width (old_width);
389     const int new_val_count = value_cnt_from_width (new_width);
390
391     if ( old_val_count != new_val_count)
392          dict_var_resized (v, new_val_count - old_val_count);
393   }
394
395   dict_var_changed (v);
396 }
397
398 /* Returns true if variable V is numeric, false otherwise. */
399 bool
400 var_is_numeric (const struct variable *v)
401 {
402   return var_get_type (v) == VAR_NUMERIC;
403 }
404
405 /* Returns true if variable V is a string variable, false
406    otherwise. */
407 bool
408 var_is_alpha (const struct variable *v)
409 {
410   return var_get_type (v) == VAR_STRING;
411 }
412
413 /* Returns true if variable V is a short string variable, false
414    otherwise. */
415 bool
416 var_is_short_string (const struct variable *v)
417 {
418   return v->width > 0 && v->width <= MAX_SHORT_STRING;
419 }
420
421 /* Returns true if variable V is a long string variable, false
422    otherwise. */
423 bool
424 var_is_long_string (const struct variable *v)
425 {
426   return v->width > MAX_SHORT_STRING;
427 }
428
429 /* Returns the number of "union value"s need to store a value of
430    variable V. */
431 size_t
432 var_get_value_cnt (const struct variable *v)
433 {
434   return value_cnt_from_width (v->width);
435 }
436 \f
437 /* Returns variable V's missing values. */
438 const struct missing_values *
439 var_get_missing_values (const struct variable *v)
440 {
441   return &v->miss;
442 }
443
444 /* Sets variable V's missing values to MISS, which must be of V's
445    width or at least resizable to V's width.
446    If MISS is null, then V's missing values, if any, are
447    cleared. */
448 void
449 var_set_missing_values (struct variable *v, const struct missing_values *miss)
450 {
451   if (miss != NULL)
452     {
453       assert (mv_is_resizable (miss, v->width));
454       mv_copy (&v->miss, miss);
455       mv_resize (&v->miss, v->width);
456     }
457   else
458     mv_init (&v->miss, v->width);
459
460   dict_var_changed (v);
461 }
462
463 /* Sets variable V to have no user-missing values. */
464 void
465 var_clear_missing_values (struct variable *v)
466 {
467   var_set_missing_values (v, NULL);
468 }
469
470 /* Returns true if V has any user-missing values,
471    false otherwise. */
472 bool
473 var_has_missing_values (const struct variable *v)
474 {
475   return !mv_is_empty (&v->miss);
476 }
477
478 /* Returns true if VALUE is in the given CLASS of missing values
479    in V, false otherwise. */
480 bool
481 var_is_value_missing (const struct variable *v, const union value *value,
482                       enum mv_class class)
483 {
484   return mv_is_value_missing (&v->miss, value, class);
485 }
486
487 /* Returns true if D is in the given CLASS of missing values in
488    V, false otherwise.
489    V must be a numeric variable. */
490 bool
491 var_is_num_missing (const struct variable *v, double d, enum mv_class class)
492 {
493   return mv_is_num_missing (&v->miss, d, class);
494 }
495
496 /* Returns true if S[] is a missing value for V, false otherwise.
497    S[] must contain exactly as many characters as V's width.
498    V must be a string variable. */
499 bool
500 var_is_str_missing (const struct variable *v, const char s[],
501                     enum mv_class class)
502 {
503   return mv_is_str_missing (&v->miss, s, class);
504 }
505 \f
506 /* Returns variable V's value labels,
507    possibly a null pointer if it has none. */
508 const struct val_labs *
509 var_get_value_labels (const struct variable *v)
510 {
511   return v->val_labs;
512 }
513
514 /* Returns true if variable V has at least one value label. */
515 bool
516 var_has_value_labels (const struct variable *v)
517 {
518   return val_labs_count (v->val_labs) > 0;
519 }
520
521 /* Sets variable V's value labels to a copy of VLS,
522    which must have a width equal to V's width or one that can be
523    changed to V's width.
524    If VLS is null, then V's value labels, if any, are removed. */
525 void
526 var_set_value_labels (struct variable *v, const struct val_labs *vls)
527 {
528   val_labs_destroy (v->val_labs);
529   v->val_labs = NULL;
530
531   if (vls != NULL)
532     {
533       assert (val_labs_can_set_width (vls, v->width));
534       v->val_labs = val_labs_copy (vls);
535       val_labs_set_width (v->val_labs, v->width);
536       dict_var_changed (v);
537     }
538 }
539
540 /* Makes sure that V has a set of value labels,
541    by assigning one to it if necessary. */
542 static void
543 alloc_value_labels (struct variable *v)
544 {
545   assert (!var_is_long_string (v));
546   if (v->val_labs == NULL)
547     v->val_labs = val_labs_create (v->width);
548 }
549
550 /* Attempts to add a value label with the given VALUE and LABEL
551    to V.  Returns true if successful, false if VALUE has an
552    existing label.
553    V must not be a long string variable. */
554 bool
555 var_add_value_label (struct variable *v,
556                      const union value *value, const char *label)
557 {
558   alloc_value_labels (v);
559   return val_labs_add (v->val_labs, *value, label);
560 }
561
562 /* Adds or replaces a value label with the given VALUE and LABEL
563    to V.
564    V must not be a long string variable. */
565 void
566 var_replace_value_label (struct variable *v,
567                          const union value *value, const char *label)
568 {
569   alloc_value_labels (v);
570   val_labs_replace (v->val_labs, *value, label);
571 }
572
573 /* Removes V's value labels, if any. */
574 void
575 var_clear_value_labels (struct variable *v)
576 {
577   var_set_value_labels (v, NULL);
578 }
579
580 /* Returns the label associated with VALUE for variable V,
581    or a null pointer if none. */
582 const char *
583 var_lookup_value_label (const struct variable *v, const union value *value)
584 {
585   return val_labs_find (v->val_labs, *value);
586 }
587
588 /* Get a string representing VALUE for variable V.
589    That is, if VALUE has a label, return that label,
590    otherwise format VALUE and return the formatted string. */
591 const char *
592 var_get_value_name (const struct variable *v, const union value *value)
593 {
594   const char *name = var_lookup_value_label (v, value);
595   if (name == NULL)
596     {
597       static char buf[MAX_STRING + 1];
598       data_out (value, &v->print, buf);
599       buf[v->print.w] = '\0';
600       name = buf;
601     }
602   return name;
603 }
604 \f
605 /* Print and write formats. */
606
607 /* Returns V's print format specification. */
608 const struct fmt_spec *
609 var_get_print_format (const struct variable *v)
610 {
611   return &v->print;
612 }
613
614 /* Sets V's print format specification to PRINT, which must be a
615    valid format specification for outputting a variable of V's
616    width. */
617 void
618 var_set_print_format (struct variable *v, const struct fmt_spec *print)
619 {
620   assert (fmt_check_width_compat (print, v->width));
621   v->print = *print;
622   dict_var_changed (v);
623 }
624
625 /* Returns V's write format specification. */
626 const struct fmt_spec *
627 var_get_write_format (const struct variable *v)
628 {
629   return &v->write;
630 }
631
632 /* Sets V's write format specification to WRITE, which must be a
633    valid format specification for outputting a variable of V's
634    width. */
635 void
636 var_set_write_format (struct variable *v, const struct fmt_spec *write)
637 {
638   assert (fmt_check_width_compat (write, v->width));
639   v->write = *write;
640   dict_var_changed (v);
641 }
642
643 /* Sets V's print and write format specifications to FORMAT,
644    which must be a valid format specification for outputting a
645    variable of V's width. */
646 void
647 var_set_both_formats (struct variable *v, const struct fmt_spec *format)
648 {
649   var_set_print_format (v, format);
650   var_set_write_format (v, format);
651 }
652 \f
653 /* Return a string representing this variable, in the form most
654    appropriate from a human factors perspective, that is, its
655    variable label if it has one, otherwise its name. */
656 const char *
657 var_to_string (const struct variable *v)
658 {
659   return v->label != NULL ? v->label : v->name;
660 }
661
662 /* Returns V's variable label, or a null pointer if it has none. */
663 const char *
664 var_get_label (const struct variable *v)
665 {
666   return v->label;
667 }
668
669 /* Sets V's variable label to LABEL, stripping off leading and
670    trailing white space and truncating to 255 characters.
671    If LABEL is a null pointer or if LABEL is an empty string
672    (after stripping white space), then V's variable label (if
673    any) is removed. */
674 void
675 var_set_label (struct variable *v, const char *label)
676 {
677   free (v->label);
678   v->label = NULL;
679
680   if (label != NULL)
681     {
682       struct substring s = ss_cstr (label);
683       ss_trim (&s, ss_cstr (CC_SPACES));
684       ss_truncate (&s, 255);
685       if (!ss_is_empty (s))
686         v->label = ss_xstrdup (s);
687       dict_var_changed (v);
688     }
689 }
690
691 /* Removes any variable label from V. */
692 void
693 var_clear_label (struct variable *v)
694 {
695   var_set_label (v, NULL);
696 }
697
698 /* Returns true if V has a variable V,
699    false otherwise. */
700 bool
701 var_has_label (const struct variable *v)
702 {
703   return v->label != NULL;
704 }
705 \f
706 /* Returns true if M is a valid variable measurement level,
707    false otherwise. */
708 bool
709 measure_is_valid (enum measure m)
710 {
711   return m == MEASURE_NOMINAL || m == MEASURE_ORDINAL || m == MEASURE_SCALE;
712 }
713
714 /* Returns V's measurement level. */
715 enum measure
716 var_get_measure (const struct variable *v)
717 {
718   return v->measure;
719 }
720
721 /* Sets V's measurement level to MEASURE. */
722 void
723 var_set_measure (struct variable *v, enum measure measure)
724 {
725   assert (measure_is_valid (measure));
726   v->measure = measure;
727   dict_var_changed (v);
728 }
729 \f
730 /* Returns V's display width, which applies only to GUIs. */
731 int
732 var_get_display_width (const struct variable *v)
733 {
734   return v->display_width;
735 }
736
737
738
739
740 /* Sets V's display width to DISPLAY_WIDTH. */
741 void
742 var_set_display_width (struct variable *v, int display_width)
743 {
744   v->display_width = display_width;
745   dict_var_changed (v);
746 }
747 \f
748 /* Returns true if A is a valid alignment,
749    false otherwise. */
750 bool
751 alignment_is_valid (enum alignment a)
752 {
753   return a == ALIGN_LEFT || a == ALIGN_RIGHT || a == ALIGN_CENTRE;
754 }
755
756 /* Returns V's display alignment, which applies only to GUIs. */
757 enum alignment
758 var_get_alignment (const struct variable *v)
759 {
760   return v->alignment;
761 }
762
763 /* Sets V's display alignment to ALIGNMENT. */
764 void
765 var_set_alignment (struct variable *v, enum alignment alignment)
766 {
767   assert (alignment_is_valid (alignment));
768   v->alignment = alignment;
769   dict_var_changed (v);
770 }
771 \f
772 /* Whether variables' values should be preserved from case to
773    case. */
774
775 /* Returns true if variable V's value should be left from case to
776    case, instead of being reset to 0, system-missing, or blanks. */
777 bool
778 var_get_leave (const struct variable *v)
779 {
780   return v->leave;
781 }
782
783 /* Sets V's leave setting to LEAVE. */
784 void
785 var_set_leave (struct variable *v, bool leave)
786 {
787   assert (leave || !var_must_leave (v));
788   v->leave = leave;
789   dict_var_changed (v);
790 }
791
792 /* Returns true if V must be left from case to case,
793    false if it can be set either way. */
794 bool
795 var_must_leave (const struct variable *v)
796 {
797   return dict_class_from_id (v->name) == DC_SCRATCH;
798 }
799 \f
800 /* Returns V's short name, if it has one, or a null pointer
801    otherwise.
802
803    Short names are used only for system and portable file input
804    and output.  They are upper-case only, not necessarily unique,
805    and limited to SHORT_NAME_LEN characters (plus a null
806    terminator).  Any variable may have no short name, indicated
807    by returning a null pointer. */
808 const char *
809 var_get_short_name (const struct variable *v)
810 {
811   return v->short_name[0] != '\0' ? v->short_name : NULL;
812 }
813
814 /* Sets V's short_name to SHORT_NAME, truncating it to
815    SHORT_NAME_LEN characters and converting it to uppercase in
816    the process.  Specifying a null pointer for SHORT_NAME clears
817    the variable's short name. */
818 void
819 var_set_short_name (struct variable *v, const char *short_name)
820 {
821   assert (v != NULL);
822   assert (short_name == NULL || var_is_plausible_name (short_name, false));
823
824   if (short_name != NULL)
825     {
826       str_copy_trunc (v->short_name, sizeof v->short_name, short_name);
827       str_uppercase (v->short_name);
828     }
829   else
830     v->short_name[0] = '\0';
831   dict_var_changed (v);
832 }
833
834 /* Clears V's short name. */
835 void
836 var_clear_short_name (struct variable *v)
837 {
838   assert (v != NULL);
839
840   v->short_name[0] = '\0';
841 }
842 \f
843 /* Relationship with dictionary. */
844
845 /* Returns V's index within its dictionary, the value
846    for which "dict_get_var (dict, index)" will return V.
847    V must be in a dictionary. */
848 size_t
849 var_get_dict_index (const struct variable *v)
850 {
851   assert (v->vardict.dict_index != -1);
852   return v->vardict.dict_index;
853 }
854
855 /* Returns V's index within the case represented by its
856    dictionary, that is, the value for which "case_data_idx (case,
857    index)" will return the data for V in that case.
858    V must be in a dictionary. */
859 size_t
860 var_get_case_index (const struct variable *v)
861 {
862   assert (v->vardict.case_index != -1);
863   return v->vardict.case_index;
864 }
865 \f
866 /* Returns V's auxiliary data, or a null pointer if none has been
867    attached. */
868 void *
869 var_get_aux (const struct variable *v)
870 {
871   return v->aux;
872 }
873
874 /* Assign auxiliary data AUX to variable V, which must not
875    already have auxiliary data.  Before V's auxiliary data is
876    cleared, AUX_DTOR(V) will be called.  (var_dtor_free, below,
877    may be appropriate for use as AUX_DTOR.) */
878 void *
879 var_attach_aux (const struct variable *v_,
880                 void *aux, void (*aux_dtor) (struct variable *))
881 {
882   struct variable *v = (struct variable *) v_ ; /* cast away const  */
883   assert (v->aux == NULL);
884   assert (aux != NULL);
885   v->aux = aux;
886   v->aux_dtor = aux_dtor;
887   return aux;
888 }
889
890 /* Remove auxiliary data, if any, from V, and return it, without
891    calling any associated destructor. */
892 void *
893 var_detach_aux (struct variable *v)
894 {
895   void *aux = v->aux;
896   assert (aux != NULL);
897   v->aux = NULL;
898   return aux;
899 }
900
901 /* Clears auxiliary data, if any, from V, and calls any
902    associated destructor. */
903 void
904 var_clear_aux (struct variable *v)
905 {
906   assert (v != NULL);
907   if (v->aux != NULL)
908     {
909       if (v->aux_dtor != NULL)
910         v->aux_dtor (v);
911       v->aux = NULL;
912     }
913 }
914
915 /* This function is appropriate for use an auxiliary data
916    destructor (passed as AUX_DTOR to var_attach_aux()) for the
917    case where the auxiliary data should be passed to free(). */
918 void
919 var_dtor_free (struct variable *v)
920 {
921   free (v->aux);
922 }
923 \f
924 /* Observed categorical values. */
925
926 /* Returns V's observed categorical values,
927    which V must have. */
928 struct cat_vals *
929 var_get_obs_vals (const struct variable *v)
930 {
931   assert (v->obs_vals != NULL);
932   return v->obs_vals;
933 }
934
935 /* Sets V's observed categorical values to CAT_VALS. */
936 void
937 var_set_obs_vals (const struct variable *v_, struct cat_vals *cat_vals)
938 {
939   struct variable *v = (struct variable *) v_ ; /* cast away const */
940   cat_stored_values_destroy (v->obs_vals);
941   v->obs_vals = cat_vals;
942 }
943
944 /* Returns true if V has observed categorical values,
945    false otherwise. */
946 bool
947 var_has_obs_vals (const struct variable *v)
948 {
949   return v->obs_vals != NULL;
950 }
951 \f
952 /* Returns the dictionary class corresponding to a variable named
953    NAME. */
954 enum dict_class
955 dict_class_from_id (const char *name)
956 {
957   switch (name[0])
958     {
959     default:
960       return DC_ORDINARY;
961     case '$':
962       return DC_SYSTEM;
963     case '#':
964       return DC_SCRATCH;
965     }
966 }
967
968 /* Returns the name of dictionary class DICT_CLASS. */
969 const char *
970 dict_class_to_name (enum dict_class dict_class)
971 {
972   switch (dict_class)
973     {
974     case DC_ORDINARY:
975       return _("ordinary");
976     case DC_SYSTEM:
977       return _("system");
978     case DC_SCRATCH:
979       return _("scratch");
980     default:
981       NOT_REACHED ();
982     }
983 }
984 \f
985 /* Returns V's vardict structure. */
986 const struct vardict_info *
987 var_get_vardict (const struct variable *v)
988 {
989   assert (var_has_vardict (v));
990   return &v->vardict;
991 }
992
993 /* Sets V's vardict data to VARDICT. */
994 void
995 var_set_vardict (struct variable *v, const struct vardict_info *vardict)
996 {
997   assert (vardict->dict_index >= 0);
998   assert (vardict->case_index >= 0);
999   v->vardict = *vardict;
1000 }
1001
1002 /* Returns true if V has vardict data. */
1003 bool
1004 var_has_vardict (const struct variable *v)
1005 {
1006   return v->vardict.dict_index != -1;
1007 }
1008
1009 /* Clears V's vardict data. */
1010 void
1011 var_clear_vardict (struct variable *v)
1012 {
1013   v->vardict.dict_index = v->vardict.case_index = -1;
1014 }