From: Ben Pfaff Date: Thu, 16 Feb 2023 23:59:45 +0000 (-0800) Subject: dictionary: Fix invariant that no split file vars means SPLIT_NONE. X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=baf2ebf28012684c83613a97b3ba3bf9392490b8;p=pspp dictionary: Fix invariant that no split file vars means SPLIT_NONE. Add SHOW SPLIT to enable testing. Fixes a crash bug reported by Frans Houweling at https://lists.gnu.org/archive/html/bug-gnu-pspp/2023-01/msg00011.html --- diff --git a/src/data/dictionary.c b/src/data/dictionary.c index 60349bce61..1dffcb542f 100644 --- a/src/data/dictionary.c +++ b/src/data/dictionary.c @@ -416,19 +416,21 @@ dict_set_split_vars__ (struct dictionary *d, assert (n == 0 || split != NULL); d->n_splits = n; - d->split_type = type == SPLIT_NONE ? SPLIT_LAYERED : type; + d->split_type = (n == 0 ? SPLIT_NONE + : type == SPLIT_NONE ? SPLIT_LAYERED + : type); if (n > 0) - { - d->split = xnrealloc (d->split, n, sizeof *d->split) ; - memcpy (d->split, split, n * sizeof *d->split); - } + { + d->split = xnrealloc (d->split, n, sizeof *d->split) ; + memcpy (d->split, split, n * sizeof *d->split); + } else - { - free (d->split); - d->split = NULL; - } + { + free (d->split); + d->split = NULL; + } - if (!skip_callbacks) + if (!skip_callbacks) { if (d->changed) d->changed (d, d->changed_data); if (d->callbacks && d->callbacks->split_changed) diff --git a/src/language/commands/set.c b/src/language/commands/set.c index eb74280fed..75ba7b413e 100644 --- a/src/language/commands/set.c +++ b/src/language/commands/set.c @@ -954,6 +954,43 @@ show_SMALL (const struct dataset *ds UNUSED) return xstrdup (buf); } +static char * +show_SPLIT (const struct dataset *ds) +{ + const struct dictionary *dict = dataset_dict (ds); + + const char *type; + switch (dict_get_split_type (dict)) + { + case SPLIT_NONE: + return xstrdup ("none"); + + case SPLIT_SEPARATE: + type = "SEPARATE"; + break; + + case SPLIT_LAYERED: + type = "LAYERED"; + break; + + default: + NOT_REACHED (); + } + + struct string s = DS_EMPTY_INITIALIZER; + + size_t n = dict_get_n_splits (dict); + const struct variable *const *vars = dict_get_split_vars (dict); + for (size_t i = 0; i < n; i++) + { + if (i > 0) + ds_put_cstr (&s, ", "); + ds_put_cstr (&s, var_get_name (vars[i])); + } + ds_put_format (&s, " (%s)", type); + return ds_steal_cstr (&s); +} + static char * show_SUBTITLE (const struct dataset *ds UNUSED) { @@ -1271,6 +1308,7 @@ static const struct setting settings[] = { { "SCOMPRESSION", parse_SCOMPRESSION, show_SCOMPRESSION }, { "SEED", parse_SEED, NULL }, { "SMALL", parse_SMALL, show_SMALL }, + { "SPLIT", NULL, show_SPLIT }, { "TEMPDIR", NULL, show_TEMPDIR }, { "TNUMBERS", parse_TNUMBERS, show_TNUMBERS }, { "TVARS", parse_TVARS, show_TVARS }, diff --git a/tests/language/commands/split-file.at b/tests/language/commands/split-file.at index efdf3dcfd3..a66671278b 100644 --- a/tests/language/commands/split-file.at +++ b/tests/language/commands/split-file.at @@ -145,3 +145,76 @@ specified. | ^~~~~~~~ ]) AT_CLEANUP + +AT_SETUP([SPLIT FILE - SHOW SPLIT and SPLIT FILE OFF]) +AT_DATA([show.sps], [dnl +SET PRINTBACK=ON. + +SHOW SPLIT. + +DATA LIST LIST NOTABLE/x y z. +SPLIT FILE BY x y. +SHOW SPLIT. + +SPLIT FILE LAYERED BY y z. +SHOW SPLIT. + +SPLIT FILE SEPARATE BY x z. +SHOW SPLIT. + +SPLIT FILE OFF. +SHOW SPLIT. +]) +AT_CHECK([pspp show.sps -O box=unicode], [0], [dnl +SET PRINTBACK=ON. + +SHOW SPLIT. + + Settings +╭─────┬────╮ +│SPLIT│none│ +╰─────┴────╯ + + +DATA LIST LIST NOTABLE/x y z. + +SPLIT FILE BY x y. + +SHOW SPLIT. + + Settings +╭─────┬──────────────╮ +│SPLIT│x, y (LAYERED)│ +╰─────┴──────────────╯ + + +SPLIT FILE LAYERED BY y z. + +SHOW SPLIT. + + Settings +╭─────┬──────────────╮ +│SPLIT│y, z (LAYERED)│ +╰─────┴──────────────╯ + + +SPLIT FILE SEPARATE BY x z. + +SHOW SPLIT. + + Settings +╭─────┬───────────────╮ +│SPLIT│x, z (SEPARATE)│ +╰─────┴───────────────╯ + + +SPLIT FILE OFF. + +SHOW SPLIT. + + Settings +╭─────┬────╮ +│SPLIT│none│ +╰─────┴────╯ +]) +AT_CLEANUP \ No newline at end of file