1 /* PSPP - computes sample statistics.
2 Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
3 Written by Ben Pfaff <blp@gnu.org>.
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.
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.
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., 59 Temple Place - Suite 330, Boston, MA
29 #include "file-handle.h"
38 /*#define DEBUGGING 1*/
39 #include "debug-print.h"
42 /* Dumps one variable to standard output. */
44 dump_one_var_node (void * pnode, void *param, int level)
46 variable *node = pnode;
49 for (i = 0; i < level - 1; i++)
52 printf ("NULL_TREE\n");
54 printf ("%p=>%s\n", node, node->name ? node->name : "<null>");
57 /* Dumps a tree of the variables to standard output. */
61 printf (_("Vartree:\n"));
62 avl_walk_inorder (default_dict.var_by_name, dump_one_var_node, NULL);
66 /* Clear the default dictionary. Note: This is probably not what you
67 want to do. Use discard_variables() instead. */
69 clear_default_dict (void)
73 for (i = 0; i < default_dict.nvar; i++)
75 clear_variable (&default_dict, default_dict.var[i]);
76 free (default_dict.var[i]);
79 assert (default_dict.splits == NULL);
81 default_dict.nvar = 0;
83 default_dict.nval = 0;
84 default_handle = inline_file;
85 stop_weighting (&default_dict);
88 /* Discards all the current state in preparation for a data-input
89 command like DATA LIST or GET. */
91 discard_variables (void)
93 clear_default_dict ();
99 vfm_source->destroy_source ();
103 cancel_transformations ();
111 expr_free (process_if_expr);
112 process_if_expr = NULL;
116 pgm_state = STATE_INIT;
119 /* Find and return the variable in default_dict having name NAME, or
120 NULL if no such variable exists in default_dict. */
122 find_variable (const char *name)
124 return avl_find (default_dict.var_by_name, (struct variable *) name);
127 /* Find and return the variable in dictionary D having name NAME, or
128 NULL if no such variable exists in D. */
130 find_dict_variable (const struct dictionary *d, const char *name)
132 return avl_find (d->var_by_name, (struct variable *) name);
135 /* Creates a variable named NAME in dictionary DICT having type TYPE
136 (ALPHA or NUMERIC) and, if type==ALPHA, width WIDTH. Returns a
137 pointer to the newly created variable if successful. On failure
138 (which indicates that a variable having the specified name already
139 exists), returns NULL. */
141 create_variable (struct dictionary *dict, const char *name,
144 if (find_dict_variable (dict, name))
148 struct variable *new_var;
150 dict->var = xrealloc (dict->var, (dict->nvar + 1) * sizeof *dict->var);
151 new_var = dict->var[dict->nvar] = xmalloc (sizeof *new_var);
153 new_var->index = dict->nvar;
156 init_variable (dict, new_var, name, type, width);
163 /* For situations in which we know that there are no variables with an
164 identical name in the dictionary. */
166 force_create_variable (struct dictionary *dict, const char *name,
169 struct variable *new_var = create_variable (dict, name, type, width);
170 assert (new_var != NULL);
174 /* For situations in which we know that there are no variables with an
175 identical name in the dictionary. */
177 force_dup_variable (struct dictionary *dict, const struct variable *src,
180 struct variable *new_var = dup_variable (dict, src, name);
181 assert (new_var != NULL);
186 /* Delete variable V from DICT. It should only be used when there are
187 guaranteed to be absolutely NO REFERENCES to it, for instance in
188 the very same function that created it. */
190 delete_variable (struct dictionary *dict, struct variable *v)
194 clear_variable (dict, v);
196 for (i = v->index; i < dict->nvar; i++)
198 dict->var[i] = dict->var[i + 1];
199 dict->var[i]->index = i;
204 /* Initialize fields in variable V inside dictionary D with name NAME,
205 type TYPE, and width WIDTH. Initializes some other fields too. */
207 common_init_stuff (struct dictionary *dict, struct variable *v,
208 const char *name, int type, int width)
211 /* Avoid problems with overlap. */
212 strcpy (v->name, name);
214 avl_force_insert (dict->var_by_name, v);
217 v->left = name[0] == '#';
218 v->width = type == NUMERIC ? 0 : width;
219 v->miss_type = MISSING_NONE;
220 if (v->type == NUMERIC)
222 v->print.type = FMT_F;
228 v->print.type = FMT_A;
229 v->print.w = v->width;
235 /* Initialize (for the first time) a variable V in dictionary DICT
236 with name NAME, type TYPE, and width WIDTH. */
238 init_variable (struct dictionary *dict, struct variable *v, const char *name,
241 common_init_stuff (dict, v, name, type, width);
242 v->nv = type == NUMERIC ? 1 : DIV_RND_UP (width, 8);
249 if (vfm_source == &input_program_source
250 || vfm_source == &file_type_source)
252 size_t nbytes = DIV_RND_UP (v->fv + 1, 4);
255 if (inp_init_size < nbytes)
257 inp_init = xrealloc (inp_init, nbytes);
258 memset (&inp_init[inp_init_size], 0, nbytes - inp_init_size);
259 inp_init_size = nbytes;
262 if (v->type == ALPHA)
266 inp_init[v->fv / 4] |= val << ((unsigned) (v->fv) % 4 * 2);
270 /* Replace variable V in default_dict with a different variable having
271 name NAME, type TYPE, and width WIDTH. */
273 replace_variable (struct variable *v, const char *name, int type, int width)
277 assert (v && name && (type == NUMERIC || type == ALPHA) && width >= 0
278 && (type == ALPHA || width == 0));
279 clear_variable (&default_dict, v);
280 common_init_stuff (&default_dict, v, name, type, width);
282 nv = (type == NUMERIC) ? 1 : DIV_RND_UP (width, 8);
286 v->fv = default_dict.nval;
287 default_dict.nval += nv;
292 /* Changes the name of variable V in dictionary DICT to name NEW_NAME.
293 NEW_NAME must be known not to already exist in dictionary DICT. */
295 rename_variable (struct dictionary * dict, struct variable *v,
296 const char *new_name)
298 assert (dict && dict->var_by_name && v && new_name);
299 avl_delete (dict->var_by_name, v);
300 strncpy (v->name, new_name, 9);
301 avl_force_insert (dict->var_by_name, v);
304 /* Delete the contents of variable V within dictionary DICT. Does not
305 remove the variable from the vector of variables in the dictionary.
308 clear_variable (struct dictionary *dict, struct variable *v)
313 printf (_("clearing variable %d:%s %s\n"), v->index, v->name,
314 (dict == &default_dict ? _("in default dictionary")
315 : _("in auxiliary dictionary")));
316 if (dict->var_by_name != NULL)
320 if (dict->var_by_name != NULL)
321 avl_force_delete (dict->var_by_name, v);
325 avl_destroy (v->val_lab, free_val_lab);
337 struct variable **iter, **trailer;
339 for (trailer = iter = dict->splits; *iter; iter++)
347 if (dict->n_splits == 0)
355 if (dict->var_by_name != NULL)
360 /* Creates a new variable in dictionary DICT, whose properties are
361 copied from variable SRC, and returns a pointer to the new variable
362 of name NAME, if successful. If unsuccessful (which only happens
363 if a variable of the same name NAME exists in DICT), returns
366 dup_variable (struct dictionary *dict, const struct variable *src,
369 if (find_dict_variable (dict, name))
373 struct variable *new_var;
375 dict->var = xrealloc (dict->var, (dict->nvar + 1) * sizeof *dict->var);
376 new_var = dict->var[dict->nvar] = xmalloc (sizeof *new_var);
378 new_var->index = dict->nvar;
380 new_var->get.fv = -1;
381 new_var->get.nv = -1;
384 copy_variable (new_var, src);
386 assert (new_var->nv >= 0);
387 new_var->fv = dict->nval;
388 dict->nval += new_var->nv;
390 strcpy (new_var->name, name);
391 avl_force_insert (dict->var_by_name, new_var);
398 /* Decrements the reference count for value label V. Destroys the
399 value label if the reference count reaches zero. */
401 free_value_label (struct value_label * v)
403 assert (v->ref_count >= 1);
404 if (--v->ref_count == 0)
411 /* Frees value label P. PARAM is ignored. Used as a callback with
414 free_val_lab (void *p, void *param unused)
416 free_value_label ((struct value_label *) p);
419 /* Returns a value label corresponding to VAL in variable V padded to
420 length N. If N==0 then no padding is performed, and NULL is
421 returned if no label exists. (Normally a string of spaces is
422 returned in this case.) */
424 get_val_lab (const struct variable *v, union value val, int n)
428 struct value_label template, *find;
432 buf = xrealloc (buf, n + 1);
440 find = avl_find (v->val_lab, &template);
445 st_pad_copy (buf, find->s, n + 1);
455 memset (buf, ' ', n);
464 /* Return nonzero only if X is a user-missing value for numeric
467 is_num_user_missing (double x, const struct variable *v)
469 switch (v->miss_type)
474 return approx_eq (x, v->missing[0].f);
476 return (approx_eq (x, v->missing[0].f)
477 || approx_eq (x, v->missing[1].f));
479 return (approx_eq (x, v->missing[0].f)
480 || approx_eq (x, v->missing[1].f)
481 || approx_eq (x, v->missing[2].f));
483 return (approx_ge (x, v->missing[0].f)
484 && approx_le (x, v->missing[1].f));
486 return approx_le (x, v->missing[0].f);
488 return approx_ge (x, v->missing[0].f);
489 case MISSING_RANGE_1:
490 return ((approx_ge (x, v->missing[0].f)
491 && approx_le (x, v->missing[1].f))
492 || approx_eq (x, v->missing[2].f));
494 return (approx_le (x, v->missing[0].f)
495 || approx_eq (x, v->missing[1].f));
497 return (approx_ge (x, v->missing[0].f)
498 || approx_eq (x, v->missing[1].f));
505 /* Return nonzero only if string S is a user-missing variable for
506 string variable V. */
508 is_str_user_missing (const unsigned char s[], const struct variable *v)
510 switch (v->miss_type)
515 return !strncmp (s, v->missing[0].s, v->width);
517 return (!strncmp (s, v->missing[0].s, v->width)
518 || !strncmp (s, v->missing[1].s, v->width));
520 return (!strncmp (s, v->missing[0].s, v->width)
521 || !strncmp (s, v->missing[1].s, v->width)
522 || !strncmp (s, v->missing[2].s, v->width));
529 /* Return nonzero only if value VAL is system-missing for variable
532 is_system_missing (const union value *val, const struct variable *v)
534 return v->type == NUMERIC && val->f == SYSMIS;
537 /* Return nonzero only if value VAL is system- or user-missing for
540 is_missing (const union value *val, const struct variable *v)
545 if (val->f == SYSMIS)
547 return is_num_user_missing (val->f, v);
549 return is_str_user_missing (val->s, v);
556 /* Return nonzero only if value VAL is user-missing for variable V. */
558 is_user_missing (const union value *val, const struct variable *v)
563 return is_num_user_missing (val->f, v);
565 return is_str_user_missing (val->s, v);