Small cleanup of extensions code
[AROS.git] / compiler / clib / sscanf.c
blobfcd8b11c33c4e611d12572a43423ef2be73fe50d
1 /*
2 Copyright © 1995-2003, The AROS Development Team. All rights reserved.
3 $Id$
5 ANSI C function sscanf().
6 */
8 #define sscanf sscanf
10 #include <string.h>
11 #include <stdio.h>
12 #include <ctype.h>
13 #include <stdlib.h>
14 #include <stdarg.h>
17 /*****************************************************************************
19 NAME */
21 int sscanf (
23 /* SYNOPSIS */
24 const char *str,
25 const char *format,
26 ...)
28 /* FUNCTION
29 Scan the specified string and convert it into the arguments as
30 specified by format.
32 INPUTS
33 str - The routine examines this string.
34 format - Format string. See scanf() for a description
35 ... - Arguments for the result
37 RESULT
38 The number of converted parameters.
40 NOTES
42 EXAMPLE
44 BUGS
46 SEE ALSO
47 fscanf(), vscanf(), vfscanf(), vsscanf()
49 INTERNALS
51 ******************************************************************************/
53 int _sscanf(char * str, const char * format, ... )
56 #if 1
57 int retval;
58 va_list args;
60 va_start(args, format);
61 retval = vsscanf(str, format, args);
62 va_end(args);
64 return retval;
66 #else
68 #define TRUE 1
69 #define FALSE 0
71 int n = 0; /* Counter of the number of processed letters in
72 the input string s */
74 char * s_end;
75 char * s = str;
76 char * format_end;
77 long int result;
78 #ifndef AROS_NOFPU
79 double D_result;
80 #endif
82 int maxwidth;
83 int base;
84 int size;
85 int assignment;
87 int retval = 0;
89 va_list arg;
91 va_start(arg, format);
93 /* process the format string as long as there is a character */
94 while (*format)
96 /* search for the first letter in the format string
97 that is not a space */
99 while ( isspace(*format) )
100 format++;
102 /* see if there is a command */
103 if ('%' == *format)
105 /* Examine the next char */
106 format++;
108 /* Initialize some variables */
109 maxwidth = -1;
110 base = 10;
111 size = 4;
113 /* The next char can be a '*' */
115 if ('*' == *format)
117 /* No assignment to variable */
118 assignment = FALSE;
119 /* Advance to next character */
120 format++;
122 else
124 assignment = TRUE;
127 /* Next there can be a number, a letter h,l or L or a * */
128 switch (*format)
130 case 'h' : size = sizeof(short int);
131 format++;
132 break;
134 case 'l' : size = sizeof(long int);
135 format++;
136 break;
138 case 'L' : size = sizeof(long double);
139 format++;
140 break;
146 /* now let us see for the format letter */
147 switch (*format++)
149 case 'd' : /* let us look for a signed integer number in the string */
150 result = strtol(s, &s_end, 10);
151 n += (s_end - s);
152 s = s_end; /* Ptr to the rest of the string in s */
154 if (TRUE == assignment)
156 retval++;
157 if (sizeof(short int) == size)
158 *va_arg(arg, short int *) = result;
159 else
160 *va_arg(arg, long int *) = result;
163 break;
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
170 for the base */
171 base = strtol(format, &format_end, 10);
172 format = format_end;
173 result = strtol(s, &s_end, base);
174 n += (s_end - s);
175 s = s_end; /* Ptr to the rest of the string in s */
177 if (TRUE == assignment)
179 retval++;
180 if (sizeof(short int) == size)
181 *va_arg(arg, short int *) = result;
182 else
183 *va_arg(arg, long int *) = result;
186 break;
188 case 'o' : /* let us read in a signed octal number */
189 base = 8;
190 result = strtol(s, &s_end, base);
191 n += (s_end - s);
192 s = s_end; /* Ptr to the rest of the string in s */
194 if (TRUE == assignment)
196 retval++;
197 if (sizeof(short int) == size)
198 *va_arg(arg, short int *) = result;
199 else
200 *va_arg(arg, long int *) = result;
203 break;
205 case 'x' :
206 case 'X' : /* let us read in a signed hexadecimal number */
207 base = 16;
208 result = strtol(s, &s_end, base);
209 n+= (s_end - s);
210 s = s_end; /* Ptr to the rest of the string in s */
212 if (TRUE == assignment)
214 retval++;
215 if (sizeof(short int) == size)
216 *va_arg(arg, short int *) = result;
217 else
218 *va_arg(arg, long int *) = result;
221 break;
223 case 'u' : /* let us read in an unsigned integer */
224 base = 10;
225 result = strtoul(s, &s_end, base);
226 n += (s_end - s);
227 s = s_end; /* Ptr to the rest of the string in s */
229 if (TRUE == assignment)
231 retval++;
232 if (sizeof(short int) == size)
233 *va_arg(arg, short int *) = result;
234 else
235 *va_arg(arg, long int *) = result;
238 break;
240 case 'c' : /* let us read in one single character */
241 /* do not skip whitespaces in s */
243 if (TRUE == assignment)
245 retval++;
246 *va_arg(arg, char *) = *s++;
249 n++;
250 break;
252 case 's' : /* let us read in a string until the next whitespace comes
253 along */
254 /* skip leading whitespaces in s */
256 while (isspace(*s))
258 s++;
259 n++;
261 /* s points to the start of the string */
262 s_end = s;
263 /* let us look for the end of the string in s */
264 while (*s_end && isalpha(*s_end))
266 s_end++;
267 n++;
270 /* s_end points to the end of the string */
272 if(TRUE == assignment)
274 char * dest = va_arg(arg, char *);
275 retval++;
276 strncpy(dest, s, (long)s_end-(long)s);
277 *(dest+((long)s_end-(long)s))='\0';
279 s = s_end;
280 break;
282 #ifndef AROS_NOFPU
283 case 'e' :
284 case 'E' :
285 case 'f' :
286 case 'g' :
287 case 'G' : /* a real number with optional sign, opt. decimal point and
288 optional exponent */
290 D_result = strtod(s, &s_end);
292 if (TRUE == assignment)
294 retval++;
295 *va_arg(arg, double *) = D_result;
298 n += (long)(s_end - s);
299 s = s_end;
301 break;
302 #endif
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;
313 break;
315 default : /* no known letter -> error!! */
316 return retval;
318 } /* if */
319 else
320 return retval;
321 } /* while() */
322 va_end(arg);
323 return retval;
325 #endif
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); \
337 printf("\n"); \
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); \
347 printf("\n"); \
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); \
359 printf("\n"); \
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); \
370 printf("\n"); \
374 void main(void)
376 short int si1,si2;
377 long int li1,li2;
378 double d11,d12,d21,d22;
379 float f1,f2;
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");
418 free(str1);
419 free(str2);