#include "language/command.h"
#include "language/lexer/format-parser.h"
#include "language/lexer/lexer.h"
+#include "language/lexer/token.h"
#include "language/lexer/variable-parser.h"
#include "libpspp/array.h"
#include "libpspp/assertion.h"
struct substring s, struct dictionary *dict,
enum fmt_type format, double *n)
{
- printf ("parse %.*s as %s\n", (int) s.length, s.string, fmt_name (format));
union value v;
char *error = data_in (s, dict_get_encoding (dict), format,
settings_get_fmt_settings (), &v, 0, NULL);
if (var_missing)
is_missing = true;
- printf ("ctables_cell_insert %s: ", var_get_name (var));
cats[a][i] = ctables_categories_match (
s->table->categories[var_get_dict_index (var)], value, var);
if (!cats[a][i])
pivot_table_set_caption (
pt, pivot_value_new_user_text (t->caption, SIZE_MAX));
if (t->corner)
- pivot_table_set_caption (
+ pivot_table_set_corner_text (
pt, pivot_value_new_user_text (t->corner, SIZE_MAX));
bool summary_dimension = (t->summary_axis != t->slabels_axis
return false;
}
+static void
+put_strftime (struct string *out, time_t now, const char *format)
+{
+ const struct tm *tm = localtime (&now);
+ char value[128];
+ strftime (value, sizeof value, format, tm);
+ ds_put_cstr (out, value);
+}
+
+static bool
+skip_prefix (struct substring *s, struct substring prefix)
+{
+ if (ss_starts_with (*s, prefix))
+ {
+ ss_advance (s, prefix.length);
+ return true;
+ }
+ else
+ return false;
+}
+
+static void
+put_table_expression (struct string *out, struct lexer *lexer,
+ struct dictionary *dict, int expr_start, int expr_end)
+{
+ size_t nest = 0;
+ for (int ofs = expr_start; ofs < expr_end; ofs++)
+ {
+ const struct token *t = lex_ofs_token (lexer, ofs);
+ if (t->type == T_LBRACK)
+ nest++;
+ else if (t->type == T_RBRACK && nest > 0)
+ nest--;
+ else if (nest > 0)
+ {
+ /* Nothing. */
+ }
+ else if (t->type == T_ID)
+ {
+ const struct variable *var
+ = dict_lookup_var (dict, t->string.string);
+ const char *label = var ? var_get_label (var) : NULL;
+ ds_put_cstr (out, label ? label : t->string.string);
+ }
+ else
+ {
+ if (ofs != expr_start && t->type != T_RPAREN && ds_last (out) != ' ')
+ ds_put_byte (out, ' ');
+
+ char *repr = lex_ofs_representation (lexer, ofs, ofs);
+ ds_put_cstr (out, repr);
+ free (repr);
+
+ if (ofs + 1 != expr_end && t->type != T_LPAREN)
+ ds_put_byte (out, ' ');
+ }
+ }
+}
+
+static void
+put_title_text (struct string *out, struct substring in, time_t now,
+ struct lexer *lexer, struct dictionary *dict,
+ int expr_start, int expr_end)
+{
+ for (;;)
+ {
+ size_t chunk = ss_find_byte (in, ')');
+ ds_put_substring (out, ss_head (in, chunk));
+ ss_advance (&in, chunk);
+ if (ss_is_empty (in))
+ return;
+
+ if (skip_prefix (&in, ss_cstr (")DATE")))
+ put_strftime (out, now, "%x");
+ else if (skip_prefix (&in, ss_cstr (")TIME")))
+ put_strftime (out, now, "%X");
+ else if (skip_prefix (&in, ss_cstr (")TABLE")))
+ put_table_expression (out, lexer, dict, expr_start, expr_end);
+ else
+ {
+ ds_put_byte (out, ')');
+ ss_advance (&in, 1);
+ }
+ }
+}
+
int
cmd_ctables (struct lexer *lexer, struct dataset *ds)
{
.postcomputes = HMAP_INITIALIZER (ct->postcomputes),
};
+ time_t now = time (NULL);
+
struct ctf
{
enum fmt_type type;
ct->tables[ct->n_tables++] = t;
lex_match (lexer, T_EQUALS);
+ int expr_start = lex_ofs (lexer);
if (!ctables_axis_parse (lexer, dataset_dict (ds), ct, t, PIVOT_AXIS_ROW))
goto error;
if (lex_match (lexer, T_BY))
goto error;
}
}
+ int expr_end = lex_ofs (lexer);
if (!t->axes[PIVOT_AXIS_ROW] && !t->axes[PIVOT_AXIS_COLUMN]
&& !t->axes[PIVOT_AXIS_LAYER])
{
if (!ds_is_empty (&s))
ds_put_byte (&s, ' ');
- ds_put_substring (&s, lex_tokss (lexer));
+ put_title_text (&s, lex_tokss (lexer), now,
+ lexer, dataset_dict (ds),
+ expr_start, expr_end);
lex_get (lexer);
}
free (*textp);