99
|
1
|
|
2
|
|
3 #define FBSIZE sizeof(FILE)
|
|
4 #define NFILES 16
|
|
5
|
|
6 #define NULL 0
|
|
7 #define EOF (-1)
|
|
8
|
|
9 #define stdin _fptbl[0]
|
|
10 #define stdout _fptbl[1]
|
|
11 #define stderr _fptbl[2]
|
|
12
|
|
13 #define STDIN 0xffff
|
|
14 #define STDOUT 0xfffe
|
|
15 #define STDERR 0xfffd
|
|
16
|
|
17 typedef struct {
|
|
18 int _fcb[FCBSIZE];
|
|
19 int _fbp;
|
|
20 char _fbuf[1024];
|
|
21 } FILE;
|
|
22
|
|
23 FILE *_fptbl[NFILES];
|
|
24
|
|
25 char _ch;
|
|
26 int _fch = 0;
|
|
27
|
|
28 _main(argc,argv)
|
|
29 int argc;
|
|
30 char **argv;
|
|
31 {int i;
|
|
32 initheap();
|
|
33 stdin = STDIN;
|
|
34 stdout = STDOUT;
|
|
35 stderr = STDERR;
|
|
36 for (i = 3; i < NFILES; ++i) _fptbl[i] = NULL;
|
|
37 main(argc,argv);
|
|
38 for (i = 0; i < NFILES; ++i) fflush(_fptbl[i]);
|
|
39 }
|
|
40
|
|
41 ungetc(c,fp)
|
|
42 char c;
|
|
43 FILE *fp;
|
|
44 { if (fp == STDIN)
|
|
45 { _fch = 1;
|
|
46 return _ch = c;
|
|
47 }
|
|
48 fp->_fcb[62] = 1;
|
|
49 return fp->_fcb[61] = c;
|
|
50 }
|
|
51
|
|
52 getc(fp)
|
|
53 FILE *fp;
|
|
54 {
|
|
55 switch ( fp ) {
|
|
56 case STDIN:
|
|
57 if (_fch) { _fch = 0; return _ch; }
|
|
58 return GETCH();
|
|
59 case STDOUT:
|
|
60 case STDERR:
|
|
61 return EOF;
|
|
62 default:
|
|
63 if (fp->_fcb[2] != 1) return EOF;
|
|
64 if (fp->_fcb[62]) { fp->_fcb[62] = 0; return fp->_fcb[61]; }
|
|
65 return FMS(fp->_fcb,0);
|
|
66 }
|
|
67 }
|
|
68
|
|
69 putc(c,fp)
|
|
70 char c;
|
|
71 FILE *fp;
|
|
72 { switch ( fp ) {
|
|
73 case STDIN:
|
|
74 return EOF;
|
|
75 case STDOUT:
|
|
76 return PUTCH(c);
|
|
77 case STDERR:
|
|
78 return PUTCH2(c);
|
|
79 default:
|
|
80 if (fp->_fcb[2] != 2) return EOF;
|
|
81 if (FMS(fp->_fcb,0,c) < 0) return EOF;
|
|
82 return c;
|
|
83 }
|
|
84 }
|
|
85
|
|
86 ugetch(c)
|
|
87 char c;
|
|
88 { return ungetc(c,stdin);
|
|
89 }
|
|
90
|
|
91 getchar()
|
|
92 { return getc(stdin);
|
|
93 }
|
|
94
|
|
95 putchar(c)
|
|
96 char c;
|
|
97 { return putc(c,stdout);
|
|
98 }
|
|
99
|
|
100 printf(s)
|
|
101 char *s;
|
|
102 { _fprintf(stdout,s,(int *)&s+1);
|
|
103 }
|
|
104
|
|
105 fprintf(fp,s)
|
|
106 FILE *fp;
|
|
107 char *s;
|
|
108 { _fprintf(fp,s,(int *)&s+1);
|
|
109 }
|
|
110
|
|
111 _fprintf(fp,s,p)
|
|
112 FILE *fp;
|
|
113 char *s;
|
|
114 int *p;
|
|
115 {int l,m,n;
|
|
116 char c,buf[8];
|
|
117 while(c = *s++)
|
|
118 if (c != '%') putc(c,fp);
|
|
119 else
|
|
120 { if (l=(*s == '-')) ++s;
|
|
121 if (isdigit(*s)) s += _getint(&m,s);
|
|
122 else m = 0;
|
|
123 if (*s == '.') ++s;
|
|
124 if (isdigit(*s)) s += _getint(&n,s);
|
|
125 else n = 32767;
|
|
126 switch(c = *s++)
|
|
127 {case 'd':
|
|
128 itoa(*p++,buf);
|
|
129 break;
|
|
130 case 'o':
|
|
131 itooa(*p++,buf);
|
|
132 break;
|
|
133 case 'x':
|
|
134 itoxa(*p++,buf);
|
|
135 break;
|
|
136 case 'u':
|
|
137 itoua(*p++,buf);
|
|
138 break;
|
|
139 case 'c':
|
|
140 ctos(*p++,buf);
|
|
141 break;
|
|
142 case 's':
|
|
143 _putstr(fp,*p++,l,m,n);
|
|
144 continue;
|
|
145 case '\0':
|
|
146 return;
|
|
147 default:
|
|
148 ctos(c,buf);
|
|
149 break;
|
|
150 }
|
|
151 _putstr(fp,buf,l,m,n);
|
|
152 }
|
|
153 }
|
|
154
|
|
155 _getint(p,s)
|
|
156 int *p;
|
|
157 char *s;
|
|
158 {int i;
|
|
159 for(*p = i = 0; isdigit(*s); ++i) *p = *p * 10 + *s++ - '0';
|
|
160 return i;
|
|
161 }
|
|
162
|
|
163 _putstr(fp,s,l,m,n)
|
|
164 FILE fp;
|
|
165 char *s;
|
|
166 int l,m,n;
|
|
167 {int k;
|
|
168 k = (strlen(s) < n ? strlen(s) : n);
|
|
169 m = (k < m ? m - k : 0);
|
|
170 if (l)
|
|
171 { _putsn(fp,s,n);
|
|
172 _putspc(fp,m);
|
|
173 }
|
|
174 else
|
|
175 { _putspc(fp,m);
|
|
176 _putsn(fp,s,n);
|
|
177 }
|
|
178 }
|
|
179
|
|
180 _putsn(fp,s,n)
|
|
181 FILE fp;
|
|
182 char *s;
|
|
183 int n;
|
|
184 { while(*s)
|
|
185 if (--n >= 0) putc(*s++,fp);
|
|
186 else break;
|
|
187 }
|
|
188
|
|
189 _putspc(fp,n)
|
|
190 FILE *fp;
|
|
191 int n;
|
|
192 { while(--n >= 0) putc(' ',fp);
|
|
193 }
|
|
194
|
|
195 itoa(n,s)
|
|
196 int n;
|
|
197 char *s;
|
|
198 { if (n < 0)
|
|
199 { *s++ = '-';
|
|
200 return (itoua(-n,s) + 1);
|
|
201 }
|
|
202 return itoua(n,s);
|
|
203 }
|
|
204
|
|
205 itoua(n,s)
|
|
206 int n;
|
|
207 char *s;
|
|
208 { return _itoda(n,s,10);
|
|
209 }
|
|
210
|
|
211 ctos(c,s)
|
|
212 char c,*s;
|
|
213 { s[0] = c;
|
|
214 s[1] = '\0';
|
|
215 return s;
|
|
216 }
|
|
217
|
|
218 itooa(n,s)
|
|
219 int n;
|
|
220 char *s;
|
|
221 { return _itoda(n,s,8);
|
|
222 }
|
|
223
|
|
224 itoxa(n,s)
|
|
225 int n;
|
|
226 char *s;
|
|
227 { return _itoda(n,s,16);
|
|
228 }
|
|
229
|
|
230 _itoac(n);
|
|
231 int n;
|
|
232 { return (n + ((n < 10) ? '0' : ('A'-10)));
|
|
233 }
|
|
234
|
|
235 _itoda(n,s,r)
|
|
236 unsigned n;
|
|
237 int r;
|
|
238 char *s;
|
|
239 {int i;
|
|
240 char t[8],*u;
|
|
241 u = t;
|
|
242 *u++ = '\0';
|
|
243 do *u++ = _itoac(n % r); while(n /= r);
|
|
244 for (i=0; *s++ = *--u; ++i);
|
|
245 return i;
|
|
246 }
|
|
247
|
|
248 isdigit(c)
|
|
249 char c;
|
|
250 { return ('0' <= c && c <= '9');
|
|
251 }
|
|
252
|
|
253 isspace(c)
|
|
254 char c;
|
|
255 { return (c == ' ' || c == '\t' || c == '\n');
|
|
256 }
|
|
257
|
|
258 isalpha(c)
|
|
259 char c;
|
|
260 { return (isupper(c) || islower(c) || c == '_');
|
|
261 }
|
|
262
|
|
263 isupper(c)
|
|
264 char c;
|
|
265 { return ('A' <= c && c <= 'Z');
|
|
266 }
|
|
267
|
|
268 islower(c)
|
|
269 char c;
|
|
270 { return ('a' <= c && c <= 'z');
|
|
271 }
|
|
272
|
|
273 toupper(c)
|
|
274 char c;
|
|
275 { return (islower(c) ? c + ('A'-'a') : c);
|
|
276 }
|
|
277
|
|
278 tolower(c)
|
|
279 char c;
|
|
280 { return (isupper(c) ? c + ('a'-'A') : c);
|
|
281 }
|
|
282
|
|
283 atoi(s)
|
|
284 char *s;
|
|
285 {int i,m;
|
|
286 while (isspace(*s)) ++s;
|
|
287 if (m = (*s == '-')) ++s;
|
|
288 for (i = 0; isdigit(*s);) i = i * 10 + *s++ - '0';
|
|
289 return (m ? -i : i);
|
|
290 }
|
|
291 strlen(s)
|
|
292 char *s;
|
|
293 {int i;
|
|
294 for (i = 0; *s++; ++i);
|
|
295 return i;
|
|
296 }
|