usbdi.9: Some small fixes.
[dragonfly.git] / usr.sbin / zic / scheck.c
1 /*
2  * $FreeBSD: src/usr.sbin/zic/scheck.c,v 1.4 1999/08/28 01:21:19 peter Exp $
3  */
4 /*LINTLIBRARY*/
5
6 #include "private.h"
7
8 const char *
9 scheck(const char * const string, const char * const format)
10 {
11         char *fbuf;
12         const char *fp;
13         char *tp;
14         int c;
15         const char *result;
16         char dummy;
17
18         result = "";
19         if (string == NULL || format == NULL)
20                 return result;
21         fbuf = malloc(2 * strlen(format) + 4);
22         if (fbuf == NULL)
23                 return result;
24         fp = format;
25         tp = fbuf;
26
27         /*
28         ** Copy directives, suppressing each conversion that is not
29         ** already suppressed.  Scansets containing '%' are not
30         ** supported; e.g., the conversion specification "%[%]" is not
31         ** supported.  Also, multibyte characters containing a
32         ** non-leading '%' byte are not supported.
33         */
34         while ((*tp++ = c = *fp++) != '\0') {
35                 if (c != '%')
36                         continue;
37                 if (is_digit(*fp)) {
38                         char const *f = fp;
39                         char *t = tp;
40                         do {
41                                 *t++ = c = *f++;
42                         } while (is_digit(c));
43                         if (c == '$') {
44                                 fp = f;
45                                 tp = t;
46                         }
47                 }
48                 *tp++ = '*';
49                 if (*fp == '*')
50                         ++fp;
51                 if ((*tp++ = *fp++) == '\0')
52                         break;
53         }
54
55         *(tp - 1) = '%';
56         *tp++ = 'c';
57         *tp = '\0';
58         if (sscanf(string, fbuf, &dummy) != 1)
59                 result = format;
60         free(fbuf);
61         return result;
62 }