{
struct substring ss = ss_cstr (SvPV_nolen (sv));
if ( ! data_in (ss, LEGACY_NATIVE, ifmt->type, 0, 0, 0,
+ sfi->dict,
case_data_rw (c, v),
var_get_width (v)) )
{
#include "settings.h"
#include "value.h"
#include "format.h"
+#include "dictionary.h"
#include <libpspp/assertion.h>
#include <libpspp/legacy-encoding.h>
/* Information about parsing one data field. */
struct data_in
{
- const char *encoding; /* Encoding of source. */
+ const char *src_enc; /* Encoding of source. */
struct substring input; /* Source. */
enum fmt_type format; /* Input format. */
int implied_decimals; /* Number of implied decimal places. */
representation in OUTPUT, which the caller must have
initialized with the given WIDTH (0 for a numeric field,
otherwise the string width).
+ Iff FORMAT is a string format, then DICT must be a pointer
+ to the dictionary associated with OUTPUT. Otherwise, DICT
+ may be null.
If no decimal point is included in a numeric format, then
IMPLIED_DECIMALS decimal places are implied. Specify 0 if no
bool
data_in (struct substring input, const char *encoding,
enum fmt_type format, int implied_decimals,
- int first_column, int last_column, union value *output, int width)
+ int first_column, int last_column,
+ const struct dictionary *dict,
+ union value *output, int width)
{
static data_in_parser_func *const handlers[FMT_NUMBER_OF_FORMATS] =
{
};
struct data_in i;
- void *copy = NULL;
+
bool ok;
assert ((width != 0) == fmt_is_string (format));
- if (0 == strcmp (encoding, LEGACY_NATIVE)
- || fmt_get_category (format) & (FMT_CAT_BINARY | FMT_CAT_STRING))
- {
- i.input = input;
- i.encoding = encoding;
- }
- else
- {
- char *s;
- ss_alloc_uninit (&i.input, ss_length (input));
-
- s = recode_string (LEGACY_NATIVE, encoding, ss_data (input), ss_length (input));
- memcpy (ss_data (i.input), s, ss_length (input));
- free (s);
- i.encoding = LEGACY_NATIVE;
- copy = ss_data (i.input);
- }
i.format = format;
i.implied_decimals = implied_decimals;
i.first_column = first_column;
i.last_column = last_column;
+ i.src_enc = encoding;
- if (!ss_is_empty (i.input))
+ if (ss_is_empty (input))
{
- ok = handlers[i.format] (&i);
- if (!ok)
- default_result (&i);
+ default_result (&i);
+ return true;
+ }
+
+ if (fmt_get_category (format) & ( FMT_CAT_BINARY | FMT_CAT_HEXADECIMAL | FMT_CAT_LEGACY))
+ {
+ i.input = input;
}
else
{
- default_result (&i);
- ok = true;
+ const char *dest_encoding;
+ char *s = NULL;
+ if ( dict == NULL)
+ {
+ assert (0 == (fmt_get_category (format) & (FMT_CAT_BINARY | FMT_CAT_STRING)));
+ dest_encoding = LEGACY_NATIVE;
+ }
+ else
+ dest_encoding = dict_get_encoding (dict);
+
+ s = recode_string (dest_encoding, i.src_enc, ss_data (input), ss_length (input));
+ ss_alloc_uninit (&i.input, strlen (s));
+ memcpy (ss_data (i.input), s, ss_length (input));
+ free (s);
}
- if (copy)
- free (copy);
+ ok = handlers[i.format] (&i);
+ if (!ok)
+ default_result (&i);
return ok;
}
const char *src = ss_data (i->input);
size_t src_size = ss_length (i->input);
- char *s = recode_string (LEGACY_NATIVE, i->encoding, src, MIN (src_size, dst_size));
- memcpy (dst, s, dst_size);
- free (s);
+ memcpy (dst, src, MIN (src_size, dst_size));
+
if (dst_size > src_size)
memset (&dst[src_size], ' ', dst_size - src_size);
return false;
}
- if (0 != strcmp (i->encoding, LEGACY_NATIVE))
+ if (0 != strcmp (i->src_enc, LEGACY_NATIVE))
{
- hi = legacy_to_native (i->encoding, hi);
- lo = legacy_to_native (i->encoding, lo);
+ hi = legacy_to_native (i->src_enc, hi);
+ lo = legacy_to_native (i->src_enc, lo);
}
if (!c_isxdigit (hi) || !c_isxdigit (lo))
{
enum fmt_type;
union value;
+struct dictionary;
bool data_in (struct substring input, const char *encoding,
enum fmt_type, int implied_decimals,
int first_column, int last_column,
+ const struct dictionary *dict,
union value *output, int width);
#endif /* data/data-in.h */
bool ok;
dict = in_input_program () ? dataset_dict (ds) : dict_create ();
- parser = data_parser_create ();
+ parser = data_parser_create (dict);
reader = NULL;
table = -1; /* Print table if nonzero, -1=undecided. */
/* Data parser for textual data like that read by DATA LIST. */
struct data_parser
{
+ const struct dictionary *dict; /*Dictionary of destination */
enum data_parser_type type; /* Type of data to parse. */
int skip_records; /* Records to skip before first real data. */
casenumber max_cases; /* Max number of cases to read. */
/* Creates and returns a new data parser. */
struct data_parser *
-data_parser_create (void)
+data_parser_create (const struct dictionary *dict)
{
struct data_parser *parser = xmalloc (sizeof *parser);
parser->fields = NULL;
parser->field_cnt = 0;
parser->field_allocated = 0;
+ parser->dict = dict;
parser->span = true;
parser->empty_line_has_field = false;
f->format.w),
encoding, f->format.type, f->format.d,
f->first_column, f->first_column + f->format.w,
+ parser->dict,
case_data_rw_idx (c, f->case_idx),
fmt_var_width (&f->format));
data_in (s, encoding, f->format.type, 0,
first_column, last_column,
+ parser->dict,
case_data_rw_idx (c, f->case_idx),
fmt_var_width (&f->format));
}
data_in (s, encoding, f->format.type, 0,
first_column, last_column,
+ parser->dict,
case_data_rw_idx (c, f->case_idx),
fmt_var_width (&f->format));
}
};
/* Creating and configuring any parser. */
-struct data_parser *data_parser_create (void);
+struct data_parser *data_parser_create (const struct dictionary *dict);
void data_parser_destroy (struct data_parser *);
enum data_parser_type data_parser_get_type (const struct data_parser *);
parse_get_txt (struct lexer *lexer, struct dataset *ds)
{
struct data_parser *parser = NULL;
- struct dictionary *dict = NULL;
+ struct dictionary *dict = dict_create ();
struct file_handle *fh = NULL;
struct dfm_reader *reader = NULL;
if (fh == NULL)
goto error;
- parser = data_parser_create ();
+ parser = data_parser_create (dict);
has_type = false;
data_parser_set_type (parser, DP_DELIMITED);
data_parser_set_span (parser, false);
}
lex_match (lexer, '=');
- dict = dict_create ();
+
record = 1;
type = data_parser_get_type (parser);
do
function NUMBER (string s, ni_format f)
{
union value out;
- data_in (ss_head (s, f->w), LEGACY_NATIVE, f->type, f->d, 0, 0, &out, 0);
+ data_in (ss_head (s, f->w), LEGACY_NATIVE, f->type, f->d, 0, 0, NULL, &out, 0);
return out.f;
}
else if (lex_token (lexer) == T_STRING && format != NULL)
{
union value v;
+ assert (! (fmt_get_category (*format) & ( FMT_CAT_STRING )));
data_in (ds_ss (lex_tokstr (lexer)), LEGACY_NATIVE,
- *format, 0, 0, 0, &v, 0);
+ *format, 0, 0, 0, NULL, &v, 0);
lex_get (lexer);
*x = v.f;
if (*x == SYSMIS)
{
struct pool *pool;
+
+
/* Variable types, for convenience. */
enum val_type src_type; /* src_vars[*] type. */
enum val_type dst_type; /* dst_vars[*] type. */
/* Variables. */
const struct variable **src_vars; /* Source variables. */
const struct variable **dst_vars; /* Destination variables. */
+ const struct dictionary *dst_dict; /* Dictionary of dst_vars */
char **dst_names; /* Name of dest variables, if they're new. */
size_t var_cnt; /* Number of variables. */
{
size_t i;
+ trns->dst_dict = dict;
+
for (i = 0; i < trns->var_cnt; i++)
{
const struct variable **var = &trns->dst_vars[i];
msg_disable ();
match = data_in (ss_buffer (value, width), LEGACY_NATIVE,
- FMT_F, 0, 0, 0, &uv, 0);
+ FMT_F, 0, 0, 0, trns->dst_dict, &uv, 0);
msg_enable ();
out->value.f = uv.f;
break;
LEGACY_NATIVE,
fmt->type,
0, 0, 0,
+ NULL,
&vc->pattern, width) )
{
value_destroy (&vc->pattern, width);
gboolean
text_to_value (const gchar *text, union value *v,
+ const PsppireDict *dict,
struct fmt_spec format)
{
bool ok;
msg_disable ();
ok = data_in (ss_cstr (text), LEGACY_NATIVE, format.type, 0, 0, 0,
+ dict->dict,
v, fmt_var_width (&format));
msg_enable ();
gboolean text_to_value (const gchar *text, union value *v,
+ const PsppireDict *dict,
struct fmt_spec format);
GObject *get_object_assert (GtkBuilder *builder, const gchar *name, GType type);
continue;
}
- if ( text_to_value (text, &v, *write_spec))
+ if ( text_to_value (text, &v,
+ dialog->dict, *write_spec))
{
nvals++;
mv_add_value (&dialog->mvl, &v);
const gchar *low_text = gtk_entry_get_text (GTK_ENTRY (dialog->low));
const gchar *high_text = gtk_entry_get_text (GTK_ENTRY (dialog->high));
- if ( text_to_value (low_text, &low_val, *write_spec)
+ if ( text_to_value (low_text, &low_val, dialog->dict, *write_spec)
&&
- text_to_value (high_text, &high_val, *write_spec) )
+ text_to_value (high_text, &high_val, dialog->dict, *write_spec) )
{
if ( low_val.f > high_val.f )
{
{
union value discrete_val;
if ( !text_to_value (discrete_text, &discrete_val,
+ dialog->dict,
*write_spec))
{
err_dialog (_("Incorrect value for variable type"),
FALSE);
value_init (&value, width);
ok = (datasheet_get_value (ds->datasheet, casenum, idx, &value)
- && data_in (input, dict_get_encoding (dict->dict), fmt->type, 0, 0, 0, &value, width)
+ && data_in (input, UTF8, fmt->type, 0, 0, 0,
+ dict->dict, &value, width)
&& datasheet_put_value (ds->datasheet, casenum, idx, &value));
value_destroy (&value, width);
if (field.string != NULL)
{
msg_disable ();
+ /* FIXME: NULL should be replaced with the destination dictionary */
if (!data_in (field, LEGACY_NATIVE, in->type, 0, 0, 0,
+ NULL,
&val, var_get_width (var)))
{
char fmt_string[FMT_STRING_LEN_MAX + 1];
text = gtk_entry_get_text (GTK_ENTRY (dialog->value_entry));
text_to_value (text, &v,
+ dialog->var_store->dict,
*var_get_write_format (dialog->pv));
union value v;
text_to_value (text, &v,
+ dialog->var_store->dict,
*var_get_write_format (dialog->pv));
union value v;
text_to_value (val_text, &v,
+ dialog->var_store->dict,
*var_get_write_format (dialog->pv));
val_labs_replace (dialog->labs, &v,
const gchar *text = gtk_entry_get_text (GTK_ENTRY (dialog->value_entry));
text_to_value (text, &v,
+ dialog->var_store->dict,
*var_get_write_format (dialog->pv));
v_in.f = number;
s = data_out (&v_in, "FIXME", format);
msg_disable ();
+ /* FIXME: UTF8 encoded strings will fail here */
ok = data_in (ss_cstr (s), LEGACY_NATIVE,
- format->type, false, 0, 0, &v_out, 0);
+ format->type, false, 0, 0, NULL, &v_out, 0);
msg_enable ();
if (ok && v_out.f == number)
{