1 /* $FreeBSD: src/lib/libc/gen/fmtcheck.c,v 1.1.2.1 2001/07/05 07:43:42 kris Exp $ */
2 /* $NetBSD: fmtcheck.c,v 1.2 2000/11/01 01:17:20 briggs Exp $ */
5 * Copyright (c) 2000 The NetBSD Foundation, Inc.
8 * This code was contributed to The NetBSD Foundation by Allen Briggs.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by the NetBSD
21 * Foundation, Inc. and its contributors.
22 * 4. Neither the name of The NetBSD Foundation nor the names of its
23 * contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
39 #include <sys/cdefs.h>
41 static const char rcsid[] =
42 "$FreeBSD: src/lib/libc/gen/fmtcheck.c,v 1.1.2.1 2001/07/05 07:43:42 kris Exp $";
51 __weak_alias(fmtcheck,__fmtcheck)
54 enum __e_fmtcheck_types {
60 FMTCHECK_SHORTPOINTER,
72 typedef enum __e_fmtcheck_types EFT;
74 #define RETURN(pf,f,r) do { \
77 } /*NOTREACHED*/ /*CONSTCOND*/ while (0)
80 get_next_format_from_precision(const char **pf)
82 int sh, lg, quad, longdouble;
85 sh = lg = quad = longdouble = 0;
95 if (!*f) RETURN(pf,f,FMTCHECK_UNKNOWN);
114 if (!*f) RETURN(pf,f,FMTCHECK_UNKNOWN);
115 if (strchr("diouxX", *f)) {
117 RETURN(pf,f,FMTCHECK_UNKNOWN);
119 RETURN(pf,f,FMTCHECK_LONG);
121 RETURN(pf,f,FMTCHECK_QUAD);
122 RETURN(pf,f,FMTCHECK_INT);
126 RETURN(pf,f,FMTCHECK_UNKNOWN);
128 RETURN(pf,f,FMTCHECK_SHORTPOINTER);
130 RETURN(pf,f,FMTCHECK_LONGPOINTER);
132 RETURN(pf,f,FMTCHECK_QUADPOINTER);
133 RETURN(pf,f,FMTCHECK_INTPOINTER);
135 if (strchr("DOU", *f)) {
136 if (sh + lg + quad + longdouble)
137 RETURN(pf,f,FMTCHECK_UNKNOWN);
138 RETURN(pf,f,FMTCHECK_LONG);
140 if (strchr("eEfg", *f)) {
142 RETURN(pf,f,FMTCHECK_LONGDOUBLE);
144 RETURN(pf,f,FMTCHECK_UNKNOWN);
145 RETURN(pf,f,FMTCHECK_DOUBLE);
148 if (sh + lg + quad + longdouble)
149 RETURN(pf,f,FMTCHECK_UNKNOWN);
150 RETURN(pf,f,FMTCHECK_INT);
153 if (sh + lg + quad + longdouble)
154 RETURN(pf,f,FMTCHECK_UNKNOWN);
155 RETURN(pf,f,FMTCHECK_STRING);
158 if (sh + lg + quad + longdouble)
159 RETURN(pf,f,FMTCHECK_UNKNOWN);
160 RETURN(pf,f,FMTCHECK_LONG);
162 RETURN(pf,f,FMTCHECK_UNKNOWN);
167 get_next_format_from_width(const char **pf)
175 RETURN(pf,f,FMTCHECK_PRECISION);
177 /* eat any precision (empty is allowed) */
178 while (isdigit(*f)) f++;
179 if (!*f) RETURN(pf,f,FMTCHECK_UNKNOWN);
181 RETURN(pf,f,get_next_format_from_precision(pf));
186 get_next_format(const char **pf, EFT eft)
191 if (eft == FMTCHECK_WIDTH) {
193 return get_next_format_from_width(pf);
194 } else if (eft == FMTCHECK_PRECISION) {
196 return get_next_format_from_precision(pf);
204 RETURN(pf,f,FMTCHECK_DONE);
207 RETURN(pf,f,FMTCHECK_UNKNOWN);
214 /* Eat any of the flags */
215 while (*f && (strchr("#0- +", *f)))
219 RETURN(pf,f,FMTCHECK_WIDTH);
222 while (isdigit(*f)) f++;
224 RETURN(pf,f,FMTCHECK_UNKNOWN);
227 RETURN(pf,f,get_next_format_from_width(pf));
232 fmtcheck(const char *f1, const char *f2)
234 const char *f1p, *f2p;
240 f1t = FMTCHECK_START;
242 f2t = FMTCHECK_START;
243 while ((f1t = get_next_format(&f1p, f1t)) != FMTCHECK_DONE) {
244 if (f1t == FMTCHECK_UNKNOWN)
246 f2t = get_next_format(&f2p, f2t);