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 $
37 * $DragonFly: src/lib/libc/gen/fmtcheck.c,v 1.3 2003/08/22 19:31:21 asmodai Exp $
44 __weak_reference(__fmtcheck, fmtcheck);
46 enum __e_fmtcheck_types {
57 FMTCHECK_SHORTPOINTER,
61 FMTCHECK_INTMAXTPOINTER,
62 FMTCHECK_PTRDIFFTPOINTER,
63 FMTCHECK_SIZETPOINTER,
64 #ifndef NO_FLOATING_POINT
75 typedef enum __e_fmtcheck_types EFT;
89 #define RETURN(pf,f,r) do { \
92 } /*NOTREACHED*/ /*CONSTCOND*/ while (0)
95 get_next_format_from_precision(const char **pf)
97 enum e_modifier modifier;
104 if (!*f) RETURN(pf,f,FMTCHECK_UNKNOWN);
109 modifier = MOD_SHORT;
114 modifier = MOD_INTMAXT;
118 if (!*f) RETURN(pf,f,FMTCHECK_UNKNOWN);
132 modifier = MOD_PTRDIFFT;
136 modifier = MOD_SIZET;
140 modifier = MOD_LONGDOUBLE;
146 if (!*f) RETURN(pf,f,FMTCHECK_UNKNOWN);
147 if (strchr("diouxX", *f)) {
150 RETURN(pf,f,FMTCHECK_LONG);
152 RETURN(pf,f,FMTCHECK_QUAD);
154 RETURN(pf,f,FMTCHECK_INTMAXT);
156 RETURN(pf,f,FMTCHECK_PTRDIFFT);
158 RETURN(pf,f,FMTCHECK_SIZET);
162 RETURN(pf,f,FMTCHECK_INT);
164 RETURN(pf,f,FMTCHECK_UNKNOWN);
170 RETURN(pf,f,FMTCHECK_CHARPOINTER);
172 RETURN(pf,f,FMTCHECK_SHORTPOINTER);
174 RETURN(pf,f,FMTCHECK_LONGPOINTER);
176 RETURN(pf,f,FMTCHECK_QUADPOINTER);
178 RETURN(pf,f,FMTCHECK_INTMAXTPOINTER);
180 RETURN(pf,f,FMTCHECK_PTRDIFFTPOINTER);
182 RETURN(pf,f,FMTCHECK_SIZETPOINTER);
184 RETURN(pf,f,FMTCHECK_INTPOINTER);
186 RETURN(pf,f,FMTCHECK_UNKNOWN);
189 if (strchr("DOU", *f)) {
190 if (modifier != MOD_NONE)
191 RETURN(pf,f,FMTCHECK_UNKNOWN);
192 RETURN(pf,f,FMTCHECK_LONG);
194 #ifndef NO_FLOATING_POINT
195 if (strchr("aAeEfFgG", *f)) {
198 RETURN(pf,f,FMTCHECK_LONGDOUBLE);
201 RETURN(pf,f,FMTCHECK_DOUBLE);
203 RETURN(pf,f,FMTCHECK_UNKNOWN);
210 RETURN(pf,f,FMTCHECK_WINTT);
212 RETURN(pf,f,FMTCHECK_INT);
214 RETURN(pf,f,FMTCHECK_UNKNOWN);
218 if (modifier != MOD_NONE)
219 RETURN(pf,f,FMTCHECK_UNKNOWN);
220 RETURN(pf,f,FMTCHECK_WINTT);
225 RETURN(pf,f,FMTCHECK_WSTRING);
227 RETURN(pf,f,FMTCHECK_STRING);
229 RETURN(pf,f,FMTCHECK_UNKNOWN);
233 if (modifier != MOD_NONE)
234 RETURN(pf,f,FMTCHECK_UNKNOWN);
235 RETURN(pf,f,FMTCHECK_WSTRING);
238 if (modifier != MOD_NONE)
239 RETURN(pf,f,FMTCHECK_UNKNOWN);
240 RETURN(pf,f,FMTCHECK_LONG);
242 RETURN(pf,f,FMTCHECK_UNKNOWN);
247 get_next_format_from_width(const char **pf)
255 RETURN(pf,f,FMTCHECK_PRECISION);
257 /* eat any precision (empty is allowed) */
258 while (isdigit(*f)) f++;
259 if (!*f) RETURN(pf,f,FMTCHECK_UNKNOWN);
261 RETURN(pf,f,get_next_format_from_precision(pf));
266 get_next_format(const char **pf, EFT eft)
271 if (eft == FMTCHECK_WIDTH) {
273 return get_next_format_from_width(pf);
274 } else if (eft == FMTCHECK_PRECISION) {
276 return get_next_format_from_precision(pf);
284 RETURN(pf,f,FMTCHECK_DONE);
287 RETURN(pf,f,FMTCHECK_UNKNOWN);
294 /* Eat any of the flags */
295 while (*f && (strchr("#'0- +", *f)))
299 RETURN(pf,f,FMTCHECK_WIDTH);
302 while (isdigit(*f)) f++;
304 RETURN(pf,f,FMTCHECK_UNKNOWN);
307 RETURN(pf,f,get_next_format_from_width(pf));
312 __fmtcheck(const char *f1, const char *f2)
314 const char *f1p, *f2p;
320 f1t = FMTCHECK_START;
322 f2t = FMTCHECK_START;
323 while ((f1t = get_next_format(&f1p, f1t)) != FMTCHECK_DONE) {
324 if (f1t == FMTCHECK_UNKNOWN)
326 f2t = get_next_format(&f2p, f2t);