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
);