]>
Commit | Line | Data |
---|---|---|
1 | /* | |
2 | ** This file is in the public domain, so clarified as of | |
3 | ** 2006-07-17 by Arthur David Olson. | |
4 | */ | |
5 | ||
6 | /*LINTLIBRARY*/ | |
7 | ||
8 | #include "private.h" | |
9 | ||
10 | const char * | |
11 | scheck(const char *const string, const char *const format) | |
12 | { | |
13 | register char * fbuf; | |
14 | register const char * fp; | |
15 | register char * tp; | |
16 | register int c; | |
17 | register const char * result; | |
18 | char dummy; | |
19 | ||
20 | result = ""; | |
21 | if (string == NULL || format == NULL) | |
22 | return result; | |
23 | fbuf = malloc(2 * strlen(format) + 4); | |
24 | if (fbuf == NULL) | |
25 | return result; | |
26 | fp = format; | |
27 | tp = fbuf; | |
28 | ||
29 | /* | |
30 | ** Copy directives, suppressing each conversion that is not | |
31 | ** already suppressed. Scansets containing '%' are not | |
32 | ** supported; e.g., the conversion specification "%[%]" is not | |
33 | ** supported. Also, multibyte characters containing a | |
34 | ** non-leading '%' byte are not supported. | |
35 | */ | |
36 | while ((*tp++ = c = *fp++) != '\0') { | |
37 | if (c != '%') | |
38 | continue; | |
39 | if (is_digit(*fp)) { | |
40 | char const *f = fp; | |
41 | char *t = tp; | |
42 | do { | |
43 | *t++ = c = *f++; | |
44 | } while (is_digit(c)); | |
45 | if (c == '$') { | |
46 | fp = f; | |
47 | tp = t; | |
48 | } | |
49 | } | |
50 | *tp++ = '*'; | |
51 | if (*fp == '*') | |
52 | ++fp; | |
53 | if ((*tp++ = *fp++) == '\0') | |
54 | break; | |
55 | } | |
56 | ||
57 | *(tp - 1) = '%'; | |
58 | *tp++ = 'c'; | |
59 | *tp = '\0'; | |
60 | if (sscanf(string, fbuf, &dummy) != 1) | |
61 | result = format; | |
62 | free(fbuf); | |
63 | return result; | |
64 | } |