#include <setjmp.h>
#include <stdlib.h>
+ #include <libpspp/i18n.h>
#include <libpspp/assertion.h>
#include <libpspp/message.h>
#include <libpspp/compiler.h>
size_t size, size_t count,
struct dictionary *);
+ /* Convert all the strings in DICT from the dict encoding to UTF8 */
+ static void
+ recode_strings (struct dictionary *dict)
+ {
+ int i;
+
+ const char *enc = dict_get_encoding (dict);
+
+ if ( NULL == enc)
+ enc = get_default_encoding ();
+
+ for (i = 0 ; i < dict_get_var_cnt (dict); ++i)
+ {
+ /* Convert the long variable name */
+ struct variable *var = dict_get_var (dict, i);
+ const char *native_name = var_get_name (var);
+ char *utf8_name = recode_string (UTF8, enc, native_name, -1);
+ if ( 0 != strcmp (utf8_name, native_name))
+ {
+ if ( NULL == dict_lookup_var (dict, utf8_name))
+ dict_rename_var (dict, var, utf8_name);
+ else
+ msg (MW,
+ _("Recoded variable name duplicates an existing `%s' within system file."), utf8_name);
+ }
+
+ free (utf8_name);
+
+ /* Convert the variable label */
+ if (var_has_label (var))
+ {
+ char *utf8_label = recode_string (UTF8, enc, var_get_label (var), -1);
+ var_set_label (var, utf8_label);
+ free (utf8_label);
+ }
+
+ if (var_has_value_labels (var))
+ {
+ const struct val_lab *vl = NULL;
+ const struct val_labs *vlabs = var_get_value_labels (var);
+
+ for (vl = val_labs_first (vlabs); vl != NULL; vl = val_labs_next (vlabs, vl))
+ {
+ const union value *val = val_lab_get_value (vl);
+ const char *label = val_lab_get_label (vl);
+ char *new_label = NULL;
+
+ new_label = recode_string (UTF8, enc, label, -1);
+
+ var_replace_value_label (var, val, new_label);
+ free (new_label);
+ }
+ }
+ }
+ }
+
/* Opens the system file designated by file handle FH for
reading. Reads the system file's dictionary into *DICT.
If INFO is non-null, then it receives additional info about the
r->has_long_var_names = true;
}
+ recode_strings (*dict);
+
/* Read record 999 data, which is just filler. */
read_int (r);
/* Create variable. */
if (width < 0 || width > 255)
- sys_error (r, _("Bad variable width %d."), width);
+ sys_error (r, _("Bad width %d for variable %s."), width, name);
var = dict_create_var (dict, name, width);
if (var == NULL)
sys_error (r,
value_set_missing (&value, mv_width);
for (i = 0; i < missing_value_code; i++)
{
- char *s = value_str_rw (&value, mv_width);
+ uint8_t *s = value_str_rw (&value, mv_width);
read_bytes (r, s, 8);
mv_add_str (&mv, s);
}
size, count);
if (sysmis != SYSMIS)
- sys_warn (r, _("File specifies unexpected value %g as SYSMIS."), sysmis);
+ sys_warn (r, _("File specifies unexpected value %g as %s."),
+ sysmis, "SYSMIS");
+
if (highest != HIGHEST)
- sys_warn (r, _("File specifies unexpected value %g as HIGHEST."), highest);
+ sys_warn (r, _("File specifies unexpected value %g as %s."),
+ highest, "HIGHEST");
+
if (lowest != LOWEST)
- sys_warn (r, _("File specifies unexpected value %g as LOWEST."), lowest);
+ sys_warn (r, _("File specifies unexpected value %g as %s."),
+ lowest, "LOWEST");
}
/* Read record type 7, subtype 11, which specifies how variables
struct label
{
- char raw_value[8]; /* Value as uninterpreted bytes. */
+ uint8_t raw_value[8]; /* Value as uninterpreted bytes. */
union value value; /* Value. */
char *label; /* Null-terminated label string. */
};
value_init_pool (subpool, &label->value, max_width);
if (var_is_alpha (var[0]))
- buf_copy_rpad (value_str_rw (&label->value, max_width), max_width,
+ u8_buf_copy_rpad (value_str_rw (&label->value, max_width), max_width,
label->raw_value, sizeof label->raw_value, ' ');
else
label->value.f = float_get_double (r->float_format, label->raw_value);
/* Read value. */
value_length = read_int (r);
if (value_length == width)
- read_string (r, value_str_rw (&value, width), width + 1);
+ read_bytes (r, value_str_rw (&value, width), width);
else
{
sys_warn (r, _("Ignoring long string value %zu for variable %s, "
static void read_error (struct casereader *, const struct sfm_reader *);
static bool read_case_number (struct sfm_reader *, double *);
- static bool read_case_string (struct sfm_reader *, char *, size_t);
+ static bool read_case_string (struct sfm_reader *, uint8_t *, size_t);
static int read_opcode (struct sfm_reader *);
static bool read_compressed_number (struct sfm_reader *, double *);
- static bool read_compressed_string (struct sfm_reader *, char *);
- static bool read_whole_strings (struct sfm_reader *, char *, size_t);
+ static bool read_compressed_string (struct sfm_reader *, uint8_t *);
+ static bool read_whole_strings (struct sfm_reader *, uint8_t *, size_t);
static bool skip_whole_strings (struct sfm_reader *, size_t);
/* Reads and returns one case from READER's file. Returns a null
}
else
{
- char *s = value_str_rw (v, sv->var_width);
+ uint8_t *s = value_str_rw (v, sv->var_width);
if (!read_case_string (r, s + sv->offset, sv->segment_width))
goto eof;
if (!skip_whole_strings (r, ROUND_DOWN (sv->padding, 8)))
Returns true if successful, false if end of file is
reached immediately. */
static bool
- read_case_string (struct sfm_reader *r, char *s, size_t length)
+ read_case_string (struct sfm_reader *r, uint8_t *s, size_t length)
{
size_t whole = ROUND_DOWN (length, 8);
size_t partial = length % 8;
if (partial)
{
- char bounce[8];
+ uint8_t bounce[8];
if (!read_whole_strings (r, bounce, sizeof bounce))
{
if (whole)
Returns true if successful, false if end of file is
reached immediately. */
static bool
- read_compressed_string (struct sfm_reader *r, char *dst)
+ read_compressed_string (struct sfm_reader *r, uint8_t *dst)
{
switch (read_opcode (r))
{
Returns true if successful, false if end of file is
reached immediately. */
static bool
- read_whole_strings (struct sfm_reader *r, char *s, size_t length)
+ read_whole_strings (struct sfm_reader *r, uint8_t *s, size_t length)
{
assert (length % 8 == 0);
if (!r->compressed)
static bool
skip_whole_strings (struct sfm_reader *r, size_t length)
{
- char buffer[1024];
+ uint8_t buffer[1024];
assert (length < sizeof buffer);
return read_whole_strings (r, buffer, length);
}
#include <assert.h>
#include <stdbool.h>
#include <stdlib.h>
+ #include <stdint.h>
#include <string.h>
#include "xalloc.h"
\f
union value
{
double f;
- char short_string[MAX_SHORT_STRING];
- char *long_string;
+ uint8_t short_string[MAX_SHORT_STRING];
+ uint8_t *long_string;
};
static inline void value_init (union value *, int width);
static inline void value_destroy (union value *, int width);
static inline double value_num (const union value *);
- static inline const char *value_str (const union value *, int width);
- static inline char *value_str_rw (union value *, int width);
+ static inline const uint8_t *value_str (const union value *, int width);
+ static inline uint8_t *value_str_rw (union value *, int width);
-int compare_values (const void *, const void *, const void *var);
-unsigned hash_value (const void *, const void *var);
-
static inline void value_copy (union value *, const union value *, int width);
void value_copy_rpad (union value *, int dst_width,
const union value *, int src_width,
char pad);
- void value_copy_str_rpad (union value *, int dst_width, const char *,
+ void value_copy_str_rpad (union value *, int dst_width, const uint8_t *,
char pad);
void value_copy_buf_rpad (union value *dst, int dst_width,
- const char *src, size_t src_len, char pad);
+ const uint8_t *src, size_t src_len, char pad);
void value_set_missing (union value *, int width);
int value_compare_3way (const union value *, const union value *, int width);
bool value_equal (const union value *, const union value *, int width);
It is important that WIDTH be the actual value that was passed
to value_init. Passing, e.g., a smaller value because only
that number of bytes will be accessed will not always work. */
- static inline const char *
+ static inline const uint8_t *
value_str (const union value *v, int width)
{
assert (width > 0);
It is important that WIDTH be the actual value that was passed
to value_init. Passing, e.g., a smaller value because only
that number of bytes will be accessed will not always work. */
- static inline char *
+ static inline uint8_t *
value_str_rw (union value *v, int width)
{
assert (width > 0);
/* 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;
parse_fixed (const struct data_parser *parser, struct dfm_reader *reader,
struct ccase *c)
{
- enum legacy_encoding encoding = dfm_reader_get_legacy_encoding (reader);
+ const char *encoding = dfm_reader_get_legacy_encoding (reader);
struct field *f;
int row;
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));
parse_delimited_span (const struct data_parser *parser,
struct dfm_reader *reader, struct ccase *c)
{
- enum legacy_encoding encoding = dfm_reader_get_legacy_encoding (reader);
+ const char *encoding = dfm_reader_get_legacy_encoding (reader);
struct string tmp = DS_EMPTY_INITIALIZER;
struct field *f;
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));
}
parse_delimited_no_span (const struct data_parser *parser,
struct dfm_reader *reader, struct ccase *c)
{
- enum legacy_encoding encoding = dfm_reader_get_legacy_encoding (reader);
+ const char *encoding = dfm_reader_get_legacy_encoding (reader);
struct string tmp = DS_EMPTY_INITIALIZER;
struct substring s;
struct field *f;
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));
}
int row = i + 1;
tab_text (t, 0, row, TAB_LEFT, f->name);
- tab_text (t, 1, row, TAT_PRINTF, "%d", f->record);
- tab_text (t, 2, row, TAT_PRINTF, "%3d-%3d",
- f->first_column, f->first_column + f->format.w - 1);
+ tab_text_format (t, 1, row, 0, "%d", f->record);
+ tab_text_format (t, 2, row, 0, "%3d-%3d",
+ f->first_column, f->first_column + f->format.w - 1);
tab_text (t, 3, row, TAB_LEFT | TAB_FIX,
fmt_to_string (&f->format, fmt_string));
}
#include <language/lexer/lexer.h>
#include <language/lexer/variable-parser.h>
#include <libpspp/assertion.h>
+ #include <libpspp/i18n.h>
#include <libpspp/compiler.h>
#include <libpspp/ll.h>
#include <libpspp/message.h>
struct pool *pool; /* Stores related data. */
bool eject; /* Eject page before printing? */
bool include_prefix; /* Prefix lines with space? */
- enum legacy_encoding encoding; /* Encoding to use for output. */
+ const char *encoding; /* Encoding to use for output. */
struct dfm_writer *writer; /* Output file, NULL=listing file. */
struct ll_list specs; /* List of struct prt_out_specs. */
size_t record_cnt; /* Number of records to write. */
switch (spec->type)
{
case PRT_LITERAL:
- tab_text (t, 0, row, TAB_LEFT | TAB_FIX | TAT_PRINTF, "\"%.*s\"",
- (int) ds_length (&spec->string), ds_data (&spec->string));
+ tab_text_format (t, 0, row, TAB_LEFT | TAB_FIX, "\"%.*s\"",
+ (int) ds_length (&spec->string),
+ ds_data (&spec->string));
width = ds_length (&spec->string);
break;
case PRT_VAR:
default:
NOT_REACHED ();
}
- tab_text (t, 1, row, TAT_PRINTF, "%d", spec->record);
- tab_text (t, 2, row, TAT_PRINTF, "%3d-%3d",
- spec->first_column, spec->first_column + width - 1);
+ tab_text_format (t, 1, row, 0, "%d", spec->record);
+ tab_text_format (t, 2, row, 0, "%3d-%3d",
+ spec->first_column, spec->first_column + width - 1);
row++;
}
else
{
ds_put_substring (&trns->line, ds_ss (&spec->string));
- if (trns->encoding != LEGACY_NATIVE)
+ if (0 != strcmp (trns->encoding, LEGACY_NATIVE))
{
size_t length = ds_length (&spec->string);
char *data = ss_data (ds_tail (&trns->line, length));
- legacy_recode (LEGACY_NATIVE, data,
- trns->encoding, data, length);
+ char *s = recode_string (trns->encoding, LEGACY_NATIVE, data, length);
+ memcpy (data, s, length);
+ free (s);
}
}
}
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));
+ tab_text_format (t, 0, i + 1, TAB_LEFT, "%s", var_get_name (v));
- data_out (case_data (c, v), print, temp_buf);
- temp_buf[print->w] = 0;
-
- tab_text_format (t, 1, i + 1, 0, "%.*s", print->w, temp_buf);
+ s = data_out (case_data (c, v), dict_get_encoding (dict), print);
++ tab_text_format (t, 1, i + 1, 0, "%.*s", print->w, s);
- 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);
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;
{
tab_double (summary, i * 2 + 1, 0, TAB_RIGHT, n[i],
&proc->weight_format);
- tab_text (summary, i * 2 + 2, 0, TAB_RIGHT | TAT_PRINTF, "%.1f%%",
- n[i] / n[2] * 100.);
+ tab_text_format (summary, i * 2 + 2, 0, TAB_RIGHT, "%.1f%%",
+ n[i] / n[2] * 100.);
}
tab_next_row (summary);
{
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], 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),
ss_cstr (" ")));
}
tab_text (chisq, 3, 0, TAB_RIGHT | TAT_TITLE,
_("Asymp. Sig. (2-sided)"));
tab_text (chisq, 4, 0, TAB_RIGHT | TAT_TITLE,
- _("Exact. Sig. (2-sided)"));
+ _("Exact Sig. (2-sided)"));
tab_text (chisq, 5, 0, TAB_RIGHT | TAT_TITLE,
- _("Exact. Sig. (1-sided)"));
+ _("Exact Sig. (1-sided)"));
tab_offset (chisq, 0, 1);
return chisq;
tab_title (risk, _("Risk estimate."));
tab_offset (risk, pt->n_vars - 2, 0);
- tab_joint_text (risk, 2, 0, 3, 0, TAB_CENTER | TAT_TITLE | TAT_PRINTF,
- _("95%% Confidence Interval"));
+ tab_joint_text_format (risk, 2, 0, 3, 0, TAB_CENTER | TAT_TITLE,
+ _("95%% Confidence Interval"));
tab_text (risk, 0, 1, TAB_LEFT | TAT_TITLE, _("Statistic"));
tab_text (risk, 1, 1, TAB_RIGHT | TAT_TITLE, _("Value"));
tab_text (risk, 2, 1, TAB_RIGHT | TAT_TITLE, _("Lower"));
return;
}
- s.string = tab_alloc (table, print->w);
- data_out (v, print, s.string);
- s.length = print->w;
+ s = ss_cstr (data_out_pool (v, dict_get_encoding (proc->dict), print,
+ table->container));
if (proc->exclude == MV_NEVER && var_is_num_missing (var, v->f, MV_USER))
s.string[s.length++] = 'M';
while (s.length && *s.string == ' ')
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;
struct substring s;
- s.length = 10;
- s.string = tab_alloc (table, 16);
v.f = value;
- data_out (&v, &f, s.string);
+ s = ss_cstr (data_out_pool (&v, dict_get_encoding (dict), &f, table->container));
+
while (*s.string == ' ')
{
s.length--;
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;
}
else
string = var_get_name (pt->vars[1]);
- tab_text (direct, j, 0, TAB_LEFT | TAT_PRINTF,
- gettext (stats_names[j][k]), string);
+ tab_text_format (direct, j, 0, TAB_LEFT,
+ gettext (stats_names[j][k]), string);
}
}
}
if (var != NULL)
{
int val_width = 1;
- char *val;
+ uint8_t *val;
result = xmalloc (sizeof (*result));
result->intr = var;
{
size_t i;
size_t n_vars;
- const struct variable *intr;
const struct variable *member;
const union value **vals = NULL;
n_vars = interaction_get_n_vars (iv);
- intr = interaction_get_variable (iv);
vals = xnmalloc (n_vars, sizeof (*vals));
for (i = 0; i < n_vars; i++)
#include <data/data-out.h>
#include <data/format.h>
#include <data/value.h>
+ #include <data/dictionary.h>
#include <libpspp/assertion.h>
#include <libpspp/compiler.h>
#include <libpspp/misc.h>
}
}
-/* Formats text TEXT and arguments ARGS as indicated in OPT in
- TABLE's pool and returns the resultant string. */
-static struct substring
-text_format (struct tab_table *table, int opt, const char *text, va_list args)
-{
- assert (table != NULL && text != NULL);
-
- return ss_cstr (opt & TAT_PRINTF
- ? pool_vasprintf (table->container, text, args)
- : pool_strdup (table->container, text));
-}
-
/* Set the title of table T to TITLE, which is formatted as if
passed to printf(). */
void
from V, displayed with format spec F. */
void
tab_value (struct tab_table *table, int c, int r, unsigned char opt,
- const union value *v, const struct fmt_spec *f)
+ const union value *v, const struct dictionary *dict,
+ const struct fmt_spec *f)
{
char *contents;
}
#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, dict_get_encoding (dict), 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, LEGACY_NATIVE, &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
tab_double (struct tab_table *table, int c, int r, unsigned char opt,
double val, const struct fmt_spec *fmt)
{
- int w;
- char *contents;
- char buf[40], *cp;
-
- union value double_value;
+ struct substring ss;
+ union value double_value ;
assert (table != NULL);
#endif
double_value.f = val;
- data_out (&double_value, fmt, buf);
+ ss = ss_cstr (data_out_pool (&double_value, LEGACY_NATIVE, fmt, table->container));
- cp = buf;
- while (isspace ((unsigned char) *cp) && cp < &buf[fmt->w])
- cp++;
- w = fmt->w - (cp - buf);
+ ss_ltrim (&ss, ss_cstr (" "));
- contents = pool_alloc (table->container, w);
- table->cc[c + r * table->cf] = ss_buffer (contents, w);
+ table->cc[c + r * table->cf] = ss;
table->ct[c + r * table->cf] = opt;
- memcpy (contents, cp, w);
}
-/* Sets cell (C,R) in TABLE, with options OPT, to have text value
- TEXT. */
-void
-tab_text (struct tab_table *table, int c, int r, unsigned opt, const char *text, ...)
+static void
+do_tab_text (struct tab_table *table, int c, int r, unsigned opt, char *text)
{
- va_list args;
-
- assert (table != NULL && text != NULL);
-
- assert (c >= 0 );
- assert (r >= 0 );
+ assert (c >= 0);
+ assert (r >= 0);
assert (c < table->nc);
assert (r < table->nr);
-
#if DEBUGGING
if (c + table->col_ofs < 0 || r + table->row_ofs < 0
|| c + table->col_ofs >= table->nc
}
#endif
- va_start (args, text);
- table->cc[c + r * table->cf] = text_format (table, opt, text, args);
+ table->cc[c + r * table->cf] = ss_cstr (text);
table->ct[c + r * table->cf] = opt;
- va_end (args);
}
-/* Joins cells (X1,X2)-(Y1,Y2) inclusive in TABLE, and sets them with
- options OPT to have text value TEXT. */
+/* Sets cell (C,R) in TABLE, with options OPT, to have text value
+ TEXT. */
void
-tab_joint_text (struct tab_table *table, int x1, int y1, int x2, int y2,
- unsigned opt, const char *text, ...)
+tab_text (struct tab_table *table, int c, int r, unsigned opt,
+ const char *text)
{
- struct tab_joined_cell *j;
+ do_tab_text (table, c, r, opt, pool_strdup (table->container, text));
+}
- assert (table != NULL && text != NULL);
+/* Sets cell (C,R) in TABLE, with options OPT, to have text value
+ FORMAT, which is formatted as if passed to printf. */
+void
+tab_text_format (struct tab_table *table, int c, int r, unsigned opt,
+ const char *format, ...)
+{
+ va_list args;
+
+ va_start (args, format);
+ do_tab_text (table, c, r, opt,
+ pool_vasprintf (table->container, format, args));
+ va_end (args);
+}
+
+static void
+do_tab_joint_text (struct tab_table *table, int x1, int y1, int x2, int y2,
+ unsigned opt, char *text)
+{
+ struct tab_joined_cell *j;
assert (x1 + table->col_ofs >= 0);
assert (y1 + table->row_ofs >= 0);
j->y1 = y1 + table->row_ofs;
j->x2 = ++x2 + table->col_ofs;
j->y2 = ++y2 + table->row_ofs;
-
- {
- va_list args;
-
- va_start (args, text);
- j->contents = text_format (table, opt, text, args);
- va_end (args);
- }
+ j->contents = ss_cstr (text);
opt |= TAB_JOIN;
}
}
+/* Joins cells (X1,X2)-(Y1,Y2) inclusive in TABLE, and sets them with
+ options OPT to have text value TEXT. */
+void
+tab_joint_text (struct tab_table *table, int x1, int y1, int x2, int y2,
+ unsigned opt, const char *text)
+{
+ do_tab_joint_text (table, x1, y1, x2, y2, opt,
+ pool_strdup (table->container, text));
+}
+
+/* Joins cells (X1,X2)-(Y1,Y2) inclusive in TABLE, and sets them
+ with options OPT to have text value FORMAT, which is formatted
+ as if passed to printf. */
+void
+tab_joint_text_format (struct tab_table *table, int x1, int y1, int x2, int y2,
+ unsigned opt, const char *format, ...)
+{
+ va_list args;
+
+ va_start (args, format);
+ do_tab_joint_text (table, x1, y1, x2, y2, opt,
+ pool_vasprintf (table->container, format, args));
+ va_end (args);
+}
+
/* Sets cell (C,R) in TABLE, with options OPT, to contents STRING. */
void
tab_raw (struct tab_table *table, int c, int r, unsigned opt,
t->h[0] = tab_natural_height (t, d, 0);
}
-/* Outputs text BUF as a table with a single cell having cell options
+static void
+do_tab_output_text (struct tab_table *t, int options, char *text)
+{
+ do_tab_text (t, 0, 0, options, text);
+ tab_flags (t, SOMF_NO_TITLE | SOMF_NO_SPACING);
+ tab_dim (t, options & TAT_NOWRAP ? nowrap_dim : wrap_dim, NULL);
+ tab_submit (t);
+}
+
+/* Outputs TEXT as a table with a single cell having cell options
OPTIONS, which is a combination of the TAB_* and TAT_*
- constants. */
+ constants. */
void
-tab_output_text (int options, const char *buf, ...)
+tab_output_text (int options, const char *text)
{
- struct tab_table *t = tab_create (1, 1, 0);
- char *tmp_buf = NULL;
-
- if (options & TAT_PRINTF)
- {
- va_list args;
+ struct tab_table *table = tab_create (1, 1, 0);
+ do_tab_output_text (table, options, pool_strdup (table->container, text));
+}
- va_start (args, buf);
- buf = tmp_buf = xvasprintf (buf, args);
- va_end (args);
- }
+/* Outputs FORMAT as a table with a single cell having cell
+ options OPTIONS, which is a combination of the TAB_* and TAT_*
+ constants. FORMAT is formatted as if it was passed through
+ printf. */
+void
+tab_output_text_format (int options, const char *format, ...)
+{
+ struct tab_table *table;
+ va_list args;
- tab_text (t, 0, 0, options & ~TAT_PRINTF, buf);
- tab_flags (t, SOMF_NO_TITLE | SOMF_NO_SPACING);
- tab_dim (t, options & TAT_NOWRAP ? nowrap_dim : wrap_dim, NULL);
- tab_submit (t);
+ table = tab_create (1, 1, 0);
- free (tmp_buf);
+ va_start (args, format);
+ do_tab_output_text (table, options,
+ pool_vasprintf (table->container, format, args));
+ va_end (args);
}
/* Set table flags to FLAGS. */
enum
{
TAT_NONE = 0, /* No options. */
- TAT_PRINTF = 0x0100, /* Format the text string with sprintf. */
TAT_TITLE = 0x0200 | TAB_EMPH, /* Title attributes. */
TAT_NOWRAP = 0x0800 /* No text wrap (tab_output_text() only). */
};
/* Cells. */
struct fmt_spec;
+ struct dictionary;
union value;
void tab_value (struct tab_table *, int c, int r, unsigned char opt,
- const union value *, const struct fmt_spec *);
+ const union value *, const struct dictionary *dict,
+ const struct fmt_spec *);
void tab_fixed (struct tab_table *, int c, int r, unsigned char opt,
double v, int w, int d);
void tab_double (struct tab_table *, int c, int r, unsigned char opt,
double v, const struct fmt_spec *);
-void tab_text (struct tab_table *, int c, int r, unsigned opt,
- const char *, ...)
+void tab_text (struct tab_table *, int c, int r, unsigned opt, const char *);
+void tab_text_format (struct tab_table *, int c, int r, unsigned opt,
+ const char *, ...)
PRINTF_FORMAT (5, 6);
+
void tab_joint_text (struct tab_table *, int x1, int y1, int x2, int y2,
- unsigned opt, const char *, ...)
+ unsigned opt, const char *);
+void tab_joint_text_format (struct tab_table *, int x1, int y1, int x2, int y2,
+ unsigned opt, const char *, ...)
PRINTF_FORMAT (7, 8);
/* Cell low-level access. */
#define tab_col(TABLE) ((TABLE)->col_ofs)
/* Simple output. */
-void tab_output_text (int options, const char *string, ...)
+void tab_output_text (int options, const char *string);
+void tab_output_text_format (int options, const char *, ...)
PRINTF_FORMAT (2, 3);
/* Embedding the command name in the output. */