Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – planix.SVN – Blame – /os/branches/feature_fixcpp/sys/src/ape/lib/ap/stdio/vfscanf.c – Rev 2

Subversion Repositories planix.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/*
2
 * pANS stdio -- vfscanf
3
 */
4
#include "iolib.h"
5
#include <stdarg.h>
6
#include <math.h>
7
#include <stdlib.h>
8
#include <ctype.h>
9
static int icvt_f(FILE *f, va_list *args, int store, int width, int type);
10
static int icvt_x(FILE *f, va_list *args, int store, int width, int type);
11
static int icvt_sq(FILE *f, va_list *args, int store, int width, int type);
12
static int icvt_c(FILE *f, va_list *args, int store, int width, int type);
13
static int icvt_d(FILE *f, va_list *args, int store, int width, int type);
14
static int icvt_i(FILE *f, va_list *args, int store, int width, int type);
15
static int icvt_n(FILE *f, va_list *args, int store, int width, int type);
16
static int icvt_o(FILE *f, va_list *args, int store, int width, int type);
17
static int icvt_p(FILE *f, va_list *args, int store, int width, int type);
18
static int icvt_s(FILE *f, va_list *args, int store, int width, int type);
19
static int icvt_u(FILE *f, va_list *args, int store, int width, int type);
20
static int (*icvt[])(FILE *, va_list *, int, int, int)={
21
0,	0,	0,	0,	0,	0,	0,	0,	/* ^@ ^A ^B ^C ^D ^E ^F ^G */
22
0,	0,	0,	0,	0,	0,	0,	0,	/* ^H ^I ^J ^K ^L ^M ^N ^O */
23
0,	0,	0,	0,	0,	0,	0,	0,	/* ^P ^Q ^R ^S ^T ^U ^V ^W */
24
0,	0,	0,	0,	0,	0,	0,	0,	/* ^X ^Y ^Z ^[ ^\ ^] ^^ ^_ */
25
0,	0,	0,	0,	0,	0,	0,	0,	/* sp  !  "  #  $  %  &  ' */
26
0,	0,	0,	0,	0,	0,	0,	0,	/*  (  )  *  +  ,  -  .  / */
27
0,	0,	0,	0,	0,	0,	0,	0,	/*  0  1  2  3  4  5  6  7 */
28
0,	0,	0,	0,	0,	0,	0,	0,	/*  8  9  :  ;  <  =  >  ? */
29
0,	0,	0,	0,	0,	icvt_f,	0,	icvt_f,	/*  @  A  B  C  D  E  F  G */
30
0,	0,	0,	0,	0,	0,	0,	0,	/*  H  I  J  K  L  M  N  O */
31
0,	0,	0,	0,	0,	0,	0,	0,	/*  P  Q  R  S  T  U  V  W */
32
icvt_x,	0,	0,	icvt_sq,0,	0,	0,	0,	/*  X  Y  Z  [  \  ]  ^  _ */
33
0,	0,	0,	icvt_c,	icvt_d,	icvt_f,	icvt_f,	icvt_f,	/*  `  a  b  c  d  e  f  g */
34
0,	icvt_i,	0,	0,	0,	0,	icvt_n,	icvt_o,	/*  h  i  j  k  l  m  n  o */
35
icvt_p,	0,	0,	icvt_s,	0,	icvt_u,	0,	0,	/*  p  q  r  s  t  u  v  w */
36
icvt_x,	0,	0,	0,	0,	0,	0,	0,	/*  x  y  z  {  |  }  ~ ^? */
37
 
38
0,	0,	0,	0,	0,	0,	0,	0,
39
0,	0,	0,	0,	0,	0,	0,	0,
40
0,	0,	0,	0,	0,	0,	0,	0,
41
0,	0,	0,	0,	0,	0,	0,	0,
42
0,	0,	0,	0,	0,	0,	0,	0,
43
0,	0,	0,	0,	0,	0,	0,	0,
44
0,	0,	0,	0,	0,	0,	0,	0,
45
0,	0,	0,	0,	0,	0,	0,	0,
46
0,	0,	0,	0,	0,	0,	0,	0,
47
0,	0,	0,	0,	0,	0,	0,	0,
48
0,	0,	0,	0,	0,	0,	0,	0,
49
0,	0,	0,	0,	0,	0,	0,	0,
50
0,	0,	0,	0,	0,	0,	0,	0,
51
0,	0,	0,	0,	0,	0,	0,	0,
52
0,	0,	0,	0,	0,	0,	0,	0,
53
0,	0,	0,	0,	0,	0,	0,	0,
54
 
55
};
56
#define	ngetc(f)		(nread++, getc(f))
57
#define	nungetc(c, f)		(--nread, ungetc((c), f))
58
#define	wgetc(c, f, out)	if(width--==0) goto out; (c)=ngetc(f)
59
#define	wungetc(c, f)		(++width, nungetc(c, f))
60
static int nread, ncvt;
61
static const char *fmtp;
62
 
