xref: /dragonfly/usr.sbin/zic/scheck.c (revision 9348a738)
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 }
63