1 /* $FreeBSD: src/lib/libc/gen/fmtcheck.c,v 1.1.2.1 2001/07/05 07:43:42 kris Exp $ */
2 /* $DragonFly: src/lib/libc/gen/fmtcheck.c,v 1.3 2003/08/22 19:31:21 asmodai Exp $ */
3 /* $NetBSD: fmtcheck.c,v 1.2 2000/11/01 01:17:20 briggs Exp $ */
6 * Copyright (c) 2000 The NetBSD Foundation, Inc.
9 * This code was contributed to The NetBSD Foundation by Allen Briggs.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. All advertising materials mentioning features or use of this software
20 * must display the following acknowledgement:
21 * This product includes software developed by the NetBSD
22 * Foundation, Inc. and its contributors.
23 * 4. Neither the name of The NetBSD Foundation nor the names of its
24 * contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
27 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
28 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
29 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
31 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 * POSSIBILITY OF SUCH DAMAGE.
39 * $FreeBSD: src/lib/libc/gen/fmtcheck.c,v 1.1.2.1 2001/07/05 07:43:42 kris Exp $
42 #include <sys/cdefs.h>
50 __weak_alias(fmtcheck,__fmtcheck)
53 enum __e_fmtcheck_types {
59 FMTCHECK_SHORTPOINTER,
71 typedef enum __e_fmtcheck_types EFT;
73 #define RETURN(pf,f,r) do { \
76 } /*NOTREACHED*/ /*CONSTCOND*/ while (0)
79 get_next_format_from_precision(const char **pf)
81 int sh, lg, quad, longdouble;
84 sh = lg = quad = longdouble = 0;
94 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);
121 RETURN(pf,f,FMTCHECK_INT);
125 RETURN(pf,f,FMTCHECK_UNKNOWN);
127 RETURN(pf,f,FMTCHECK_SHORTPOINTER);
129 RETURN(pf,f,FMTCHECK_LONGPOINTER);
131 RETURN(pf,f,FMTCHECK_QUADPOINTER);
132 RETURN(pf,f,FMTCHECK_INTPOINTER);
134 if (strchr("DOU", *f)) {
135 if (sh + lg + quad + longdouble)
136 RETURN(pf,f,FMTCHECK_UNKNOWN);
137 RETURN(pf,f,FMTCHECK_LONG);
139 if (strchr("eEfg", *f)) {
141 RETURN(pf,f,FMTCHECK_LONGDOUBLE);
143 RETURN(pf,f,FMTCHECK_UNKNOWN);
144 RETURN(pf,f,FMTCHECK_DOUBLE);
147 if (sh + lg + quad + longdouble)
148 RETURN(pf,f,FMTCHECK_UNKNOWN);
149 RETURN(pf,f,FMTCHECK_INT);
152 if (sh + lg + quad + longdouble)
153 RETURN(pf,f,FMTCHECK_UNKNOWN);
154 RETURN(pf,f,FMTCHECK_STRING);
157 if (sh + lg + quad + longdouble)
158 RETURN(pf,f,FMTCHECK_UNKNOWN);
159 RETURN(pf,f,FMTCHECK_LONG);
161 RETURN(pf,f,FMTCHECK_UNKNOWN);
166 get_next_format_from_width(const char **pf)
174 RETURN(pf,f,FMTCHECK_PRECISION);
176 /* eat any precision (empty is allowed) */
177 while (isdigit(*f)) f++;
178 if (!*f) RETURN(pf,f,FMTCHECK_UNKNOWN);
180 RETURN(pf,f,get_next_format_from_precision(pf));
185 get_next_format(const char **pf, EFT eft)
190 if (eft == FMTCHECK_WIDTH) {
192 return get_next_format_from_width(pf);
193 } else if (eft == FMTCHECK_PRECISION) {
195 return get_next_format_from_precision(pf);
203 RETURN(pf,f,FMTCHECK_DONE);
206 RETURN(pf,f,FMTCHECK_UNKNOWN);
213 /* Eat any of the flags */
214 while (*f && (strchr("#0- +", *f)))
218 RETURN(pf,f,FMTCHECK_WIDTH);
221 while (isdigit(*f)) f++;
223 RETURN(pf,f,FMTCHECK_UNKNOWN);
226 RETURN(pf,f,get_next_format_from_width(pf));
231 fmtcheck(const char *f1, const char *f2)
233 const char *f1p, *f2p;
239 f1t = FMTCHECK_START;
241 f2t = FMTCHECK_START;
242 while ((f1t = get_next_format(&f1p, f1t)) != FMTCHECK_DONE) {
243 if (f1t == FMTCHECK_UNKNOWN)
245 f2t = get_next_format(&f2p, f2t);