8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / lib / libbc / libc / stdio / common / scanf.c
blobe024fb7c4fdcde195be02b1b8e8ef483650f66f8
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
20 * CDDL HEADER END
23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 /* Copyright (c) 1984 AT&T */
28 /* All Rights Reserved */
30 #pragma ident "%Z%%M% %I% %E% SMI"
32 /*LINTLIBRARY*/
33 #include <stdio.h>
34 #include <ctype.h>
35 #include <stdarg.h>
36 #include <errno.h>
37 #include <string.h>
38 #include <malloc.h>
40 #define ON 1
41 #define OFF 0
43 #define ARGMAX 64
44 static unsigned char newap[ARGMAX * sizeof(double)];
45 static unsigned char newform[256];
47 extern int _doscan();
49 static int format_arg(unsigned char *, unsigned char *, unsigned char *);
51 int
52 scanf(char *fmt, ...)
54 va_list ap;
55 char *nf;
56 int ret_val;
59 va_start(ap, fmt);
60 if (strlen(fmt) >= sizeof(newform)) {
61 nf = malloc(strlen(fmt)+1);
62 if (format_arg((unsigned char *)strcpy(nf, fmt), ap, newap)
63 == ON) {
64 va_end(ap);
65 ret_val = _doscan(stdin, nf, newap);
66 free(nf);
67 return(ret_val);
69 free(nf);
70 } else if (format_arg((unsigned char *)strcpy(newform, fmt), ap, newap)
71 == ON) {
72 va_end(ap);
73 return(_doscan(stdin, newform, newap));
75 ret_val = _doscan(stdin, fmt, ap);
76 va_end(ap);
77 return (ret_val);
80 int
81 fscanf(FILE *iop, char *fmt, ...)
83 va_list ap;
84 char *nf;
85 int ret_val;
87 #ifdef POSIX
88 if ( !(iop->_flag & (_IOREAD|_IORW)) ) {
89 iop->_flag |= _IOERR;
90 errno = EBADF;
91 return (EOF);
93 #endif /* POSIX */
94 va_start(ap, fmt);
95 if (strlen(fmt) >= sizeof(newform)) {
96 nf = malloc(strlen(fmt)+1);
97 if (format_arg((unsigned char *)strcpy(nf, fmt), ap, newap)
98 == ON) {
99 va_end(ap);
100 ret_val = _doscan(stdin, nf, newap);
101 free(nf);
102 return(ret_val);
104 free(nf);
105 } else if (format_arg((unsigned char *)strcpy(newform, fmt), ap, newap)
106 == ON) {
107 va_end(ap);
108 return(_doscan(iop, newform, newap));
110 ret_val = _doscan(iop, fmt, ap);
111 va_end(ap);
112 return (ret_val);
116 sscanf(char *str, char *fmt, ...)
118 va_list ap;
119 FILE strbuf;
120 char *nf;
121 int ret_val;
123 va_start(ap, fmt);
124 strbuf._flag = _IOREAD|_IOSTRG;
125 strbuf._ptr = strbuf._base = (unsigned char*)str;
126 strbuf._cnt = strlen(str);
127 strbuf._bufsiz = strbuf._cnt;
128 if (strlen(fmt) >= sizeof(newform)) {
129 nf = malloc(strlen(fmt)+1);
130 if (format_arg((unsigned char *)strcpy(nf, fmt), ap, newap)
131 == ON) {
132 va_end(ap);
133 ret_val = _doscan(stdin, nf, newap);
134 free(nf);
135 return(ret_val);
137 free(nf);
138 } else if (format_arg((unsigned char *)strcpy(newform, fmt), ap, newap)
139 == ON) {
140 va_end(ap);
141 return(_doscan(&strbuf, newform, newap));
143 ret_val = _doscan(&strbuf, fmt, ap);
144 va_end(ap);
145 return (ret_val);
149 * This function reorganises the format string and argument list.
153 #ifndef NL_ARGMAX
154 #define NL_ARGMAX 9
155 #endif
157 struct al {
158 int a_num; /* arg # specified at this position */
159 unsigned char *a_start; /* ptr to 'n' part of '%n$' in format str */
160 unsigned char *a_end; /* ptr to '$'+1 part of '%n$' in format str */
161 int *a_val; /* pointers to arguments */
164 static int
165 format_arg(unsigned char *format, unsigned char *list, unsigned char *newlist)
167 unsigned char *aptr, *bptr, *cptr;
168 int i, fcode, nl_fmt, num, length, j;
169 unsigned char *fmtsav;
170 struct al args[ARGMAX + 1];
172 #ifdef VTEST
174 int fd;
175 fd = creat("/tmp/SCANF", 0666);
177 #endif
178 for (i = 0; i <= ARGMAX; args[i++].a_num = 0);
179 nl_fmt = 0;
180 i = j = 1;
181 while (*format) {
182 while ((fcode = *format++) != '\0' && fcode != '%') ;
183 if (!fcode || i > ARGMAX)
184 break;
185 charswitch:
186 switch (fcode = *format++) {
187 case 'l':
188 case 'h':
189 goto charswitch;
190 case '0': case '1': case '2':
191 case '3': case '4': case '5':
192 case '6': case '7': case '8':
193 case '9':
194 num = fcode - '0';
195 fmtsav = format;
196 while (isdigit(fcode = *format)) {
197 num = num * 10 + fcode - '0';
198 format++;
200 if (*format == '$') {
201 nl_fmt++;
202 args[i].a_start = fmtsav - 1;
203 args[i].a_end = ++format;
204 if (num > NL_ARGMAX)
205 num = num;
206 args[i].a_num = num;
208 goto charswitch;
209 /* now have arg type only to parse */
210 case 'd': case 'u': case 'o':
211 case 'x': case 'e': case 'f':
212 case 'g': case 'c': case '[':
213 case 's':
214 if (nl_fmt == 0)
215 return(OFF);
216 if (!args[i].a_num) {
217 args[i].a_start = args[i].a_end = format - 1;
218 args[i].a_num = j++;
220 i++;
221 break;
222 case '*':
223 case '%':
224 break;
225 default:
226 format--;
227 break;
230 length = i;
231 if (nl_fmt == 0)
232 return (OFF);
233 for (i = 1; i < length && args[i].a_num == 0; i++);
236 * Reformat the format string
238 cptr = aptr = args[i].a_start;
239 do {
240 bptr = args[i++].a_end;
241 for (; i < length && args[i].a_num == 0; i++);
242 if (i == length)
243 while (*cptr++);
244 else
245 cptr = args[i].a_start;
246 for (; bptr != cptr; *aptr++ = *bptr++);
247 } while (i < length);
250 * Create arglist
251 * assuming that pointer to all variable type have
252 * same size.
254 for (i = 1; i < length; i++)
255 args[i].a_val = ((int **)(list += sizeof(int *)))[-1];
257 for (i = 1; i < length; i++) {
258 int **ptr;
259 ptr = (int **)newlist;
260 *ptr = args[args[i].a_num].a_val;
261 newlist += sizeof(int *);
263 return(ON);