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(), vsscanf()
51 ******************************************************************************/
53 int _sscanf(char * str, const char * format, ... )
60 va_start(args
, format
);
61 retval
= vsscanf(str
, format
, args
);
71 int n
= 0; /* Counter of the number of processed letters in
91 va_start(arg
, format
);
93 /* process the format string as long as there is a character */
96 /* search for the first letter in the format string
97 that is not a space */
99 while ( isspace(*format
) )
102 /* see if there is a command */
105 /* Examine the next char */
108 /* Initialize some variables */
113 /* The next char can be a '*' */
117 /* No assignment to variable */
119 /* Advance to next character */
127 /* Next there can be a number, a letter h,l or L or a * */
130 case 'h' : size
= sizeof(short int);
134 case 'l' : size
= sizeof(long int);
138 case 'L' : size
= sizeof(long double);
146 /* now let us see for the format letter */
149 case 'd' : /* let us look for a signed integer number in the string */
150 result
= strtol(s
, &s_end
, 10);
152 s
= s_end
; /* Ptr to the rest of the string in s */
154 if (TRUE
== assignment
)
157 if (sizeof(short int) == size
)
158 *va_arg(arg
, short int *) = result
;
160 *va_arg(arg
, long int *) = result
;
167 case 'i' : /* let us look for a signed integer number that can have a
168 different base, i.e. hex or octal. Here we have
169 to examine the next few letters in the format string
171 base
= strtol(format
, &format_end
, 10);
173 result
= strtol(s
, &s_end
, base
);
175 s
= s_end
; /* Ptr to the rest of the string in s */
177 if (TRUE
== assignment
)
180 if (sizeof(short int) == size
)
181 *va_arg(arg
, short int *) = result
;
183 *va_arg(arg
, long int *) = result
;
188 case 'o' : /* let us read in a signed octal number */
190 result
= strtol(s
, &s_end
, base
);
192 s
= s_end
; /* Ptr to the rest of the string in s */
194 if (TRUE
== assignment
)
197 if (sizeof(short int) == size
)
198 *va_arg(arg
, short int *) = result
;
200 *va_arg(arg
, long int *) = result
;
206 case 'X' : /* let us read in a signed hexadecimal number */
208 result
= strtol(s
, &s_end
, base
);
210 s
= s_end
; /* Ptr to the rest of the string in s */
212 if (TRUE
== assignment
)
215 if (sizeof(short int) == size
)
216 *va_arg(arg
, short int *) = result
;
218 *va_arg(arg
, long int *) = result
;
223 case 'u' : /* let us read in an unsigned integer */
225 result
= strtoul(s
, &s_end
, base
);
227 s
= s_end
; /* Ptr to the rest of the string in s */
229 if (TRUE
== assignment
)
232 if (sizeof(short int) == size
)
233 *va_arg(arg
, short int *) = result
;
235 *va_arg(arg
, long int *) = result
;
240 case 'c' : /* let us read in one single character */
241 /* do not skip whitespaces in s */
243 if (TRUE
== assignment
)
246 *va_arg(arg
, char *) = *s
++;
252 case 's' : /* let us read in a string until the next whitespace comes
254 /* skip leading whitespaces in s */
261 /* s points to the start of the string */
263 /* let us look for the end of the string in s */
264 while (*s_end
&& isalpha(*s_end
))
270 /* s_end points to the end of the string */
272 if(TRUE
== assignment
)
274 char * dest
= va_arg(arg
, char *);
276 strncpy(dest
, s
, (long)s_end
-(long)s
);
277 *(dest
+((long)s_end
-(long)s
))='\0';
287 case 'G' : /* a real number with optional sign, opt. decimal point and
290 D_result
= strtod(s
, &s_end
);
292 if (TRUE
== assignment
)
295 *va_arg(arg
, double *) = D_result
;
298 n
+= (long)(s_end
- s
);
303 case 'n' : /* the user wants to know how many letters we already
304 processed on the input (not format!!) string. So
305 we give hime the content of letter variable n */
306 if (TRUE
== assignment
)
308 /* NO retval++; here!! */
310 *va_arg(arg
, long *) = n
;
315 default : /* no known letter -> error!! */
331 #define Test_sscanf1(buffer, format, res1, res2, output) \
333 int retval1 = sscanf(buffer, format, &res1); \
334 int retval2 = _sscanf(buffer, format, &res2); \
335 printf(output,res1,res2); \
336 if (retval1 != retval2) printf("wrong returnvalue (%i!=%i)",retval1,retval2); \
340 #define Test_sscanfStr2(buffer, format, res11, res12, res21, res22, out1, out2) \
342 int retval1 = _sscanf(buffer, format, res11, &res12); \
343 int retval2 = _sscanf(buffer, format, res21, &res22); \
344 printf(out1, res11, res21); \
345 printf(out2, res12, res22); \
346 if (retval1 != retval2) printf("wrong returnvalue (%i!=%i)",retval1,retval2); \
352 #define Test_sscanf2(buffer, format, res11, res12, res21, res22, out1, out2) \
354 int retval1 = sscanf(buffer, format, &res11, &res12); \
355 int retval2 = _sscanf(buffer, format, &res21, &res22); \
356 printf(out1, res11, res21); \
357 printf(out2, res12, res22); \
358 if (retval1 != retval2) printf("wrong returnvalue (%i!=%i)",retval1,retval2); \
362 #define Test_sscanf3(buffer, format, res11, res12, res13, res21, res22, res23, out1, out2, out3) \
364 int retval1 = sscanf(buffer, format, &res11, &res12, &res13); \
365 int retval2 = _sscanf(buffer, format, &res21, &res22, &res23); \
366 printf(out1, res11, res21); \
367 printf(out2, res12, res22); \
368 printf(out3, res13, res23); \
369 if (retval1 != retval2) printf("wrong returnvalue (%i!=%i)",retval1,retval2); \
378 double d11,d12,d21,d22;
380 char c11,c12,c21,c22;
382 char * str1 = (char *) malloc(100);
383 char * str2 = (char *) malloc(100);
384 Test_sscanf1("100","%hi", si1, si2, "%i = %i (100)\n");
385 Test_sscanf1(" 100","%hi",si1, si2, "%i = %i (100)\n");
387 Test_sscanf1(" ABCDEF","%x",li1, li2, "%i = %i (100)\n");
389 Test_sscanf1(" FEDCBA","%X",li1, li2, "%i = %i (100)\n");
391 Test_sscanf1("123456789","%li", li1, li2, "%i = %i (123456789)\n");
392 Test_sscanf1("1.234","%le", d11, d21, "%f = %f (1.234)\n");
393 Test_sscanf1("1.234","%lE", d11, d21, "%f = %f (1.234)\n");
395 Test_sscanf2("100 200","%hi %li", si1, li1,
396 si2, li2, "%i = %i (100)\n", "%i = %i (200)\n");
398 Test_sscanf2(" 1","%c%c", c11, c12,
399 c21, c22, "%c = %c\n", "%c = %c\n");
401 Test_sscanf3("AC","%c%c%n", c11, c12, li1,
402 c21, c22, li2, "%c = %c\n", "%c = %c\n", "%i = %i\n");
405 Test_sscanf2("1.234E1 0.5E2","%le %le", d11, d12,
406 d21, d22, "%e = %e\n", "%f = %f\n");
408 si1=0;si2=0;li1=0;li2=0;
409 Test_sscanf3("1.234E1 1234","%le%n%hi", d11, li1, si1,
410 d21, li2, si2, "%e = %e\n", "%i = %i\n","%i = %i\n");
412 Test_sscanf2("100 1111","%*hi %li", si1, li1,
413 si2, li2, "%i = %i (should NOT be 100 )\n","%i = %i (1111)\n");
415 Test_sscanfStr2("ABCDEFGH 23","%s %li", str1, li1,
416 str2, li2,"%s = %s (ABCDEFGH)\n","%i = %i\n");