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.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by the NetBSD
18 * Foundation, Inc. and its contributors.
19 * 4. Neither the name of The NetBSD Foundation nor the names of its
20 * contributors may be used to endorse or promote products derived
21 * from this software without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
24 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
25 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
26 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
27 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 * POSSIBILITY OF SUCH DAMAGE.
35 * $NetBSD: fmtcheck.c,v 1.2 2000/11/01 01:17:20 briggs Exp $
36 * $FreeBSD: src/lib/libc/gen/fmtcheck.c,v 1.9 2008/08/02 06:02:42 das Exp $
43 const char *__fmtcheck(const char *, const char *);
45 enum __e_fmtcheck_types {
56 FMTCHECK_SHORTPOINTER,
60 FMTCHECK_INTMAXTPOINTER,
61 FMTCHECK_PTRDIFFTPOINTER,
62 FMTCHECK_SIZETPOINTER,
63 #ifndef NO_FLOATING_POINT
74 typedef enum __e_fmtcheck_types EFT;
88 #define RETURN(pf,f,r) do { \
91 } /*NOTREACHED*/ /*CONSTCOND*/ while (0)
94 get_next_format_from_precision(const char **pf)
96 enum e_modifier modifier;
103 if (!*f) RETURN(pf,f,FMTCHECK_UNKNOWN);
108 modifier = MOD_SHORT;
113 modifier = MOD_INTMAXT;
117 if (!*f) RETURN(pf,f,FMTCHECK_UNKNOWN);
131 modifier = MOD_PTRDIFFT;
135 modifier = MOD_SIZET;
139 modifier = MOD_LONGDOUBLE;
145 if (!*f) RETURN(pf,f,FMTCHECK_UNKNOWN);
146 if (strchr("diouxX", *f)) {
149 RETURN(pf,f,FMTCHECK_LONG);
151 RETURN(pf,f,FMTCHECK_QUAD);
153 RETURN(pf,f,FMTCHECK_INTMAXT);
155 RETURN(pf,f,FMTCHECK_PTRDIFFT);
157 RETURN(pf,f,FMTCHECK_SIZET);
161 RETURN(pf,f,FMTCHECK_INT);
163 RETURN(pf,f,FMTCHECK_UNKNOWN);
169 RETURN(pf,f,FMTCHECK_CHARPOINTER);
171 RETURN(pf,f,FMTCHECK_SHORTPOINTER);
173 RETURN(pf,f,FMTCHECK_LONGPOINTER);
175 RETURN(pf,f,FMTCHECK_QUADPOINTER);
177 RETURN(pf,f,FMTCHECK_INTMAXTPOINTER);
179 RETURN(pf,f,FMTCHECK_PTRDIFFTPOINTER);
181 RETURN(pf,f,FMTCHECK_SIZETPOINTER);
183 RETURN(pf,f,FMTCHECK_INTPOINTER);
185 RETURN(pf,f,FMTCHECK_UNKNOWN);
188 if (strchr("DOU", *f)) {
189 if (modifier != MOD_NONE)
190 RETURN(pf,f,FMTCHECK_UNKNOWN);
191 RETURN(pf,f,FMTCHECK_LONG);
193 #ifndef NO_FLOATING_POINT
194 if (strchr("aAeEfFgG", *f)) {
197 RETURN(pf,f,FMTCHECK_LONGDOUBLE);
200 RETURN(pf,f,FMTCHECK_DOUBLE);
202 RETURN(pf,f,FMTCHECK_UNKNOWN);
209 RETURN(pf,f,FMTCHECK_WINTT);
211 RETURN(pf,f,FMTCHECK_INT);
213 RETURN(pf,f,FMTCHECK_UNKNOWN);
217 if (modifier != MOD_NONE)
218 RETURN(pf,f,FMTCHECK_UNKNOWN);
219 RETURN(pf,f,FMTCHECK_WINTT);
224 RETURN(pf,f,FMTCHECK_WSTRING);
226 RETURN(pf,f,FMTCHECK_STRING);
228 RETURN(pf,f,FMTCHECK_UNKNOWN);
232 if (modifier != MOD_NONE)
233 RETURN(pf,f,FMTCHECK_UNKNOWN);
234 RETURN(pf,f,FMTCHECK_WSTRING);
237 if (modifier != MOD_NONE)
238 RETURN(pf,f,FMTCHECK_UNKNOWN);
239 RETURN(pf,f,FMTCHECK_LONG);
241 RETURN(pf,f,FMTCHECK_UNKNOWN);
246 get_next_format_from_width(const char **pf)
254 RETURN(pf,f,FMTCHECK_PRECISION);
256 /* eat any precision (empty is allowed) */
257 while (isdigit(*f)) f++;
258 if (!*f) RETURN(pf,f,FMTCHECK_UNKNOWN);
260 RETURN(pf,f,get_next_format_from_precision(pf));
265 get_next_format(const char **pf, EFT eft)
270 if (eft == FMTCHECK_WIDTH) {
272 return get_next_format_from_width(pf);
273 } else if (eft == FMTCHECK_PRECISION) {
275 return get_next_format_from_precision(pf);
283 RETURN(pf,f,FMTCHECK_DONE);
286 RETURN(pf,f,FMTCHECK_UNKNOWN);
293 /* Eat any of the flags */
294 while (*f && (strchr("#'0- +", *f)))
298 RETURN(pf,f,FMTCHECK_WIDTH);
301 while (isdigit(*f)) f++;
303 RETURN(pf,f,FMTCHECK_UNKNOWN);
306 RETURN(pf,f,get_next_format_from_width(pf));
311 __fmtcheck(const char *f1, const char *f2)
313 const char *f1p, *f2p;
319 f1t = FMTCHECK_START;
321 f2t = FMTCHECK_START;
322 while ((f1t = get_next_format(&f1p, f1t)) != FMTCHECK_DONE) {
323 if (f1t == FMTCHECK_UNKNOWN)
325 f2t = get_next_format(&f2p, f2t);
332 __weak_reference(__fmtcheck, fmtcheck);