aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2018-05-29 10:36:59 +0300
committerSergey Poznyakoff <gray@gnu.org>2018-05-29 10:36:59 +0300
commita2528b04a987bdbff4763edd2258622ad3141024 (patch)
tree18fafe3ac7c1208dd7e12574fc8cb0093301cd5a /tests
parent120727f7c5b36bddaa3ef232dd9b105148ac7433 (diff)
downloadgdbm-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.c125
1 files changed, 80 insertions, 45 deletions
diff --git a/tests/num2word.c b/tests/num2word.c
index 1ac54a4..2a1878a 100644
--- a/tests/num2word.c
+++ b/tests/num2word.c
@@ -209,24 +209,46 @@ xstrtoul (char *arg, char **endp)
209 return num; 209 return num;
210} 210}
211 211
212struct numrange 212struct numrange /* Range of numbers */
213{ 213{
214 numeral_t start; 214 numeral_t start; /* Starting number */
215 numeral_t count; 215 numeral_t count; /* Count of numbers in the range */
216}; 216};
217 217
218struct numrange *range; 218struct numrange *range; /* Array of ranges */
219size_t range_count; 219size_t range_max; /* Number of elements in RANGE */
220size_t range_max; 220size_t range_total; /* Total count of numbers (sum of range[i].count) */
221size_t range_total;
222 221
223#define RANGE_INITIAL_ALLOC 16 222#define RANGE_INITIAL_ALLOC 16 /* Initial allocation for the range (entries) */
224 223
224/* List of available entries.
225
226 Unallocated entries in RANGE form a singly-linked list. Each unallocated
227 entry has COUNT set to 0, and START set to the index of the next
228 unallocated entry, or AVAIL_NIL, if that's the last free entry.
229 */
230#define AVAIL_NIL ((size_t)-1) /* Marks end of the list */
231size_t range_avail = AVAIL_NIL; /* Index of the first available entry */
232
233/* Return entry I to the list of available ones */
234static void
235range_remove (size_t i)
236{
237 range[i].count = 0;
238 range[i].start = range_avail;
239 range_avail = i;
240}
241
242/* Add interval [start, start + count) */
225static void 243static void
226range_add (numeral_t start, numeral_t count) 244range_add (numeral_t start, numeral_t count)
227{ 245{
228 if (range_count == range_max) 246 size_t i;
247
248 if (range_avail == AVAIL_NIL)
229 { 249 {
250 size_t n = range_max;
251
230 if (range_max == 0) 252 if (range_max == 0)
231 range_max = RANGE_INITIAL_ALLOC; 253 range_max = RANGE_INITIAL_ALLOC;
232 else 254 else
@@ -234,39 +256,41 @@ range_add (numeral_t start, numeral_t count)
234 assert ((size_t)-1 / 3 * 2 / sizeof (range[0]) > range_max); 256 assert ((size_t)-1 / 3 * 2 / sizeof (range[0]) > range_max);
235 range_max += (range_max + 1) / 2; 257 range_max += (range_max + 1) / 2;
236 } 258 }
259
237 range = realloc (range, range_max * sizeof (range[0])); 260 range = realloc (range, range_max * sizeof (range[0]));
238 if (!range) 261 if (!range)
239 abort (); 262 abort ();
263
264 for (i = range_max; i > n; i--)
265 range_remove (i - 1);
240 } 266 }
241 range[range_count].start = start; 267
242 range[range_count].count = count; 268 i = range_avail;
243 ++range_count; 269 range_avail = range[i].start;
270
271 range[i].start = start;
272 range[i].count = count;
244 range_total += count; 273 range_total += count;
245} 274}
246 275
276/* Treating RANGE as a contiguous array of numbers, return the number in
277 position IDX and remove it from the array. */
247numeral_t 278numeral_t
248range_get (size_t idx) 279range_get (size_t idx)
249{ 280{
250 numeral_t n; 281 numeral_t n;
251 size_t i; 282 size_t i;
252 283
253 assert (range_count > 0); 284 for (i = 0; i < range_max; i++)
254
255 for (i = 0; i < range_count; i++)
256 { 285 {
257 if (idx < range[i].count) 286 if (idx < range[i].count)
258 break; 287 break;
259 idx -= range[i].count; 288 idx -= range[i].count;
260 } 289 }
290 assert (i < range_max);
261 n = range[i].start + idx; 291 n = range[i].start + idx;
262 if (range[i].count == 1) 292 if (range[i].count == 1)
263 { 293 range_remove (i);
264 /* Remove range */
265 if (i + 1 < range_count)
266 memmove (range + i, range + i + 1,
267 (range_count - i - 1) * sizeof (range[0]));
268 range_count--;
269 }
270 else if (idx == 0) 294 else if (idx == 0)
271 { 295 {
272 range[i].start++; 296 range[i].start++;
@@ -286,25 +310,33 @@ range_get (size_t idx)
286 return n; 310 return n;
287} 311}
288 312
313void
314usage (FILE *fp)
315{
316 fprintf (fp, "usage: %s [-revert] [-random] RANGE [RANGE...]\n", progname);
317 fprintf (fp, "Lists english numerals in given ranges\n\n");
318 fprintf (fp, "Each RANGE is one of:\n\n");
319 fprintf (fp, " X:N N numerals starting from X; interval [X,X+N]\n");
320 fprintf (fp, " X-Y numerals from X to Y; interval [X,Y]\n\n");
321 fprintf (fp, "Options are:\n\n");
322 fprintf (fp, " -random produce list in random order\n");
323 fprintf (fp, " -revert revert output columns (numeral first)\n");
324 fprintf (fp, " -help display this help summary\n");
325 fprintf (fp, "\n");
326}
327
289int 328int
290main (int argc, char **argv) 329main (int argc, char **argv)
291{ 330{
292 progname = argv[0]; 331 progname = *argv++;
332 --argc;
293 333
294 while (--argc) 334 for (; argc; argc--, argv++)
295 { 335 {
296 char *arg = *++argv; 336 char *arg = *argv;
297 if (strcmp (arg, "-h") == 0 || strcmp (arg, "-help") == 0) 337 if (strcmp (arg, "-h") == 0 || strcmp (arg, "-help") == 0)
298 { 338 {
299 printf ("usage: %s [-revert] [-random] RANGE [RANGE...]\n", progname); 339 usage (stdout);
300 printf ("Lists english numerals in given ranges\n\n");
301 printf ("Each RANGE is one of:\n\n");
302 printf (" X:N N numerals starting from X; interval [X,X+N]\n");
303 printf (" X-Y numerals from X to Y; interval [X,Y]\n\n");
304 printf ("Options are:\n\n");
305 printf (" -revert revert output columns (numeral first)\n");
306 printf (" -random produce list in random order\n");
307 printf ("\n");
308 exit (0); 340 exit (0);
309 } 341 }
310 else if (strcmp (arg, "-revert") == 0) 342 else if (strcmp (arg, "-revert") == 0)
@@ -321,22 +353,18 @@ main (int argc, char **argv)
321 return 1; 353 return 1;
322 } 354 }
323 else 355 else
324 { 356 break;
325 argc++;
326 argv--;
327 break;
328 }
329 } 357 }
330 358
331 while (--argc) 359 for (; argc; argc--, argv++)
332 { 360 {
333 char *arg = *++argv; 361 char *arg = *argv;
334 numeral_t num, num2; 362 numeral_t num, num2;
335 char *p; 363 char *p;
336 364
337 num = xstrtoul (arg, &p); 365 num = xstrtoul (arg, &p);
338 if (*p == 0) 366 if (*p == 0)
339 print_number (num); 367 range_add (num, 1);
340 else if (*p == ':') 368 else if (*p == ':')
341 { 369 {
342 *p++ = 0; 370 *p++ = 0;
@@ -367,6 +395,12 @@ main (int argc, char **argv)
367 } 395 }
368 } 396 }
369 397
398 if (range_total == 0)
399 {
400 usage (stderr);
401 exit (1);
402 }
403
370 if (random_option) 404 if (random_option)
371 { 405 {
372 srandom (time (NULL)); 406 srandom (time (NULL));
@@ -379,8 +413,9 @@ main (int argc, char **argv)
379 else 413 else
380 { 414 {
381 size_t i; 415 size_t i;
382 for (i = 0; i < range_count; i++) 416 for (i = 0; i < range_max; i++)
383 print_range (range[i].start, range[i].start + range[i].count - 1); 417 if (range[i].count)
418 print_range (range[i].start, range[i].start + range[i].count - 1);
384 } 419 }
385 exit (0); 420 exit (0);
386} 421}

Return to:

Send suggestions and report system problems to the System administrator.