2 Copyright © 1995-2003, The AROS Development Team. All rights reserved.
5 ANSI C function sscanf().
17 /*****************************************************************************
29 Scan the specified string and convert it into the arguments as
33 str - The routine examines this string.
34 format - Format string. See scanf() for a description
35 ... - Arguments for the result
38 The number of converted parameters.
47 fscanf(), vscanf(), vfscanf(), snscanf(), vsscanf(),
52 ******************************************************************************/
54 int _sscanf(char * str, const char * format, ... )
61 va_start(args
, format
);
62 retval
= vsscanf(str
, format
, args
);
72 int n
= 0; /* Counter of the number of processed letters in
92 va_start(arg
, format
);
94 /* process the format string as long as there is a character */
97 /* search for the first letter in the format string
98 that is not a space */
100 while ( isspace(*format
) )
103 /* see if there is a command */
106 /* Examine the next char */
109 /* Initialize some variables */
114 /* The next char can be a '*' */
118 /* No assignment to variable */
120 /* Advance to next character */
128 /* Next there can be a number, a letter h,l or L or a * */
131 case 'h' : size
= sizeof(short int);
135 case 'l' : size
= sizeof(long int);
139 case 'L' : size
= sizeof(long double);
147 /* now let us see for the format letter */
150 case 'd' : /* let us look for a signed integer number in the string */
151 result
= strtol(s
, &s_end
, 10);
153 s
= s_end
; /* Ptr to the rest of the string in s */
155 if (TRUE
== assignment
)
158 if (sizeof(short int) == size
)
159 *va_arg(arg
, short int *) = result
;
161 *va_arg(arg
, long int *) = result
;
168 case 'i' : /* let us look for a signed integer number that can have a
169 different base, i.e. hex or octal. Here we have
170 to examine the next few letters in the format string
172 base
= strtol(format
, &format_end
, 10);
174 result
= strtol(s
, &s_end
, base
);
176 s
= s_end
; /* Ptr to the rest of the string in s */
178 if (TRUE
== assignment
)
181 if (sizeof(short int) == size
)
182 *va_arg(arg
, short int *) = result
;
184 *va_arg(arg
, long int *) = result
;
189 case 'o' : /* let us read in a signed octal number */
191 result
= strtol(s
, &s_end
, base
);
193 s
= s_end
; /* Ptr to the rest of the string in s */
195 if (TRUE
== assignment
)
198 if (sizeof(short int) == size
)
199 *va_arg(arg
, short int *) = result
;
201 *va_arg(arg
, long int *) = result
;
207 case 'X' : /* let us read in a signed hexadecimal number */
209 result
= strtol(s
, &s_end
, base
);
211 s
= s_end
; /* Ptr to the rest of the string in s */
213 if (TRUE
== assignment
)
216 if (sizeof(short int) == size
)
217 *va_arg(arg
, short int *) = result
;
219 *va_arg(arg
, long int *) = result
;
224 case 'u' : /* let us read in an unsigned integer */
226 result
= strtoul(s
, &s_end
, base
);
228 s
= s_end
; /* Ptr to the rest of the string in s */
230 if (TRUE
== assignment
)
233 if (sizeof(short int) == size
)
234 *va_arg(arg
, short int *) = result
;
236 *va_arg(arg
, long int *) = result
;
241 case 'c' : /* let us read in one single character */
242 /* do not skip whitespaces in s */
244 if (TRUE
== assignment
)
247 *va_arg(arg
, char *) = *s
++;
253 case 's' : /* let us read in a string until the next whitespace comes
255 /* skip leading whitespaces in s */
262 /* s points to the start of the string */
264 /* let us look for the end of the string in s */
265 while (*s_end
&& isalpha(*s_end
))
271 /* s_end points to the end of the string */
273 if(TRUE
== assignment
)
275 char * dest
= va_arg(arg
, char *);
277 strncpy(dest
, s
, (long)s_end
-(long)s
);
278 *(dest
+((long)s_end
-(long)s
))='\0';
288 case 'G' : /* a real number with optional sign, opt. decimal point and
291 D_result
= strtod(s
, &s_end
);
293 if (TRUE
== assignment
)
296 *va_arg(arg
, double *) = D_result
;
299 n
+= (long)(s_end
- s
);
304 case 'n' : /* the user wants to know how many letters we already
305 processed on the input (not format!!) string. So
306 we give hime the content of letter variable n */
307 if (TRUE
== assignment
)
309 /* NO retval++; here!! */
311 *va_arg(arg
, long *) = n
;
316 default : /* no known letter -> error!! */
332 #define Test_sscanf1(buffer, format, res1, res2, output) \
334 int retval1 = sscanf(buffer, format, &res1); \
335 int retval2 = _sscanf(buffer, format, &res2); \
336 printf(output,res1,res2); \
337 if (retval1 != retval2) printf("wrong returnvalue (%i!=%i)",retval1,retval2); \
341 #define Test_sscanfStr2(buffer, format, res11, res12, res21, res22, out1, out2) \
343 int retval1 = _sscanf(buffer, format, res11, &res12); \
344 int retval2 = _sscanf(buffer, format, res21, &res22); \
345 printf(out1, res11, res21); \
346 printf(out2, res12, res22); \
347 if (retval1 != retval2) printf("wrong returnvalue (%i!=%i)",retval1,retval2); \
353 #define Test_sscanf2(buffer, format, res11, res12, res21, res22, out1, out2) \
355 int retval1 = sscanf(buffer, format, &res11, &res12); \
356 int retval2 = _sscanf(buffer, format, &res21, &res22); \
357 printf(out1, res11, res21); \
358 printf(out2, res12, res22); \
359 if (retval1 != retval2) printf("wrong returnvalue (%i!=%i)",retval1,retval2); \
363 #define Test_sscanf3(buffer, format, res11, res12, res13, res21, res22, res23, out1, out2, out3) \
365 int retval1 = sscanf(buffer, format, &res11, &res12, &res13); \
366 int retval2 = _sscanf(buffer, format, &res21, &res22, &res23); \
367 printf(out1, res11, res21); \
368 printf(out2, res12, res22); \
369 printf(out3, res13, res23); \
370 if (retval1 != retval2) printf("wrong returnvalue (%i!=%i)",retval1,retval2); \
379 double d11,d12,d21,d22;
381 char c11,c12,c21,c22;
383 char * str1 = (char *) malloc(100);
384 char * str2 = (char *) malloc(100);
385 Test_sscanf1("100","%hi", si1, si2, "%i = %i (100)\n");
386 Test_sscanf1(" 100","%hi",si1, si2, "%i = %i (100)\n");
388 Test_sscanf1(" ABCDEF","%x",li1, li2, "%i = %i (100)\n");
390 Test_sscanf1(" FEDCBA","%X",li1, li2, "%i = %i (100)\n");
392 Test_sscanf1("123456789","%li", li1, li2, "%i = %i (123456789)\n");
393 Test_sscanf1("1.234","%le", d11, d21, "%f = %f (1.234)\n");
394 Test_sscanf1("1.234","%lE", d11, d21, "%f = %f (1.234)\n");
396 Test_sscanf2("100 200","%hi %li", si1, li1,
397 si2, li2, "%i = %i (100)\n", "%i = %i (200)\n");
399 Test_sscanf2(" 1","%c%c", c11, c12,
400 c21, c22, "%c = %c\n", "%c = %c\n");
402 Test_sscanf3("AC","%c%c%n", c11, c12, li1,
403 c21, c22, li2, "%c = %c\n", "%c = %c\n", "%i = %i\n");
406 Test_sscanf2("1.234E1 0.5E2","%le %le", d11, d12,
407 d21, d22, "%e = %e\n", "%f = %f\n");
409 si1=0;si2=0;li1=0;li2=0;
410 Test_sscanf3("1.234E1 1234","%le%n%hi", d11, li1, si1,
411 d21, li2, si2, "%e = %e\n", "%i = %i\n","%i = %i\n");
413 Test_sscanf2("100 1111","%*hi %li", si1, li1,
414 si2, li2, "%i = %i (should NOT be 100 )\n","%i = %i (1111)\n");
416 Test_sscanfStr2("ABCDEFGH 23","%s %li", str1, li1,
417 str2, li2,"%s = %s (ABCDEFGH)\n","%i = %i\n");