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