X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flanguage%2Fxforms%2Fcount.c;h=9db76f6c652b11e5a12586208eb83102faa1fd51;hb=f4491cda2715c59495d963d0a3d8ae4518c1c13d;hp=c42bdc34cf01bedba7d5aa86756cdefca797ee4b;hpb=fe8dc2171009e90d2335f159d05f7e6660e24780;p=pspp diff --git a/src/language/xforms/count.c b/src/language/xforms/count.c index c42bdc34cf..9db76f6c65 100644 --- a/src/language/xforms/count.c +++ b/src/language/xforms/count.c @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 1997-9, 2000, 2009, 2010, 2011 Free Software Foundation, Inc. + Copyright (C) 1997-9, 2000, 2009, 2010, 2011, 2015 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -58,14 +58,14 @@ struct criteria /* Variables to count. */ const struct variable **vars; - size_t var_cnt; + size_t n_vars; /* Count special values? */ bool count_system_missing; /* Count system missing? */ bool count_user_missing; /* Count user missing? */ /* Criterion values. */ - size_t value_cnt; + size_t n_values; union { struct num_value *num; @@ -88,13 +88,13 @@ struct count_trns struct pool *pool; }; -static trns_proc_func count_trns_proc; -static trns_free_func count_trns_free; +static const struct trns_class count_trns_class; static bool parse_numeric_criteria (struct lexer *, struct pool *, struct criteria *); static bool parse_string_criteria (struct lexer *, struct pool *, struct criteria *, const char *dict_encoding); +static bool count_trns_free (void *trns_); int cmd_count (struct lexer *lexer, struct dataset *ds) @@ -142,7 +142,7 @@ cmd_count (struct lexer *lexer, struct dataset *ds) crit->next = NULL; crit->vars = NULL; if (!parse_variables_const (lexer, dict, &crit->vars, - &crit->var_cnt, + &crit->n_vars, PV_DUPLICATE | PV_SAME_TYPE)) goto fail; pool_register (trns->pool, free, crit->vars); @@ -150,7 +150,7 @@ cmd_count (struct lexer *lexer, struct dataset *ds) if (!lex_force_match (lexer, T_LPAREN)) goto fail; - crit->value_cnt = 0; + crit->n_values = 0; if (var_is_numeric (crit->vars[0])) ok = parse_numeric_criteria (lexer, trns->pool, crit); else @@ -185,7 +185,7 @@ cmd_count (struct lexer *lexer, struct dataset *ds) dv->var = dict_create_var_assert (dataset_dict (ds), dv->name, 0); } - add_transformation (ds, count_trns_proc, count_trns_free, trns); + add_transformation (ds, &count_trns_class, trns); return CMD_SUCCESS; fail: @@ -209,16 +209,16 @@ parse_numeric_criteria (struct lexer *lexer, struct pool *pool, struct criteria if (lex_match_id (lexer, "SYSMIS")) crit->count_system_missing = true; else if (lex_match_id (lexer, "MISSING")) - crit->count_user_missing = true; + crit->count_system_missing = crit->count_user_missing = true; else if (parse_num_range (lexer, &low, &high, NULL)) { struct num_value *cur; - if (crit->value_cnt >= allocated) + if (crit->n_values >= allocated) crit->values.num = pool_2nrealloc (pool, crit->values.num, &allocated, sizeof *crit->values.num); - cur = &crit->values.num[crit->value_cnt++]; + cur = &crit->values.num[crit->n_values++]; cur->type = low == high ? CNT_SINGLE : CNT_RANGE; cur->a = low; cur->b = high; @@ -242,7 +242,7 @@ parse_string_criteria (struct lexer *lexer, struct pool *pool, size_t allocated = 0; size_t i; - for (i = 0; i < crit->var_cnt; i++) + for (i = 0; i < crit->n_vars; i++) if (var_get_width (crit->vars[i]) > len) len = var_get_width (crit->vars[i]); @@ -252,7 +252,7 @@ parse_string_criteria (struct lexer *lexer, struct pool *pool, char **cur; char *s; - if (crit->value_cnt >= allocated) + if (crit->n_values >= allocated) crit->values.str = pool_2nrealloc (pool, crit->values.str, &allocated, sizeof *crit->values.str); @@ -263,7 +263,7 @@ parse_string_criteria (struct lexer *lexer, struct pool *pool, s = recode_string (dict_encoding, "UTF-8", lex_tokcstr (lexer), ss_length (lex_tokss (lexer))); - cur = &crit->values.str[crit->value_cnt++]; + cur = &crit->values.str[crit->n_values++]; *cur = pool_alloc (pool, len + 1); str_copy_rpad (*cur, len + 1, s); lex_get (lexer); @@ -287,28 +287,28 @@ count_numeric (struct criteria *crit, const struct ccase *c) int counter = 0; size_t i; - for (i = 0; i < crit->var_cnt; i++) + for (i = 0; i < crit->n_vars; i++) { double x = case_num (c, crit->vars[i]); - if (var_is_num_missing (crit->vars[i], x, MV_ANY)) - { - if (x == SYSMIS - ? crit->count_system_missing - : crit->count_user_missing) + struct num_value *v; + + for (v = crit->values.num; v < crit->values.num + crit->n_values; + v++) + if (v->type == CNT_SINGLE ? x == v->a : x >= v->a && x <= v->b) + { counter++; - } - else + break; + } + + if (var_is_num_missing (crit->vars[i], x) + && (x == SYSMIS + ? crit->count_system_missing + : crit->count_user_missing)) { - struct num_value *v; - - for (v = crit->values.num; v < crit->values.num + crit->value_cnt; - v++) - if (v->type == CNT_SINGLE ? x == v->a : x >= v->a && x <= v->b) - { - counter++; - break; - } + counter++; + continue; } + } return counter; @@ -321,10 +321,10 @@ count_string (struct criteria *crit, const struct ccase *c) int counter = 0; size_t i; - for (i = 0; i < crit->var_cnt; i++) + for (i = 0; i < crit->n_vars; i++) { char **v; - for (v = crit->values.str; v < crit->values.str + crit->value_cnt; v++) + for (v = crit->values.str; v < crit->values.str + crit->n_values; v++) if (!memcmp (case_str (c, crit->vars[i]), *v, var_get_width (crit->vars[i]))) { @@ -337,7 +337,7 @@ count_string (struct criteria *crit, const struct ccase *c) } /* Performs the COUNT transformation T on case C. */ -static int +static enum trns_result count_trns_proc (void *trns_, struct ccase **c, casenumber case_num UNUSED) { @@ -356,7 +356,7 @@ count_trns_proc (void *trns_, struct ccase **c, counter += count_numeric (crit, *c); else counter += count_string (crit, *c); - case_data_rw (*c, dv->var)->f = counter; + *case_num_rw (*c, dv->var) = counter; } return TRNS_CONTINUE; } @@ -369,3 +369,9 @@ count_trns_free (void *trns_) pool_destroy (trns->pool); return true; } + +static const struct trns_class count_trns_class = { + .name = "COUNT", + .execute = count_trns_proc, + .destroy = count_trns_free, +};