63
int vfscanf(FILE *f, const char *s, va_list args){
64
	int c, width, type, store;
65
	nread=0;
66
	ncvt=0;
67
	fmtp=s;
68
	for(;*fmtp;fmtp++) switch(*fmtp){
69
	default:
70
		if(isspace(*fmtp)){
71
			do
72
				c=ngetc(f);
73
			while(isspace(c));
74
			if(c==EOF) return ncvt?ncvt:EOF;
75
			nungetc(c, f);
76
			break;
77
		}
78
	NonSpecial:
79
		c=ngetc(f);
80
		if(c==EOF) return ncvt?ncvt:EOF;
81
		if(c!=*fmtp){
82
			nungetc(c, f);
83
			return ncvt;
84
		}
85
		break;
86
	case '%':
87
		fmtp++;
88
		if(*fmtp!='*') store=1;
89
		else{
90
			store=0;
91
			fmtp++;
92
		}
93
		if('0'<=*fmtp && *fmtp<='9'){
94
			width=0;
95
			while('0'<=*fmtp && *fmtp<='9') width=width*10 + *fmtp++ - '0';
96
		}
97
		else
98
			width=-1;
99
		type=*fmtp=='h' || *fmtp=='l' || *fmtp=='L'?*fmtp++:'n';
100
		if(!icvt[*fmtp]) goto NonSpecial;
101
		if(!(*icvt[*fmtp])(f, &args, store, width, type))
102
			return ncvt?ncvt:EOF;
103
		if(*fmtp=='\0') break;
104
		if(store) ncvt++;
105
	}
106
	return ncvt;	
107
}
108
static int icvt_n(FILE *f, va_list *args, int store, int width, int type){
109
#pragma ref f
110
#pragma ref width
111
	if(store){
112
		--ncvt;	/* this assignment doesn't count! */
113
		switch(type){
114
		case 'h': *va_arg(*args, short *)=nread; break;
115
		case 'n': *va_arg(*args, int *)=nread; break;
116
		case 'l':
117
		case 'L': *va_arg(*args, long *)=nread; break;
118
		}
119
	}
120
	return 1;
121
}
122
#define	SIGNED		1
123
#define	UNSIGNED	2
124
#define	POINTER		3
125
/*
126
 * Generic fixed-point conversion
127
 *	f is the input FILE *;
128
 *	args is the va_list * into which to store the number;
129
 *	store is a flag to enable storing;
130
 *	width is the maximum field width;
131
 *	type is 'h' 'l' or 'L', the scanf type modifier;
132
 *	unsgned is SIGNED, UNSIGNED or POINTER, giving part of the type to store in;
133
 *	base is the number base -- if 0, C number syntax is used.
134
 */
