lh | 9ed821d | 2023-04-07 01:36:19 -0700 | [diff] [blame] | 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 | } |