X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;ds=sidebyside;f=src%2Fmatrix-data.c;h=fd3d3807671c96fda81a872e48f90f0de18c8190;hb=5906e30c29662d12594199e1652ba3a7e5670944;hp=538074d0f0b568d35bcd77abf9981b1952f3920c;hpb=fcb9e49b2a2d57af7c001ae5d2eda9ac443ba36b;p=pspp diff --git a/src/matrix-data.c b/src/matrix-data.c index 538074d0f0..fd3d380767 100644 --- a/src/matrix-data.c +++ b/src/matrix-data.c @@ -17,28 +17,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* AIX requires this to be the first thing in the file. */ #include -#if __GNUC__ -#define alloca __builtin_alloca -#else -#if HAVE_ALLOCA_H -#include -#else -#ifdef _AIX -#pragma alloca -#else -#ifndef alloca /* predefined by HP cc +Olibcalls */ -char *alloca (); -#endif -#endif -#endif -#endif - #include #include #include #include +#include "algorithm.h" #include "alloc.h" #include "command.h" #include "data-in.h" @@ -232,8 +216,8 @@ cmd_matrix_data (void) if (strcmp (v[i], "ROWTYPE_")) { - new_var = force_create_variable (&default_dict, v[i], - NUMERIC, 0); + new_var = dict_create_var (default_dict, v[i], 0); + assert (new_var != NULL); new_var->p.mxd.vartype = MXD_CONTINUOUS; new_var->p.mxd.subtype = i; } @@ -245,8 +229,8 @@ cmd_matrix_data (void) } { - rowtype_ = force_create_variable (&default_dict, "ROWTYPE_", - ALPHA, 8); + rowtype_ = dict_create_var (default_dict, "ROWTYPE_", 8); + assert (rowtype_ != NULL); rowtype_->p.mxd.vartype = MXD_ROWTYPE; rowtype_->p.mxd.subtype = 0; } @@ -302,7 +286,7 @@ cmd_matrix_data (void) goto lossage; } - if (!is_varname (tokid) + if (dict_lookup_var (default_dict, tokid) == NULL && (lex_look_ahead () == '.' || lex_look_ahead () == '/')) { if (!strcmp (tokid, "ROWTYPE_") || !strcmp (tokid, "VARNAME_")) @@ -312,44 +296,41 @@ cmd_matrix_data (void) goto lossage; } - single_split = force_create_variable (&default_dict, tokid, - NUMERIC, 0); + single_split = dict_create_var (default_dict, tokid, 0); + assert (single_split != NULL); lex_get (); single_split->p.mxd.vartype = MXD_CONTINUOUS; - default_dict.n_splits = 1; - default_dict.splits = xmalloc (2 * sizeof *default_dict.splits); - default_dict.splits[0] = single_split; - default_dict.splits[1] = NULL; + dict_set_split_vars (default_dict, &single_split, 1); } else { - struct variable **v; + struct variable **split; int n; - if (!parse_variables (NULL, &v, &n, PV_NO_DUPLICATE)) + if (!parse_variables (default_dict, &split, &n, PV_NO_DUPLICATE)) goto lossage; - default_dict.n_splits = n; - default_dict.splits = v = xrealloc (v, sizeof *v * (n + 1)); - v[n] = NULL; + dict_set_split_vars (default_dict, split, n); } { - int i; - - for (i = 0; i < default_dict.n_splits; i++) - { - if (default_dict.splits[i]->p.mxd.vartype != MXD_CONTINUOUS) + struct variable *const *split = dict_get_split_vars (default_dict); + size_t split_cnt = dict_get_split_cnt (default_dict); + int i; + + for (i = 0; i < split_cnt; i++) + { + if (split[i]->p.mxd.vartype != MXD_CONTINUOUS) { msg (SE, _("Split variable %s is already another type."), tokid); goto lossage; } - default_dict.splits[i]->p.mxd.vartype = MXD_SPLIT; - default_dict.splits[i]->p.mxd.subtype = i; - } + split[i]->p.mxd.vartype = MXD_SPLIT; + split[i]->p.mxd.subtype = i; + } } } else if (lex_match_id ("FACTORS")) @@ -363,7 +344,7 @@ cmd_matrix_data (void) } seen |= 4; - if (!parse_variables (NULL, &factors, &n_factors, PV_NONE)) + if (!parse_variables (default_dict, &factors, &n_factors, PV_NONE)) goto lossage; { @@ -559,8 +540,8 @@ cmd_matrix_data (void) /* Create VARNAME_. */ { - varname_ = force_create_variable (&default_dict, "VARNAME_", - ALPHA, 8); + varname_ = dict_create_var (default_dict, "VARNAME_", 8); + assert (varname_ != NULL); varname_->p.mxd.vartype = MXD_VARNAME; varname_->p.mxd.subtype = 0; } @@ -568,13 +549,13 @@ cmd_matrix_data (void) /* Sort the dictionary variables into the desired order for the system file output. */ { - int i; - - qsort (default_dict.var, default_dict.nvar, sizeof *default_dict.var, - compare_variables_by_mxd_vartype); + struct variable **v; + size_t nv; - for (i = 0; i < default_dict.nvar; i++) - default_dict.var[i]->index = i; + dict_get_vars (default_dict, &v, &nv, 0); + qsort (v, nv, sizeof *v, compare_variables_by_mxd_vartype); + dict_reorder_vars (default_dict, v, nv); + free (v); } /* Set formats. */ @@ -591,9 +572,9 @@ cmd_matrix_data (void) int i; first_continuous = -1; - for (i = 0; i < default_dict.nvar; i++) + for (i = 0; i < dict_get_var_cnt (default_dict); i++) { - struct variable *v = default_dict.var[i]; + struct variable *v = dict_get_var (default_dict, i); int type = v->p.mxd.vartype; assert (type >= 0 && type < MXD_COUNT); @@ -680,14 +661,17 @@ string_to_content_type (char *s, int *collide) /* Compare two variables using p.mxd.vartype and p.mxd.subtype fields. */ static int -compare_variables_by_mxd_vartype (const void *pa, const void *pb) +compare_variables_by_mxd_vartype (const void *a_, const void *b_) { - struct matrix_data_proc *a = &(*((struct variable **) pa))->p.mxd; - struct matrix_data_proc *b = &(*((struct variable **) pb))->p.mxd; - - return (a->vartype != b->vartype - ? a->vartype - b->vartype - : a->subtype - b->subtype); + struct variable *const *pa = a_; + struct variable *const *pb = b_; + const struct matrix_data_proc *a = &(*pa)->p.mxd; + const struct matrix_data_proc *b = &(*pb)->p.mxd; + + if (a->vartype != b->vartype) + return a->vartype > b->vartype ? 1 : -1; + else + return a->subtype < b->subtype ? -1 : a->subtype > b->subtype; } #if DEBUGGING @@ -727,13 +711,13 @@ debug_print (void) else assert (0); - if (default_dict.n_splits) + if (dict_get_split_cnt (default_dict) != 0) { int i; printf ("\t/SPLIT="); - for (i = 0; i < default_dict.n_splits; i++) - printf ("%s ", default_dict.splits[i]->name); + for (i = 0; i < dict_get_split_cnt (default_dict); i++) + printf ("%s ", dict_get_split_vars (default_dict)[i]->name); if (single_split) printf ("\t/* single split"); printf ("\n"); @@ -1045,8 +1029,9 @@ static double *split_values; static int nr_read_splits (int compare); static int nr_read_factors (int cell); -static void nr_output_data (void); -static int matrix_data_read_without_rowtype (void); +static void nr_output_data (write_case_func *, write_case_data); +static void matrix_data_read_without_rowtype (write_case_func *, + write_case_data); /* Read from the data file and write it to the active file. */ static void @@ -1056,14 +1041,15 @@ read_matrices_without_rowtype (void) cells = 1; mtoken = MNULL; - split_values = xmalloc (sizeof *split_values * default_dict.n_splits); + split_values = xmalloc (sizeof *split_values + * dict_get_split_cnt (default_dict)); nr_factor_values = xmalloc (sizeof *nr_factor_values * n_factors * cells); max_cell_index = 0; - matrix_data_source.read = (void (*)(void)) matrix_data_read_without_rowtype; + matrix_data_source.read = matrix_data_read_without_rowtype; vfm_source = &matrix_data_source; - procedure (NULL, NULL, NULL); + procedure (NULL, NULL, NULL, NULL); free (split_values); free (nr_factor_values); @@ -1206,7 +1192,7 @@ nr_read_data_lines (int per_factor, int cell, int content, int compare) if (mtoken != MNUM) { msg (SE, _("expecting value for %s %s"), - default_dict.var[j]->name, context ()); + dict_get_var (default_dict, j)->name, context ()); return 0; } @@ -1228,8 +1214,9 @@ nr_read_data_lines (int per_factor, int cell, int content, int compare) /* When ROWTYPE_ does not appear in the data, reads the matrices and writes them to the output file. Returns success. */ -static int -matrix_data_read_without_rowtype (void) +static void +matrix_data_read_without_rowtype (write_case_func *write_case, + write_case_data wc_data) { { int *cp; @@ -1272,7 +1259,7 @@ matrix_data_read_without_rowtype (void) int *bp, *ep, *np; if (!nr_read_splits (0)) - return 0; + return; for (bp = contents; *bp != EOC; bp = np) { @@ -1307,15 +1294,15 @@ matrix_data_read_without_rowtype (void) for (cp = bp; cp < ep; cp++) if (!nr_read_data_lines (per_factor, i, *cp, cp != bp)) - return 0; + return; } } } - nr_output_data (); + nr_output_data (write_case, wc_data); - if (default_dict.n_splits == 0 || !another_token ()) - return 1; + if (dict_get_split_cnt (default_dict) == 0 || !another_token ()) + return; } } @@ -1326,6 +1313,8 @@ static int nr_read_splits (int compare) { static int just_read = 0; + size_t split_cnt; + size_t i; if (compare && just_read) { @@ -1333,43 +1322,41 @@ nr_read_splits (int compare) return 1; } - if (default_dict.n_splits == 0) + if (dict_get_split_vars (default_dict) == NULL) return 1; if (single_split) { if (!compare) - split_values[0] = ++default_dict.splits[0]->p.mxd.subtype; + split_values[0] + = ++dict_get_split_vars (default_dict)[0]->p.mxd.subtype; return 1; } if (!compare) just_read = 1; - - { - int i; - - for (i = 0; i < default_dict.n_splits; i++) - { - if (!mget_token ()) - return 0; - if (mtoken != MNUM) - { - msg (SE, _("Syntax error expecting SPLIT FILE value %s."), - context ()); - return 0; - } - if (!compare) - split_values[i] = mtokval; - else if (split_values[i] != mtokval) - { - msg (SE, _("Expecting value %g for %s."), - split_values[i], default_dict.splits[i]->name); - return 0; - } - } - } + split_cnt = dict_get_split_cnt (default_dict); + for (i = 0; i < split_cnt; i++) + { + if (!mget_token ()) + return 0; + if (mtoken != MNUM) + { + msg (SE, _("Syntax error expecting SPLIT FILE value %s."), + context ()); + return 0; + } + + if (!compare) + split_values[i] = mtokval; + else if (split_values[i] != mtokval) + { + msg (SE, _("Expecting value %g for %s."), + split_values[i], dict_get_split_vars (default_dict)[i]->name); + return 0; + } + } return 1; } @@ -1426,7 +1413,8 @@ nr_read_factors (int cell) /* Write the contents of a cell having content type CONTENT and data CP to the active file. */ static void -dump_cell_content (int content, double *cp) +dump_cell_content (int content, double *cp, + write_case_func *write_case, write_case_data wc_data) { int type = content_type[content]; @@ -1448,32 +1436,32 @@ dump_cell_content (int content, double *cp) for (j = 0; j < n_continuous; j++) { - temp_case->data[(default_dict.var - [first_continuous + j]->fv)].f = *cp; - debug_printf (("c:%s(%g) ", - default_dict.var[first_continuous + j]->name, - *cp)); + int fv = dict_get_var (default_dict, first_continuous + j)->fv; + temp_case->data[fv].f = *cp; cp++; } if (type == 1) st_bare_pad_copy (temp_case->data[varname_->fv].s, - default_dict.var[first_continuous + i]->name, + dict_get_var (default_dict, + first_continuous + i)->name, 8); - debug_printf (("\n")); - write_case (); + write_case (wc_data); } } } /* Finally dump out everything from nr_data[] to the output file. */ static void -nr_output_data (void) +nr_output_data (write_case_func *write_case, write_case_data wc_data) { { - int i; + struct variable *const *split; + size_t split_cnt; + size_t i; - for (i = 0; i < default_dict.n_splits; i++) - temp_case->data[default_dict.splits[i]->fv].f = split_values[i]; + split_cnt = dict_get_split_cnt (default_dict); + for (i = 0; i < split_cnt; i++) + temp_case->data[split[i]->fv].f = split_values[i]; } if (n_factors) @@ -1502,7 +1490,8 @@ nr_output_data (void) assert (nr_data[content] != NULL && nr_data[content][cell] != NULL); - dump_cell_content (content, nr_data[content][cell]); + dump_cell_content (content, nr_data[content][cell], + write_case, wc_data); } } } @@ -1520,7 +1509,8 @@ nr_output_data (void) for (content = 0; content <= PROX; content++) if (!is_per_factor[content] && nr_data[content] != NULL) - dump_cell_content (content, nr_data[content][0]); + dump_cell_content (content, nr_data[content][0], + write_case, wc_data); } } @@ -1544,12 +1534,13 @@ struct factor_data *wr_data; /* Current factor. */ struct factor_data *wr_current; -static int wr_read_splits (void); -static int wr_output_data (void); +static int wr_read_splits (write_case_func *, write_case_data); +static int wr_output_data (write_case_func *, write_case_data); static int wr_read_rowtype (void); static int wr_read_factors (void); static int wr_read_indeps (void); -static int matrix_data_read_with_rowtype (void); +static void matrix_data_read_with_rowtype (write_case_func *, + write_case_data); /* When ROWTYPE_ appears in the data, reads the matrices and writes them to the output file. */ @@ -1561,44 +1552,46 @@ read_matrices_with_rowtype (void) split_values = NULL; cells = 0; - matrix_data_source.read = (void (*)(void)) matrix_data_read_with_rowtype; + matrix_data_source.read = matrix_data_read_with_rowtype; vfm_source = &matrix_data_source; - procedure (NULL, NULL, NULL); + procedure (NULL, NULL, NULL, NULL); free (split_values); fh_close_handle (data_file); } /* Read from the data file and write it to the active file. */ -static int -matrix_data_read_with_rowtype (void) +static void +matrix_data_read_with_rowtype (write_case_func *write_case, + write_case_data wc_data) { do { - if (!wr_read_splits ()) - return 0; + if (!wr_read_splits (write_case, wc_data)) + return; if (!wr_read_factors ()) - return 0; + return; if (!wr_read_indeps ()) - return 0; + return; } while (another_token ()); - wr_output_data (); - return 1; + wr_output_data (write_case, wc_data); } /* Read the split file variables. If they differ from the previous set of split variables then output the data. Returns success. */ static int -wr_read_splits (void) +wr_read_splits (write_case_func *write_case, write_case_data wc_data) { int compare; - - if (default_dict.n_splits == 0) + size_t split_cnt; + + split_cnt = dict_get_split_cnt (default_dict); + if (split_cnt == 0) return 1; if (split_values) @@ -1606,14 +1599,15 @@ wr_read_splits (void) else { compare = 0; - split_values = xmalloc (sizeof *split_values * default_dict.n_splits); + split_values = xmalloc (split_cnt * sizeof *split_values); } { int different = 0; + size_t split_cnt; int i; - - for (i = 0; i < default_dict.n_splits; i++) + + for (i = 0; i < split_cnt; i++) { if (!mget_token ()) return 0; @@ -1626,7 +1620,7 @@ wr_read_splits (void) if (compare && split_values[i] != mtokval && !different) { - if (!wr_output_data ()) + if (!wr_output_data (write_case, wc_data)) return 0; different = 1; cells = 0; @@ -1638,41 +1632,54 @@ wr_read_splits (void) return 1; } -/* Return strcmp()-type comparison of the n_factors factors at _A and - _B. Sort missing values toward the end. */ +/* Compares doubles A and B, treating SYSMIS as greatest. */ static int -compare_factors (const void *pa, const void *pb) +compare_doubles (const void *a_, const void *b_, void *aux UNUSED) { - const double *a = (*(struct factor_data **) pa)->factors; - const double *b = (*(struct factor_data **) pb)->factors; - int i; + const double *a = a_; + const double *b = b_; - for (i = 0; i < n_factors; i++, a++, b++) - { - if (*a == *b) - continue; - - if (*a == SYSMIS) - return 1; - else if (*b == SYSMIS) - return -1; - else - return *a - *b < 0 ? -1 : 1; - } + if (*a == *b) + return 0; + else if (*a == SYSMIS) + return 1; + else if (*b == SYSMIS) + return -1; + else if (*a > *b) + return 1; + else + return -1; +} - return 0; +/* Return strcmp()-type comparison of the n_factors factors at _A and + _B. Sort missing values toward the end. */ +static int +compare_factors (const void *a_, const void *b_) +{ + struct factor_data *const *pa = a_; + struct factor_data *const *pb = b_; + const double *a = (*pa)->factors; + const double *b = (*pb)->factors; + + return lexicographical_compare (a, n_factors, + b, n_factors, + sizeof *a, + compare_doubles, NULL); } /* Write out the data for the current split file to the active file. */ static int -wr_output_data (void) +wr_output_data (write_case_func *write_case, write_case_data wc_data) { { - int i; + struct variable *const *split; + size_t split_cnt; + size_t i; - for (i = 0; i < default_dict.n_splits; i++) - temp_case->data[default_dict.splits[i]->fv].f = split_values[i]; + split_cnt = dict_get_split_cnt (default_dict); + for (i = 0; i < split_cnt; i++) + temp_case->data[split[i]->fv].f = split_values[i]; } /* Sort the wr_data list. */ @@ -1741,7 +1748,8 @@ wr_output_data (void) fill_matrix (content, iter->data[content]); - dump_cell_content (content, iter->data[content]); + dump_cell_content (content, iter->data[content], + write_case, wc_data); } } } @@ -1989,7 +1997,8 @@ wr_read_indeps (void) if (mtoken != MNUM) { msg (SE, _("Syntax error expecting value for %s %s."), - default_dict.var[first_continuous + j]->name, context ()); + dict_get_var (default_dict, first_continuous + j)->name, + context ()); return 0; }