X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fsort.c;h=8dad3566ccdcca1ad8e9fabf63ace81b42d7019f;hb=40271dcbfdecb01dfe808684741215eb2ddeb508;hp=a16055f971725953ade58241b1f8f8ea67e30bb9;hpb=9ae6b7c129dd6dd6bf97d66050fbed3ada7b2025;p=pspp-builds.git diff --git a/src/sort.c b/src/sort.c index a16055f9..8dad3566 100644 --- a/src/sort.c +++ b/src/sort.c @@ -26,7 +26,7 @@ #include #include "algorithm.h" #include "alloc.h" -#include "bool.h" +#include #include "case.h" #include "casefile.h" #include "command.h" @@ -36,34 +36,16 @@ #include "lexer.h" #include "misc.h" #include "settings.h" +#include "sort-prs.h" #include "str.h" #include "var.h" #include "vfm.h" #include "vfmP.h" -#include "debug-print.h" +#include "gettext.h" +#define _(msgid) gettext (msgid) -/* Sort direction. */ -enum sort_direction - { - SRT_ASCEND, /* A, B, C, ..., X, Y, Z. */ - SRT_DESCEND /* Z, Y, X, ..., C, B, A. */ - }; - -/* A sort criterion. */ -struct sort_criterion - { - int fv; /* Variable data index. */ - int width; /* 0=numeric, otherwise string widthe. */ - enum sort_direction dir; /* Sort direction. */ - }; - -/* A set of sort criteria. */ -struct sort_criteria - { - struct sort_criterion *crits; - size_t crit_cnt; - }; +#include "debug-print.h" /* These should only be changed for testing purposes. */ static int min_buffers = 64; @@ -86,11 +68,11 @@ cmd_sort_cases (void) lex_match (T_BY); - criteria = sort_parse_criteria (default_dict, NULL, NULL, NULL); + criteria = sort_parse_criteria (default_dict, NULL, NULL, NULL, NULL); if (criteria == NULL) return CMD_FAILURE; - if (test_mode && lex_match ('/')) + if (get_testing_mode () && lex_match ('/')) { if (!lex_force_match_id ("BUFFERS") || !lex_match ('=') || !lex_force_int ()) @@ -169,101 +151,6 @@ sort_active_file_to_casefile (const struct sort_criteria *criteria) return sort_execute (casefile_get_reader (src), criteria); } -/* Parses a list of sort keys and returns a struct sort_criteria - based on it. Returns a null pointer on error. - If SAW_DIRECTION is nonnull, sets *SAW_DIRECTION to true if at - least one parenthesized sort direction was specified, false - otherwise. */ -struct sort_criteria * -sort_parse_criteria (const struct dictionary *dict, - struct variable ***vars, int *var_cnt, - bool *saw_direction) -{ - struct sort_criteria *criteria; - struct variable **local_vars = NULL; - size_t local_var_cnt; - - assert ((vars == NULL) == (var_cnt == NULL)); - if (vars == NULL) - { - vars = &local_vars; - var_cnt = &local_var_cnt; - } - - criteria = xmalloc (sizeof *criteria); - criteria->crits = NULL; - criteria->crit_cnt = 0; - - *vars = NULL; - *var_cnt = 0; - if (saw_direction != NULL) - *saw_direction = false; - - do - { - int prev_var_cnt = *var_cnt; - enum sort_direction direction; - - /* Variables. */ - if (!parse_variables (dict, vars, var_cnt, - PV_NO_DUPLICATE | PV_APPEND | PV_NO_SCRATCH)) - goto error; - - /* Sort direction. */ - if (lex_match ('(')) - { - if (lex_match_id ("D") || lex_match_id ("DOWN")) - direction = SRT_DESCEND; - else if (lex_match_id ("A") || lex_match_id ("UP")) - direction = SRT_ASCEND; - else - { - msg (SE, _("`A' or `D' expected inside parentheses.")); - goto error; - } - if (!lex_match (')')) - { - msg (SE, _("`)' expected.")); - goto error; - } - if (saw_direction != NULL) - *saw_direction = true; - } - else - direction = SRT_ASCEND; - - criteria->crits = xrealloc (criteria->crits, - sizeof *criteria->crits * *var_cnt); - criteria->crit_cnt = *var_cnt; - for (; prev_var_cnt < criteria->crit_cnt; prev_var_cnt++) - { - struct sort_criterion *c = &criteria->crits[prev_var_cnt]; - c->fv = (*vars)[prev_var_cnt]->fv; - c->width = (*vars)[prev_var_cnt]->width; - c->dir = direction; - } - } - while (token != '.' && token != '/'); - - free (local_vars); - return criteria; - - error: - free (local_vars); - sort_destroy_criteria (criteria); - return NULL; -} - -/* Destroys a SORT CASES program. */ -void -sort_destroy_criteria (struct sort_criteria *criteria) -{ - if (criteria != NULL) - { - free (criteria->crits); - free (criteria); - } -} /* Reads all the cases from READER, which is destroyed. Sorts the cases according to CRITERIA. Returns the sorted cases in @@ -308,7 +195,7 @@ do_internal_sort (struct casereader *reader, dst = casefile_create (casefile_get_value_cnt (src)); if (case_cnt != 0) { - struct indexed_case *cases = malloc (sizeof *cases * case_cnt); + struct indexed_case *cases = nmalloc (sizeof *cases, case_cnt); if (cases != NULL) { unsigned long i; @@ -391,7 +278,7 @@ do_external_sort (struct casereader *reader, xsrt->value_cnt = casefile_get_value_cnt (casereader_get_casefile (reader)); xsrt->run_cap = 512; xsrt->run_cnt = 0; - xsrt->runs = xmalloc (sizeof *xsrt->runs * xsrt->run_cap); + xsrt->runs = xnmalloc (xsrt->run_cap, sizeof *xsrt->runs); if (write_runs (xsrt, reader)) { struct casefile *output = merge (xsrt); @@ -556,16 +443,17 @@ allocate_cases (struct initial_run_state *irs) approx_case_cost = (sizeof *irs->records + irs->xsrt->value_cnt * sizeof (union value) + 4 * sizeof (void *)); - max_cases = get_max_workspace() / approx_case_cost; + max_cases = get_workspace() / approx_case_cost; if (max_cases > max_buffers) max_cases = max_buffers; - irs->records = malloc (sizeof *irs->records * max_cases); - for (i = 0; i < max_cases; i++) - if (!case_try_create (&irs->records[i].record, irs->xsrt->value_cnt)) - { - max_cases = i; - break; - } + irs->records = nmalloc (sizeof *irs->records, max_cases); + if (irs->records != NULL) + for (i = 0; i < max_cases; i++) + if (!case_try_create (&irs->records[i].record, irs->xsrt->value_cnt)) + { + max_cases = i; + break; + } irs->record_cap = max_cases; /* Fail if we didn't allocate an acceptable number of cases. */ @@ -574,7 +462,7 @@ allocate_cases (struct initial_run_state *irs) msg (SE, _("Out of memory. Could not allocate room for minimum of %d " "cases of %d bytes each. (PSPP workspace is currently " "restricted to a maximum of %d KB.)"), - min_buffers, approx_case_cost, get_max_workspace() / 1024); + min_buffers, approx_case_cost, get_workspace() / 1024); return 0; } return 1; @@ -661,8 +549,8 @@ end_run (struct initial_run_state *irs) if (xsrt->run_cnt >= xsrt->run_cap) { xsrt->run_cap *= 2; - xsrt->runs = xrealloc (xsrt->runs, - sizeof *xsrt->runs * xsrt->run_cap); + xsrt->runs = xnrealloc (xsrt->runs, + xsrt->run_cap, sizeof *xsrt->runs); } xsrt->runs[xsrt->run_cnt++] = irs->casefile; irs->casefile = NULL; @@ -787,7 +675,7 @@ merge_once (struct external_sort *xsrt, int i; /* Open input files. */ - runs = xmalloc (sizeof *runs * run_cnt); + runs = xnmalloc (run_cnt, sizeof *runs); for (i = 0; i < run_cnt; i++) { struct run *r = &runs[i];