Adopt use of gnulib for portability.
[pspp-builds.git] / src / var.h
1 /* PSPP - computes sample statistics.
2    Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
3    Written by Ben Pfaff <blp@gnu.org>.
4
5    This program is free software; you can redistribute it and/or
6    modify it under the terms of the GNU General Public License as
7    published by the Free Software Foundation; either version 2 of the
8    License, or (at your option) any later version.
9
10    This program is distributed in the hope that it will be useful, but
11    WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    General Public License for more details.
14
15    You should have received a copy of the GNU General Public License
16    along with this program; if not, write to the Free Software
17    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18    02110-1301, USA. */
19
20 #if !var_h
21 #define var_h 1
22
23
24 #include <stddef.h>
25 #include "config.h"
26 #include <stdbool.h>
27 #include "format.h"
28 #include "val.h"
29
30
31
32 /* Script variables. */
33
34 /* Variable type. */
35 enum
36   {
37     NUMERIC,                    /* A numeric variable. */
38     ALPHA                       /* A string variable.
39                                    (STRING is pre-empted by lexer.h.) */
40   };
41
42 /* Types of missing values.  Order is significant, see
43    mis-val.c:parse_numeric(), sfm-read.c, sfm-write.c,
44    sysfile-info.c:cmd_sysfile_info(), mis-val.c:copy_missing_values(),
45    pfm-read.c:read_variables(), pfm-write.c:write_variables(),
46    apply-dict.c:cmd_apply_dictionary(), and more (?). */
47 enum
48   {
49     MISSING_NONE,               /* No user-missing values. */
50     MISSING_1,                  /* One user-missing value. */
51     MISSING_2,                  /* Two user-missing values. */
52     MISSING_3,                  /* Three user-missing values. */
53     MISSING_RANGE,              /* [a,b]. */
54     MISSING_LOW,                /* (-inf,a]. */
55     MISSING_HIGH,               /* (a,+inf]. */
56     MISSING_RANGE_1,            /* [a,b], c. */
57     MISSING_LOW_1,              /* (-inf,a], b. */
58     MISSING_HIGH_1,             /* (a,+inf), b. */
59     MISSING_COUNT
60   };
61
62
63 /* A variable's dictionary entry.  */
64 struct variable
65   {
66     /* Basic information. */
67     char name[LONG_NAME_LEN + 1]; /* Variable name.  Mixed case. */
68     int type;                   /* NUMERIC or ALPHA. */
69     int width;                  /* Size of string variables in chars. */
70     int fv, nv;                 /* Index into `value's, number of values. */
71     unsigned init : 1;          /* 1=VFM must init and possibly reinit. */
72     unsigned reinit : 1;        /* Cases are: 1=reinitialized; 0=left. */
73
74     /* Data for use by containing dictionary. */
75     int index;                  /* Dictionary index. */
76
77     /* Missing values. */
78     int miss_type;              /* One of the MISSING_* constants. */
79     union value missing[3];     /* User-missing value. */
80
81     /* Display formats. */
82     struct fmt_spec print;      /* Default format for PRINT. */
83     struct fmt_spec write;      /* Default format for WRITE. */
84
85     /* Labels. */
86     struct val_labs *val_labs;  /* Value labels. */
87     char *label;                /* Variable label. */
88
89     /* GUI display parameters. */
90     enum measure measure;       /* Nominal ordinal or continuous */
91     int display_width;          /* Width of data editor column */
92     enum alignment alignment;   /* Alignment of data in gui */
93
94     /* Short name, used only for system and portable file input
95        and output.  Upper case only.  There is no index for short
96        names.  Short names are not necessarily unique.  Any
97        variable may have no short name, indicated by an empty
98        string. */
99     char short_name[SHORT_NAME_LEN + 1];
100
101     /* Per-command info. */
102     void *aux;
103     void (*aux_dtor) (struct variable *);
104   };
105
106 /* Variable names. */
107 bool var_is_valid_name (const char *, bool issue_error);
108 int compare_var_names (const void *, const void *, void *);
109 unsigned hash_var_name (const void *, void *);
110
111 /* Short names. */
112 void var_set_short_name (struct variable *, const char *);
113 void var_set_short_name_suffix (struct variable *, const char *, int suffix);
114 void var_clear_short_name (struct variable *);
115
116 /* Pointers to `struct variable', by name. */
117 int compare_var_ptr_names (const void *, const void *, void *);
118 unsigned hash_var_ptr_name (const void *, void *);
119
120 /* Variable auxiliary data. */
121 void *var_attach_aux (struct variable *,
122                       void *aux, void (*aux_dtor) (struct variable *));
123 void var_clear_aux (struct variable *);
124 void *var_detach_aux (struct variable *);
125 void var_dtor_free (struct variable *);
126
127 /* Classes of variables. */
128 enum dict_class 
129   {
130     DC_ORDINARY,                /* Ordinary identifier. */
131     DC_SYSTEM,                  /* System variable. */
132     DC_SCRATCH                  /* Scratch variable. */
133   };
134
135 enum dict_class dict_class_from_id (const char *name);
136 const char *dict_class_to_name (enum dict_class dict_class);
137 \f
138 /* Vector of variables. */
139 struct vector
140   {
141     int idx;                    /* Index for dict_get_vector(). */
142     char name[LONG_NAME_LEN + 1]; /* Name. */
143     struct variable **var;      /* Vector of variables. */
144     int cnt;                    /* Number of variables. */
145   };
146 \f
147 void discard_variables (void);
148
149 /* This is the active file dictionary. */
150 extern struct dictionary *default_dict;
151 \f
152 /* Transformation state. */
153
154 /* Default file handle for DATA LIST, REREAD, REPEATING DATA
155    commands. */
156 extern struct file_handle *default_handle;
157
158 /* PROCESS IF expression. */
159 extern struct expression *process_if_expr;
160 \f
161 /* TEMPORARY support. */
162
163 /* 1=TEMPORARY has been executed at some point. */
164 extern int temporary;
165
166 /* If temporary!=0, the saved dictionary. */
167 extern struct dictionary *temp_dict;
168
169 /* If temporary!=0, index into t_trns[] (declared far below) that
170    gives the point at which data should be written out.  -1 means that
171    the data shouldn't be changed since all transformations are
172    temporary. */
173 extern int temp_trns;
174
175 /* If FILTER is active, whether it was executed before or after
176    TEMPORARY. */
177 extern int FILTER_before_TEMPORARY;
178
179 void cancel_temporary (void);
180 \f
181 /* Functions. */
182
183 struct ccase;
184 void dump_split_vars (const struct ccase *);
185 typedef int (* is_missing_func )(const union value *, const struct variable *);
186
187 int is_num_user_missing (double, const struct variable *);
188 int is_str_user_missing (const unsigned char[], const struct variable *);
189 int is_missing (const union value *, const struct variable *);
190 int is_system_missing (const union value *, const struct variable *);
191 int is_user_missing (const union value *, const struct variable *);
192 void copy_missing_values (struct variable *dest, const struct variable *src);
193 \f
194 /* Transformations. */
195
196 struct trns_header;
197 typedef int trns_proc_func (struct trns_header *, struct ccase *, int);
198 typedef void trns_free_func (struct trns_header *);
199
200 /* Header for all transformations. */
201 struct trns_header
202   {
203     int index;                  /* Index into t_trns[]. */
204     trns_proc_func *proc;       /* Transformation proc. */
205     trns_free_func *free;       /* Garbage collector proc. */
206   };
207
208 /* Array of transformations */
209 extern struct trns_header **t_trns;
210
211 /* Number of transformations, maximum number in array currently. */
212 extern int n_trns, m_trns;
213
214 /* Index of first transformation that is really a transformation.  Any
215    transformations before this belong to INPUT PROGRAM. */
216 extern int f_trns;
217
218 void add_transformation (struct trns_header *trns);
219 void cancel_transformations (void);
220 \f
221 struct var_set;
222
223 struct var_set *var_set_create_from_dict (const struct dictionary *d);
224 struct var_set *var_set_create_from_array (struct variable *const *var,
225                                            size_t);
226
227 size_t var_set_get_cnt (const struct var_set *vs);
228 struct variable *var_set_get_var (const struct var_set *vs, size_t idx);
229 struct variable *var_set_lookup_var (const struct var_set *vs,
230                                      const char *name);
231 int var_set_lookup_var_idx (const struct var_set *vs, const char *name);
232 void var_set_destroy (struct var_set *vs);
233 \f
234 /* Variable parsers. */
235
236 enum
237   {
238     PV_NONE = 0,                /* No options. */
239     PV_SINGLE = 0001,           /* Restrict to a single name or TO use. */
240     PV_DUPLICATE = 0002,        /* Don't merge duplicates. */
241     PV_APPEND = 0004,           /* Append to existing list. */
242     PV_NO_DUPLICATE = 0010,     /* Error on duplicates. */
243     PV_NUMERIC = 0020,          /* Vars must be numeric. */
244     PV_STRING = 0040,           /* Vars must be string. */
245     PV_SAME_TYPE = 00100,       /* All vars must be the same type. */
246     PV_NO_SCRATCH = 00200       /* Disallow scratch variables. */
247   };
248
249 struct variable *parse_variable (void);
250 struct variable *parse_dict_variable (const struct dictionary *);
251 int parse_variables (const struct dictionary *, struct variable ***, int *,
252                      int opts);
253 int parse_var_set_vars (const struct var_set *, struct variable ***, int *,
254                         int opts);
255 int parse_DATA_LIST_vars (char ***names, int *cnt, int opts);
256 int parse_mixed_vars (char ***names, int *cnt, int opts);
257
258
259
260 /* Return a string representing this variable, in the form most 
261    appropriate from a human factors perspective.
262    (IE: the label if it has one, otherwise the name )
263 */
264 const char * var_to_string(const struct variable *var);
265
266
267 #endif /* !var_h */