Changed a lot of non-const pointers to const.
[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. 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   enum var_type new_type = var_type_from_width (new_width);
354
355   if (mv_is_resizable (&v->miss, new_width))
356     mv_resize (&v->miss, new_width);
357   else
358     mv_init (&v->miss, new_width);
359
360   if (v->val_labs != NULL)
361     {
362       if (val_labs_can_set_width (v->val_labs, new_width))
363         val_labs_set_width (v->val_labs, new_width);
364       else
365         {
366           val_labs_destroy (v->val_labs);
367           v->val_labs = NULL;
368         }
369     }
370
371   if (var_get_type (v) != new_type)
372     {
373       v->print = (new_type == VAR_NUMERIC
374                   ? fmt_for_output (FMT_F, 8, 2)
375                   : fmt_for_output (FMT_A, new_width, 0));
376       v->write = v->print;
377     }
378   else if (new_type == VAR_STRING) 
379     {
380       v->print.w = v->print.type == FMT_AHEX ? new_width * 2 : new_width;
381       v->write.w = v->write.type == FMT_AHEX ? new_width * 2 : new_width;
382     }
383
384   v->width = new_width;
385
386   dict_var_changed (v);
387 }
388
389 /* Returns true if variable V is numeric, false otherwise. */
390 bool
391 var_is_numeric (const struct variable *v) 
392 {
393   return var_get_type (v) == VAR_NUMERIC;
394 }
395
396 /* Returns true if variable V is a string variable, false
397    otherwise. */
398 bool
399 var_is_alpha (const struct variable *v) 
400 {
401   return var_get_type (v) == VAR_STRING;
402 }
403
404 /* Returns true if variable V is a short string variable, false
405    otherwise. */
406 bool
407 var_is_short_string (const struct variable *v) 
408 {
409   return v->width > 0 && v->width <= MAX_SHORT_STRING;
410 }
411
412 /* Returns true if variable V is a long string variable, false
413    otherwise. */
414 bool
415 var_is_long_string (const struct variable *v) 
416 {
417   return v->width > MAX_SHORT_STRING;
418 }
419
420 /* Returns the number of "union value"s need to store a value of
421    variable V. */
422 size_t
423 var_get_value_cnt (const struct variable *v) 
424 {
425   return v->width == 0 ? 1 : DIV_RND_UP (v->width, MAX_SHORT_STRING);
426 }
427 \f
428 /* Returns variable V's missing values. */
429 const struct missing_values *
430 var_get_missing_values (const struct variable *v) 
431 {
432   return &v->miss;
433 }
434
435 /* Sets variable V's missing values to MISS, which must be of V's
436    width or at least resizable to V's width.
437    If MISS is null, then V's missing values, if any, are
438    cleared. */
439 void
440 var_set_missing_values (struct variable *v, const struct missing_values *miss)
441 {
442   if (miss != NULL) 
443     {
444       assert (mv_is_resizable (miss, v->width));
445       mv_copy (&v->miss, miss);
446       mv_resize (&v->miss, v->width);
447     }
448   else
449     mv_init (&v->miss, v->width);
450
451   dict_var_changed (v);
452 }
453
454 /* Sets variable V to have no user-missing values. */
455 void
456 var_clear_missing_values (struct variable *v) 
457 {
458   var_set_missing_values (v, NULL);
459 }
460
461 /* Returns true if V has any user-missing values,
462    false otherwise. */
463 bool
464 var_has_missing_values (const struct variable *v) 
465 {
466   return !mv_is_empty (&v->miss);
467 }
468
469 /* Returns true if VALUE is in the given CLASS of missing values
470    in V, false otherwise. */
471 bool
472 var_is_value_missing (const struct variable *v, const union value *value,
473                       enum mv_class class) 
474 {
475   return mv_is_value_missing (&v->miss, value, class);
476 }
477
478 /* Returns true if D is in the given CLASS of missing values in
479    V, false otherwise.
480    V must be a numeric variable. */
481 bool
482 var_is_num_missing (const struct variable *v, double d, enum mv_class class) 
483 {
484   return mv_is_num_missing (&v->miss, d, class);
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                     enum mv_class class) 
493 {
494   return mv_is_str_missing (&v->miss, s, class);
495 }
496 \f
497 /* Returns variable V's value labels,
498    possibly a null pointer if it has none. */
499 const struct val_labs *
500 var_get_value_labels (const struct variable *v) 
501 {
502   return v->val_labs;
503 }
504
505 /* Returns true if variable V has at least one value label. */
506 bool
507 var_has_value_labels (const struct variable *v) 
508 {
509   return val_labs_count (v->val_labs) > 0;
510 }
511
512 /* Sets variable V's value labels to a copy of VLS,
513    which must have a width equal to V's width or one that can be
514    changed to V's width.
515    If VLS is null, then V's value labels, if any, are removed. */
516 void
517 var_set_value_labels (struct variable *v, const struct val_labs *vls) 
518 {
519   val_labs_destroy (v->val_labs);
520   v->val_labs = NULL;
521
522   if (vls != NULL)
523     {
524       assert (val_labs_can_set_width (vls, v->width));
525       v->val_labs = val_labs_copy (vls);
526       val_labs_set_width (v->val_labs, v->width);
527       dict_var_changed (v);
528     }
529 }
530
531 /* Makes sure that V has a set of value labels,
532    by assigning one to it if necessary. */
533 static void
534 alloc_value_labels (struct variable *v) 
535 {
536   assert (!var_is_long_string (v));
537   if (v->val_labs == NULL)
538     v->val_labs = val_labs_create (v->width);
539 }
540
541 /* Attempts to add a value label with the given VALUE and LABEL
542    to V.  Returns true if successful, false if VALUE has an
543    existing label.
544    V must not be a long string variable. */
545 bool
546 var_add_value_label (struct variable *v,
547                      const union value *value, const char *label) 
548 {
549   alloc_value_labels (v);
550   return val_labs_add (v->val_labs, *value, label);
551 }
552
553 /* Adds or replaces a value label with the given VALUE and LABEL
554    to V.
555    V must not be a long string variable. */
556 void
557 var_replace_value_label (struct variable *v,
558                          const union value *value, const char *label)
559 {
560   alloc_value_labels (v);
561   val_labs_replace (v->val_labs, *value, label);
562 }
563
564 /* Removes V's value labels, if any. */
565 void
566 var_clear_value_labels (struct variable *v) 
567 {
568   var_set_value_labels (v, NULL);
569 }
570
571 /* Returns the label associated with VALUE for variable V,
572    or a null pointer if none. */
573 const char *
574 var_lookup_value_label (const struct variable *v, const union value *value) 
575 {
576   return val_labs_find (v->val_labs, *value);
577 }
578
579 /* Get a string representing VALUE for variable V.
580    That is, if VALUE has a label, return that label,
581    otherwise format VALUE and return the formatted string. */
582 const char *
583 var_get_value_name (const struct variable *v, const union value *value)
584 {
585   const char *name = var_lookup_value_label (v, value);
586   if (name == NULL) 
587     {
588       static char buf[MAX_STRING + 1];
589       data_out (value, &v->print, buf);
590       buf[v->print.w] = '\0';
591       name = buf;
592     }
593   return name;
594 }
595 \f
596 /* Print and write formats. */
597
598 /* Returns V's print format specification. */
599 const struct fmt_spec *
600 var_get_print_format (const struct variable *v) 
601 {
602   return &v->print;
603 }
604
605 /* Sets V's print format specification to PRINT, which must be a
606    valid format specification for outputting a variable of V's
607    width. */
608 void
609 var_set_print_format (struct variable *v, const struct fmt_spec *print) 
610 {
611   assert (fmt_check_width_compat (print, v->width));
612   v->print = *print;
613   dict_var_changed (v);
614 }
615
616 /* Returns V's write format specification. */
617 const struct fmt_spec *
618 var_get_write_format (const struct variable *v) 
619 {
620   return &v->write;
621 }
622
623 /* Sets V's write format specification to WRITE, which must be a
624    valid format specification for outputting a variable of V's
625    width. */
626 void
627 var_set_write_format (struct variable *v, const struct fmt_spec *write) 
628 {
629   assert (fmt_check_width_compat (write, v->width));
630   v->write = *write;
631   dict_var_changed (v);
632 }
633
634 /* Sets V's print and write format specifications to FORMAT,
635    which must be a valid format specification for outputting a
636    variable of V's width. */
637 void
638 var_set_both_formats (struct variable *v, const struct fmt_spec *format) 
639 {
640   var_set_print_format (v, format);
641   var_set_write_format (v, format);
642 }
643 \f
644 /* Return a string representing this variable, in the form most
645    appropriate from a human factors perspective, that is, its
646    variable label if it has one, otherwise its name. */
647 const char *
648 var_to_string (const struct variable *v)
649 {
650   return v->label != NULL ? v->label : v->name;
651 }
652
653 /* Returns V's variable label, or a null pointer if it has none. */
654 const char *
655 var_get_label (const struct variable *v) 
656 {
657   return v->label;
658 }
659
660 /* Sets V's variable label to LABEL, stripping off leading and
661    trailing white space and truncating to 255 characters.
662    If LABEL is a null pointer or if LABEL is an empty string
663    (after stripping white space), then V's variable label (if
664    any) is removed. */
665 void
666 var_set_label (struct variable *v, const char *label) 
667 {
668   free (v->label);
669   v->label = NULL;
670
671   if (label != NULL) 
672     {
673       struct substring s = ss_cstr (label);
674       ss_trim (&s, ss_cstr (CC_SPACES));
675       ss_truncate (&s, 255);
676       if (!ss_is_empty (s)) 
677         v->label = ss_xstrdup (s);
678       dict_var_changed (v);
679     }
680 }
681
682 /* Removes any variable label from V. */
683 void
684 var_clear_label (struct variable *v) 
685 {
686   var_set_label (v, NULL);
687 }
688
689 /* Returns true if V has a variable V,
690    false otherwise. */
691 bool
692 var_has_label (const struct variable *v) 
693 {
694   return v->label != NULL;
695 }
696 \f
697 /* Returns true if M is a valid variable measurement level,
698    false otherwise. */
699 bool
700 measure_is_valid (enum measure m)
701 {
702   return m == MEASURE_NOMINAL || m == MEASURE_ORDINAL || m == MEASURE_SCALE;
703 }
704
705 /* Returns V's measurement level. */
706 enum measure
707 var_get_measure (const struct variable *v) 
708 {
709   return v->measure;
710 }
711
712 /* Sets V's measurement level to MEASURE. */
713 void
714 var_set_measure (struct variable *v, enum measure measure) 
715 {
716   assert (measure_is_valid (measure));
717   v->measure = measure;
718   dict_var_changed (v);
719 }
720 \f
721 /* Returns V's display width, which applies only to GUIs. */
722 int
723 var_get_display_width (const struct variable *v) 
724 {
725   return v->display_width;
726 }
727
728
729
730
731 /* Sets V's display width to DISPLAY_WIDTH. */
732 void
733 var_set_display_width (struct variable *v, int display_width) 
734 {
735   v->display_width = display_width;
736   dict_var_changed (v);
737 }
738 \f
739 /* Returns true if A is a valid alignment,
740    false otherwise. */
741 bool
742 alignment_is_valid (enum alignment a)
743 {
744   return a == ALIGN_LEFT || a == ALIGN_RIGHT || a == ALIGN_CENTRE;
745 }
746
747 /* Returns V's display alignment, which applies only to GUIs. */
748 enum alignment
749 var_get_alignment (const struct variable *v) 
750 {
751   return v->alignment;
752 }
753
754 /* Sets V's display alignment to ALIGNMENT. */
755 void
756 var_set_alignment (struct variable *v, enum alignment alignment) 
757 {
758   assert (alignment_is_valid (alignment));
759   v->alignment = alignment;
760   dict_var_changed (v);
761 }
762 \f
763 /* Whether variables' values should be preserved from case to
764    case. */
765
766 /* Returns true if variable V's value should be left from case to
767    case, instead of being reset to 0, system-missing, or blanks. */
768 bool
769 var_get_leave (const struct variable *v) 
770 {
771   return v->leave;
772 }
773
774 /* Sets V's leave setting to LEAVE. */
775 void
776 var_set_leave (struct variable *v, bool leave) 
777 {
778   assert (leave || !var_must_leave (v));
779   v->leave = leave;
780   dict_var_changed (v);
781 }
782
783 /* Returns true if V must be left from case to case,
784    false if it can be set either way. */
785 bool
786 var_must_leave (const struct variable *v) 
787 {
788   return dict_class_from_id (v->name) == DC_SCRATCH;
789 }
790 \f
791 /* Returns V's short name, if it has one, or a null pointer
792    otherwise.
793
794    Short names are used only for system and portable file input
795    and output.  They are upper-case only, not necessarily unique,
796    and limited to SHORT_NAME_LEN characters (plus a null
797    terminator).  Any variable may have no short name, indicated
798    by returning a null pointer. */
799 const char *
800 var_get_short_name (const struct variable *v) 
801 {
802   return v->short_name[0] != '\0' ? v->short_name : NULL;
803 }
804
805 /* Sets V's short_name to SHORT_NAME, truncating it to
806    SHORT_NAME_LEN characters and converting it to uppercase in
807    the process.  Specifying a null pointer for SHORT_NAME clears
808    the variable's short name. */
809 void
810 var_set_short_name (struct variable *v, const char *short_name) 
811 {
812   assert (v != NULL);
813   assert (short_name == NULL || var_is_plausible_name (short_name, false));
814
815   if (short_name != NULL) 
816     {
817       str_copy_trunc (v->short_name, sizeof v->short_name, short_name);
818       str_uppercase (v->short_name); 
819     }
820   else
821     v->short_name[0] = '\0';
822   dict_var_changed (v);
823 }
824
825 /* Clears V's short name. */
826 void
827 var_clear_short_name (struct variable *v) 
828 {
829   assert (v != NULL);
830
831   v->short_name[0] = '\0';
832 }
833 \f
834 /* Relationship with dictionary. */
835
836 /* Returns V's index within its dictionary, the value
837    for which "dict_get_var (dict, index)" will return V.
838    V must be in a dictionary. */
839 size_t
840 var_get_dict_index (const struct variable *v) 
841 {
842   assert (v->vardict.dict_index != -1);
843   return v->vardict.dict_index;
844 }
845
846 /* Returns V's index within the case represented by its
847    dictionary, that is, the value for which "case_data_idx (case,
848    index)" will return the data for V in that case.
849    V must be in a dictionary. */
850 size_t
851 var_get_case_index (const struct variable *v) 
852 {
853   assert (v->vardict.case_index != -1);
854   return v->vardict.case_index;
855 }
856 \f
857 /* Returns V's auxiliary data, or a null pointer if none has been
858    attached. */
859 void *
860 var_get_aux (const struct variable *v) 
861 {
862   return v->aux;
863 }
864
865 /* Assign auxiliary data AUX to variable V, which must not
866    already have auxiliary data.  Before V's auxiliary data is
867    cleared, AUX_DTOR(V) will be called.  (var_dtor_free, below,
868    may be appropriate for use as AUX_DTOR.) */
869 void *
870 var_attach_aux (const struct variable *v_,
871                 void *aux, void (*aux_dtor) (struct variable *)) 
872 {
873   struct variable *v = (struct variable *) v_ ; /* cast away const  */
874   assert (v->aux == NULL);
875   assert (aux != NULL);
876   v->aux = aux;
877   v->aux_dtor = aux_dtor;
878   return aux;
879 }
880
881 /* Remove auxiliary data, if any, from V, and return it, without
882    calling any associated destructor. */
883 void *
884 var_detach_aux (struct variable *v) 
885 {
886   void *aux = v->aux;
887   assert (aux != NULL);
888   v->aux = NULL;
889   return aux;
890 }
891
892 /* Clears auxiliary data, if any, from V, and calls any
893    associated destructor. */
894 void
895 var_clear_aux (struct variable *v) 
896 {
897   assert (v != NULL);
898   if (v->aux != NULL) 
899     {
900       if (v->aux_dtor != NULL)
901         v->aux_dtor (v);
902       v->aux = NULL;
903     }
904 }
905
906 /* This function is appropriate for use an auxiliary data
907    destructor (passed as AUX_DTOR to var_attach_aux()) for the
908    case where the auxiliary data should be passed to free(). */
909 void
910 var_dtor_free (struct variable *v) 
911 {
912   free (v->aux);
913 }
914 \f
915 /* Observed categorical values. */
916
917 /* Returns V's observed categorical values,
918    which V must have. */
919 struct cat_vals *
920 var_get_obs_vals (const struct variable *v) 
921 {
922   assert (v->obs_vals != NULL);
923   return v->obs_vals;
924 }
925
926 /* Sets V's observed categorical values to CAT_VALS. */
927 void
928 var_set_obs_vals (const struct variable *v_, struct cat_vals *cat_vals) 
929 {
930   struct variable *v = (struct variable *) v_ ; /* cast away const */ 
931   cat_stored_values_destroy (v->obs_vals);
932   v->obs_vals = cat_vals;
933 }
934
935 /* Returns true if V has observed categorical values,
936    false otherwise. */
937 bool
938 var_has_obs_vals (const struct variable *v) 
939 {
940   return v->obs_vals != NULL;
941 }
942 \f
943 /* Returns the dictionary class corresponding to a variable named
944    NAME. */
945 enum dict_class
946 dict_class_from_id (const char *name) 
947 {
948   switch (name[0]) 
949     {
950     default:
951       return DC_ORDINARY;
952     case '$':
953       return DC_SYSTEM;
954     case '#':
955       return DC_SCRATCH;
956     }
957 }
958
959 /* Returns the name of dictionary class DICT_CLASS. */
960 const char *
961 dict_class_to_name (enum dict_class dict_class) 
962 {
963   switch (dict_class) 
964     {
965     case DC_ORDINARY:
966       return _("ordinary");
967     case DC_SYSTEM:
968       return _("system");
969     case DC_SCRATCH:
970       return _("scratch");
971     default:
972       NOT_REACHED ();
973     }
974 }
975 \f
976 /* Returns V's vardict structure. */
977 const struct vardict_info *
978 var_get_vardict (const struct variable *v) 
979 {
980   assert (var_has_vardict (v));
981   return &v->vardict;
982 }
983
984 /* Sets V's vardict data to VARDICT. */
985 void
986 var_set_vardict (struct variable *v, const struct vardict_info *vardict) 
987 {
988   assert (vardict->dict_index >= 0);
989   assert (vardict->case_index >= 0);
990   v->vardict = *vardict;
991 }
992
993 /* Returns true if V has vardict data. */
994 bool
995 var_has_vardict (const struct variable *v) 
996 {
997   return v->vardict.dict_index != -1;
998 }
999
1000 /* Clears V's vardict data. */
1001 void
1002 var_clear_vardict (struct variable *v) 
1003 {
1004   v->vardict.dict_index = v->vardict.case_index = -1;
1005 }