X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fdata%2Fdata-in.c;h=b9907c2d7303069348a670320957ff099d10260a;hb=09f992ebd556113e28cdf0829459121e3d2ec865;hp=bcc880e402761a407de0917c562a62a1cfdd2af3;hpb=f5c108becd49d78f4898cab11352291f5689d24e;p=pspp diff --git a/src/data/data-in.c b/src/data/data-in.c index bcc880e402..b9907c2d73 100644 --- a/src/data/data-in.c +++ b/src/data/data-in.c @@ -1,20 +1,18 @@ -/* PSPP - computes sample statistics. +/* PSPP - a program for statistical analysis. Copyright (C) 1997-9, 2000, 2006 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 @@ -36,16 +34,15 @@ #include "value.h" #include +#include #include #include -#include #include #include #include - #include "c-ctype.h" +#include "c-strtod.h" #include "minmax.h" -#include "size_max.h" #include "xalloc.h" #include "gettext.h" @@ -54,6 +51,7 @@ /* Information about parsing one data field. */ struct data_in { + enum legacy_encoding encoding;/* Encoding of source. */ struct substring input; /* Source. */ enum fmt_type format; /* Input format. */ int implied_decimals; /* Number of implied decimal places. */ @@ -87,9 +85,10 @@ static bool trim_spaces_and_check_missing (struct data_in *); static int hexit_value (int c); -/* Parses the characters in INPUT according to FORMAT. Stores - the parsed representation in OUTPUT, which has the given WIDTH - (0 for a numeric field, otherwise the string width). +/* Parses the characters in INPUT, which are encoded in the given + ENCODING, according to FORMAT. Stores the parsed + representation in OUTPUT, which has the given WIDTH (0 for + a numeric field, otherwise the string width). If no decimal point is included in a numeric format, then IMPLIED_DECIMALS decimal places are implied. Specify 0 if no @@ -99,7 +98,7 @@ static int hexit_value (int c); column number of the first character in INPUT, used in error messages. */ bool -data_in (struct substring input, +data_in (struct substring input, enum legacy_encoding encoding, enum fmt_type format, int implied_decimals, int first_column, union value *output, int width) { @@ -110,11 +109,25 @@ data_in (struct substring input, }; struct data_in i; + void *copy = NULL; bool ok; assert ((width != 0) == fmt_is_string (format)); - i.input = input; + if (encoding == LEGACY_NATIVE + || fmt_get_category (format) & (FMT_CAT_BINARY | FMT_CAT_STRING)) + { + i.input = input; + i.encoding = encoding; + } + else + { + ss_alloc_uninit (&i.input, ss_length (input)); + legacy_recode (encoding, ss_data (input), LEGACY_NATIVE, + ss_data (i.input), ss_length (input)); + i.encoding = LEGACY_NATIVE; + copy = ss_data (i.input); + } i.format = format; i.implied_decimals = implied_decimals; @@ -136,6 +149,9 @@ data_in (struct substring input, ok = true; } + if (copy) + free (copy); + return ok; } @@ -275,10 +291,10 @@ parse_number (struct data_in *i) return false; } - /* Let strtod() do the conversion. */ + /* Let c_strtod() do the conversion. */ save_errno = errno; errno = 0; - i->output->f = strtod (ds_cstr (&tmp), &tail); + i->output->f = c_strtod (ds_cstr (&tmp), &tail); if (*tail != '\0') { data_warning (i, _("Invalid numeric syntax.")); @@ -465,10 +481,10 @@ parse_Z (struct data_in *i) return false; } - /* Let strtod() do the conversion. */ + /* Let c_strtod() do the conversion. */ save_errno = errno; errno = 0; - i->output->f = strtod (ds_cstr (&tmp), NULL); + i->output->f = c_strtod (ds_cstr (&tmp), NULL); if (errno == ERANGE) { if (fabs (i->output->f) > 1) @@ -613,8 +629,17 @@ parse_RB (struct data_in *i) static bool parse_A (struct data_in *i) { - buf_copy_rpad (i->output->s, i->width, - ss_data (i->input), ss_length (i->input)); + /* This is equivalent to buf_copy_rpad, except that we posibly + do a character set recoding in the middle. */ + char *dst = i->output->s; + size_t dst_size = i->width; + const char *src = ss_data (i->input); + size_t src_size = ss_length (i->input); + + legacy_recode (i->encoding, src, LEGACY_NATIVE, dst, MIN (src_size, dst_size)); + if (dst_size > src_size) + memset (&dst[src_size], ' ', dst_size - src_size); + return true; } @@ -636,6 +661,11 @@ parse_AHEX (struct data_in *i) return false; } + if (i->encoding != LEGACY_NATIVE) + { + hi = legacy_to_native (i->encoding, hi); + lo = legacy_to_native (i->encoding, lo); + } if (!c_isxdigit (hi) || !c_isxdigit (lo)) { data_warning (i, _("Field must contain only hex digits."));