add a missing section header table index conversion
[tangerine.git] / compiler / clib / sscanf.c
blob7a69b5a632ebb436bfda932472a44082d4f44368
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(), snscanf(), vsscanf(),
48 vnsscanf()
50 INTERNALS
52 ******************************************************************************/
54 int _sscanf(char * str, const char * format, ... )
57 #if 1
58 int retval;
59 va_list args;
61 va_start(args, format);
62 retval = vsscanf(str, format, args);
63 va_end(args);
65 return retval;
67 #else
69 #define TRUE 1
70 #define FALSE 0
72 int n = 0; /* Counter of the number of processed letters in
73 the input string s */
75 char * s_end;
76 char * s = str;
77 char * format_end;
78 long int result;
79 #ifndef AROS_NOFPU
80 double D_result;
81 #endif
83 int maxwidth;
84 int base;
85 int size;
86 int assignment;
88 int retval = 0;
90 va_list arg;
92 va_start(arg, format);
94 /* process the format string as long as there is a character */
95 while (*format)
97 /* search for the first letter in the format string
98 that is not a space */
100 while ( isspace(*format) )
101 format++;
103 /* see if there is a command */
104 if ('%' == *format)
106 /* Examine the next char */
107 format++;
109 /* Initialize some variables */
110 maxwidth = -1;
111 base = 10;
112 size = 4;
114 /* The next char can be a '*' */
116 if ('*' == *format)
118 /* No assignment to variable */
119 assignment = FALSE;
120 /* Advance to next character */
121 format++;
123 else
125 assignment = TRUE;
128 /* Next there can be a number, a letter h,l or L or a * */
129 switch (*format)
131 case 'h' : size = sizeof(short int);
132 format++;
133 break;
135 case 'l' : size = sizeof(long int);
136 format++;
137 break;
139 case 'L' : size = sizeof(long double);
140 format++;
141 break;
147 /* now let us see for the format letter */
148 switch (*format++)
150 case 'd' : /* let us look for a signed integer number in the string */
151 result = strtol(s, &s_end, 10);
152 n += (s_end - s);
153 s = s_end; /* Ptr to the rest of the string in s */
155 if (TRUE == assignment)
157 retval++;
158 if (sizeof(short int) == size)
159 *va_arg(arg, short int *) = result;
160 else
161 *va_arg(arg, long int *) = result;
164 break;
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
171 for the base */
172 base = strtol(format, &format_end, 10);
173 format = format_end;
174 result = strtol(s, &s_end, base);
175 n += (s_end - s);
176 s = s_end; /* Ptr to the rest of the string in s */
178 if (TRUE == assignment)
180 retval++;
181 if (sizeof(short int) == size)
182 *va_arg(arg, short int *) = result;
183 else
184 *va_arg(arg, long int *) = result;
187 break;
189 case 'o' : /* let us read in a signed octal number */
190 base = 8;
191 result = strtol(s, &s_end, base);
192 n += (s_end - s);
193 s = s_end; /* Ptr to the rest of the string in s */
195 if (TRUE == assignment)
197 retval++;
198 if (sizeof(short int) == size)
199 *va_arg(arg, short int *) = result;
200 else
201 *va_arg(arg, long int *) = result;
204 break;
206 case 'x' :
207 case 'X' : /* let us read in a signed hexadecimal number */
208 base = 16;
209 result = strtol(s, &s_end, base);
210 n+= (s_end - s);
211 s = s_end; /* Ptr to the rest of the string in s */
213 if (TRUE == assignment)
215 retval++;
216 if (sizeof(short int) == size)
217 *va_arg(arg, short int *) = result;
218 else
219 *va_arg(arg, long int *) = result;
222 break;
224 case 'u' : /* let us read in an unsigned integer */
225 base = 10;
226 result = strtoul(s, &s_end, base);
227 n += (s_end - s);
228 s = s_end; /* Ptr to the rest of the string in s */
230 if (TRUE == assignment)
232 retval++;
233 if (sizeof(short int) == size)
234 *va_arg(arg, short int *) = result;
235 else
236 *va_arg(arg, long int *) = result;
239 break;
241 case 'c' : /* let us read in one single character */
242 /* do not skip whitespaces in s */
244 if (TRUE == assignment)
246 retval++;
247 *va_arg(arg, char *) = *s++;
250 n++;
251 break;
253 case 's' : /* let us read in a string until the next whitespace comes
254 along */
255 /* skip leading whitespaces in s */
257 while (isspace(*s))
259 s++;
260 n++;
262 /* s points to the start of the string */
263 s_end = s;
264 /* let us look for the end of the string in s */
265 while (*s_end && isalpha(*s_end))
267 s_end++;
268 n++;
271 /* s_end points to the end of the string */
273 if(TRUE == assignment)
275 char * dest = va_arg(arg, char *);
276 retval++;
277 strncpy(dest, s, (long)s_end-(long)s);
278 *(dest+((long)s_end-(long)s))='\0';
280 s = s_end;
281 break;
283 #ifndef AROS_NOFPU
284 case 'e' :
285 case 'E' :
286 case 'f' :
287 case 'g' :
288 case 'G' : /* a real number with optional sign, opt. decimal point and
289 optional exponent */
291 D_result = strtod(s, &s_end);
293 if (TRUE == assignment)
295 retval++;
296 *va_arg(arg, double *) = D_result;
299 n += (long)(s_end - s);
300 s = s_end;
302 break;
303 #endif
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;
314 break;
316 default : /* no known letter -> error!! */
317 return retval;
319 } /* if */
320 else
321 return retval;
322 } /* while() */
323 va_end(arg);
324 return retval;
326 #endif
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); \
338 printf("\n"); \
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); \
348 printf("\n"); \
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); \
360 printf("\n"); \
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); \
371 printf("\n"); \
375 void main(void)
377 short int si1,si2;
378 long int li1,li2;
379 double d11,d12,d21,d22;
380 float f1,f2;
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");
419 free(str1);
420 free(str2);