135
static int icvt_fixed(FILE *f, va_list *args,
136
				int store, int width, int type, int unsgned, int base){
137
	unsigned long int num=0;
138
	int sign=1, ndig=0, dig;
139
	int c;
140
	do
141
		c=ngetc(f);
142
	while(isspace(c));
143
	if(width--==0){
144
		nungetc(c, f);
145
		goto Done;
146
	}
147
	if(c=='+'){
148
		wgetc(c, f, Done);
149
	}
150
	else if(c=='-'){
151
		sign=-1;
152
		wgetc(c, f, Done);
153
	}
154
	switch(base){
155
	case 0:
156
		if(c=='0'){
157
			wgetc(c, f, Done);
158
			if(c=='x' || c=='X'){
159
				wgetc(c, f, Done);
160
				base=16;
161
			}
162
			else{
163
				ndig=1;
164
				base=8;
165
			}
166
		}
167
		else
168
			base=10;
169
		break;
170
	case 16:
171
		if(c=='0'){
172
			wgetc(c, f, Done);
173
			if(c=='x' || c=='X'){
174
				wgetc(c, f, Done);
175
			}
176
			else ndig=1;
177
		}
178
		break;
179
	}
180
	while('0'<=c && c<='9' || 'a'<=c && c<='f' || 'A'<=c && c<='F'){
181
		dig='0'<=c && c<='9'?c-'0':'a'<=c && c<='f'?c-'a'+10:c-'A'+10;
182
		if(dig>=base) break;
183
		ndig++;
184
		num=num*base+dig;
185
		wgetc(c, f, Done);
186
	}
187
	nungetc(c, f);
188
Done:
189
	if(ndig==0) return 0;
190
	if(store){
191
		switch(unsgned){
192
		case SIGNED:
193
			switch(type){
194
			case 'h': *va_arg(*args,  short *)=num*sign; break;
195
			case 'n': *va_arg(*args,  int *)=num*sign; break;
196
			case 'l':
197
			case 'L': *va_arg(*args,  long *)=num*sign; break;
198
			}
199
			break;
200
		case UNSIGNED:
201
			switch(type){
202
			case 'h': *va_arg(*args, unsigned short *)=num*sign; break;
203
			case 'n': *va_arg(*args, unsigned int *)=num*sign; break;
204
			case 'l':
205
			case 'L': *va_arg(*args, unsigned long *)=num*sign; break;
206
			}
207
			break;
208
		case POINTER:
209
			*va_arg(*args, void **)=(void *)(num*sign); break;
210
		}
211
	}
212
	return 1;
213
}
214
static int icvt_d(FILE *f, va_list *args, int store, int width, int type){
215
	return icvt_fixed(f, args, store, width, type, SIGNED, 10);
216
}
217
static int icvt_x(FILE *f, va_list *args, int store, int width, int type){
218
	return icvt_fixed(f, args, store, width, type, UNSIGNED, 16);
219
}
220
static int icvt_o(FILE *f, va_list *args, int store, int width, int type){
221
	return icvt_fixed(f, args, store, width, type, UNSIGNED, 8);
222
}
223
static int icvt_i(FILE *f, va_list *args, int store, int width, int type){
224
	return icvt_fixed(f, args, store, width, type, SIGNED, 0);
225
}
226
static int icvt_u(FILE *f, va_list *args, int store, int width, int type){
227
	return icvt_fixed(f, args, store, width, type, UNSIGNED, 10);
228
}
229
static int icvt_p(FILE *f, va_list *args, int store, int width, int type){
230
	return icvt_fixed(f, args, store, width, type, POINTER, 16);
231
}
232
#define	NBUF	509
233
static int icvt_f(FILE *f, va_list *args, int store, int width, int type){
234
	char buf[NBUF+1];
235
	char *s=buf;
236
	int c, ndig=0, ndpt=0, nexp=1;
237
	if(width<0 || NBUF<width) width=NBUF;	/* bug -- no limit specified in ansi */
238
	do
239
		c=ngetc(f);
240
	while(isspace(c));
241
	if(width--==0){
242
		nungetc(c, f);
243
		goto Done;
244
	}
245
	if(c=='+' || c=='-'){
246
		*s++=c;
247
		wgetc(c, f, Done);
248
	}
249
	while('0'<=c && c<='9' || ndpt==0 && c=='.'){
250
		if(c=='.') ndpt++;
251
		else ndig++;
252
		*s++=c;
253
		wgetc(c, f, Done);
254
	}
255
	if(c=='e' || c=='E'){
256
		*s++=c;
257
		nexp=0;
258
		wgetc(c, f, Done);
259
		if(c=='+' || c=='-'){
260
			*s++=c;
261
			wgetc(c, f, Done);
262
		}
263
		while('0'<=c && c<='9'){
264
			*s++=c;
265
			nexp++;
266
			wgetc(c, f, Done);
267
		}
268
	}
269
	nungetc(c, f);
270
Done:
271
	if(ndig==0 || nexp==0) return 0;
272
	*s='\0';
273
	if(store) switch(type){
274
	case 'h':
275
	case 'n': *va_arg(*args, float *)=atof(buf); break;
276
	case 'L': /* bug -- should store in a long double */
277
	case 'l': *va_arg(*args, double *)=atof(buf); break;
278
	}
279
	return 1;
280
}
281
static int icvt_s(FILE *f, va_list *args, int store, int width, int type){
282
#pragma ref type
283
	int c, nn;
284
	register char *s;
285
	if(store) s=va_arg(*args, char *);
286
	do
287
		c=ngetc(f);
288
	while(isspace(c));
289
	if(width--==0){
290
		nungetc(c, f);
291
		goto Done;
292
	}
293
	nn=0;
294
	while(!isspace(c)){
295
		if(c==EOF){
296
			nread--;
297
			if(nn==0) return 0;
298
			else goto Done;
299
		}
300
		nn++;
301
		if(store) *s++=c;
302
		wgetc(c, f, Done);
303
	}
304
	nungetc(c, f);
305
Done:
306
	if(store) *s='\0';
307
	return 1;
308
}
309
static int icvt_c(FILE *f, va_list *args, int store, int width, int type){
310
#pragma ref type
311
	int c;
312
	register char *s;
313
	if(store) s=va_arg(*args, char *);
314
	if(width<0) width=1;
315
	for(;;){
316
		wgetc(c, f, Done);
317
		if(c==EOF) return 0;
318
		if(store) *s++=c;
319
	}
320
Done:
321
	return 1;
322
}
323
static int match(int c, const char *pat){
324
	int ok=1;
325
	if(*pat=='^'){
326
		ok=!ok;
327
		pat++;
328
	}
329
	while(pat!=fmtp){
330
		if(pat+2<fmtp && pat[1]=='-'){
331
			if(pat[0]<=c && c<=pat[2]
332
			|| pat[2]<=c && c<=pat[0])
333
				return ok;
334
			pat+=2;
335
		}
336
		else if(c==*pat) return ok;
337
		pat++;
338
	}
339
	return !ok;
340
}
341
static int icvt_sq(FILE *f, va_list *args, int store, int width, int type){
342
#pragma ref type
343
	int c, nn;
344
	register char *s;
345
	register const char *pat;
346
	pat=++fmtp;
347
	if(*fmtp=='^') fmtp++;
348
	if(*fmtp!='\0') fmtp++;
349
	while(*fmtp!='\0' && *fmtp!=']') fmtp++;
350
	if(store) s=va_arg(*args, char *);
351
	nn=0;
352
	for(;;){
353
		wgetc(c, f, Done);
354
		if(c==EOF){
355
			nread--;
356
			if(nn==0) return 0;
357
			else goto Done;
358
		}
359
		if(!match(c, pat)) break;
360
		if(store) *s++=c;
361
		nn++;
362
	}
363
	nungetc(c, f);
364
Done:
365
	if(store) *s='\0';
366
	return 1;
367
}