1 /* $NetBSD: fmtcheck.c,v 1.9 2014/06/14 08:18:24 apb Exp $ */
4 * Copyright (c) 2000 The NetBSD Foundation, Inc.
7 * This code was contributed to The NetBSD Foundation by Allen Briggs.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
18 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
19 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
20 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
22 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
31 #include <sys/cdefs.h>
32 #if defined(LIBC_SCCS) && !defined(lint)
33 __RCSID("$NetBSD: fmtcheck.c,v 1.9 2014/06/14 08:18:24 apb Exp $");
36 #include "namespace.h"
43 __weak_alias(fmtcheck
,__fmtcheck
)
46 enum __e_fmtcheck_types
{
53 FMTCHECK_SHORTPOINTER
,
65 typedef enum __e_fmtcheck_types EFT
;
67 #define RETURN(pf,f,r) do { \
70 } /*NOTREACHED*/ /*CONSTCOND*/ while (0)
73 get_next_format_from_precision(const char **pf
)
75 int sh
, lg
, quad
, longdouble
;
78 sh
= lg
= quad
= longdouble
= 0;
88 if (!*f
) RETURN(pf
,f
,FMTCHECK_UNKNOWN
);
107 if (!*f
) RETURN(pf
,f
,FMTCHECK_UNKNOWN
);
108 if (strchr("diouxX", *f
)) {
110 RETURN(pf
,f
,FMTCHECK_UNKNOWN
);
112 RETURN(pf
,f
,FMTCHECK_LONG
);
114 RETURN(pf
,f
,FMTCHECK_QUAD
);
115 RETURN(pf
,f
,FMTCHECK_INT
);
119 RETURN(pf
,f
,FMTCHECK_UNKNOWN
);
121 RETURN(pf
,f
,FMTCHECK_SHORTPOINTER
);
123 RETURN(pf
,f
,FMTCHECK_LONGPOINTER
);
125 RETURN(pf
,f
,FMTCHECK_QUADPOINTER
);
126 RETURN(pf
,f
,FMTCHECK_INTPOINTER
);
128 if (strchr("DOU", *f
)) {
129 if (sh
+ lg
+ quad
+ longdouble
)
130 RETURN(pf
,f
,FMTCHECK_UNKNOWN
);
131 RETURN(pf
,f
,FMTCHECK_LONG
);
133 if (strchr("eEfg", *f
)) {
135 RETURN(pf
,f
,FMTCHECK_LONGDOUBLE
);
137 RETURN(pf
,f
,FMTCHECK_UNKNOWN
);
138 RETURN(pf
,f
,FMTCHECK_DOUBLE
);
141 if (sh
+ lg
+ quad
+ longdouble
)
142 RETURN(pf
,f
,FMTCHECK_UNKNOWN
);
143 RETURN(pf
,f
,FMTCHECK_INT
);
146 if (sh
+ lg
+ quad
+ longdouble
)
147 RETURN(pf
,f
,FMTCHECK_UNKNOWN
);
148 RETURN(pf
,f
,FMTCHECK_STRING
);
151 if (sh
+ lg
+ quad
+ longdouble
)
152 RETURN(pf
,f
,FMTCHECK_UNKNOWN
);
153 RETURN(pf
,f
,FMTCHECK_POINTER
);
155 RETURN(pf
,f
,FMTCHECK_UNKNOWN
);
160 get_next_format_from_width(const char **pf
)
168 RETURN(pf
,f
,FMTCHECK_PRECISION
);
170 /* eat any precision (empty is allowed) */
171 while (isdigit((unsigned char)*f
)) f
++;
172 if (!*f
) RETURN(pf
,f
,FMTCHECK_UNKNOWN
);
174 RETURN(pf
,f
,get_next_format_from_precision(pf
));
179 get_next_format(const char **pf
, EFT eft
)
184 if (eft
== FMTCHECK_WIDTH
) {
186 return get_next_format_from_width(pf
);
187 } else if (eft
== FMTCHECK_PRECISION
) {
189 return get_next_format_from_precision(pf
);
197 RETURN(pf
,f
,FMTCHECK_DONE
);
200 RETURN(pf
,f
,FMTCHECK_UNKNOWN
);
207 /* Eat any of the flags */
208 while (*f
&& (strchr("#0- +", *f
)))
212 RETURN(pf
,f
,FMTCHECK_WIDTH
);
215 while (isdigit((unsigned char)*f
)) f
++;
217 RETURN(pf
,f
,FMTCHECK_UNKNOWN
);
220 RETURN(pf
,f
,get_next_format_from_width(pf
));
225 fmtcheck(const char *f1
, const char *f2
)
227 const char *f1p
, *f2p
;
233 f1t
= FMTCHECK_START
;
235 f2t
= FMTCHECK_START
;
236 while ((f1t
= get_next_format(&f1p
, f1t
)) != FMTCHECK_DONE
) {
237 if (f1t
== FMTCHECK_UNKNOWN
)
239 f2t
= get_next_format(&f2p
, f2t
);