X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Frecode.c;h=b25ac4567ea621609825abf39f1752ccd7adc6a3;hb=4de79b34b329d1da6cdeb145993d3efd911e2967;hp=12f682c8684a77627856ab7223a6369916eb8c15;hpb=205ac3afa4c2b19c85819d8695abf3975bb11807;p=pspp diff --git a/src/recode.c b/src/recode.c index 12f682c868..b25ac4567e 100644 --- a/src/recode.c +++ b/src/recode.c @@ -14,8 +14,8 @@ 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 "error.h" @@ -23,12 +23,17 @@ #include #include #include "alloc.h" +#include "case.h" #include "command.h" +#include "dictionary.h" #include "error.h" #include "lexer.h" #include "magic.h" #include "str.h" #include "var.h" + +#include "gettext.h" +#define _(msgid) gettext (msgid) /* Definitions. */ @@ -64,7 +69,7 @@ struct rcd_var struct variable *src; /* Source variable. */ struct variable *dest; /* Destination variable. */ - char dest_name[9]; /* Name of dest variable if we're creating it. */ + char dest_name[LONG_NAME_LEN + 1]; /* Name of dest variable if we're creating it. */ int has_sysmis; /* Do we recode for SYSMIS? */ union value sysmis; /* Coding for SYSMIS (if src is numeric). */ @@ -105,7 +110,7 @@ static int parse_dest_spec (struct rcd_var * rcd, union value *v, static int parse_src_spec (struct rcd_var * rcd, int type, size_t max_src_width); static trns_proc_func recode_trns_proc; static trns_free_func recode_trns_free; -static double convert_to_double (char *, int); +static double convert_to_double (const char *, int); /* Parser. */ @@ -232,7 +237,7 @@ cmd_recode (void) else { for (i = mark; i < rcd->nmap; i++) - rcd->map[i].t.c = xstrdup (output.c); + rcd->map[i].t.c = (output.c?xstrdup (output.c):NULL); free (output.c); } } @@ -376,7 +381,7 @@ cmd_recode (void) /* The NULL is only really necessary for the debugging code. */ char *repl = xmalloc (max_dst_width + 1); - st_pad_copy (repl, cp->t.c, max_dst_width + 1); + str_copy_rpad (repl, max_dst_width + 1, cp->t.c); free (cp->t.c); cp->t.c = repl; } @@ -388,14 +393,14 @@ cmd_recode (void) } + free (v); + v = NULL; + if (!lex_match ('/')) break; while (rcd->next) rcd = rcd->next; rcd = rcd->next = xmalloc (sizeof *rcd); - - free (v); - v = NULL; } if (token != '.') @@ -410,7 +415,7 @@ cmd_recode (void) rcd->dest = dict_create_var (default_dict, rcd->dest_name, 0); if (!rcd->dest) { - /* FIXME: This can occur if a destname is duplicated. + /* FIXME: This can fail if a destname is duplicated. We could give an error at parse time but I don't care enough. */ rcd->dest = dict_lookup_var_assert (default_dict, rcd->dest_name); @@ -443,7 +448,7 @@ parse_dest_spec (struct rcd_var * rcd, union value * v, size_t *max_dst_width) v->c = NULL; - if (token == T_NUM) + if (lex_is_number ()) { v->f = tokval; lex_get (); @@ -461,7 +466,7 @@ parse_dest_spec (struct rcd_var * rcd, union value * v, size_t *max_dst_width) if (toklen > max) max = toklen; v->c = xmalloc (max + 1); - st_pad_copy (v->c, ds_value (&tokstr), max + 1); + str_copy_rpad (v->c, max + 1, ds_c_str (&tokstr)); flags = RCD_DEST_STRING; *max_dst_width = max; lex_get (); @@ -538,7 +543,7 @@ parse_src_spec (struct rcd_var * rcd, int type, size_t max_src_width) return 0; if (lex_match_id ("HI") || lex_match_id ("HIGHEST")) c->type = RCD_ELSE; - else if (token == T_NUM) + else if (lex_is_number ()) { c->type = RCD_LOW; c->f1.f = tokval; @@ -566,7 +571,7 @@ parse_src_spec (struct rcd_var * rcd, int type, size_t max_src_width) return 0; } } - else if (token == T_NUM) + else if (lex_is_number ()) { c->f1.f = tokval; lex_get (); @@ -574,7 +579,7 @@ parse_src_spec (struct rcd_var * rcd, int type, size_t max_src_width) { if (lex_match_id ("HI") || lex_match_id ("HIGHEST")) c->type = RCD_HIGH; - else if (token == T_NUM) + else if (lex_is_number ()) { c->type = RCD_RANGE; c->f2.f = tokval; @@ -624,7 +629,7 @@ parse_src_spec (struct rcd_var * rcd, int type, size_t max_src_width) if (!lex_force_string ()) return 0; c->f1.c = xmalloc (max_src_width + 1); - st_pad_copy (c->f1.c, ds_value (&tokstr), max_src_width + 1); + str_copy_rpad (c->f1.c, max_src_width + 1, ds_c_str (&tokstr)); lex_get (); } } @@ -687,7 +692,7 @@ recode_trns_free (struct trns_header * t) static inline struct coding * find_src_numeric (struct rcd_var * v, struct ccase * c) { - double cmp = c->data[v->src->fv].f; + double cmp = case_num (c, v->src->fv); struct coding *cp; if (cmp == SYSMIS) @@ -695,9 +700,9 @@ find_src_numeric (struct rcd_var * v, struct ccase * c) if (v->sysmis.f != -SYSMIS) { if ((v->flags & RCD_DEST_MASK) == RCD_DEST_NUMERIC) - c->data[v->dest->fv].f = v->sysmis.f; + case_data_rw (c, v->dest->fv)->f = v->sysmis.f; else - memcpy (c->data[v->dest->fv].s, v->sysmis.c, + memcpy (case_data_rw (c, v->dest->fv)->s, v->sysmis.s, v->dest->width); } return NULL; @@ -738,7 +743,7 @@ find_src_numeric (struct rcd_var * v, struct ccase * c) static inline struct coding * find_src_string (struct rcd_var * v, struct ccase * c) { - char *cmp = c->data[v->src->fv].s; + const char *cmp = case_str (c, v->src->fv); int w = v->src->width; struct coding *cp; @@ -758,7 +763,7 @@ find_src_string (struct rcd_var * v, struct ccase * c) double f = convert_to_double (cmp, w); if (f != -SYSMIS) { - c->data[v->dest->fv].f = f; + case_data_rw (c, v->dest->fv)->f = f; return NULL; } break; @@ -770,7 +775,7 @@ find_src_string (struct rcd_var * v, struct ccase * c) static int recode_trns_proc (struct trns_header * t, struct ccase * c, - int case_num UNUSED) + int case_idx UNUSED) { struct rcd_var *v; @@ -788,6 +793,7 @@ recode_trns_proc (struct trns_header * t, struct ccase * c, break; default: assert (0); + abort (); } if (!cp) continue; @@ -796,20 +802,24 @@ recode_trns_proc (struct trns_header * t, struct ccase * c, if ((v->flags & RCD_DEST_MASK) == RCD_DEST_NUMERIC) { double val = cp->t.f; + double *out = &case_data_rw (c, v->dest->fv)->f; if (val == -SYSMIS) - c->data[v->dest->fv].f = c->data[v->src->fv].f; + *out = case_num (c, v->src->fv); else - c->data[v->dest->fv].f = val; + *out = val; } else { char *val = cp->t.c; - if (val == NULL) - st_bare_pad_len_copy (c->data[v->dest->fv].s, - c->data[v->src->fv].c, - v->dest->width, v->src->width); + if (val == NULL) + { + if (v->dest->fv != v->src->fv) + buf_copy_rpad (case_data_rw (c, v->dest->fv)->s, + v->dest->width, + case_str (c, v->src->fv), v->src->width); + } else - memcpy (c->data[v->dest->fv].s, cp->t.c, v->dest->width); + memcpy (case_data_rw (c, v->dest->fv)->s, cp->t.c, v->dest->width); } } @@ -821,13 +831,13 @@ recode_trns_proc (struct trns_header * t, struct ccase * c, first character after the number into *ENDPTR. From the GNU C library. */ static long int -string_to_long (char *nptr, int width, char **endptr) +string_to_long (const char *nptr, int width, const char **endptr) { int negative; register unsigned long int cutoff; register unsigned int cutlim; register unsigned long int i; - register char *s; + register const char *s; register unsigned char c; const char *save; @@ -897,7 +907,7 @@ string_to_long (char *nptr, int width, char **endptr) found, or -SYSMIS if there was no valid number in s. WIDTH is the length of string S. From the GNU C library. */ static double -convert_to_double (char *s, int width) +convert_to_double (const char *s, int width) { register const char *end = &s[width];