Previously, the output value of data_out was of arbitrary encoding.
This change attempts to ensure that it is always utf8.
#include <libpspp/misc.h>
#include <libpspp/str.h>
#include <libpspp/pool.h>
+#include <libpspp/i18n.h>
#include "minmax.h"
legacy_recode (LEGACY_NATIVE, output, encoding, output, format->w);
}
-/* Converts the INPUT value into printable form, according to format
+/* Converts the INPUT value into a UTF8 encoded string, according to format
specification FORMAT.
VALUE must be the correct width for FORMAT, that is, its
allocated on that pool.
*/
char *
-data_out_pool (const union value *input, const struct fmt_spec *format,
+data_out_pool (const union value *input, const char *encoding, const struct fmt_spec *format,
struct pool *pool)
{
- char *output = pool_malloc (pool, format->w + 1);
+ char *output = xmalloc (format->w + 1);
+ char *t ;
assert (fmt_check_output (format));
converters[format->type] (input, format, output);
output[format->w] = '\0';
- return output;
+
+ t = recode_string_pool (UTF8, encoding, output, format->w, pool);
+ free (output);
+ return t;
}
char *
-data_out (const union value *input, const struct fmt_spec *format)
+data_out (const union value *input, const char *encoding, const struct fmt_spec *format)
{
- return data_out_pool (input, format, NULL);
+ return data_out_pool (input, encoding, format, NULL);
}
\f
struct fmt_spec;
union value;
-char * data_out (const union value *, const struct fmt_spec *);
+char * data_out (const union value *, const char *encoding, const struct fmt_spec *);
-char * data_out_pool (const union value *, const struct fmt_spec *, struct pool *pool);
+char * data_out_pool (const union value *, const char *encoding, const struct fmt_spec *, struct pool *pool);
void data_out_legacy (const union value *input, const char *encoding,
const struct fmt_spec *format, char *output);
struct string *str)
{
const char *name = var_lookup_value_label (v, value);
+ const struct dictionary *dict = var_get_vardict (v)->dict;
if (name == NULL)
{
- char *s = data_out (value, &v->print);
+ char *s = data_out (value, dict_get_encoding (dict), &v->print);
ds_put_cstr (str, s);
free (s);
}
if (fmt_is_string (print->type)
|| dict_contains_var (dict, v))
{
- char *s = data_out (case_data (c, v), print);
+ char *s = data_out (case_data (c, v), dict_get_encoding (dict), print);
ds_put_cstr (&line_buffer, s);
free (s);
}
char *s;
union value case_idx_value;
case_idx_value.f = case_idx;
- s = data_out (&case_idx_value, print);
+ s = data_out (&case_idx_value, dict_get_encoding (dict), print);
ds_put_cstr (&line_buffer, s);
free (s);
}
if (fmt_is_string (print->type)
|| dict_contains_var (dict, v))
- s = data_out (case_data (c, v), print);
+ s = data_out (case_data (c, v), dict_get_encoding (dict), print);
else
{
union value case_idx_value;
case_idx_value.f = case_idx;
- s = data_out (&case_idx_value, print);
+ s = data_out (&case_idx_value, dict_get_encoding (dict), print);
}
fputs (" <TD>", x->file);
tab_text (t, 0, i + 1, TAB_LEFT | TAT_PRINTF, "%s", var_get_name (v));
- s = data_out (case_data (c, v), print);
+ s = data_out (case_data (c, v), dict_get_encoding (dict), print);
tab_text (t, 1, i + 1, TAT_PRINTF, "%.*s", print->w, s);
free (s);
v.f = x;
assert (!fmt_is_string (f->type));
- s = data_out (&v, f);
+ s = data_out (&v, "no-such-encoding", f);
dst = alloc_string (e, strlen (s));
strcpy (dst.string, s);
free (s);
struct crosstabs_proc
{
+ const struct dictionary *dict;
enum { INTEGER, GENERAL } mode;
enum mv_class exclude;
bool pivot;
init_proc (struct crosstabs_proc *proc, struct dataset *ds)
{
const struct variable *wv = dict_get_weight (dataset_dict (ds));
+ proc->dict = dataset_dict (ds);
proc->bad_warn = true;
proc->variables = NULL;
proc->n_variables = 0;
/* Insert the formatted value of the variable, then trim
leading spaces in what was just inserted. */
ofs = ds_length (&title);
- s = data_out (&pt->const_values[i], var_get_print_format (var));
+ s = data_out (&pt->const_values[i], dict_get_encoding (proc->dict), var_get_print_format (var));
ds_put_cstr (&title, s);
free (s);
ds_remove (&title, ofs, ss_cspan (ds_substr (&title, ofs, SIZE_MAX),
}
s.string = tab_alloc (table, print->w);
- ss = data_out (v, print);
+ ss = data_out (v, dict_get_encoding (proc->dict), print);
strcpy (s.string, ss);
free (ss);
s.length = print->w;
additionally suffixed with a letter `M'. */
static void
format_cell_entry (struct tab_table *table, int c, int r, double value,
- char suffix, bool mark_missing)
+ char suffix, bool mark_missing, const struct dictionary *dict)
{
const struct fmt_spec f = {FMT_F, 10, 1};
union value v;
s.length = 10;
s.string = tab_alloc (table, 16);
v.f = value;
- ss = data_out (&v, &f);
+ ss = data_out (&v, dict_get_encoding (dict), &f);
strcpy (s.string, ss);
free (ss);
while (*s.string == ' ')
default:
NOT_REACHED ();
}
- format_cell_entry (table, c, i, v, suffix, mark_missing);
+ format_cell_entry (table, c, i, v, suffix, mark_missing, proc->dict);
}
mp++;
NOT_REACHED ();
}
- format_cell_entry (table, pt->n_cols, 0, v, suffix, mark_missing);
+ format_cell_entry (table, pt->n_cols, 0, v, suffix, mark_missing, proc->dict);
tab_next_row (table);
}
}
NOT_REACHED ();
}
- format_cell_entry (table, c, i, v, suffix, mark_missing);
+ format_cell_entry (table, c, i, v, suffix, mark_missing, proc->dict);
}
last_row = i;
}
#include "assertion.h"
#include "hmapx.h"
#include "hash-functions.h"
+#include "pool.h"
#include "i18n.h"
return converter->conv;
}
+char *
+recode_string (const char *to, const char *from,
+ const char *text, int length)
+{
+ return recode_string_pool (to, from, text, length, NULL);
+}
+
+
/* Return a string based on TEXT converted according to HOW.
If length is not -1, then it must be the number of bytes in TEXT.
The returned string must be freed when no longer required.
*/
char *
-recode_string (const char *to, const char *from,
- const char *text, int length)
+recode_string_pool (const char *to, const char *from,
+ const char *text, int length, struct pool *pool)
{
char *outbuf = 0;
size_t outbufferlength;
if ( outbufferlength > length)
break;
- outbuf = xmalloc(outbufferlength);
+ outbuf = pool_malloc (pool, outbufferlength);
op = outbuf;
outbytes = outbufferlength;
case E2BIG:
free (outbuf);
outbufferlength <<= 1;
- outbuf = xmalloc (outbufferlength);
+ outbuf = pool_malloc (pool, outbufferlength);
op = outbuf;
outbytes = outbufferlength;
inbytes = length;
if (outbytes == 0 )
{
char *const oldaddr = outbuf;
- outbuf = xrealloc (outbuf, outbufferlength + 1);
+ outbuf = pool_realloc (pool, outbuf, outbufferlength + 1);
op += (outbuf - oldaddr) ;
}
#define UTF8 "UTF-8"
-char * recode_string (const char *to, const char *from,
+struct pool;
+
+char *recode_string_pool (const char *to, const char *from,
+ const char *text, int length, struct pool *pool);
+
+char *recode_string (const char *to, const char *from,
const char *text, int len);
}
#endif
- contents = data_out_pool (v, f, table->container);
+ contents = data_out_pool (v, "FIXME", f, table->container);
table->cc[c + r * table->cf] = ss_cstr (contents);
table->ct[c + r * table->cf] = opt;
#endif
double_value.f = val;
- s = data_out_pool (&double_value, &f, table->container);
+ s = data_out_pool (&double_value, "FIXME", &f, table->container);
cp = s;
while (isspace ((unsigned char) *cp) && cp < &s[w])
#endif
double_value.f = val;
- s = data_out_pool (&double_value, fmt, table->container);
+ s = data_out_pool (&double_value, "FIXME", fmt, table->container);
cp = s;
while (isspace ((unsigned char) *cp) && cp < s + fmt->w)
gint *idx;
struct variable *var;
GtkTreeIter dict_iter;
- gchar *name;
GtkTextBuffer *buffer;
g_return_if_fail (GTK_IS_TEXT_VIEW (dest));
gtk_tree_path_free (path);
- name = recode_string (UTF8, psppire_dict_encoding (dict),
- var_get_name (var),
- -1);
-
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (dest));
erase_selection (buffer);
- gtk_text_buffer_insert_at_cursor (buffer, name, -1);
+ gtk_text_buffer_insert_at_cursor (buffer, var_get_name (var), -1);
- g_free (name);
}
gpointer data)
{
PsppireDict *dict = data;
- struct variable *var;
- gchar *name;
-
- var = get_selected_variable (tree_model, iter, dict);
+ const struct variable *var = get_selected_variable (tree_model, iter, dict);
- name = recode_string (UTF8, psppire_dict_encoding (dict),
- var_get_name (var), -1);
- g_object_set (cell, "text", name, NULL);
- g_free (name);
+ g_object_set (cell, "text", var_get_name (var), NULL);
}
gint *idx;
struct variable *var;
GtkTreeIter dict_iter;
- gchar *name;
g_return_if_fail (GTK_IS_ENTRY(dest));
gtk_tree_path_free (path);
- name = recode_string (UTF8, psppire_dict_encoding (PSPPIRE_DICT (dict)),
- var_get_name (var), -1);
- gtk_entry_set_text (GTK_ENTRY (dest), name);
- g_free (name);
+ gtk_entry_set_text (GTK_ENTRY (dest), var_get_name (var));
}
PsppireSelector *selector)
{
gboolean result;
- gchar *name;
GtkTreeIter dict_iter;
GtkTreeModel *dict;
struct variable *var;
gint dict_index;
gint *indeces;
GtkTreePath *path;
- const gchar *text = gtk_entry_get_text (GTK_ENTRY (selector->dest));
+ const gchar *text = gtk_entry_get_text (GTK_ENTRY (selector->dest));
get_base_model (model, iter, &dict, &dict_iter);
gtk_tree_path_free (path);
- name = recode_string (UTF8, psppire_dict_encoding (PSPPIRE_DICT (dict)),
- var_get_name (var), -1);
- result = ( 0 == strcmp (text, name));
- g_free (name);
+ result = ( 0 == strcmp (text, var_get_name (var) ));
return result;
}
/* Formats a value according to FORMAT
The returned string must be freed when no longer required */
gchar *
-value_to_text (union value v, struct fmt_spec format)
+value_to_text (union value v, const struct dictionary *dict, struct fmt_spec format)
{
gchar *s = 0;
- s = data_out (&v, &format);
+ s = data_out (&v, dict_get_encoding (dict), &format);
g_strchug (s);
return s;
void paste_syntax_in_new_window (const gchar *syntax);
struct fmt_spec;
+struct dictionary;
/* Formats a value according to FORMAT
The returned string must be freed when no longer required */
-gchar * value_to_text (union value v, struct fmt_spec format);
+gchar * value_to_text (union value v, const struct dictionary *dict, struct fmt_spec format);
gboolean text_to_value (const gchar *text, union value *v,
gchar *high_text;
mv_get_range (&dialog->mvl, &low.f, &high.f);
- low_text = value_to_text (low, *write_spec);
- high_text = value_to_text (high, *write_spec);
+
+ low_text = value_to_text (low, dialog->dict, *write_spec);
+ high_text = value_to_text (high, dialog->dict, *write_spec);
gtk_entry_set_text (GTK_ENTRY (dialog->low), low_text);
gtk_entry_set_text (GTK_ENTRY (dialog->high), high_text);
if ( mv_has_value (&dialog->mvl))
{
gchar *text;
- text = value_to_text (*mv_get_value (&dialog->mvl, 0), *write_spec);
+ text = value_to_text (*mv_get_value (&dialog->mvl, 0), dialog->dict, *write_spec);
gtk_entry_set_text (GTK_ENTRY (dialog->discrete), text);
g_free (text);
}
{
gchar *text ;
- text = value_to_text (*mv_get_value (&dialog->mvl, i),
+ text = value_to_text (*mv_get_value (&dialog->mvl, i), dialog->dict,
*write_spec);
gtk_entry_set_text (GTK_ENTRY (dialog->mv[i]), text);
g_free (text);
/* The variable whose missing values are to be updated */
struct variable *pv;
+ /* The dictionary to which that value belongs */
+ const struct dictionary *dict;
+
/* local copy */
struct missing_values mvl;
/* Perform data_out for case CC, variable V, appending to STRING */
static void
-data_out_g_string (GString *string, const struct variable *v,
+data_out_g_string (GString *string, const struct dictionary *dict, const struct variable *v,
const struct ccase *cc)
{
const struct fmt_spec *fs = var_get_print_format (v);
const union value *val = case_data (cc, v);
- char *s = data_out (val, fs);
+ char *s = data_out (val, dict_get_encoding (dict), fs);
g_string_append_len (string, s, fs->w);
for (c = 0 ; c < var_cnt ; ++c)
{
const struct variable *v = dict_get_var (clip_dict, c);
- data_out_g_string (string, v, cc);
+ data_out_g_string (string, clip_dict, v, cc);
if ( c < val_cnt - 1 )
g_string_append (string, "\t");
}
{
const struct variable *v = dict_get_var (clip_dict, c);
g_string_append (string, "<td>");
- data_out_g_string (string, v, cc);
+ data_out_g_string (string, clip_dict, v, cc);
g_string_append (string, "</td>\n");
}
char *text;
const struct fmt_spec *fp ;
const struct variable *pv ;
+ const struct dictionary *dict;
union value v;
int width;
g_return_val_if_fail (store->dict, NULL);
g_return_val_if_fail (store->datasheet, NULL);
+ dict = store->dict->dict;
+
if (column >= psppire_dict_get_var_cnt (store->dict))
return NULL;
if (label)
{
value_destroy (&v, width);
- return recode_string (UTF8, psppire_dict_encoding (store->dict),
- label, -1);
+ return g_strdup (label);
}
}
fp = var_get_write_format (pv);
- /* Converts binary value V into printable form in the exactly
- FP->W character in buffer S according to format specification
- FP. No null terminator is appended to the buffer. */
- text = data_out (&v, fp);
+ text = data_out (&v, dict_get_encoding (dict), fp);
g_strchomp (text);
static gchar *
get_row_button_label (const PsppireSheetModel *model, gint unit)
{
- PsppireDataStore *ds = PSPPIRE_DATA_STORE (model);
- gchar *s = g_strdup_printf (_("%d"), unit + FIRST_CASE_NUMBER);
-
- gchar *text = recode_string (UTF8, psppire_dict_encoding (ds->dict),
- s, -1);
+ // PsppireDataStore *ds = PSPPIRE_DATA_STORE (model);
- g_free (s);
-
- return text;
+ return g_strdup_printf (_("%d"), unit + FIRST_CASE_NUMBER);
}
{
case DICT_TVM_COL_NAME:
{
- gchar *name = recode_string (UTF8, psppire_dict_encoding (dict),
- var_get_name (var), -1);
g_value_init (value, G_TYPE_STRING);
- g_value_set_string (value, name);
- g_free (name);
+ g_value_set_string (value, var_get_name (var));
}
break;
case DICT_TVM_COL_VAR:
"<span stretch=\"condensed\">%s</span>",
var_get_label (var));
- char *utf8 = recode_string (UTF8, psppire_dict_encoding (dict),
- text, -1);
-
+ g_object_set (cell, "markup", text, NULL);
g_free (text);
- g_object_set (cell, "markup", utf8, NULL);
- g_free (utf8);
}
else
{
- char *name = recode_string (UTF8, psppire_dict_encoding (dict),
- var_get_name (var), -1);
- g_object_set (cell, "text", name, NULL);
- g_free (name);
+ g_object_set (cell, "text", var_get_name (var), NULL);
}
}
return FALSE;
{
- gchar *tip ;
+ const gchar *tip ;
GtkTreeModel *m;
PsppireDict *dict;
dict = PSPPIRE_DICT (m);
if ( PSPPIRE_DICT_VIEW (treeview)->prefer_labels )
- tip = recode_string (UTF8, psppire_dict_encoding (dict),
- var_get_name (var), -1);
+ tip = var_get_name (var);
else
- tip = recode_string (UTF8, psppire_dict_encoding (dict),
- var_get_label (var), -1);
+ tip = var_get_label (var);
gtk_tooltip_set_text (tooltip, tip);
-
- g_free (tip);
}
return TRUE;
vs->missing_val_dialog->pv =
psppire_var_store_get_var (var_store, row);
+ vs->missing_val_dialog->dict = var_store->dict->dict;
+
g_signal_connect_swapped (customEntry,
"clicked",
G_CALLBACK (missing_val_dialog_show),
g_assert (vl);
{
- gchar *const vstr = value_to_text (vl->value, *write_spec);
+ gchar *const vstr = value_to_text (vl->value, dict->dict, *write_spec);
return g_strdup_printf ( "{%s,\"%s\"}_", vstr, val_lab_get_label (vl));
}
}
if (outputp != NULL)
{
- *outputp = data_out (&val, &out);
+ *outputp = data_out (&val, dict_get_encoding (ia->formats.dict), &out);
}
value_destroy (&val, var_get_width (var));
gchar *text;
get_selected_tuple (dialog, &value, &label);
- text = value_to_text (value, *var_get_write_format (dialog->pv));
+ text = value_to_text (value, NULL, *var_get_write_format (dialog->pv));
g_signal_handler_block (GTK_ENTRY (dialog->value_entry),
dialog->value_handler_id);
const struct val_lab *vl = labels[i];
gchar *const vstr =
- value_to_text (vl->value,
+ value_to_text (vl->value, NULL,
*var_get_write_format (dialog->pv));
gchar *const text = g_strdup_printf ("%s = \"%s\"",
gint i;
for (i = 0 ; i < n; ++i )
{
- mv[i] = value_to_text (*mv_get_value (miss, i), *fmt);
+ mv[i] = value_to_text (*mv_get_value (miss, i), dict->dict, *fmt);
if ( i > 0 )
g_string_append (gstr, ", ");
g_string_append (gstr, mv[i]);
g_free (mv[i]);
}
- s = recode_string (UTF8, psppire_dict_encoding (dict),
- gstr->str, gstr->len);
- g_string_free (gstr, TRUE);
+ s = gstr->str;
+ g_string_free (gstr, FALSE);
}
else
{
union value low, high;
mv_get_range (miss, &low.f, &high.f);
- l = value_to_text (low, *fmt);
- h = value_to_text (high, *fmt);
+ l = value_to_text (low, dict->dict, *fmt);
+ h = value_to_text (high, dict->dict,*fmt);
g_string_printf (gstr, "%s - %s", l, h);
g_free (l);
{
gchar *ss = 0;
- ss = value_to_text (*mv_get_value (miss, 0), *fmt);
+ ss = value_to_text (*mv_get_value (miss, 0), dict->dict, *fmt);
g_string_append (gstr, ", ");
g_string_append (gstr, ss);
free (ss);
}
- s = recode_string (UTF8, psppire_dict_encoding (dict),
- gstr->str, gstr->len);
- g_string_free (gstr, TRUE);
+ s = gstr->str;
+ g_string_free (gstr, FALSE);
}
return s;
union value v;
v.f = 1234.56;
- sample_text = value_to_text (v, dialog->fmt_l);
+ sample_text = value_to_text (v, NULL, dialog->fmt_l);
gtk_label_set_text (GTK_LABEL (dialog->label_psample), sample_text);
g_free (sample_text);
v.f = -v.f;
- sample_text = value_to_text (v, dialog->fmt_l);
+ sample_text = value_to_text (v, NULL, dialog->fmt_l);
gtk_label_set_text (GTK_LABEL (dialog->label_nsample), sample_text);
g_free (sample_text);
}
static const gchar none[] = N_("None");
-static gchar *
-name_to_string (const struct variable *var, PsppireDict *dict)
-{
- const char *name = var_get_name (var);
- g_assert (name);
-
- return recode_string (UTF8, psppire_dict_encoding (dict),
- name, -1);
-}
-
-
-static gchar *
-label_to_string (const struct variable *var, PsppireDict *dict)
+static const gchar *
+label_to_string (const struct variable *var)
{
const char *label = var_get_label (var);
- if (! label) return g_strdup (none);
+ if (NULL == label) return g_strdup (none);
- return recode_string (UTF8, psppire_dict_encoding (dict),
- label, -1);
+ return label;
}
NULL);
gstring = g_string_sized_new (200);
- text = name_to_string (var, dict);
- g_string_assign (gstring, text);
- g_free (text);
+ g_string_assign (gstring, var_get_name (var));
g_string_append (gstring, "\n");
- text = label_to_string (var, dict);
- g_string_append_printf (gstring, _("Label: %s\n"), text);
- g_free (text);
-
+ g_string_append_printf (gstring, _("Label: %s\n"), label_to_string (var));
{
const struct fmt_spec *fmt = var_get_print_format (var);
char buffer[FMT_STRING_LEN_MAX + 1];
{
const struct val_lab *vl = labels[i];
gchar *const vstr =
- value_to_text (vl->value, *var_get_print_format (var));
-
- text = recode_string (UTF8, psppire_dict_encoding (dict),
- val_lab_get_label (vl), -1);
+ value_to_text (vl->value, dict->dict, *var_get_print_format (var));
- g_string_append_printf (gstring, _("%s %s\n"), vstr, text);
+ g_string_append_printf (gstring, _("%s %s\n"), vstr, val_lab_get_label (vl));
- g_free (text);
g_free (vstr);
}
free (labels);
bool ok;
v_in.f = number;
- s = data_out (&v_in, format);
+ s = data_out (&v_in, "FIXME", format);
msg_disable ();
ok = data_in (ss_cstr (s), LEGACY_NATIVE,
format->type, false, 0, 0, &v_out, 0);