4 * the function that ANSI forgot...
6 * © 1994-1998 Straylight
9 /*----- Licensing note ----------------------------------------------------*
11 * This file is part of Straylight's Steel library.
13 * Steel is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2, or (at your option)
18 * Steel is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with Steel. If not, write to the Free Software Foundation,
25 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
49 /* This union type is to avoid problems with converting between signed and
59 static int vsscanf__getWidth(char **p)
62 for (;isdigit(**p);(*p)++)
67 static void vsscanf__skipSpace(char **p)
73 static void vsscanf__readFloat
78 vsscanf__length length,
83 /*-------------------------------------------------------------------------*/
84 /* Note: this code relies on the fact that long double and double are */
85 /* identical on this architecture. This can't be chacked at compile time, */
86 /* and it is pointless checking at run-time. The reason for this is that */
87 /* I don't have a function for turning a string into a long double. */
88 /*-------------------------------------------------------------------------*/
91 vsscanf__skipSpace(p);
97 case vsscanf__DEFAULT:
99 *va_arg(ap,float *)=(float)result;
102 case vsscanf__VERY_LONG:
103 *va_arg(ap,double *)=(double)result;
110 static void vsscanf__readScanset
120 char trans[256]; /* A trt (translate and test) table */
128 (*q)++; /* Move past the opening '[' */
138 trans[']']=TRUE; /* euch using a char as an index, but it works */
141 while (**q!=']' && **q!=0)/* results of incorrect syntax are 'undefined' */
147 dest=va_arg(ap,char *);
150 if (**p!=0 && (width==-1 || width!=done) && (trans[**p] ^ reversed))
167 static void vsscanf__readString
181 dest=va_arg(ap,char *);
183 vsscanf__skipSpace(p);
191 if ((!isspace(**p) || chars) && **p && (done!=width || width==-1))
202 if (!ignore && !chars)
203 *dest=0; /* Finish off the string */
208 static void vsscanf__readInteger
215 vsscanf__length length,
220 vsscanf__genlongu result;
221 vsscanf__skipSpace(p);
227 if (tolower(*(++(*p)))=='x')
239 result.l=strtol(start,p,base);
241 result.ul=strtoul(start,p,base);
246 case vsscanf__DEFAULT:
247 case vsscanf__VERY_LONG: /* Ignore silly option */
248 *va_arg(ap,int *)=(int)result.l;
251 *va_arg(ap,long *)=(long)result.l;
252 /* This is machine dependant - r.r[2] is an int, but longs are the same */
256 *va_arg(ap,short *)=(short)result.l;
257 /* If the number is too big, the results are wierd. */
264 static BOOL vsscanf__processFormat
273 vsscanf__length length=vsscanf__DEFAULT;
281 width=vsscanf__getWidth(q);
284 length=vsscanf__SHORT;
289 length=vsscanf__LONG;
294 length=vsscanf__VERY_LONG;
297 /* Right - now we come to the business end of the thing. **q is the */
298 /* actual format specifier. */
303 *(va_arg(ap,int *))=*processed;
307 vsscanf__readString(p,width,ignore,FALSE,processed,ap);
311 vsscanf__readString(p,width,ignore,TRUE,processed,ap);
315 vsscanf__readInteger(p,ignore,processed,TRUE,10,length,ap);
320 case 'p': /* Flat memory model - pointer==hex number */
321 vsscanf__readInteger(p,ignore,processed,FALSE,16,length,ap);
325 vsscanf__readInteger(p,ignore,processed,FALSE,8,length,ap);
329 vsscanf__readInteger(p,ignore,processed,FALSE,10,length,ap);
333 vsscanf__readInteger(p,ignore,processed,TRUE,0,length,ap);
339 vsscanf__readFloat(p,ignore,processed,length,ap);
343 vsscanf__readScanset(p,q,width,ignore,processed,ap);
347 vsscanf__skipSpace(p);
348 if (*((*q)++)!=*((*p)++))
354 int vsscanf(char *string,char *format,va_list ap)
362 if (isspace(c)) /* Skip whitespace in format and source */
364 vsscanf__skipSpace(&p);
365 vsscanf__skipSpace(&q);
367 else if (c=='%') /* A format specifier */
369 if (vsscanf__processFormat(&p,&q,&processed,ap))
372 else /* R&D (Read and Discard) */
374 vsscanf__skipSpace(&p);
378 if (*p==0) /* This is the dreaded EOF (well, EOL) */