CTPO_CONSTANT, /* 5 */
CTPO_CAT_NUMBER, /* [5] */
CTPO_CAT_STRING, /* ["STRING"] */
- CTPO_CAT_RANGE, /* [LO THRU 5] */
+ CTPO_CAT_NRANGE, /* [LO THRU 5] */
+ CTPO_CAT_SRANGE, /* ["A" THRU "B"] */
CTPO_CAT_MISSING, /* MISSING */
CTPO_CAT_OTHERNM, /* OTHERNM */
CTPO_CAT_SUBTOTAL, /* SUBTOTAL */
/* CTPO_CAT_STRING, in dictionary encoding. */
struct substring string;
- /* CTPO_CAT_RANGE. */
- double range[2];
+ /* CTPO_CAT_NRANGE. */
+ double nrange[2];
+
+ /* CTPO_CAT_SRANGE. */
+ struct substring srange[2];
/* CTPO_CAT_SUBTOTAL. */
size_t subtotal_index;
best = cat;
break;
- case CTPO_CAT_RANGE:
+ case CTPO_CAT_NRANGE:
if (cat->type == CCT_NRANGE
- && cat->nrange[0] == e->range[0]
- && cat->nrange[1] == e->range[1])
+ && cat->nrange[0] == e->nrange[0]
+ && cat->nrange[1] == e->nrange[1])
+ best = cat;
+ break;
+
+ case CTPO_CAT_SRANGE:
+ if (cat->type == CCT_SRANGE
+ && nullable_substring_equal (&cat->srange[0], &e->srange[0])
+ && nullable_substring_equal (&cat->srange[1], &e->srange[1]))
best = cat;
break;
{
case CTPO_CAT_NUMBER:
case CTPO_CAT_STRING:
- case CTPO_CAT_RANGE:
+ case CTPO_CAT_NRANGE:
case CTPO_CAT_MISSING:
case CTPO_CAT_OTHERNM:
case CTPO_CAT_SUBTOTAL:
case CTPO_CONSTANT:
return e->number;
- case CTPO_CAT_RANGE:
+ case CTPO_CAT_NRANGE:
+ case CTPO_CAT_SRANGE:
{
struct ctables_cell_value cv = {
.category = ctables_find_category_for_postcompute (ctx->cats, e)
ss_dealloc (&e->string);
break;
+ case CTPO_CAT_SRANGE:
+ for (size_t i = 0; i < 2; i++)
+ ss_dealloc (&e->srange[i]);
+ break;
+
case CTPO_ADD:
case CTPO_SUB:
case CTPO_MUL:
case CTPO_CONSTANT:
case CTPO_CAT_NUMBER:
- case CTPO_CAT_RANGE:
+ case CTPO_CAT_NRANGE:
case CTPO_CAT_MISSING:
case CTPO_CAT_OTHERNM:
case CTPO_CAT_SUBTOTAL:
struct dictionary *);
static struct ctables_pcexpr
-ctpo_cat_range (double low, double high)
+ctpo_cat_nrange (double low, double high)
{
return (struct ctables_pcexpr) {
- .op = CTPO_CAT_RANGE,
- .range = { low, high },
+ .op = CTPO_CAT_NRANGE,
+ .nrange = { low, high },
};
}
{
if (!lex_force_match_id (lexer, "THRU") || lex_force_num (lexer))
return false;
- e = ctpo_cat_range (-DBL_MAX, lex_number (lexer));
+ e = ctpo_cat_nrange (-DBL_MAX, lex_number (lexer));
lex_get (lexer);
}
else if (lex_is_number (lexer))
if (lex_match_id (lexer, "THRU"))
{
if (lex_match_id (lexer, "HI"))
- e = ctpo_cat_range (number, DBL_MAX);
+ e = ctpo_cat_nrange (number, DBL_MAX);
else
{
if (!lex_force_num (lexer))
return false;
- e = ctpo_cat_range (number, lex_number (lexer));
+ e = ctpo_cat_nrange (number, lex_number (lexer));
lex_get (lexer);
}
}
dnl * Data-dependent sorting.
dnl - PCOMPUTE:
dnl * multi-dimensional (multiple CCT_POSTCOMPUTE in one cell
-dnl * MISSING, OTHERNM
-dnl * strings
+dnl * dates
dnl
dnl Features not yet tested:
dnl - Parsing (positive and negative)
dnl - test CLABELS ROWLABELS=LAYER.
dnl - Test VLABELS.
dnl - Test WEIGHT and adjustment weights.
-dnl - Test PCOMPUTE and PPROPERTIES.
-dnl * PCOMPUTE for more than one kind of summary (e.g. [COUNT, ROWPCT]).
dnl - EMPTY=INCLUDE For string ranges.
dnl - Summary functions:
dnl * Separate summary functions for totals and subtotals.
dnl - Date/time variables and values
dnl - Special formats for summary functions: NEGPAREN, NEQUAL, PAREN, PCTPAREN.
dnl - TITLES: )DATE, )TIME, )TABLE.
+dnl - Test PCOMPUTE:
+dnl * PCOMPUTE for more than one kind of summary (e.g. [COUNT, ROWPCT]).
+dnl * MISSING, OTHERNM
+dnl * strings and string ranges
dnl - PPROPERTIES:
dnl * )LABEL[N].
dnl