aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/gdbmtool.c4
-rw-r--r--tests/num2word.c125
2 files changed, 82 insertions, 47 deletions
diff --git a/src/gdbmtool.c b/src/gdbmtool.c
index 6096c07..feca51e 100644
--- a/src/gdbmtool.c
+++ b/src/gdbmtool.c
@@ -299,12 +299,12 @@ _gdbm_print_bucket_cache (FILE *fp, GDBM_FILE dbf)
299 if (dbf->bucket_cache != NULL) 299 if (dbf->bucket_cache != NULL)
300 { 300 {
301 fprintf (fp, 301 fprintf (fp,
302 _("Bucket Cache (size %zu):\n Index: Address Changed Data_Hash \n"), 302 _("Bucket Cache (size %zu):\n Index: Address Changed Data_Hash \n"),
303 dbf->cache_size); 303 dbf->cache_size);
304 for (index = 0; index < dbf->cache_size; index++) 304 for (index = 0; index < dbf->cache_size; index++)
305 { 305 {
306 changed = dbf->bucket_cache[index].ca_changed; 306 changed = dbf->bucket_cache[index].ca_changed;
307 fprintf (fp, " %5d: %7lu %7s %x\n", 307 fprintf (fp, " %5d: %15lu %7s %x\n",
308 index, 308 index,
309 (unsigned long) dbf->bucket_cache[index].ca_adr, 309 (unsigned long) dbf->bucket_cache[index].ca_adr,
310 (changed ? _("True") : _("False")), 310 (changed ? _("True") : _("False")),
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;