diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2018-05-29 10:36:59 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2018-05-29 10:36:59 +0300 |
commit | a2528b04a987bdbff4763edd2258622ad3141024 (patch) | |
tree | 18fafe3ac7c1208dd7e12574fc8cb0093301cd5a /tests | |
parent | 120727f7c5b36bddaa3ef232dd9b105148ac7433 (diff) | |
download | gdbm-a2528b04a987bdbff4763edd2258622ad3141024.tar.gz gdbm-a2528b04a987bdbff4763edd2258622ad3141024.tar.bz2 |
Minor changes
* src/gdbmtool.c: Reduce memory consuption in -random mode. Some
minor bugfixes as well.
Diffstat (limited to 'tests')
-rw-r--r-- | tests/num2word.c | 119 |
1 files changed, 77 insertions, 42 deletions
diff --git a/tests/num2word.c b/tests/num2word.c index 1ac54a4..2a1878a 100644 --- a/tests/num2word.c +++ b/tests/num2word.c @@ -211,15 +211,33 @@ xstrtoul (char *arg, char **endp) -struct numrange +struct numrange /* Range of numbers */ { - numeral_t start; - numeral_t count; + numeral_t start; /* Starting number */ + numeral_t count; /* Count of numbers in the range */ }; -struct numrange *range; -size_t range_count; -size_t range_max; -size_t range_total; +struct numrange *range; /* Array of ranges */ +size_t range_max; /* Number of elements in RANGE */ +size_t range_total; /* Total count of numbers (sum of range[i].count) */ -#define RANGE_INITIAL_ALLOC 16 +#define RANGE_INITIAL_ALLOC 16 /* Initial allocation for the range (entries) */ +/* List of available entries. + + Unallocated entries in RANGE form a singly-linked list. Each unallocated + entry has COUNT set to 0, and START set to the index of the next + unallocated entry, or AVAIL_NIL, if that's the last free entry. + */ +#define AVAIL_NIL ((size_t)-1) /* Marks end of the list */ +size_t range_avail = AVAIL_NIL; /* Index of the first available entry */ + +/* Return entry I to the list of available ones */ +static void +range_remove (size_t i) +{ + range[i].count = 0; + range[i].start = range_avail; + range_avail = i; +} + +/* Add interval [start, start + count) */ static void @@ -227,4 +245,8 @@ range_add (numeral_t start, numeral_t count) { - if (range_count == range_max) + size_t i; + + if (range_avail == AVAIL_NIL) { + size_t n = range_max; + if (range_max == 0) @@ -236,2 +258,3 @@ range_add (numeral_t start, numeral_t count) } + range = realloc (range, range_max * sizeof (range[0])); @@ -239,6 +262,12 @@ range_add (numeral_t start, numeral_t count) abort (); + + for (i = range_max; i > n; i--) + range_remove (i - 1); } - range[range_count].start = start; - range[range_count].count = count; - ++range_count; + + i = range_avail; + range_avail = range[i].start; + + range[i].start = start; + range[i].count = count; range_total += count; @@ -246,2 +275,4 @@ range_add (numeral_t start, numeral_t count) +/* Treating RANGE as a contiguous array of numbers, return the number in + position IDX and remove it from the array. */ numeral_t @@ -252,5 +283,3 @@ range_get (size_t idx) - assert (range_count > 0); - - for (i = 0; i < range_count; i++) + for (i = 0; i < range_max; i++) { @@ -260,11 +289,6 @@ range_get (size_t idx) } + assert (i < range_max); n = range[i].start + idx; if (range[i].count == 1) - { - /* Remove range */ - if (i + 1 < range_count) - memmove (range + i, range + i + 1, - (range_count - i - 1) * sizeof (range[0])); - range_count--; - } + range_remove (i); else if (idx == 0) @@ -288,2 +312,17 @@ range_get (size_t idx) +void +usage (FILE *fp) +{ + fprintf (fp, "usage: %s [-revert] [-random] RANGE [RANGE...]\n", progname); + fprintf (fp, "Lists english numerals in given ranges\n\n"); + fprintf (fp, "Each RANGE is one of:\n\n"); + fprintf (fp, " X:N N numerals starting from X; interval [X,X+N]\n"); + fprintf (fp, " X-Y numerals from X to Y; interval [X,Y]\n\n"); + fprintf (fp, "Options are:\n\n"); + fprintf (fp, " -random produce list in random order\n"); + fprintf (fp, " -revert revert output columns (numeral first)\n"); + fprintf (fp, " -help display this help summary\n"); + fprintf (fp, "\n"); +} + int @@ -291,18 +330,11 @@ main (int argc, char **argv) { - progname = argv[0]; + progname = *argv++; + --argc; - while (--argc) + for (; argc; argc--, argv++) { - char *arg = *++argv; + char *arg = *argv; if (strcmp (arg, "-h") == 0 || strcmp (arg, "-help") == 0) { - printf ("usage: %s [-revert] [-random] RANGE [RANGE...]\n", progname); - printf ("Lists english numerals in given ranges\n\n"); - printf ("Each RANGE is one of:\n\n"); - printf (" X:N N numerals starting from X; interval [X,X+N]\n"); - printf (" X-Y numerals from X to Y; interval [X,Y]\n\n"); - printf ("Options are:\n\n"); - printf (" -revert revert output columns (numeral first)\n"); - printf (" -random produce list in random order\n"); - printf ("\n"); + usage (stdout); exit (0); @@ -323,12 +355,8 @@ main (int argc, char **argv) else - { - argc++; - argv--; break; } - } - while (--argc) + for (; argc; argc--, argv++) { - char *arg = *++argv; + char *arg = *argv; numeral_t num, num2; @@ -338,3 +366,3 @@ main (int argc, char **argv) if (*p == 0) - print_number (num); + range_add (num, 1); else if (*p == ':') @@ -369,2 +397,8 @@ main (int argc, char **argv) + if (range_total == 0) + { + usage (stderr); + exit (1); + } + if (random_option) @@ -381,3 +415,4 @@ main (int argc, char **argv) size_t i; - for (i = 0; i < range_count; i++) + for (i = 0; i < range_max; i++) + if (range[i].count) print_range (range[i].start, range[i].start + range[i].count - 1); |