X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fcount.c;h=90275084a6e5848f1ef01f31ea411a938168bb48;hb=45b8514ebb8a7b10eb5d911a231a9fc7974f8ba9;hp=7c0420def0401f8540bad79c90777420a410a2b8;hpb=3838b041ea9a749d3a0d604f62f7d9523f91f3d8;p=pspp-builds.git diff --git a/src/count.c b/src/count.c index 7c0420de..90275084 100644 --- a/src/count.c +++ b/src/count.c @@ -14,20 +14,24 @@ 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. */ #include -#include +#include "error.h" #include #include "alloc.h" -#include "approx.h" +#include "case.h" #include "command.h" +#include "dictionary.h" #include "error.h" #include "lexer.h" #include "str.h" #include "var.h" +#include "gettext.h" +#define _(msgid) gettext (msgid) + /* Implementation details: The S?SS manuals do not specify the order that COUNT subcommands are @@ -55,8 +59,6 @@ Perhaps simultaneity could be implemented as an option. On the other hand, what good are the above commands? */ - -#include "debug-print.h" /* Definitions. */ @@ -109,7 +111,7 @@ struct cnt_var_info struct cnt_var_info *next; struct variable *d; /* Destination variable. */ - char n[9]; /* Name of dest var. */ + char n[LONG_NAME_LEN + 1]; /* Name of dest var. */ struct counting *c; /* The counting specifications. */ }; @@ -119,53 +121,23 @@ struct count_trns struct trns_header h; struct cnt_var_info *specs; }; - -#if DEBUGGING -static void debug_print (void); -#endif - -/* First counting in chain. */ -static struct cnt_var_info *head; /* Parser. */ -static int count_trns_proc (struct trns_header *, struct ccase *); -static void count_trns_free (struct trns_header *); +static trns_proc_func count_trns_proc; +static trns_free_func count_trns_free; static int parse_numeric_criteria (struct counting *); static int parse_string_criteria (struct counting *); -int cmd_count (void); - -int -internal_cmd_count (void) -{ - int code = cmd_count (); - if (!code) - { - struct count_trns c; - c.specs = head; - count_trns_free ((struct trns_header *) & c); - } - return code; -} - int cmd_count (void) { - /* Specification currently being parsed. */ - struct cnt_var_info *cnt; - - /* Counting currently being parsed. */ - struct counting *c; - - /* Return value from parsing function. */ - int ret; - - /* Transformation. */ - struct count_trns *trns; - - lex_match_id ("COUNT"); + struct cnt_var_info *cnt; /* Specification currently being parsed. */ + struct counting *c; /* Counting currently being parsed. */ + int ret; /* Return value from parsing function. */ + struct count_trns *trns; /* Transformation. */ + struct cnt_var_info *head; /* First counting in chain. */ /* Parses each slash-delimited specification. */ head = cnt = xmalloc (sizeof *cnt); @@ -176,10 +148,10 @@ cmd_count (void) cnt->d = NULL; cnt->c = NULL; - /* Get destination struct variable, or at least its name. */ + /* Get destination variable, or at least its name. */ if (!lex_force_id ()) goto fail; - cnt->d = find_variable (tokid); + cnt->d = dict_lookup_var (default_dict, tokid); if (cnt->d) { if (cnt->d->type == ALPHA) @@ -189,7 +161,7 @@ cmd_count (void) } } else - strcpy (cnt->n, tokid); + str_copy_trunc (cnt->n, sizeof cnt->n, tokid); lex_get (); if (!lex_force_match ('=')) @@ -200,7 +172,8 @@ cmd_count (void) { c->next = NULL; c->v = NULL; - if (!parse_variables (NULL, &c->v, &c->n, PV_DUPLICATE | PV_SAME_TYPE)) + if (!parse_variables (default_dict, &c->v, &c->n, + PV_DUPLICATE | PV_SAME_TYPE)) goto fail; if (!lex_force_match ('(')) @@ -230,18 +203,14 @@ cmd_count (void) for (cnt = head; cnt; cnt = cnt->next) if (!cnt->d) { - /* It's legal, though motivationally questionable, to count to + /* It's valid, though motivationally questionable, to count to the same dest var more than once. */ - cnt->d = find_variable (cnt->n); + cnt->d = dict_lookup_var (default_dict, cnt->n); - if (!cnt->d) - cnt->d = force_create_variable (&default_dict, cnt->n, NUMERIC, 0); + if (cnt->d == NULL) + cnt->d = dict_create_var_assert (default_dict, cnt->n, 0); } -#if DEBUGGING - debug_print (); -#endif - trns = xmalloc (sizeof *trns); trns->h.proc = count_trns_proc; trns->h.free = count_trns_free; @@ -278,13 +247,13 @@ parse_numeric_criteria (struct counting * c) } cur = &c->crit.n[n++]; - if (token == T_NUM) + if (lex_is_number ()) { cur->a = tokval; lex_get (); if (lex_match_id ("THRU")) { - if (token == T_NUM) + if (lex_is_number ()) { if (!lex_force_num ()) return 0; @@ -316,7 +285,7 @@ parse_numeric_criteria (struct counting * c) { if (!lex_force_match_id ("THRU")) return 0; - if (token == T_NUM) + if (lex_is_number ()) { cur->type = CNT_LOW; cur->a = tokval; @@ -383,7 +352,7 @@ parse_string_criteria (struct counting * c) cur = &c->crit.s[n++]; cur->type = CNT_SINGLE; cur->s = malloc (len + 1); - st_pad_copy (cur->s, ds_value (&tokstr), len + 1); + str_copy_rpad (cur->s, len + 1, ds_c_str (&tokstr)); lex_get (); lex_match (','); @@ -402,23 +371,21 @@ static inline int count_numeric (struct counting * cnt, struct ccase * c) { int counter = 0; - - struct cnt_num *num; - - double cmp; int i; for (i = 0; i < cnt->n; i++) { + struct cnt_num *num; + /* Extract the variable value and eliminate missing values. */ - cmp = c->data[cnt->v[i]->fv].f; + double cmp = case_num (c, cnt->v[i]->fv); if (cmp == SYSMIS) { if (cnt->missing >= 1) counter++; continue; } - if (cnt->missing >= 2 && is_num_user_missing (cmp, cnt->v[i])) + if (cnt->missing >= 2 && mv_is_num_user_missing (&cnt->v[i]->miss, cmp)) { counter++; continue; @@ -432,22 +399,22 @@ count_numeric (struct counting * cnt, struct ccase * c) assert (0); break; case CNT_SINGLE: - if (approx_ne (cmp, num->a)) + if (cmp != num->a) break; counter++; goto done; case CNT_HIGH: - if (approx_lt (cmp, num->a)) + if (cmp < num->a) break; counter++; goto done; case CNT_LOW: - if (approx_gt (cmp, num->a)) + if (cmp > num->a) break; counter++; goto done; case CNT_RANGE: - if (approx_lt (cmp, num->a) || approx_gt (cmp, num->b)) + if (cmp < num->a || cmp > num->b) break; counter++; goto done; @@ -469,27 +436,21 @@ static inline int count_string (struct counting * cnt, struct ccase * c) { int counter = 0; - - struct cnt_str *str; - - char *cmp; - int len; - int i; for (i = 0; i < cnt->n; i++) { - /* Extract the variable value, variable width. */ - cmp = c->data[cnt->v[i]->fv].s; - len = cnt->v[i]->width; + struct cnt_str *str; + /* Extract the variable value, variable width. */ for (str = cnt->crit.s;; str++) switch (str->type) { case CNT_ERROR: assert (0); case CNT_SINGLE: - if (memcmp (cmp, str->s, len)) + if (memcmp (case_str (c, cnt->v[i]->fv), str->s, + cnt->v[i]->width)) break; counter++; goto done; @@ -505,7 +466,8 @@ count_string (struct counting * cnt, struct ccase * c) /* Performs the COUNT transformation T on case C. */ static int -count_trns_proc (struct trns_header * trns, struct ccase * c) +count_trns_proc (struct trns_header * trns, struct ccase * c, + int case_num UNUSED) { struct cnt_var_info *info; struct counting *cnt; @@ -519,7 +481,7 @@ count_trns_proc (struct trns_header * trns, struct ccase * c) counter += count_numeric (cnt, c); else counter += count_string (cnt, c); - c->data[info->d->fv].f = counter; + case_data_rw (c, info->d->fv)->f = counter; } return -1; } @@ -559,81 +521,3 @@ count_trns_free (struct trns_header * t) free (iter); } } - -/* Debugging. */ - -#if DEBUGGING -static void -debug_print (void) -{ - struct cnt_var_info *iter; - struct counting *i; - int j; - - printf ("COUNT\n"); - for (iter = head; iter; iter = iter->next) - { - printf (" %s=", iter->d->name); - for (i = iter->c; i; i = i->next) - { - for (j = 0; j < i->n; j++) - printf ("%s%s", j ? " " : "", i->v[j]->name); - printf (" ("); - if (i->v[0]->type == NUMERIC) - { - struct cnt_num *n; - - if (i->missing == 2) - printf ("MISSING"); - else if (i->missing == 1) - printf ("SYSMIS"); - else - assert (i->missing == 0); - - for (n = i->crit.n; n->type != CNT_SENTINEL; n++) - { - if (i->missing && n != i->crit.n) - printf (","); - switch (n->type) - { - case CNT_SINGLE: - printf ("%g", n->a); - break; - case CNT_HIGH: - printf ("%g THRU HIGH", n->a); - break; - case CNT_LOW: - printf ("LOW THRU %g", n->a); - break; - case CNT_RANGE: - printf ("%g THRU %g", n->a, n->b); - break; - case CNT_ANY: - printf ("LOW THRU HIGH"); - break; - default: - printf ("", n->type); - break; - } - } - } - else - { - struct cnt_str *s; - - for (s = i->crit.s; s->type != CNT_SENTINEL; s++) - { - if (s != i->crit.s) - printf (","); - if (s->type == CNT_SINGLE) - printf ("'%s'", s->s); - else - printf ("", s->type); - } - } - printf (") "); - } - printf ("\n"); - } -} -#endif /* DEBUGGING */