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