aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2018-05-28 23:08:43 +0300
committerSergey Poznyakoff <gray@gnu.org>2018-05-28 23:08:43 +0300
commit120727f7c5b36bddaa3ef232dd9b105148ac7433 (patch)
tree737ccf80008c823f37b760f6a26bbb96e1ff0528 /tests
parent4011b4ce9a4c4fa505843381d43a1157cf0c782e (diff)
downloadgdbm-120727f7c5b36bddaa3ef232dd9b105148ac7433.tar.gz
gdbm-120727f7c5b36bddaa3ef232dd9b105148ac7433.tar.bz2
Improve num2word
* tests/num2word.c: New options: -revert and -random
Diffstat (limited to 'tests')
-rw-r--r--tests/num2word.c171
1 files changed, 151 insertions, 20 deletions
diff --git a/tests/num2word.c b/tests/num2word.c
index c9d5bc4..1ac54a4 100644
--- a/tests/num2word.c
+++ b/tests/num2word.c
@@ -20,6 +20,8 @@
20#include <string.h> 20#include <string.h>
21#include <unistd.h> 21#include <unistd.h>
22#include <errno.h> 22#include <errno.h>
23#include <time.h>
24#include <assert.h>
23 25
24const char *progname; 26const char *progname;
25 27
@@ -68,10 +70,14 @@ const char *short_scale[] = {
68}; 70};
69size_t short_scale_max = sizeof (short_scale) / sizeof (short_scale[0]); 71size_t short_scale_max = sizeof (short_scale) / sizeof (short_scale[0]);
70 72
73typedef unsigned long numeral_t;
74
71char buffer[1024]; 75char buffer[1024];
72size_t bufsize = sizeof(buffer); 76size_t bufsize = sizeof(buffer);
73size_t bufoff; 77size_t bufoff;
74int delim = 0; 78int delim = 0;
79int revert_option = 0;
80int random_option = 0;
75 81
76void 82void
77copy (const char *str, int dch) 83copy (const char *str, int dch)
@@ -87,7 +93,7 @@ copy (const char *str, int dch)
87} 93}
88 94
89void 95void
90format_100 (unsigned long num) 96format_100 (numeral_t num)
91{ 97{
92 if (num == 0) 98 if (num == 0)
93 ; 99 ;
@@ -97,7 +103,7 @@ format_100 (unsigned long num)
97 copy (nstr[1][num-10], delim); 103 copy (nstr[1][num-10], delim);
98 else 104 else
99 { 105 {
100 unsigned long tens = num / 10; 106 numeral_t tens = num / 10;
101 num %= 10; 107 num %= 10;
102 if (num) 108 if (num)
103 { 109 {
@@ -111,7 +117,7 @@ format_100 (unsigned long num)
111} 117}
112 118
113void 119void
114format_1000 (unsigned long num, int more) 120format_1000 (numeral_t num, int more)
115{ 121{
116 size_t n = num % 100; 122 size_t n = num % 100;
117 num /= 100; 123 num /= 100;
@@ -128,7 +134,7 @@ format_1000 (unsigned long num, int more)
128 134
129 135
130void 136void
131format_number (unsigned long num) 137format_number (numeral_t num)
132{ 138{
133 int s = 0; 139 int s = 0;
134 size_t off; 140 size_t off;
@@ -140,7 +146,7 @@ format_number (unsigned long num)
140 146
141 do 147 do
142 { 148 {
143 unsigned long n = num % 1000; 149 numeral_t n = num % 1000;
144 150
145 num /= 1000; 151 num /= 1000;
146 152
@@ -161,23 +167,26 @@ format_number (unsigned long num)
161 167
162 168
163void 169void
164print_number (unsigned long num) 170print_number (numeral_t num)
165{ 171{
166 format_number (num); 172 format_number (num);
167 printf ("%lu\t%s\n", num, buffer + bufoff); 173 if (revert_option)
174 printf ("%s\t%lu\n", buffer + bufoff, num);
175 else
176 printf ("%lu\t%s\n", num, buffer + bufoff);
168} 177}
169 178
170void 179void
171print_range (unsigned long num, unsigned long to) 180print_range (numeral_t num, numeral_t to)
172{ 181{
173 for (; num <= to; num++) 182 for (; num <= to; num++)
174 print_number (num); 183 print_number (num);
175} 184}
176 185
177unsigned long 186numeral_t
178xstrtoul (char *arg, char **endp) 187xstrtoul (char *arg, char **endp)
179{ 188{
180 unsigned long num; 189 numeral_t num;
181 char *p; 190 char *p;
182 191
183 errno = 0; 192 errno = 0;
@@ -199,23 +208,130 @@ xstrtoul (char *arg, char **endp)
199 208
200 return num; 209 return num;
201} 210}
211
212struct numrange
213{
214 numeral_t start;
215 numeral_t count;
216};
217
218struct numrange *range;
219size_t range_count;
220size_t range_max;
221size_t range_total;
222
223#define RANGE_INITIAL_ALLOC 16
224
225static void
226range_add (numeral_t start, numeral_t count)
227{
228 if (range_count == range_max)
229 {
230 if (range_max == 0)
231 range_max = RANGE_INITIAL_ALLOC;
232 else
233 {
234 assert ((size_t)-1 / 3 * 2 / sizeof (range[0]) > range_max);
235 range_max += (range_max + 1) / 2;
236 }
237 range = realloc (range, range_max * sizeof (range[0]));
238 if (!range)
239 abort ();
240 }
241 range[range_count].start = start;
242 range[range_count].count = count;
243 ++range_count;
244 range_total += count;
245}
246
247numeral_t
248range_get (size_t idx)
249{
250 numeral_t n;
251 size_t i;
252
253 assert (range_count > 0);
254
255 for (i = 0; i < range_count; i++)
256 {
257 if (idx < range[i].count)
258 break;
259 idx -= range[i].count;
260 }
261 n = range[i].start + idx;
262 if (range[i].count == 1)
263 {
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)
271 {
272 range[i].start++;
273 range[i].count--;
274 }
275 else
276 {
277 /* Split range */
278 if (range[i].count > idx - 1)
279 {
280 range_total -= range[i].count - idx - 1;
281 range_add (range[i].start + idx + 1, range[i].count - idx - 1);
282 }
283 range[i].count = idx;
284 }
285 range_total--;
286 return n;
287}
202 288
203int 289int
204main (int argc, char **argv) 290main (int argc, char **argv)
205{ 291{
206 progname = argv[0]; 292 progname = argv[0];
207 293
208 if (argc == 1 || strcmp (argv[1], "-h") == 0) 294 while (--argc)
209 { 295 {
210 printf ("usage: %s NUM [NUM...]\n", progname); 296 char *arg = *++argv;
211 printf ("where NUM is a decimal number, NUM:COUNT or NUM-NUM\n"); 297 if (strcmp (arg, "-h") == 0 || strcmp (arg, "-help") == 0)
212 exit (0); 298 {
299 printf ("usage: %s [-revert] [-random] RANGE [RANGE...]\n", progname);
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);
309 }
310 else if (strcmp (arg, "-revert") == 0)
311 {
312 revert_option = 1;
313 }
314 else if (strcmp (arg, "-random") == 0)
315 {
316 random_option = 1;
317 }
318 else if (arg[0] == '-')
319