X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flanguage%2Fxforms%2Fcount.c;h=172a5e2c6d19238f692beb29c0d6388304a42eed;hb=81579d9e9f994fb2908f50af41c3eb033d216e58;hp=39f04574975faa4732cc682878937f888d1b222d;hpb=48386ee68a5283653435d05a9ea4e449710fd370;p=pspp-builds.git diff --git a/src/language/xforms/count.c b/src/language/xforms/count.c index 39f04574..172a5e2c 100644 --- a/src/language/xforms/count.c +++ b/src/language/xforms/count.c @@ -1,40 +1,38 @@ -/* PSPP - computes sample statistics. - Copyright (C) 1997-9, 2000 Free Software Foundation, Inc. +/* PSPP - a program for statistical analysis. + Copyright (C) 1997-9, 2000, 2009, 2010, 2011 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 the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. + 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 + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. 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., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. */ + along with this program. If not, see . */ #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "data/case.h" +#include "data/dictionary.h" +#include "data/procedure.h" +#include "data/transformations.h" +#include "data/variable.h" +#include "language/command.h" +#include "language/lexer/lexer.h" +#include "language/lexer/value-parser.h" +#include "language/lexer/variable-parser.h" +#include "libpspp/compiler.h" +#include "libpspp/message.h" +#include "libpspp/pool.h" +#include "libpspp/str.h" + +#include "gl/xalloc.h" #include "gettext.h" #define _(msgid) gettext (msgid) @@ -65,7 +63,7 @@ struct criteria bool count_system_missing; /* Count system missing? */ bool count_user_missing; /* Count user missing? */ - /* Criterion values. */ + /* Criterion values. */ size_t value_cnt; union { @@ -116,7 +114,7 @@ cmd_count (struct lexer *lexer, struct dataset *ds) /* Get destination variable, or at least its name. */ if (!lex_force_id (lexer)) goto fail; - dv->var = dict_lookup_var (dataset_dict (ds), lex_tokid (lexer)); + dv->var = dict_lookup_var (dataset_dict (ds), lex_tokcstr (lexer)); if (dv->var != NULL) { if (var_is_alpha (dv->var)) @@ -126,10 +124,10 @@ cmd_count (struct lexer *lexer, struct dataset *ds) } } else - dv->name = pool_strdup (trns->pool, lex_tokid (lexer)); + dv->name = pool_strdup (trns->pool, lex_tokcstr (lexer)); lex_get (lexer); - if (!lex_force_match (lexer, '=')) + if (!lex_force_match (lexer, T_EQUALS)) goto fail; crit = dv->crit = pool_alloc (trns->pool, sizeof *crit); @@ -139,13 +137,13 @@ cmd_count (struct lexer *lexer, struct dataset *ds) crit->next = NULL; crit->vars = NULL; - if (!parse_variables_const (lexer, dataset_dict (ds), &crit->vars, + if (!parse_variables_const (lexer, dataset_dict (ds), &crit->vars, &crit->var_cnt, PV_DUPLICATE | PV_SAME_TYPE)) goto fail; pool_register (trns->pool, free, crit->vars); - if (!lex_force_match (lexer, '(')) + if (!lex_force_match (lexer, T_LPAREN)) goto fail; crit->value_cnt = 0; @@ -156,16 +154,16 @@ cmd_count (struct lexer *lexer, struct dataset *ds) if (!ok) goto fail; - if (lex_token (lexer) == '/' || lex_token (lexer) == '.') + if (lex_token (lexer) == T_SLASH || lex_token (lexer) == T_ENDCMD) break; crit = crit->next = pool_alloc (trns->pool, sizeof *crit); } - if (lex_token (lexer) == '.') + if (lex_token (lexer) == T_ENDCMD) break; - if (!lex_force_match (lexer, '/')) + if (!lex_force_match (lexer, T_SLASH)) goto fail; dv = dv->next = pool_alloc (trns->pool, sizeof *dv); } @@ -178,7 +176,7 @@ cmd_count (struct lexer *lexer, struct dataset *ds) the same dest var more than once. */ dv->var = dict_lookup_var (dataset_dict (ds), dv->name); - if (dv->var == NULL) + if (dv->var == NULL) dv->var = dict_create_var_assert (dataset_dict (ds), dv->name, 0); } @@ -202,12 +200,12 @@ parse_numeric_criteria (struct lexer *lexer, struct pool *pool, struct criteria for (;;) { double low, high; - + if (lex_match_id (lexer, "SYSMIS")) crit->count_system_missing = true; else if (lex_match_id (lexer, "MISSING")) crit->count_user_missing = true; - else if (parse_num_range (lexer, &low, &high, NULL)) + else if (parse_num_range (lexer, &low, &high, NULL)) { struct num_value *cur; @@ -223,8 +221,8 @@ parse_numeric_criteria (struct lexer *lexer, struct pool *pool, struct criteria else return false; - lex_match (lexer, ','); - if (lex_match (lexer, ')')) + lex_match (lexer, T_COMMA); + if (lex_match (lexer, T_RPAREN)) break; } return true; @@ -255,11 +253,11 @@ parse_string_criteria (struct lexer *lexer, struct pool *pool, struct criteria * return false; cur = &crit->values.str[crit->value_cnt++]; *cur = pool_alloc (pool, len + 1); - str_copy_rpad (*cur, len + 1, ds_cstr (lex_tokstr (lexer))); + str_copy_rpad (*cur, len + 1, lex_tokcstr (lexer)); lex_get (lexer); - lex_match (lexer, ','); - if (lex_match (lexer, ')')) + lex_match (lexer, T_COMMA); + if (lex_match (lexer, T_RPAREN)) break; } @@ -269,8 +267,8 @@ parse_string_criteria (struct lexer *lexer, struct pool *pool, struct criteria * /* Transformation. */ /* Counts the number of values in case C matching CRIT. */ -static inline int -count_numeric (struct criteria *crit, struct ccase *c) +static int +count_numeric (struct criteria *crit, const struct ccase *c) { int counter = 0; size_t i; @@ -283,28 +281,28 @@ count_numeric (struct criteria *crit, struct ccase *c) if (x == SYSMIS ? crit->count_system_missing : crit->count_user_missing) - counter++; + counter++; } - else + else { 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) + v++) + if (v->type == CNT_SINGLE ? x == v->a : x >= v->a && x <= v->b) { counter++; break; - } + } } } - + return counter; } /* Counts the number of values in case C matching CRIT. */ -static inline int -count_string (struct criteria *crit, struct ccase *c) +static int +count_string (struct criteria *crit, const struct ccase *c) { int counter = 0; size_t i; @@ -326,12 +324,13 @@ count_string (struct criteria *crit, struct ccase *c) /* Performs the COUNT transformation T on case C. */ static int -count_trns_proc (void *trns_, struct ccase *c, +count_trns_proc (void *trns_, struct ccase **c, casenumber case_num UNUSED) { struct count_trns *trns = trns_; struct dst_var *dv; + *c = case_unshare (*c); for (dv = trns->dst_vars; dv; dv = dv->next) { struct criteria *crit; @@ -340,10 +339,10 @@ count_trns_proc (void *trns_, struct ccase *c, counter = 0; for (crit = dv->crit; crit; crit = crit->next) if (var_is_numeric (crit->vars[0])) - counter += count_numeric (crit, c); + counter += count_numeric (crit, *c); else - counter += count_string (crit, c); - case_data_rw (c, dv->var)->f = counter; + counter += count_string (crit, *c); + case_data_rw (*c, dv->var)->f = counter; } return TRNS_CONTINUE; } @@ -352,7 +351,7 @@ count_trns_proc (void *trns_, struct ccase *c, static bool count_trns_free (void *trns_) { - struct count_trns *trns = (struct count_trns *) trns_; + struct count_trns *trns = trns_; pool_destroy (trns->pool); return true; }