union value uv;
char *s;
make_value_from_scalar (&uv, val, var);
- s = malloc (fmt->w);
- memset (s, '\0', fmt->w);
- data_out (&uv, fmt, s);
+ s = data_out (&uv, fmt);
value_destroy (&uv, var_get_width (var));
ret = newSVpv (s, fmt->w);
free (s);
#include <libpspp/message.h>
#include <libpspp/misc.h>
#include <libpspp/str.h>
+#include <libpspp/pool.h>
#include "minmax.h"
char *);
static void output_hex (const void *, size_t bytes, char *);
\f
-/* Same as data_out, and additionally recodes the output from
- native form into the given legacy character ENCODING. */
-void
-data_out_legacy (const union value *input, const char *encoding,
- const struct fmt_spec *format, char *output)
-{
- static data_out_converter_func *const converters[FMT_NUMBER_OF_FORMATS] =
+
+static data_out_converter_func *const converters[FMT_NUMBER_OF_FORMATS] =
{
#define FMT(NAME, METHOD, IMIN, OMIN, IO, CATEGORY) output_##METHOD,
#include "format.def"
};
+/* Similar to data_out. Additionally recodes the output from
+ native form into the given legacy character ENCODING.
+ OUTPUT must be provided by the caller and must be at least
+ FORMAT->w long. No null terminator is appended to OUTPUT.
+*/
+void
+data_out_legacy (const union value *input, const char *encoding,
+ const struct fmt_spec *format, char *output)
+{
assert (fmt_check_output (format));
converters[format->type] (input, format, output);
legacy_recode (LEGACY_NATIVE, output, encoding, output, format->w);
}
-/* Converts the INPUT value into printable form in the exactly
- FORMAT->W characters in OUTPUT according to format
- specification FORMAT. No null terminator is appended to the
- buffer.
+/* Converts the INPUT value into printable form, according to format
+ specification FORMAT.
VALUE must be the correct width for FORMAT, that is, its
- width must be fmt_var_width(FORMAT). */
-void
-data_out (const union value *input, const struct fmt_spec *format,
- char *output)
+ width must be fmt_var_width(FORMAT).
+
+ The return value is dynamically allocated, and must be freed
+ by the caller. If POOL is non-null, then the return value is
+ allocated on that pool.
+*/
+char *
+data_out_pool (const union value *input, const struct fmt_spec *format,
+ struct pool *pool)
+{
+ char *output = pool_malloc (pool, format->w + 1);
+ assert (fmt_check_output (format));
+
+ converters[format->type] (input, format, output);
+ output[format->w] = '\0';
+ return output;
+}
+
+char *
+data_out (const union value *input, const struct fmt_spec *format)
{
- return data_out_legacy (input, LEGACY_NATIVE, format, output);
+ return data_out_pool (input, format, NULL);
}
\f
struct fmt_spec;
union value;
-void data_out (const union value *, const struct fmt_spec *, char *);
+char * data_out (const union value *, const struct fmt_spec *);
-void data_out_legacy (const union value *, const char *encoding,
- const struct fmt_spec *, char *);
+char * data_out_pool (const union value *, 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);
#endif /* data-out.h */
const char *name = var_lookup_value_label (v, value);
if (name == NULL)
{
- char *s = ds_put_uninit (str, v->print.w);
- data_out (value, &v->print, s);
+ char *s = data_out (value, &v->print);
+ ds_put_cstr (str, s);
+ free (s);
}
else
ds_put_cstr (str, name);
if (fmt_is_string (print->type)
|| dict_contains_var (dict, v))
{
- data_out (case_data (c, v), print,
- ds_put_uninit (&line_buffer, print->w));
+ char *s = data_out (case_data (c, v), print);
+ ds_put_cstr (&line_buffer, s);
+ free (s);
}
else
{
+ char *s;
union value case_idx_value;
case_idx_value.f = case_idx;
- data_out (&case_idx_value, print,
- ds_put_uninit (&line_buffer,print->w));
+ s = data_out (&case_idx_value, print);
+ ds_put_cstr (&line_buffer, s);
+ free (s);
}
- ds_put_char(&line_buffer, ' ');
+ ds_put_char (&line_buffer, ' ');
}
if (!n_lines_remaining (d))
{
const struct variable *v = cmd.v_variables[column];
const struct fmt_spec *print = var_get_print_format (v);
- char buf[256];
+ char *s = NULL;
if (fmt_is_string (print->type)
|| dict_contains_var (dict, v))
- data_out (case_data (c, v), print, buf);
+ s = data_out (case_data (c, v), print);
else
{
union value case_idx_value;
case_idx_value.f = case_idx;
- data_out (&case_idx_value, print, buf);
+ s = data_out (&case_idx_value, print);
}
fputs (" <TD>", x->file);
- html_put_cell_contents (d, TAB_FIX, ss_buffer (buf, print->w));
+ html_put_cell_contents (d, TAB_FIX, ss_buffer (s, print->w));
+ free (s);
fputs ("</TD>\n", x->file);
}
for (i = 0; i < split_cnt; i++)
{
const struct variable *v = split[i];
- char temp_buf[80];
+ char *s;
const char *val_lab;
const struct fmt_spec *print = var_get_print_format (v);
tab_text (t, 0, i + 1, TAB_LEFT | TAT_PRINTF, "%s", var_get_name (v));
- data_out (case_data (c, v), print, temp_buf);
- temp_buf[print->w] = 0;
-
- tab_text (t, 1, i + 1, TAT_PRINTF, "%.*s", print->w, temp_buf);
+ s = data_out (case_data (c, v), print);
+ tab_text (t, 1, i + 1, TAT_PRINTF, "%.*s", print->w, s);
+ free (s);
+
val_lab = var_lookup_value_label (v, case_data (c, v));
if (val_lab)
tab_text (t, 2, i + 1, TAB_LEFT, val_lab);
{
union value v;
struct substring dst;
+ char *s;
v.f = x;
- dst = alloc_string (e, f->w);
+
assert (!fmt_is_string (f->type));
- data_out (&v, f, dst.string);
+ s = data_out (&v, f);
+ dst = alloc_string (e, strlen (s));
+ strcpy (dst.string, s);
+ free (s);
return dst;
}
{
const struct variable *var = pt->const_vars[i];
size_t ofs;
+ char *s = NULL;
ds_put_format (&title, ", %s=", var_get_name (var));
/* Insert the formatted value of the variable, then trim
leading spaces in what was just inserted. */
ofs = ds_length (&title);
- data_out (&pt->const_values[i], var_get_print_format (var),
- ds_put_uninit (&title, var_get_width (var)));
+ s = data_out (&pt->const_values[i], var_get_print_format (var));
+ ds_put_cstr (&title, s);
+ free (s);
ds_remove (&title, ofs, ss_cspan (ds_substr (&title, ofs, SIZE_MAX),
ss_cstr (" ")));
}
const union value *v, const struct variable *var)
{
struct substring s;
+ char *ss;
const struct fmt_spec *print = var_get_print_format (var);
const char *label = var_lookup_value_label (var, v);
}
s.string = tab_alloc (table, print->w);
- data_out (v, print, s.string);
+ ss = data_out (v, print);
+ strcpy (s.string, ss);
+ free (ss);
s.length = print->w;
if (proc->exclude == MV_NEVER && var_is_num_missing (var, v->f, MV_USER))
s.string[s.length++] = 'M';
const struct fmt_spec f = {FMT_F, 10, 1};
union value v;
struct substring s;
+ char *ss;
s.length = 10;
s.string = tab_alloc (table, 16);
v.f = value;
- data_out (&v, &f, s.string);
+ ss = data_out (&v, &f);
+ strcpy (s.string, ss);
+ free (ss);
while (*s.string == ' ')
{
s.length--;
}
#endif
- contents = pool_alloc (table->container, f->w);
- table->cc[c + r * table->cf] = ss_buffer (contents, f->w);
- table->ct[c + r * table->cf] = opt;
+ contents = data_out_pool (v, f, table->container);
- data_out (v, f, contents);
+ table->cc[c + r * table->cf] = ss_cstr (contents);
+ table->ct[c + r * table->cf] = opt;
}
/* Sets cell (C,R) in TABLE, with options OPT, to have value VAL
tab_fixed (struct tab_table *table, int c, int r, unsigned char opt,
double val, int w, int d)
{
- char *contents;
- char buf[40], *cp;
+ char *s, *cp;
struct fmt_spec f;
union value double_value;
#endif
double_value.f = val;
- data_out (&double_value, &f, buf);
+ s = data_out_pool (&double_value, &f, table->container);
- cp = buf;
- while (isspace ((unsigned char) *cp) && cp < &buf[w])
+ cp = s;
+ while (isspace ((unsigned char) *cp) && cp < &s[w])
cp++;
- f.w = w - (cp - buf);
+ f.w = w - (cp - s);
- contents = pool_alloc (table->container, f.w);
- table->cc[c + r * table->cf] = ss_buffer (contents, f.w);
+ table->cc[c + r * table->cf] = ss_buffer (cp, f.w);
table->ct[c + r * table->cf] = opt;
- memcpy (contents, cp, f.w);
}
/* Sets cell (C,R) in TABLE, with options OPT, to have value VAL as
double val, const struct fmt_spec *fmt)
{
int w;
- char *contents;
- char buf[40], *cp;
+ char *s, *cp;
- union value double_value;
+ union value double_value ;
assert (table != NULL);
#endif
double_value.f = val;
- data_out (&double_value, fmt, buf);
+ s = data_out_pool (&double_value, fmt, table->container);
- cp = buf;
- while (isspace ((unsigned char) *cp) && cp < &buf[fmt->w])
- cp++;
- w = fmt->w - (cp - buf);
-
- contents = pool_alloc (table->container, w);
- table->cc[c + r * table->cf] = ss_buffer (contents, w);
+ cp = s;
+ while (isspace ((unsigned char) *cp) && cp < s + fmt->w)
+ {
+ cp++;
+ }
+ w = fmt->w - (cp - s);
+
+ table->cc[c + r * table->cf] = ss_buffer (cp, w);
table->ct[c + r * table->cf] = opt;
- memcpy (contents, cp, w);
}
{
gchar *s = 0;
- s = g_new (gchar, format.w + 1);
- data_out (&v, &format, s);
- s[format.w]='\0';
+ s = data_out (&v, &format);
g_strchug (s);
return s;
data_out_g_string (GString *string, const struct variable *v,
const struct ccase *cc)
{
- char *buf ;
-
const struct fmt_spec *fs = var_get_print_format (v);
const union value *val = case_data (cc, v);
- buf = xzalloc (fs->w);
- data_out (val, fs, buf);
+ char *s = data_out (val, fs);
- g_string_append_len (string, buf, fs->w);
+ g_string_append_len (string, s, fs->w);
- g_free (buf);
+ g_free (s);
}
static GString *
const struct variable *pv ;
union value v;
int width;
- GString *s;
g_return_val_if_fail (store->dict, NULL);
g_return_val_if_fail (store->datasheet, NULL);
fp = var_get_write_format (pv);
- s = g_string_sized_new (fp->w + 1);
- g_string_set_size (s, fp->w);
-
- memset (s->str, 0, fp->w);
-
- g_assert (fp->w == s->len);
-
/* 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. */
- data_out (&v, fp, s->str);
-
- text = recode_string (UTF8, psppire_dict_encoding (store->dict),
- s->str, fp->w);
- g_string_free (s, TRUE);
+ text = data_out (&v, fp);
g_strchomp (text);
}
if (outputp != NULL)
{
- char *output = xmalloc (out.w + 1);
- data_out (&val, &out, output);
- output[out.w] = '\0';
- *outputp = output;
+ *outputp = data_out (&val, &out);
}
value_destroy (&val, var_get_width (var));
& (FMT_CAT_DATE | FMT_CAT_TIME | FMT_CAT_DATE_COMPONENT)))
{
union value v_in, v_out;
- char buffer[FMT_MAX_NUMERIC_WIDTH];
+ char *s;
bool ok;
v_in.f = number;
- data_out (&v_in, format, buffer);
+ s = data_out (&v_in, format);
msg_disable ();
- ok = data_in (ss_buffer (buffer, format->w), LEGACY_NATIVE,
+ ok = data_in (ss_cstr (s), LEGACY_NATIVE,
format->type, false, 0, 0, &v_out, 0);
msg_enable ();
if (ok && v_out.f == number)
{
- syntax_gen_string (output, ss_buffer (buffer, format->w));
+ syntax_gen_string (output, ss_cstr (s));
+ free (s);
return;
}
+ free (s);
}
if (number == SYSMIS)