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
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]
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"
44 static unsigned char newap
[ARGMAX
* sizeof(double)];
45 static unsigned char newform
[256];
49 static int format_arg(unsigned char *, unsigned char *, unsigned char *);
60 if (strlen(fmt
) >= sizeof(newform
)) {
61 nf
= malloc(strlen(fmt
)+1);
62 if (format_arg((unsigned char *)strcpy(nf
, fmt
), ap
, newap
)
65 ret_val
= _doscan(stdin
, nf
, newap
);
70 } else if (format_arg((unsigned char *)strcpy(newform
, fmt
), ap
, newap
)
73 return(_doscan(stdin
, newform
, newap
));
75 ret_val
= _doscan(stdin
, fmt
, ap
);
81 fscanf(FILE *iop
, char *fmt
, ...)
88 if ( !(iop
->_flag
& (_IOREAD
|_IORW
)) ) {
95 if (strlen(fmt
) >= sizeof(newform
)) {
96 nf
= malloc(strlen(fmt
)+1);
97 if (format_arg((unsigned char *)strcpy(nf
, fmt
), ap
, newap
)
100 ret_val
= _doscan(stdin
, nf
, newap
);
105 } else if (format_arg((unsigned char *)strcpy(newform
, fmt
), ap
, newap
)
108 return(_doscan(iop
, newform
, newap
));
110 ret_val
= _doscan(iop
, fmt
, ap
);
116 sscanf(char *str
, char *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
)
133 ret_val
= _doscan(stdin
, nf
, newap
);
138 } else if (format_arg((unsigned char *)strcpy(newform
, fmt
), ap
, newap
)
141 return(_doscan(&strbuf
, newform
, newap
));
143 ret_val
= _doscan(&strbuf
, fmt
, ap
);
149 * This function reorganises the format string and argument list.
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 */
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];
175 fd
= creat("/tmp/SCANF", 0666);
178 for (i
= 0; i
<= ARGMAX
; args
[i
++].a_num
= 0);
182 while ((fcode
= *format
++) != '\0' && fcode
!= '%') ;
183 if (!fcode
|| i
> ARGMAX
)
186 switch (fcode
= *format
++) {
190 case '0': case '1': case '2':
191 case '3': case '4': case '5':
192 case '6': case '7': case '8':
196 while (isdigit(fcode
= *format
)) {
197 num
= num
* 10 + fcode
- '0';
200 if (*format
== '$') {
202 args
[i
].a_start
= fmtsav
- 1;
203 args
[i
].a_end
= ++format
;
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 '[':
216 if (!args
[i
].a_num
) {
217 args
[i
].a_start
= args
[i
].a_end
= format
- 1;
233 for (i
= 1; i
< length
&& args
[i
].a_num
== 0; i
++);
236 * Reformat the format string
238 cptr
= aptr
= args
[i
].a_start
;
240 bptr
= args
[i
++].a_end
;
241 for (; i
< length
&& args
[i
].a_num
== 0; i
++);
245 cptr
= args
[i
].a_start
;
246 for (; bptr
!= cptr
; *aptr
++ = *bptr
++);
247 } while (i
< length
);
251 * assuming that pointer to all variable type have
254 for (i
= 1; i
< length
; i
++)
255 args
[i
].a_val
= ((int **)(list
+= sizeof(int *)))[-1];
257 for (i
= 1; i
< length
; i
++) {
259 ptr
= (int **)newlist
;
260 *ptr
= args
[args
[i
].a_num
].a_val
;
261 newlist
+= sizeof(int *);