case CTPO_CAT_NUMBER:
case CTPO_CAT_STRING:
case CTPO_CAT_NRANGE:
+ case CTPO_CAT_SRANGE:
case CTPO_CAT_MISSING:
case CTPO_CAT_OTHERNM:
case CTPO_CAT_SUBTOTAL:
dict, e->subs[i], pc_cat, cats, cats_location))
return false;
return true;
-
- default:
- NOT_REACHED ();
}
+
+ NOT_REACHED ();
}
static bool
};
}
+static struct ctables_pcexpr
+ctpo_cat_srange (struct substring low, struct substring high)
+{
+ return (struct ctables_pcexpr) {
+ .op = CTPO_CAT_SRANGE,
+ .srange = { low, high },
+ };
+}
+
static struct ctables_pcexpr *
ctable_pcexpr_parse_primary (struct lexer *lexer, struct dictionary *dict)
{
{
if (lex_match_id (lexer, "LO"))
{
- if (!lex_force_match_id (lexer, "THRU") || !lex_force_num (lexer))
+ if (!lex_force_match_id (lexer, "THRU"))
return false;
- e = ctpo_cat_nrange (-DBL_MAX, lex_number (lexer));
- lex_get (lexer);
+
+ if (lex_is_string (lexer))
+ {
+ struct substring low = { .string = NULL };
+ struct substring high = parse_substring (lexer, dict);
+ e = ctpo_cat_srange (low, high);
+ }
+ else
+ {
+ if (lex_force_num (lexer))
+ return false;
+ e = ctpo_cat_nrange (-DBL_MAX, lex_number (lexer));
+ lex_get (lexer);
+ }
}
else if (lex_is_number (lexer))
{
}
else if (lex_is_string (lexer))
{
- struct substring s = recode_substring_pool (
- dict_get_encoding (dict), "UTF-8", lex_tokss (lexer), NULL);
- ss_rtrim (&s, ss_cstr (" "));
+ struct substring s = parse_substring (lexer, dict);
- e = (struct ctables_pcexpr) { .op = CTPO_CAT_STRING, .string = s };
- lex_get (lexer);
+ if (lex_match_id (lexer, "THRU"))
+ {
+ struct substring high;
+
+ if (lex_match_id (lexer, "HI"))
+ high = (struct substring) { .string = NULL };
+ else
+ {
+ if (!lex_force_string (lexer))
+ {
+ ss_dealloc (&s);
+ return false;
+ }
+ high = parse_substring (lexer, dict);
+ }
+
+ e = ctpo_cat_srange (s, high);
+ }
+ else
+ e = (struct ctables_pcexpr) { .op = CTPO_CAT_STRING, .string = s };
}
else
{
{
if (e.op == CTPO_CAT_STRING)
ss_dealloc (&e.string);
+ else if (e.op == CTPO_CAT_SRANGE)
+ {
+ ss_dealloc (&e.srange[0]);
+ ss_dealloc (&e.srange[1]);
+ }
return NULL;
}
}
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 * multi-dimensional (multiple CCT_POSTCOMPUTE in one cell)
dnl * dates
dnl - PPROPERTIES:
/TABLE licensed
/CATEGORIES VARIABLES=licensed ['Yes', ¬yes, 'No', 'DontKnow', 'Refused'].
CTABLES
- /PCOMPUTE ¬yes=EXPR(['No']+['DontKnow']+['Refused'])
+ /PCOMPUTE ¬yes=EXPR(['DontKnow' THRU 'No'] + ['Refused'])
/PPROPERTIES ¬yes LABEL='Not Yes' HIDESOURCECATS=YES
/TABLE licensed
/CATEGORIES VARIABLES=licensed ['Yes', ¬yes, 'DontKnow' THRU 'No', 'Refused'].
├────────────────┼─────┤
│licensed Yes │ 6379│
│ Not Yes│ 620│
+╰────────────────┴─────╯
+
+ Custom Tables
+╭────────────────┬─────╮
+│ │Count│
+├────────────────┼─────┤
+│licensed Yes │ 6379│
+│ Not Yes│ 620│
╰────────────────┴─────╯
])
AT_CLEANUP