2 * Copyright (c) 2000 The NetBSD Foundation, Inc.
5 * This code was contributed to The NetBSD Foundation by Allen Briggs.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
29 /* $NetBSD: fmtcheck.c,v 1.2 2000/11/01 01:17:20 briggs Exp $ */
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD: /repoman/r/ncvs/src/lib/libc/gen/fmtcheck.c,v 1.8 2005/03/21 08:00:55 das Exp $");
37 /* __weak_reference(__fmtcheck, fmtcheck); */
39 enum __e_fmtcheck_types {
47 FMTCHECK_SHORTPOINTER,
51 FMTCHECK_PTRDIFFTPOINTER,
52 FMTCHECK_SIZETPOINTER,
53 #ifndef NO_FLOATING_POINT
63 typedef enum __e_fmtcheck_types EFT;
65 #define RETURN(pf,f,r) do { \
68 } /*NOTREACHED*/ /*CONSTCOND*/ while (0)
71 get_next_format_from_precision(const char **pf)
73 int sh, lg, quad, longdouble, ptrdifft, sizet;
76 sh = lg = quad = longdouble = ptrdifft = sizet = 0;
86 if (!*f) RETURN(pf,f,FMTCHECK_UNKNOWN);
113 if (!*f) RETURN(pf,f,FMTCHECK_UNKNOWN);
114 if (strchr("diouxX", *f)) {
116 RETURN(pf,f,FMTCHECK_UNKNOWN);
118 RETURN(pf,f,FMTCHECK_LONG);
120 RETURN(pf,f,FMTCHECK_QUAD);
122 RETURN(pf,f,FMTCHECK_PTRDIFFT);
124 RETURN(pf,f,FMTCHECK_SIZET);
125 RETURN(pf,f,FMTCHECK_INT);
129 RETURN(pf,f,FMTCHECK_UNKNOWN);
131 RETURN(pf,f,FMTCHECK_SHORTPOINTER);
133 RETURN(pf,f,FMTCHECK_LONGPOINTER);
135 RETURN(pf,f,FMTCHECK_QUADPOINTER);
137 RETURN(pf,f,FMTCHECK_PTRDIFFTPOINTER);
139 RETURN(pf,f,FMTCHECK_SIZETPOINTER);
140 RETURN(pf,f,FMTCHECK_INTPOINTER);
142 if (strchr("DOU", *f)) {
143 if (sh + lg + quad + longdouble + ptrdifft + sizet)
144 RETURN(pf,f,FMTCHECK_UNKNOWN);
145 RETURN(pf,f,FMTCHECK_LONG);
147 #ifndef NO_FLOATING_POINT
148 if (strchr("aAeEfFgG", *f)) {
150 RETURN(pf,f,FMTCHECK_LONGDOUBLE);
151 if (sh + lg + quad + ptrdifft + sizet)
152 RETURN(pf,f,FMTCHECK_UNKNOWN);
153 RETURN(pf,f,FMTCHECK_DOUBLE);
157 if (sh + lg + quad + longdouble + ptrdifft + sizet)
158 RETURN(pf,f,FMTCHECK_UNKNOWN);
159 RETURN(pf,f,FMTCHECK_INT);
162 if (sh + lg + quad + longdouble + ptrdifft + sizet)
163 RETURN(pf,f,FMTCHECK_UNKNOWN);
164 RETURN(pf,f,FMTCHECK_STRING);
167 if (sh + lg + quad + longdouble + ptrdifft + sizet)
168 RETURN(pf,f,FMTCHECK_UNKNOWN);
169 RETURN(pf,f,FMTCHECK_LONG);
171 RETURN(pf,f,FMTCHECK_UNKNOWN);
176 get_next_format_from_width(const char **pf)
184 RETURN(pf,f,FMTCHECK_PRECISION);
186 /* eat any precision (empty is allowed) */
187 while (isdigit(*f)) f++;
188 if (!*f) RETURN(pf,f,FMTCHECK_UNKNOWN);
190 RETURN(pf,f,get_next_format_from_precision(pf));
195 get_next_format(const char **pf, EFT eft)
200 if (eft == FMTCHECK_WIDTH) {
202 return get_next_format_from_width(pf);
203 } else if (eft == FMTCHECK_PRECISION) {
205 return get_next_format_from_precision(pf);
213 RETURN(pf,f,FMTCHECK_DONE);
216 RETURN(pf,f,FMTCHECK_UNKNOWN);
223 /* Eat any of the flags */
224 while (*f && (strchr("#'0- +", *f)))
228 RETURN(pf,f,FMTCHECK_WIDTH);
231 while (isdigit(*f)) f++;
233 RETURN(pf,f,FMTCHECK_UNKNOWN);
236 RETURN(pf,f,get_next_format_from_width(pf));
241 fmtcheck(const char *f1, const char *f2)
243 const char *f1p, *f2p;
249 f1t = FMTCHECK_START;
251 f2t = FMTCHECK_START;
252 while ((f1t = get_next_format(&f1p, f1t)) != FMTCHECK_DONE) {
253 if (f1t == FMTCHECK_UNKNOWN)
255 f2t = get_next_format(&f2p, f2t);