151 int nrn_vsscanf(
const char* str,
const char** rs,
const char*
format, va_list args)
158 const char point =
'.';
160 const char point = localeconv()->decimal_point[0];
164 for (s = str, f =
format; *f; ++f) {
173 for (; isdigit((
int) (
unsigned int) *f); ++f)
174 width *= 10, width += *f -
'0';
176 if (*f ==
'h' || *f ==
'l' || *f ==
'L')
179 if (*f !=
'[' && *f !=
'c' && *f !=
'n')
180 while (isspace((
int) (
unsigned int) *s))
183 #define COPY *b++ = *s++, --width
184 #define MATCH(cond) \
185 if (width && (cond)) \
187 #define MATCH_ACTION(cond, action) \
188 if (width && (cond)) { \
192 #define MATCHES_ACTION(cond, action) \
193 while (width && (cond)) { \
197 #define FAIL (cnv) ? cnv : EOF
206 static const char types[] =
"diouxXp";
207 static const int bases[] = {10, 0, 8, 10, 16, 16, 16};
208 static const char digitset[] =
"0123456789abcdefABCDEF";
209 static const int setsizes[] = {
210 10, 0, 0, 0, 0, 0, 0, 0, 8, 0, 10, 0, 0, 0, 0, 0, 22};
211 int base = bases[strchr(types, *f) - types];
216 if (width <= 0 || width > 512)
218 MATCH(*s ==
'+' || *s ==
'-')
220 MATCH_ACTION((*s ==
'x' || *s ==
'X') && (base == 0 || base == 16),
221 base = 16)
else base = 8;)
222 setsize = setsizes[base];
230 if (*f ==
'd' || *f ==
'i') {
233 *va_arg(args,
short*) = (short)
data;
234 else if (size ==
'l')
235 *va_arg(args,
long*) =
data;
237 *va_arg(args,
int*) = (int)
data;
241 *va_arg(args,
void**) = (
void*)
data;
242 else if (size ==
'h')
243 *va_arg(args,
unsigned short*) = (
unsigned short)
data;
244 else if (size ==
'l')
245 *va_arg(args,
unsigned long*) =
data;
247 *va_arg(args,
unsigned int*) = (
unsigned int)
data;
262 if (width <= 0 || width > 512)
264 MATCH(*s ==
'+' || *s ==
'-')
269 MATCH(*s ==
'+' || *s ==
'-') digit = 0;
279 *va_arg(args,
double*) =
data;
280 else if (size ==
'L')
281 *va_arg(args,
long double*) = (
long double)
data;
283 *va_arg(args,
float*) = (float)
data;
290 char*
arg = va_arg(args,
char*);
293 while (width-- && *s && !isspace((
int) (
unsigned int) *s))
302 char*
arg = va_arg(args,
char*);
310 end = strchr((*f ==
']') ? f + 1 : f,
']');
316 while (width-- && *s) {
317 if (!setcomp && !memchr(f, *s, setsize))
319 if (setcomp && memchr(f, *s, setsize))
331 char*
arg = va_arg(args,
char*);
349 *va_arg(args,
short*) = (short) (s - str);
350 else if (size ==
'l')
351 *va_arg(args,
long*) = (long) (s - str);
353 *va_arg(args,
int*) = (int) (s - str);
369 }
else if (isspace((
int) (
unsigned int) *f)) {
370 while (isspace((
int) (
unsigned int) f[1]))
372 while (isspace((
int) (
unsigned int) *s))
389 #undef _ISOC9X_SOURCE
394 int test_sscanf(
const char *str,
const char *
format, ...)
404 int main(
int ac,
char **av)
412 long double ld1, ld2;
414 char b1[128], b2[128];
415 char c1[128], c2[128];
416 char s1[128], s2[128];
420 unsigned short su1, su2;
422 unsigned long lu1, lu2;
426 if (ac == 2 && !strcmp(av[1],
"help"))
428 printf(
"usage: %s [show]\n", *av);
432 printf(
"Testing: %s\n",
"vsscanf");
436 sprintf(str,
" abc -12 37 101 3.4e-1 12.34 102.23 xyz %p def ghi jkl %% ",
437 p1 = (
void *)0xdeadbeef
440 if (ac >= 2 && !strcmp(av[1],
"show"))
444 " abc %hd %d %ld %e %le %Le xyz %p %[^abc ] %3c %s%hn %n%% %ln",
445 &si1, &i1, &li1, &f1, &d1, &ld1, &p1, b1, c1, s1, &sn1, &in1, &ln1
448 rc2 = test_sscanf(str,
449 " abc %hd %d %ld %e %le %Le xyz %p %[^abc ] %3c %s%hn %n%% %ln",
450 &si2, &i2, &li2, &f2, &d2, &ld2, &p2, b2, c2, s2, &sn2, &in2, &ln2
454 ++errors,
printf(
"Test1: failed (returned %d, not %d)\n", rc2, rc1);
456 ++errors,
printf(
"Test2: failed (%%hd scanned %hd, not %hd)\n", si2, si1);
458 ++errors,
printf(
"Test3: failed (%%d scanned %d, not %d)\n", i2, i1);
460 ++errors,
printf(
"Test4: failed (%%ld scanned %ld, not %ld)\n", li2, li1);
461 if (
fabs(f2 - 3.4e-1) / 3.4e-1 >= 4 * FLT_EPSILON)
462 ++errors,
printf(
"Test5: failed (%%e scanned %e, not %e)\n", f2, f1);
463 if (
fabs(d2 - 12.34) / 12.34 >= 4 * DBL_EPSILON)
464 ++errors,
printf(
"Test6: failed (%%le scanned %le, not %le)\n", d2, d1);
465 if (
fabs(ld2 - 102.23) / 102.23 >= 4 * LDBL_EPSILON)
466 ++errors,
printf(
"Test7: failed (%%Le scanned %Le, not %Le)\n", ld2, ld1);
468 ++errors,
printf(
"Test8: failed (%%p scanned %p, not %p)\n", p2, p1);
470 ++errors,
printf(
"Test9: failed (%%[^abc ] scanned \"%s\", not \"%s\")\n", b2, b1);
471 if (memcmp(c1, c2, 3))
472 ++errors,
printf(
"Test10: failed (%%3c scanned \"%3.3s\", not \"%3.3s\")\n", c2, c1);
474 ++errors,
printf(
"Test11: failed (%%s scanned \"%s\", not \"%s\")\n", s2, s1);
476 ++errors,
printf(
"Test12: failed (%%hn scanned %hd, not %hd)\n", sn2, sn1);
478 ++errors,
printf(
"Test13: failed (%%n scanned %d, not %d)\n", in2, in1);
480 ++errors,
printf(
"Test14: failed (%%ln scanned %ld, not %ld)\n", ln2, ln1);
484 #define TEST_NUM(i, var, tst, str, format) \
485 rc1 = sscanf(str, format, &s##var##1, &var##1, &l##var##1); \
486 rc2 = test_sscanf(str, format, &s##var##2, &var##2, &l##var##2); \
488 ++errors, printf("Test%d: failed (returned %d, not %d)\n", (i), rc2, rc1); \
489 if (s##var##1 != s##var##2) \
490 ++errors, printf("Test%d: failed (%%h%c scanned %hd, not %hd)\n", \
495 if (var##1 != var##2) \
496 ++errors, printf("Test%d: failed (%%%c scanned %d, not %d)\n", (i), tst, var##2, var##1); \
497 if (l##var##1 != l##var##2) \
499 printf("Test%d: failed (%%l%c scanned %ld, not %ld)\n", (i), tst, l##var##2, l##var##1)
501 #define TEST_STR(i, len, str, format) \
502 rc1 = sscanf(str, format, b1, c1, s1); \
503 rc2 = test_sscanf(str, format, b2, c2, s2); \
505 ++errors, printf("Test%d: failed (returned %d, not %d)\n", (i), rc2, rc1); \
506 if (strcmp(b1, b2)) \
508 printf("Test%d: failed (%%%d[ scanned \"%s\", not \"%s\")\n", (i), (len), b2, b1); \
509 if (memcmp(c1, c2, len)) \
510 ++errors, printf("Test%d: failed (%%%dc scanned \"%*.*s\", not \"%*.*s\")\n", \
519 if (strcmp(s1, s2)) \
520 ++errors, printf("Test%d: failed (%%%ds scanned \"%s\", not \"%s\")\n", (i), (len), s2, s1)
522 TEST_NUM(15,
i,
'i',
"37 21 53",
"%hi %i %li");
523 TEST_NUM(16,
i,
'i',
"037 021 053",
"%hi %i %li");
524 TEST_NUM(17,
i,
'i',
"0x37 0x21 0x53",
"%hi %i %li");
525 TEST_NUM(18, u,
'o',
"037 021 053",
"%ho %o %lo");
526 TEST_NUM(19, u,
'u',
"37 21 53",
"%hu %u %lu");
527 TEST_NUM(20, u,
'x',
"0x37 0x21 0x53",
"%hx %x %lx");
528 TEST_NUM(21, u,
'X',
"0x37 0x21 0x53",
"%hx %x %lx");
532 TEST_NUM(22,
i,
'd',
"123456789",
"%3hd %2d %4ld");
533 TEST_NUM(23,
i,
'i',
"123456789",
"%3hi %2i %4li");
534 TEST_NUM(24,
i,
'i',
"012340789",
"%3hi %2i %4li");
535 TEST_NUM(25,
i,
'x',
"123456789",
"%3hi %2i %4li");
536 TEST_NUM(26, u,
'o',
"012340789",
"%3ho %2o %4lo");
537 TEST_NUM(27, u,
'u',
"123456789",
"%3hu %2u %4lu");
538 TEST_NUM(28, u,
'x',
"123456789",
"%3hx %2x %4lx");
539 TEST_NUM(29, u,
'X',
"123456789",
"%3hx %2X %4lX");
540 TEST_STR(30, 1,
"abcd",
"%1[a]%c%1s");
542 TEST_STR(31, 5,
"abc\001d e f g h i",
"%5[][abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789`~!@#$%^&*()_=+\\|{};':\",./<>? -]%5c%5s");
543 TEST_STR(32, 3,
"abc\001d e f g h i",
"%3[][abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789`~!@#$%^&*()_=+\\|{};':\",./<>? -]%3c%3s");
544 TEST_STR(33, 7,
"abc\001d e f g h i",
"%7[][abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789`~!@#$%^&*()_=+\\|{};':\",./<>? -]%7c%7s");
545 TEST_STR(34, 2,
"abc\001d e f g h i",
"%2[][abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789`~!@#$%^&*()_=+\\|{};':\",./<>? -]%2c%2s");
549 #define TEST_ERR(i, str, format) \
550 rc1 = sscanf(str, format); \
551 rc2 = test_sscanf(str, format); \
553 ++errors, printf("Test%d: failed (returned %d, not %d)\n", (i), rc2, rc1)
555 #define TEST_ERR_ARG(i, str, format, var) \
556 rc1 = sscanf(str, format, &var##1); \
557 rc2 = test_sscanf(str, format, &var##1); \
559 ++errors, printf("Test%d: failed (returned %d, not %d)\n", (i), rc2, rc1)
561 TEST_ERR_ARG(35,
"",
"%d",
i);
562 TEST_ERR_ARG(36,
"",
"%i",
i);
563 TEST_ERR_ARG(37,
"",
"%o", u);
564 TEST_ERR_ARG(38,
"",
"%u", u);
565 TEST_ERR_ARG(39,
"",
"%x", u);
566 TEST_ERR_ARG(40,
"",
"%X", u);
567 TEST_ERR_ARG(41,
"",
"%p",
p);
568 TEST_ERR_ARG(42,
"",
"%e", f);
569 TEST_ERR_ARG(43,
"",
"%E", f);
570 TEST_ERR_ARG(44,
"",
"%f", f);
571 TEST_ERR_ARG(45,
"",
"%g", f);
572 TEST_ERR_ARG(46,
"",
"%G", f);
573 TEST_ERR_ARG(47,
"",
"%[^]", *b);
574 TEST_ERR_ARG(48,
"",
"%c", *
c);
575 TEST_ERR(49,
"a",
"%%");
576 TEST_ERR(50,
"a",
"b");
579 printf(
"%d/50 tests failed (This system's sscanf(3) is probably wrong)\n", errors);
581 printf(
"All tests passed\n");
583 return (errors == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
sprintf(buf, " if (secondorder) {\n" " int _i;\n" " for (_i = 0; _i < %d; ++_i) {\n" " _p[_slist%d[_i]] += dt*_p[_dlist%d[_i]];\n" " }}\n", numeqn, listnum, listnum)
int vsscanf(const char *str, const char *format, va_list args)
#define MATCH_ACTION(cond, action)
#define MATCHES_ACTION(cond, action)