You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA. */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA. */
#if !var_h
#define var_h 1
-#include "format.h"
-
-/* Values. */
-
-/* Definition of the max length of a short string value, generally
- eight characters. */
-#define MAX_SHORT_STRING ((SIZEOF_DOUBLE)>=8 ? ((SIZEOF_DOUBLE)+1)/2*2 : 8)
-#define MIN_LONG_STRING (MAX_SHORT_STRING+1)
-
-/* FYI: It is a bad situation if sizeof(flt64) < MAX_SHORT_STRING:
- then short string missing values can be truncated in system files
- because there's only room for as many characters as can fit in a
- flt64. */
-#if MAX_SHORT_STRING > 8
-#error MAX_SHORT_STRING must be less than 8.
-#endif
-
-/* Special values. */
-#define SYSMIS (-DBL_MAX)
-#define LOWEST second_lowest_value
-#define HIGHEST DBL_MAX
-
-/* Describes one value, which is either a floating-point number or a
- short string. */
-union value
- {
- /* A numeric value. */
- double f;
-
- /* A short-string value. */
- unsigned char s[MAX_SHORT_STRING];
-
- /* This member is used by data-in.c to return a string result,
- since it may need to return a long string. As currently
- implemented, it's a pointer to a static internal buffer in
- data-in.c.
-
- Also used by evaluate_expression() to return a string result.
- As currently implemented, it's a pointer to a dynamic buffer in
- the appropriate expression.
-
- Also used by the AGGREGATE procedure in handling string
- values. */
- unsigned char *c;
-
- /* Sometimes we insert value's in a hash table. */
- unsigned long hash[SIZEOF_DOUBLE / SIZEOF_LONG];
- };
-
-/* Describes one value label. */
-struct value_label
- {
- union value v; /* The value being labeled. */
- char *s; /* Pointer to malloc()'d label. */
- int ref_count; /* Reference count. */
- };
-\f
-/* Frequency tables. */
-
-/* Frequency table entry. */
-struct freq
- {
- union value v; /* The value. */
- double c; /* The number of occurrences of the value. */
- };
-
-/* Types of frequency tables. */
-enum
- {
- FRQM_GENERAL,
- FRQM_INTEGER
- };
-
-/* Entire frequency table. */
-struct freq_tab
- {
- int mode; /* FRQM_GENERAL or FRQM_INTEGER. */
-
- /* General mode. */
- struct avl_tree *tree; /* Undifferentiated data. */
-
- /* Integer mode. */
- double *vector; /* Frequencies proper. */
- int min, max; /* The boundaries of the table. */
- double out_of_range; /* Sum of weights of out-of-range values. */
- double sysmis; /* Sum of weights of SYSMIS values. */
-
- /* All modes. */
- struct freq *valid; /* Valid freqs. */
- int n_valid; /* Number of total freqs. */
-
- struct freq *missing; /* Missing freqs. */
- int n_missing; /* Number of missing freqs. */
-
- /* Statistics. */
- double total_cases; /* Sum of weights of all cases. */
- double valid_cases; /* Sum of weights of valid cases. */
- };
-
-/* A complete set of 3 frequency tables. */
-struct freq_tab_set
- {
- struct freq_tab miss; /* Includes user-missing values. */
- struct freq_tab no_miss; /* Excludes user-missing values. */
- struct freq_tab sel; /* Identical to either miss or no_miss. */
- };
-\f
-/* Procedures' private per-variable data. */
-
-/* Structure name suffixes for private data:
- _proc: for a procedure (i.e., LIST -> list_proc).
- _trns: for a transformation (i.e., COMPUTE -> compute_trns.
- _pgm: for an input program (i.e., DATA LIST -> data_list_pgm). */
-
-/* CROSSTABS private data. */
-struct crosstab_proc
- {
- /* Integer mode only. */
- int min; /* Minimum value. */
- int max; /* Maximum value + 1. */
- int count; /* max - min. */
- };
-
-/* FREQUENCIES private data. */
-enum
- {
- frq_mean = 0, frq_semean, frq_median, frq_mode, frq_stddev, frq_variance,
- frq_kurt, frq_sekurt, frq_skew, frq_seskew, frq_range, frq_min, frq_max,
- frq_sum, frq_n_stats
- };
-
-struct frequencies_proc
- {
- /* General mode. */
- struct freq_tab tab; /* Frequencies table to use. */
-
- /* Percentiles. */
- int n_groups; /* Number of groups. */
- double *groups; /* Groups. */
-
- /* Statistics. */
- double stat[frq_n_stats];
- };
-
-/* LIST private data. */
-struct list_proc
- {
- int newline; /* Whether a new line begins here. */
- int width; /* Field width. */
- int vert; /* Whether to print the varname vertically. */
- };
-
-/* DESCRIPTIVES private data. Note that the DESCRIPTIVES procedure also
- has a transformation, descriptives_trns. */
-enum
- {
- /* As these are used as bit indexes, there must be 32 or fewer.
- Be very careful in adjusting these, see the structure below
- and the table in descriptives.q. */
- dsc_mean = 0, dsc_semean, dsc_stddev, dsc_variance, dsc_kurt,
- dsc_sekurt, dsc_skew, dsc_seskew, dsc_range, dsc_min,
- dsc_max, dsc_sum, dsc_n_stats
- };
-
-struct descriptives_proc
- {
- /* Miscellaneous. */
- int dup; /* Finds duplicates in list of
- variables. */
- char zname[10]; /* Name for z-score variable. */
-
- /* Counts. */
- double valid, miss; /* Valid, missing--general. */
-
- /* Mean, moments about the mean. */
- double X_bar, M2, M3, M4;
- double min, max;
-
- /* Statistics. */
- double stats[dsc_n_stats]; /* Everything glommed together. */
- };
-
-/* GET private data. */
-struct get_proc
- {
- int fv, nv; /* First, last, # of values. */
- };
-
-/* Sort order. */
-enum
- {
- SRT_ASCEND, /* A, B, C, ..., X, Y, Z. */
- SRT_DESCEND /* Z, Y, X, ..., C, B, A. */
- };
-
-/* SORT CASES private data. */
-struct sort_cases_proc
- {
- int order; /* SRT_ASCEND or SRT_DESCEND. */
- };
-
-/* MODIFY VARS private data. */
-struct modify_vars_proc
- {
- char new_name[9]; /* Variable's new name. */
- int drop_this_var; /* 0=keep this var, 1=drop this var. */
- struct variable *next; /* Next in linked list. */
- };
-
-/* MEANS private data. */
-struct means_proc
- {
- double min, max; /* Range for integer mode. */
- };
-
-/* Different types of variables for MATRIX DATA procedure. Order is
- important: these are used for sort keys. */
-enum
- {
- MXD_SPLIT, /* SPLIT FILE variables. */
- MXD_ROWTYPE, /* ROWTYPE_. */
- MXD_FACTOR, /* Factor variables. */
- MXD_VARNAME, /* VARNAME_. */
- MXD_CONTINUOUS, /* Continuous variables. */
- MXD_COUNT
- };
+#include <stddef.h>
+#include "config.h"
+#include "bool.h"
+#include "format.h"
+#include "val.h"
-/* MATRIX DATA private data. */
-struct matrix_data_proc
- {
- int vartype; /* Variable type. */
- int subtype; /* Subtype. */
- };
-/* MATCH FILES private data. */
-struct match_files_proc
- {
- struct variable *master; /* Corresponding master file variable. */
- };
-\f
/* Script variables. */
/* Variable type. */
};
/* Types of missing values. Order is significant, see
- mis-val.c:parse_numeric(), sfm-read.c:sfm_read_dictionary()
- sfm-write.c:sfm_write_dictionary(),
+ mis-val.c:parse_numeric(), sfm-read.c, sfm-write.c,
sysfile-info.c:cmd_sysfile_info(), mis-val.c:copy_missing_values(),
pfm-read.c:read_variables(), pfm-write.c:write_variables(),
apply-dict.c:cmd_apply_dictionary(), and more (?). */
MISSING_COUNT
};
-/* A variable's dictionary entry. Note: don't reorder name[] from the
- first element; a pointer to `variable' should be a pointer to
- member `name'.*/
+
+/* A variable's dictionary entry. */
struct variable
{
- /* Required by parse_variables() to be in this order. */
- char name[9]; /* As a string. */
+ char name[SHORT_NAME_LEN + 1]; /* As a string. */
+ char *longname; /* Pointer to entry in dictionary's table */
int index; /* Index into its dictionary's var[]. */
- int type; /* NUMERIC or ALPHA. */
- int foo; /* Used for temporary storage. */
+ int type; /* NUMERIC or ALPHA. */
- /* Also important but parse_variables() doesn't need it. Still,
- check before reordering. */
int width; /* Size of string variables in chars. */
int fv, nv; /* Index into `value's, number of values. */
- int left; /* 0=do not LEAVE, 1=LEAVE. */
+ unsigned init : 1; /* 1=VFM must init and possibly reinit. */
+ unsigned reinit : 1; /* Cases are: 1=reinitialized; 0=left. */
/* Missing values. */
int miss_type; /* One of the MISSING_* constants. */
struct fmt_spec write; /* Default format for WRITE. */
/* Labels. */
- struct avl_tree *val_lab; /* Avltree of value_label structures. */
+ struct val_labs *val_labs; /* Value labels. */
char *label; /* Variable label. */
- /* Per-procedure info. */
- struct get_proc get;
- union
- {
- struct crosstab_proc crs;
- struct descriptives_proc dsc;
- struct frequencies_proc frq;
- struct list_proc lst;
- struct means_proc mns;
- struct sort_cases_proc srt;
- struct modify_vars_proc mfv;
- struct matrix_data_proc mxd;
- struct match_files_proc mtf;
- }
- p;
- };
-\f
-/* Cases. */
-/* A single case. (This doesn't need to be a struct anymore, but it
- remains so for hysterical raisins.) */
-struct ccase
- {
- union value data[1];
+ /* GUI display parameters */
+ enum measure measure; /* Nominal ordinal or continuous */
+ int display_width; /* Width of data editor column */
+ enum alignment alignment; /* Alignment of data in gui */
+
+ /* Per-command info. */
+ void *aux;
+ void (*aux_dtor) (struct variable *);
};
-\f
-/* Dictionary. */
-/* Complete dictionary state. */
-struct dictionary
- {
- struct variable **var; /* Variable descriptions. */
- struct avl_tree *var_by_name; /* Variables arranged by name. */
- int nvar; /* Number of variables. */
- int N; /* Current case limit (N command). */
- int nval; /* Number of value structures per case. */
+/* A tuple containing short names and longnames */
+struct name_table_entry
+{
+ char *longname;
+ char *name;
+};
+
+bool var_is_valid_name (const char *, bool issue_error);
+int compare_var_names (const void *, const void *, void *);
+unsigned hash_var_name (const void *, void *);
+
+/* Destroy and free up an nte */
+void free_nte(struct name_table_entry *nte);
+
- int n_splits; /* Number of SPLIT FILE variables. */
- struct variable **splits; /* List of SPLIT FILE vars. */
-
- char *label; /* File label. */
+unsigned hash_long_name (const void *e_, void *aux UNUSED) ;
+int compare_long_names(const void *a_, const void *b_, void *aux);
- int n_documents; /* Number of lines of documents. */
- char *documents; /* Documents; 80*n_documents bytes in size. */
- int weight_index; /* `value' index of $WEIGHT, or -1 if none.
- Call update_weighting() before using! */
- char weight_var[9]; /* Name of WEIGHT variable. */
+int compare_var_ptr_names (const void *, const void *, void *);
+unsigned hash_var_ptr_name (const void *, void *);
- char filter_var[9]; /* Name of FILTER variable. */
- /* Do not make another field the last field! or see
- temporary.c:restore_dictionary() before doing so! */
+void *var_attach_aux (struct variable *,
+ void *aux, void (*aux_dtor) (struct variable *));
+void var_clear_aux (struct variable *);
+void *var_detach_aux (struct variable *);
+void var_dtor_free (struct variable *);
+
+/* Classes of variables. */
+enum dict_class
+ {
+ DC_ORDINARY, /* Ordinary identifier. */
+ DC_SYSTEM, /* System variable. */
+ DC_SCRATCH /* Scratch variable. */
};
+enum dict_class dict_class_from_id (const char *name);
+const char *dict_class_to_name (enum dict_class dict_class);
+\f
+/* Vector of variables. */
+struct vector
+ {
+ int idx; /* Index for dict_get_vector(). */
+ char name[SHORT_NAME_LEN + 1]; /* Name. */
+ struct variable **var; /* Vector of variables. */
+ int cnt; /* Number of variables. */
+ };
+\f
+\f
+void discard_variables (void);
+
/* This is the active file dictionary. */
-extern struct dictionary default_dict;
+extern struct dictionary *default_dict;
\f
/* Transformation state. */
\f
/* Functions. */
-int is_varname (const char *);
-int is_dict_varname (const struct dictionary *, const char *);
-
-/* Flags for passing to fill_all_vars(). */
-enum
- {
- FV_NONE = 0, /* No flags. */
- FV_NO_SYSTEM = 001, /* Don't include system variables. */
- FV_NO_SCRATCH = 002 /* Don't include scratch variables. */
- };
-
-void fill_all_vars (struct variable ***, int *, int flags);
-
-int val_lab_cmp (const void *, const void *, void *);
-char *get_val_lab (const struct variable *, union value, int);
-void free_val_lab (void *, void *);
-void free_value_label (struct value_label *);
-struct avl_tree *copy_value_labels (struct avl_tree *);
-
+struct ccase;
void dump_split_vars (const struct ccase *);
+typedef int (* is_missing_func )(const union value *, const struct variable *);
int is_num_user_missing (double, const struct variable *);
int is_str_user_missing (const unsigned char[], const struct variable *);
int is_system_missing (const union value *, const struct variable *);
int is_user_missing (const union value *, const struct variable *);
void copy_missing_values (struct variable *dest, const struct variable *src);
-
-int cmp_variable (const void *, const void *, void *);
-
-#if GLOBAL_DEBUGGING
-struct variable *force_create_variable (struct dictionary *, const char *name,
- int type, int width);
-struct variable *force_dup_variable (struct dictionary *,
- const struct variable *src,
- const char *name);
-#else
-#define force_create_variable(A, B, C, D) \
- create_variable (A, B, C, D)
-#define force_dup_variable(A, B, C) \
- dup_variable (A, B, C)
-#endif
-
-struct variable *create_variable (struct dictionary *, const char *name,
- int type, int width);
-void delete_variable (struct dictionary *, struct variable *v);
-struct variable *find_variable (const char *name);
-struct variable *find_dict_variable (const struct dictionary *,
- const char *name);
-void init_variable (struct dictionary *, struct variable *, const char *name,
- int type, int width);
-void replace_variable (struct variable *, const char *name,
- int type, int width);
-void clear_variable (struct dictionary *, struct variable *);
-void rename_variable (struct dictionary *, struct variable *v,
- const char *new_name);
-void discard_variables (void);
-void clear_default_dict (void);
-void copy_variable (struct variable *dest, const struct variable *src);
-struct variable *dup_variable (struct dictionary *dict,
- const struct variable *src, const char *name);
-
-struct variable *update_weighting (struct dictionary *);
-void stop_weighting (struct dictionary *);
-
-struct dictionary *save_dictionary (void);
-void restore_dictionary (struct dictionary *);
-void free_dictionary (struct dictionary *);
-struct dictionary *new_dictionary (int copy);
\f
/* Transformations. */
+struct trns_header;
+typedef int trns_proc_func (struct trns_header *, struct ccase *, int);
+typedef void trns_free_func (struct trns_header *);
+
/* Header for all transformations. */
struct trns_header
{
- /* Index into t_trns[]. */
- int index;
-
- /* Transformation proc. */
- int (*proc) (struct trns_header *, struct ccase *);
-
- /* Garbage collector proc. */
- void (*free) (struct trns_header *);
+ int index; /* Index into t_trns[]. */
+ trns_proc_func *proc; /* Transformation proc. */
+ trns_free_func *free; /* Garbage collector proc. */
};
/* Array of transformations */
void add_transformation (struct trns_header *trns);
void cancel_transformations (void);
\f
+struct var_set;
+
+struct var_set *var_set_create_from_dict (const struct dictionary *d);
+struct var_set *var_set_create_from_array (struct variable *const *var,
+ size_t);
+
+size_t var_set_get_cnt (const struct var_set *vs);
+struct variable *var_set_get_var (const struct var_set *vs, size_t idx);
+struct variable *var_set_lookup_var (const struct var_set *vs,
+ const char *name);
+int var_set_lookup_var_idx (const struct var_set *vs, const char *name);
+void var_set_destroy (struct var_set *vs);
+\f
/* Variable parsers. */
-/* Only parse_variables() supports options other than PV_APPEND,
- PV_SINGLE. */
enum
{
PV_NONE = 0, /* No options. */
- PV_SINGLE = 0001, /* Restrict to a single varname or TO use. */
+ PV_SINGLE = 0001, /* Restrict to a single name or TO use. */
PV_DUPLICATE = 0002, /* Don't merge duplicates. */
PV_APPEND = 0004, /* Append to existing list. */
PV_NO_DUPLICATE = 0010, /* Error on duplicates. */
PV_NUMERIC = 0020, /* Vars must be numeric. */
PV_STRING = 0040, /* Vars must be string. */
PV_SAME_TYPE = 00100, /* All vars must be the same type. */
- PV_NO_SCRATCH = 00200 /* Disallow scratch variables. */
+ PV_NO_SCRATCH = 00200 /* Disallow scratch variables. */
};
struct variable *parse_variable (void);
-struct variable *parse_dict_variable (struct dictionary *);
-int parse_variables (struct dictionary *dict, struct variable ***v,
- int *nv, int pv_opts);
-int parse_DATA_LIST_vars (char ***names, int *nnames, int pv_opts);
-int parse_mixed_vars (char ***names, int *nnames, int pv_opts);
+struct variable *parse_dict_variable (const struct dictionary *);
+int parse_variables (const struct dictionary *, struct variable ***, int *,
+ int opts);
+int parse_var_set_vars (const struct var_set *, struct variable ***, int *,
+ int opts);
+int parse_DATA_LIST_vars (char ***names, int *cnt, int opts);
+int parse_mixed_vars (char ***names, int *cnt, int opts);
+
+
+
+/* Return a string representing this variable, in the form most
+ appropriate from a human factors perspective.
+ (IE: the label if it has one, otherwise the name )
+*/
+const char * var_to_string(const struct variable *var);
+
#endif /* !var_h */