Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
718 | jacekm | 1 | #include "stdio.h" |
2 | #include "clib.h" |
||
3 | |||
4 | /* |
||
5 | ** Write string to standard output. |
||
6 | */ |
||
7 | puts(string) char *string; |
||
8 | {fputs(string,stdout); |
||
9 | OS_fputc('\n',stdout); |
||
10 | } |
||
11 | |||
12 | /* |
||
13 | ** reverse string in place |
||
14 | */ |
||
15 | reverse(s) char *s; |
||
16 | {char *j; int c; |
||
17 | |||
18 | j=s+strlen(s)-1; |
||
19 | while(s |
||
20 | {c=*s; |
||
21 | *s++ =*j; |
||
22 | *j-- =c; |
||
23 | } |
||
24 | } |
||
25 | |||
26 | /* |
||
27 | ** copy t to s |
||
28 | */ |
||
29 | strcpy(s,t) char *s,*t; |
||
30 | {char *d; |
||
31 | |||
32 | d=s; |
||
33 | while(*s++ =*t++); |
||
34 | return (d); |
||
35 | } |
||
36 | |||
37 | /* |
||
38 | ** return length of string s (fast version) |
||
39 | */ |
||
40 | strlen(s) char *s; |
||
41 | {char *ptr; |
||
42 | |||
43 | ptr=s; |
||
44 | while(*ptr) |
||
45 | {++ptr; |
||
46 | } |
||
47 | |||
48 | return (ptr-s); |
||
49 | |||
50 | #ifdef _INASM |
||
51 | #asm |
||
52 | xor al,al ; set search value to zero |
||
53 | mov cx,65535 ; set huge maximum |
||
54 | mov di,[bp+4] ; get address of s |
||
55 | cld ; set direction flag forward |
||
56 | repne scasb ; scan for zero |
||
57 | mov ax,65534 |
||
58 | sub ax,cx ; calc and return length |
||
59 | #endasm |
||
60 | #endif |
||
61 | } |
||
62 | |||
63 | /* |
||
64 | ** return upper-case of c if it is lower-case, else c |
||
65 | */ |
||
66 | toupper(c) int c; |
||
67 | {if(c<='z' && c>='a') return (c-32); |
||
68 | return (c); |
||
69 | } |
||
70 | |||
71 | /* |
||
72 | ** atoi(s) - convert s to integer. |
||
73 | */ |
||
74 | atoi(s) char *s; |
||
75 | {int sign,n; |
||
76 | |||
77 | while(isspace(*s)) ++s; |
||
78 | sign = 1; |
||
79 | switch(*s) |
||
80 | {case '-': sign=-1; |
||
81 | case '+': ++s; |
||
82 | } |
||
83 | n=0; |
||
84 | while(isdigit(*s)) n=10*n+*s++ -'0'; |
||
85 | return (sign*n); |
||
86 | } |
||
87 | |||
88 | /* |
||
89 | ** atoib(s,b) - Convert s to "unsigned" integer in base b. |
||
90 | ** NOTE: This is a non-standard function. |
||
91 | */ |
||
92 | atoib(s,b) char *s; int b; |
||
93 | {int n, digit; |
||
94 | |||
95 | n=0; |
||
96 | while(isspace(*s)) ++s; |
||
97 | while((digit=(127 & *s++))>='0') |
||
98 | { if(digit>='a') digit-=87; |
||
99 | else if(digit>='A') digit-=55; |
||
100 | else digit -= '0'; |
||
101 | if(digit>=b) break; |
||
102 | n=b*n+digit; |
||
103 | } |
||
104 | return (n); |
||
105 | } |
||
106 | |||
107 | /* |
||
108 | ** Gets an entire string (including its newline |
||
109 | ** terminator) or size-1 characters, whichever comes |
||
110 | ** first. The input is terminated by a null character. |
||
111 | ** Entry: str = Pointer to destination buffer. |
||
112 | ** size = Size of the destination buffer. |
||
113 | ** fd = File descriptor of pertinent file. |
||
114 | ** Returns str on success, else NULL. |
||
115 | */ |
||
116 | fgets(str,size,fd) char *str; unsigned size,fd; |
||
117 | {return (_gets(str,size,fd,1)); |
||
118 | } |
||
119 | |||
120 | /* |
||
121 | ** Gets an entire string from stdin (excluding its newline |
||
122 | ** terminator) or size-1 characters, whichever comes |
||
123 | ** first. The input is terminated by a null character. |
||
124 | ** The user buffer must be large enough to hold the data. |
||
125 | ** Entry: str = Pointer to destination buffer. |
||
126 | ** Returns str on success, else NULL. |
||
127 | */ |
||
128 | gets(str) char *str; |
||
129 | {return (_gets(str,32767,stdin,0)); |
||
130 | } |
||
131 | |||
132 | _gets(str,size,fd,nl) char *str; unsigned size,fd,nl; |
||
133 | {int backup; char *next; |
||
134 | |||
135 | next=str; |
||
136 | while(--size>0) |
||
137 | {switch (*next=fgetc(fd)) |
||
138 | {case EOF: |
||
139 | *next=NULL; |
||
140 | if(next==str) return (NULL); |
||
141 | return (str); |
||
142 | |||
143 | case '\n': |
||
144 | *(next+nl)=NULL; |
||
145 | return (str); |
||
146 | |||
147 | case RUB: /* \b */ |
||
148 | if(next>str) backup=1; |
||
149 | else backup=0; |
||
150 | goto backout; |
||
151 | |||
152 | case WIPE: /* \r */ |
||
153 | backup=next-str; |
||
154 | backout: |
||
155 | if(0/*iscons(fd)*/) |
||
156 | {++size; |
||
157 | while(backup--) |
||
158 | {fputs("\b \b",stderr); |
||
159 | --next;++size; |
||
160 | } |
||
161 | continue; |
||
162 | } |
||
163 | |||
164 | default: |
||
165 | ++next; |
||
166 | } |
||
167 | } |
||
168 | *next = NULL; |
||
169 | return (str); |
||
170 | } |
||
171 | |||
172 | /* |
||
173 | ** fprintf(fd, ctlstring, arg, arg, ...) - Formatted print. |
||
174 | ** Operates as described by Kernighan & Ritchie. |
||
175 | ** b, c, d, o, s, u, and x specifications are supported. |
||
176 | ** Note: b (binary) is a non-standard extension. |
||
177 | */ |
||
178 | fprintf(argc) int argc; |
||
179 | {int *nxtarg; |
||
180 | |||
181 | nxtarg=CCARGC()+&argc; |
||
182 | return(_print(*(--nxtarg),--nxtarg)); |
||
183 | } |
||
184 | |||
185 | /* |
||
186 | ** printf(ctlstring, arg, arg, ...) - Formatted print. |
||
187 | ** Operates as described by Kernighan & Ritchie. |
||
188 | ** b, c, d, o, s, u, and x specifications are supported. |
||
189 | ** Note: b (binary) is a non-standard extension. |
||
190 | */ |
||
191 | printf(argc) int argc; |
||
192 | {return(_print(stdout,CCARGC()+&argc-1)); |
||
193 | } |
||
194 | |||
195 | /* |
||
196 | ** _print(fd, ctlstring, arg, arg, ...) |
||
197 | ** Called by fprintf() and printf(). |
||
198 | */ |
||
199 | _print(fd,nxtarg) int fd,*nxtarg; |
||
200 | {int arg,left,pad,cc,len,maxchr,width; |
||
201 | char *ctl,*sptr,str[17]; |
||
202 | |||
203 | cc=0; |
||
204 | ctl=*nxtarg--; |
||
205 | while(*ctl) |
||
206 | {if(*ctl!='%') {OS_fputc(*ctl++,fd); ++cc; continue;} |
||
207 | else ++ctl; |
||
208 | if(*ctl=='%') {OS_fputc(*ctl++,fd); ++cc; continue;} |
||
209 | if(*ctl=='-') {left=1; ++ctl;} else left=0; |
||
210 | if(*ctl=='0') pad='0'; |
||
211 | else pad=' '; |
||
212 | if(isdigit(*ctl)) |
||
213 | {width=atoi(ctl++); |
||
214 | while(isdigit(*ctl)) ++ctl; |
||
215 | }else width=0; |
||
216 | if(*ctl=='.') |
||
217 | {maxchr=atoi(++ctl); |
||
218 | while(isdigit(*ctl)) ++ctl; |
||
219 | }else maxchr=0; |
||
220 | arg=*nxtarg--; |
||
221 | sptr=str; |
||
222 | switch(*ctl++) |
||
223 | {case 'c': str[0]=arg; str[1]=NULL; break; |
||
224 | case 's': sptr=arg; break; |
||
225 | case 'd': itoa(arg,str); break; |
||
226 | case 'b': itoab(arg,str,2); break; |
||
227 | case 'o': itoab(arg,str,8); break; |
||
228 | case 'u': itoab(arg,str,10); break; |
||
229 | case 'x': itoab(arg,str,16); break; |
||
230 | default: return (cc); |
||
231 | } |
||
232 | len=strlen(sptr); |
||
233 | if(maxchr && maxchr |
||
234 | if(width>len) width=width-len; else width=0; |
||
235 | if(!left) while(width--) {OS_fputc(pad,fd); ++cc;} |
||
236 | while(len--) {OS_fputc(*sptr++,fd); ++cc;} |
||
237 | if(left) while(width--) {OS_fputc(pad,fd); ++cc;} |
||
238 | } |
||
239 | return (cc); |
||
240 | } |
||
241 | |||
242 | /* |
||
243 | ** Write a string to fd. |
||
244 | ** Entry: string = Pointer to null-terminated string. |
||
245 | ** fd = File descriptor of pertinent file. |
||
246 | */ |
||
247 | fputs(string,fd) char *string; int fd; |
||
248 | {while(*string) |
||
249 | OS_fputc(*string++,fd); |
||
250 | } |
||
251 | |||
252 | /* |
||
253 | ** All character classification functions except isascii(). |
||
254 | ** Integer argument (c) must be in ASCII range (0-127) for |
||
255 | ** dependable answers. |
||
256 | */ |
||
257 | |||
258 | #define ALNUM 1 |
||
259 | #define ALPHA 2 |
||
260 | #define CNTRL 4 |
||
261 | #define DIGIT 8 |
||
262 | #define GRAPH 16 |
||
263 | #define LOWER 32 |
||
264 | #define PRINT 64 |
||
265 | #define PUNCT 128 |
||
266 | #define BLANK 256 |
||
267 | #define UPPER 512 |
||
268 | #define XDIGIT 1024 |
||
269 | |||
270 | int _is[128] = |
||
271 | {0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, |
||
272 | 0x004, 0x104, 0x104, 0x104, 0x104, 0x104, 0x004, 0x004, |
||
273 | 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, |
||
274 | 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, |
||
275 | 0x140, 0x0D0, 0x0D0, 0x0D0, 0x0D0, 0x0D0, 0x0D0, 0x0D0, |
||
276 | 0x0D0, 0x0D0, 0x0D0, 0x0D0, 0x0D0, 0x0D0, 0x0D0, 0x0D0, |
||
277 | 0x459, 0x459, 0x459, 0x459, 0x459, 0x459, 0x459, 0x459, |
||
278 | 0x459, 0x459, 0x0D0, 0x0D0, 0x0D0, 0x0D0, 0x0D0, 0x0D0, |
||
279 | 0x0D0, 0x653, 0x653, 0x653, 0x653, 0x653, 0x653, 0x253, |
||
280 | 0x253, 0x253, 0x253, 0x253, 0x253, 0x253, 0x253, 0x253, |
||
281 | 0x253, 0x253, 0x253, 0x253, 0x253, 0x253, 0x253, 0x253, |
||
282 | 0x253, 0x253, 0x253, 0x0D0, 0x0D0, 0x0D0, 0x0D0, 0x0D0, |
||
283 | 0x0D0, 0x473, 0x473, 0x473, 0x473, 0x473, 0x473, 0x073, |
||
284 | 0x073, 0x073, 0x073, 0x073, 0x073, 0x073, 0x073, 0x073, |
||
285 | 0x073, 0x073, 0x073, 0x073, 0x073, 0x073, 0x073, 0x073, |
||
286 | 0x073, 0x073, 0x073, 0x0D0, 0x0D0, 0x0D0, 0x0D0, 0x004 |
||
287 | }; |
||
288 | |||
289 | isalnum (c) int c; {return (_is[c] & ALNUM );} /* 'a'-'z', 'A'-'Z', '0'-'9' */ |
||
290 | isalpha (c) int c; {return (_is[c] & ALPHA );} /* 'a'-'z', 'A'-'Z' */ |
||
291 | iscntrl (c) int c; {return (_is[c] & CNTRL );} /* 0-31, 127 */ |
||
292 | isdigit (c) int c; {return (_is[c] & DIGIT );} /* '0'-'9' */ |
||
293 | isgraph (c) int c; {return (_is[c] & GRAPH );} /* '!'-'~' */ |
||
294 | islower (c) int c; {return (_is[c] & LOWER );} /* 'a'-'z' */ |
||
295 | isprint (c) int c; {return (_is[c] & PRINT );} /* ' '-'~' */ |
||
296 | ispunct (c) int c; {return (_is[c] & PUNCT );} /* !alnum && !cntrl && !space */ |
||
297 | isspace (c) int c; {return (_is[c] & BLANK );} /* HT, LF, VT, FF, CR, ' ' */ |
||
298 | isupper (c) int c; {return (_is[c] & UPPER );} /* 'A'-'Z' */ |
||
299 | isxdigit(c) int c; {return (_is[c] & XDIGIT);} /* '0'-'9', 'a'-'f', 'A'-'F' */ |
||
300 | |||
301 | /* |
||
302 | ** itoa(n,s) - Convert n to characters in s |
||
303 | */ |
||
304 | itoa(n,s) char *s; int n; |
||
305 | {int sign; |
||
306 | char *ptr; |
||
307 | |||
308 | ptr=s; |
||
309 | if((sign=n)<0) n=-n; |
||
310 | do |
||
311 | {*ptr++ =n%10+'0'; |
||
312 | }while((n=n/10)>0); |
||
313 | if(sign<0) *ptr++='-'; |
||
314 | *ptr='\0'; |
||
315 | reverse(s); |
||
316 | } |
||
317 | |||
318 | /* |
||
319 | ** itoab(n,s,b) - Convert "unsigned" n to characters in s using base b. |
||
320 | ** NOTE: This is a non-standard function. |
||
321 | */ |
||
322 | itoab(n,s,b) int n; char *s; int b; |
||
323 | {char *ptr; |
||
324 | int lowbit; |
||
325 | ptr=s; |
||
326 | b >>= 1; |
||
327 | do |
||
328 | {lowbit=n&1; |
||
329 | n=(n>>1)&32767; |
||
330 | *ptr=((n%b)<<1)+lowbit; |
||
331 | if(*ptr<10) *ptr+='0'; |
||
332 | else *ptr+=55; |
||
333 | ++ptr; |
||
334 | }while(n/=b); |
||
335 | *ptr=0; |
||
336 | reverse(s); |
||
337 | } |
||
338 | |||
339 | /* |
||
340 | ** itod -- convert nbr to signed decimal string of width sz |
||
341 | ** right adjusted, blank filled; returns str |
||
342 | ** |
||
343 | ** if sz > 0 terminate with null byte |
||
344 | ** if sz = 0 find end of string |
||
345 | ** if sz < 0 use last byte for data |
||
346 | */ |
||
347 | itod(nbr,str,sz) int nbr; char str[]; int sz; |
||
348 | {char sgn; |
||
349 | |||
350 | if(nbr<0) {nbr=-nbr; sgn='-';} |
||
351 | else sgn=' '; |
||
352 | if(sz>0) str[--sz]=NULL; |
||
353 | else if(sz<0) sz=-sz; |
||
354 | else while(str[sz]!=NULL) ++sz; |
||
355 | while(sz) |
||
356 | {str[--sz]=(nbr%10+'0'); |
||
357 | if((nbr=nbr/10)==0) break; |
||
358 | } |
||
359 | if(sz) str[--sz]=sgn; |
||
360 | while(sz>0) str[--sz]=' '; |
||
361 | return str; |
||
362 | } |
||
363 | |||
364 | /* |
||
365 | ** itoo -- converts nbr to octal string of length sz |
||
366 | ** right adjusted and blank filled, returns str |
||
367 | ** |
||
368 | ** if sz > 0 terminate with null byte |
||
369 | ** if sz = 0 find end of string |
||
370 | ** if sz < 0 use last byte for data |
||
371 | */ |
||
372 | itoo(nbr,str,sz) int nbr; char str[]; int sz; |
||
373 | {int digit; |
||
374 | |||
375 | if(sz>0) str[--sz]=0; |
||
376 | else if(sz<0) sz=-sz; |
||
377 | else while(str[sz]!=0) ++sz; |
||
378 | while(sz) |
||
379 | {digit=nbr&7;nbr=(nbr>>3)&8191; |
||
380 | str[--sz]=digit+48; |
||
381 | if(nbr==0) break; |
||
382 | } |
||
383 | while(sz) str[--sz]=' '; |
||
384 | return str; |
||
385 | } |
||
386 | |||
387 | /* |
||
388 | ** itou -- convert nbr to unsigned decimal string of width sz |
||
389 | ** right adjusted, blank filled; returns str |
||
390 | ** |
||
391 | ** if sz > 0 terminate with null byte |
||
392 | ** if sz = 0 find end of string |
||
393 | ** if sz < 0 use last byte for data |
||
394 | */ |
||
395 | itou(nbr,str,sz) int nbr; char str[]; int sz; |
||
396 | {int lowbit; |
||
397 | |||
398 | if(sz>0) str[--sz]=NULL; |
||
399 | else if(sz<0) sz=-sz; |
||
400 | else while(str[sz]!=NULL) ++sz; |
||
401 | while(sz) |
||
402 | {lowbit=nbr&1; |
||
403 | nbr=(nbr>>1)&32767; /* divide by 2 */ |
||
404 | str[--sz]=((nbr%5)<<1)+lowbit+'0'; |
||
405 | if((nbr=nbr/5)==0) break; |
||
406 | } |
||
407 | while(sz) str[--sz]=' '; |
||
408 | return str; |
||
409 | } |
||
410 | |||
411 | /* |
||
412 | ** itox -- converts nbr to hex string of length sz |
||
413 | ** right adjusted and blank filled, returns str |
||
414 | ** |
||
415 | ** if sz > 0 terminate with null byte |
||
416 | ** if sz = 0 find end of string |
||
417 | ** if sz < 0 use last byte for data |
||
418 | */ |
||
419 | |||
420 | itox(nbr,str,sz) int nbr; char str[]; int sz; |
||
421 | {int digit,offset; |
||
422 | |||
423 | if(sz>0) str[--sz]=0; |
||
424 | else if(sz<0) sz=-sz; |
||
425 | else while(str[sz]!=0) ++sz; |
||
426 | while(sz) |
||
427 | {digit=nbr&15; |
||
428 | nbr=nbr/16; |
||
429 | /* |
||
430 | nbr=(nbr>>4)&4095; // 268435455; // 0xFFFFFFF |
||
431 | */ |
||
432 | if(digit<10) offset=48; |
||
433 | else offset=55; |
||
434 | str[--sz]=digit+offset; |
||
435 | if(nbr==0) break; |
||
436 | } |
||
437 | while(sz) str[--sz]=' '; |
||
438 | return str; |
||
439 | }10)>0)>>1)+lowbit+'0'; |
||
440 |