Remove building with NOCRYPTO option
[minix3.git] / lib / libc / gen / fmtcheck.c
blob8d26534253d6992efbbb4f8851e9afe8929e405e
1 /* $NetBSD: fmtcheck.c,v 1.9 2014/06/14 08:18:24 apb Exp $ */
3 /*-
4 * Copyright (c) 2000 The NetBSD Foundation, Inc.
5 * All rights reserved.
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
11 * are met:
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 $");
34 #endif
36 #include "namespace.h"
38 #include <stdio.h>
39 #include <string.h>
40 #include <ctype.h>
42 #ifdef __weak_alias
43 __weak_alias(fmtcheck,__fmtcheck)
44 #endif
46 enum __e_fmtcheck_types {
47 FMTCHECK_START,
48 FMTCHECK_SHORT,
49 FMTCHECK_INT,
50 FMTCHECK_LONG,
51 FMTCHECK_QUAD,
52 FMTCHECK_POINTER,
53 FMTCHECK_SHORTPOINTER,
54 FMTCHECK_INTPOINTER,
55 FMTCHECK_LONGPOINTER,
56 FMTCHECK_QUADPOINTER,
57 FMTCHECK_DOUBLE,
58 FMTCHECK_LONGDOUBLE,
59 FMTCHECK_STRING,
60 FMTCHECK_WIDTH,
61 FMTCHECK_PRECISION,
62 FMTCHECK_DONE,
63 FMTCHECK_UNKNOWN
65 typedef enum __e_fmtcheck_types EFT;
67 #define RETURN(pf,f,r) do { \
68 *(pf) = (f); \
69 return r; \
70 } /*NOTREACHED*/ /*CONSTCOND*/ while (0)
72 static EFT
73 get_next_format_from_precision(const char **pf)
75 int sh, lg, quad, longdouble;
76 const char *f;
78 sh = lg = quad = longdouble = 0;
80 f = *pf;
81 switch (*f) {
82 case 'h':
83 f++;
84 sh = 1;
85 break;
86 case 'l':
87 f++;
88 if (!*f) RETURN(pf,f,FMTCHECK_UNKNOWN);
89 if (*f == 'l') {
90 f++;
91 quad = 1;
92 } else {
93 lg = 1;
95 break;
96 case 'q':
97 f++;
98 quad = 1;
99 break;
100 case 'L':
101 f++;
102 longdouble = 1;
103 break;
104 default:
105 break;
107 if (!*f) RETURN(pf,f,FMTCHECK_UNKNOWN);
108 if (strchr("diouxX", *f)) {
109 if (longdouble)
110 RETURN(pf,f,FMTCHECK_UNKNOWN);
111 if (lg)
112 RETURN(pf,f,FMTCHECK_LONG);
113 if (quad)
114 RETURN(pf,f,FMTCHECK_QUAD);
115 RETURN(pf,f,FMTCHECK_INT);
117 if (*f == 'n') {
118 if (longdouble)
119 RETURN(pf,f,FMTCHECK_UNKNOWN);
120 if (sh)
121 RETURN(pf,f,FMTCHECK_SHORTPOINTER);
122 if (lg)
123 RETURN(pf,f,FMTCHECK_LONGPOINTER);
124 if (quad)
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)) {
134 if (longdouble)
135 RETURN(pf,f,FMTCHECK_LONGDOUBLE);
136 if (sh + lg + quad)
137 RETURN(pf,f,FMTCHECK_UNKNOWN);
138 RETURN(pf,f,FMTCHECK_DOUBLE);
140 if (*f == 'c') {
141 if (sh + lg + quad + longdouble)
142 RETURN(pf,f,FMTCHECK_UNKNOWN);
143 RETURN(pf,f,FMTCHECK_INT);
145 if (*f == 's') {
146 if (sh + lg + quad + longdouble)
147 RETURN(pf,f,FMTCHECK_UNKNOWN);
148 RETURN(pf,f,FMTCHECK_STRING);
150 if (*f == 'p') {
151 if (sh + lg + quad + longdouble)
152 RETURN(pf,f,FMTCHECK_UNKNOWN);
153 RETURN(pf,f,FMTCHECK_POINTER);
155 RETURN(pf,f,FMTCHECK_UNKNOWN);
156 /*NOTREACHED*/
159 static EFT
160 get_next_format_from_width(const char **pf)
162 const char *f;
164 f = *pf;
165 if (*f == '.') {
166 f++;
167 if (*f == '*') {
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));
175 /*NOTREACHED*/
178 static EFT
179 get_next_format(const char **pf, EFT eft)
181 int infmt;
182 const char *f;
184 if (eft == FMTCHECK_WIDTH) {
185 (*pf)++;
186 return get_next_format_from_width(pf);
187 } else if (eft == FMTCHECK_PRECISION) {
188 (*pf)++;
189 return get_next_format_from_precision(pf);
192 f = *pf;
193 infmt = 0;
194 while (!infmt) {
195 f = strchr(f, '%');
196 if (f == NULL)
197 RETURN(pf,f,FMTCHECK_DONE);
198 f++;
199 if (!*f)
200 RETURN(pf,f,FMTCHECK_UNKNOWN);
201 if (*f != '%')
202 infmt = 1;
203 else
204 f++;
207 /* Eat any of the flags */
208 while (*f && (strchr("#0- +", *f)))
209 f++;
211 if (*f == '*') {
212 RETURN(pf,f,FMTCHECK_WIDTH);
214 /* eat any width */
215 while (isdigit((unsigned char)*f)) f++;
216 if (!*f) {
217 RETURN(pf,f,FMTCHECK_UNKNOWN);
220 RETURN(pf,f,get_next_format_from_width(pf));
221 /*NOTREACHED*/
224 const char *
225 fmtcheck(const char *f1, const char *f2)
227 const char *f1p, *f2p;
228 EFT f1t, f2t;
230 if (!f1) return f2;
232 f1p = f1;
233 f1t = FMTCHECK_START;
234 f2p = f2;
235 f2t = FMTCHECK_START;
236 while ((f1t = get_next_format(&f1p, f1t)) != FMTCHECK_DONE) {
237 if (f1t == FMTCHECK_UNKNOWN)
238 return f2;
239 f2t = get_next_format(&f2p, f2t);
240 if (f1t != f2t)
241 return f2;
243 return f1;