forked from KolibriOS/kolibrios
1967c25fac
git-svn-id: svn://kolibrios.org@718 a494cfbc-eb01-0410-851d-a64ba20cac60
441 lines
10 KiB
C
441 lines
10 KiB
C
#include "stdio.h"
|
|
#include "clib.h"
|
|
|
|
/*
|
|
** Write string to standard output.
|
|
*/
|
|
puts(string) char *string;
|
|
{fputs(string,stdout);
|
|
OS_fputc('\n',stdout);
|
|
}
|
|
|
|
/*
|
|
** reverse string in place
|
|
*/
|
|
reverse(s) char *s;
|
|
{char *j; int c;
|
|
|
|
j=s+strlen(s)-1;
|
|
while(s<j)
|
|
{c=*s;
|
|
*s++ =*j;
|
|
*j-- =c;
|
|
}
|
|
}
|
|
|
|
/*
|
|
** copy t to s
|
|
*/
|
|
strcpy(s,t) char *s,*t;
|
|
{char *d;
|
|
|
|
d=s;
|
|
while(*s++ =*t++);
|
|
return (d);
|
|
}
|
|
|
|
/*
|
|
** return length of string s (fast version)
|
|
*/
|
|
strlen(s) char *s;
|
|
{char *ptr;
|
|
|
|
ptr=s;
|
|
while(*ptr)
|
|
{++ptr;
|
|
}
|
|
|
|
return (ptr-s);
|
|
|
|
#ifdef _INASM
|
|
#asm
|
|
xor al,al ; set search value to zero
|
|
mov cx,65535 ; set huge maximum
|
|
mov di,[bp+4] ; get address of s
|
|
cld ; set direction flag forward
|
|
repne scasb ; scan for zero
|
|
mov ax,65534
|
|
sub ax,cx ; calc and return length
|
|
#endasm
|
|
#endif
|
|
}
|
|
|
|
/*
|
|
** return upper-case of c if it is lower-case, else c
|
|
*/
|
|
toupper(c) int c;
|
|
{if(c<='z' && c>='a') return (c-32);
|
|
return (c);
|
|
}
|
|
|
|
/*
|
|
** atoi(s) - convert s to integer.
|
|
*/
|
|
atoi(s) char *s;
|
|
{int sign,n;
|
|
|
|
while(isspace(*s)) ++s;
|
|
sign = 1;
|
|
switch(*s)
|
|
{case '-': sign=-1;
|
|
case '+': ++s;
|
|
}
|
|
n=0;
|
|
while(isdigit(*s)) n=10*n+*s++ -'0';
|
|
return (sign*n);
|
|
}
|
|
|
|
/*
|
|
** atoib(s,b) - Convert s to "unsigned" integer in base b.
|
|
** NOTE: This is a non-standard function.
|
|
*/
|
|
atoib(s,b) char *s; int b;
|
|
{int n, digit;
|
|
|
|
n=0;
|
|
while(isspace(*s)) ++s;
|
|
while((digit=(127 & *s++))>='0')
|
|
{ if(digit>='a') digit-=87;
|
|
else if(digit>='A') digit-=55;
|
|
else digit -= '0';
|
|
if(digit>=b) break;
|
|
n=b*n+digit;
|
|
}
|
|
return (n);
|
|
}
|
|
|
|
/*
|
|
** Gets an entire string (including its newline
|
|
** terminator) or size-1 characters, whichever comes
|
|
** first. The input is terminated by a null character.
|
|
** Entry: str = Pointer to destination buffer.
|
|
** size = Size of the destination buffer.
|
|
** fd = File descriptor of pertinent file.
|
|
** Returns str on success, else NULL.
|
|
*/
|
|
fgets(str,size,fd) char *str; unsigned size,fd;
|
|
{return (_gets(str,size,fd,1));
|
|
}
|
|
|
|
/*
|
|
** Gets an entire string from stdin (excluding its newline
|
|
** terminator) or size-1 characters, whichever comes
|
|
** first. The input is terminated by a null character.
|
|
** The user buffer must be large enough to hold the data.
|
|
** Entry: str = Pointer to destination buffer.
|
|
** Returns str on success, else NULL.
|
|
*/
|
|
gets(str) char *str;
|
|
{return (_gets(str,32767,stdin,0));
|
|
}
|
|
|
|
_gets(str,size,fd,nl) char *str; unsigned size,fd,nl;
|
|
{int backup; char *next;
|
|
|
|
next=str;
|
|
while(--size>0)
|
|
{switch (*next=fgetc(fd))
|
|
{case EOF:
|
|
*next=NULL;
|
|
if(next==str) return (NULL);
|
|
return (str);
|
|
|
|
case '\n':
|
|
*(next+nl)=NULL;
|
|
return (str);
|
|
|
|
case RUB: /* \b */
|
|
if(next>str) backup=1;
|
|
else backup=0;
|
|
goto backout;
|
|
|
|
case WIPE: /* \r */
|
|
backup=next-str;
|
|
backout:
|
|
if(0/*iscons(fd)*/)
|
|
{++size;
|
|
while(backup--)
|
|
{fputs("\b \b",stderr);
|
|
--next;++size;
|
|
}
|
|
continue;
|
|
}
|
|
|
|
default:
|
|
++next;
|
|
}
|
|
}
|
|
*next = NULL;
|
|
return (str);
|
|
}
|
|
|
|
/*
|
|
** fprintf(fd, ctlstring, arg, arg, ...) - Formatted print.
|
|
** Operates as described by Kernighan & Ritchie.
|
|
** b, c, d, o, s, u, and x specifications are supported.
|
|
** Note: b (binary) is a non-standard extension.
|
|
*/
|
|
fprintf(argc) int argc;
|
|
{int *nxtarg;
|
|
|
|
nxtarg=CCARGC()+&argc;
|
|
return(_print(*(--nxtarg),--nxtarg));
|
|
}
|
|
|
|
/*
|
|
** printf(ctlstring, arg, arg, ...) - Formatted print.
|
|
** Operates as described by Kernighan & Ritchie.
|
|
** b, c, d, o, s, u, and x specifications are supported.
|
|
** Note: b (binary) is a non-standard extension.
|
|
*/
|
|
printf(argc) int argc;
|
|
{return(_print(stdout,CCARGC()+&argc-1));
|
|
}
|
|
|
|
/*
|
|
** _print(fd, ctlstring, arg, arg, ...)
|
|
** Called by fprintf() and printf().
|
|
*/
|
|
_print(fd,nxtarg) int fd,*nxtarg;
|
|
{int arg,left,pad,cc,len,maxchr,width;
|
|
char *ctl,*sptr,str[17];
|
|
|
|
cc=0;
|
|
ctl=*nxtarg--;
|
|
while(*ctl)
|
|
{if(*ctl!='%') {OS_fputc(*ctl++,fd); ++cc; continue;}
|
|
else ++ctl;
|
|
if(*ctl=='%') {OS_fputc(*ctl++,fd); ++cc; continue;}
|
|
if(*ctl=='-') {left=1; ++ctl;} else left=0;
|
|
if(*ctl=='0') pad='0';
|
|
else pad=' ';
|
|
if(isdigit(*ctl))
|
|
{width=atoi(ctl++);
|
|
while(isdigit(*ctl)) ++ctl;
|
|
}else width=0;
|
|
if(*ctl=='.')
|
|
{maxchr=atoi(++ctl);
|
|
while(isdigit(*ctl)) ++ctl;
|
|
}else maxchr=0;
|
|
arg=*nxtarg--;
|
|
sptr=str;
|
|
switch(*ctl++)
|
|
{case 'c': str[0]=arg; str[1]=NULL; break;
|
|
case 's': sptr=arg; break;
|
|
case 'd': itoa(arg,str); break;
|
|
case 'b': itoab(arg,str,2); break;
|
|
case 'o': itoab(arg,str,8); break;
|
|
case 'u': itoab(arg,str,10); break;
|
|
case 'x': itoab(arg,str,16); break;
|
|
default: return (cc);
|
|
}
|
|
len=strlen(sptr);
|
|
if(maxchr && maxchr<len) len=maxchr;
|
|
if(width>len) width=width-len; else width=0;
|
|
if(!left) while(width--) {OS_fputc(pad,fd); ++cc;}
|
|
while(len--) {OS_fputc(*sptr++,fd); ++cc;}
|
|
if(left) while(width--) {OS_fputc(pad,fd); ++cc;}
|
|
}
|
|
return (cc);
|
|
}
|
|
|
|
/*
|
|
** Write a string to fd.
|
|
** Entry: string = Pointer to null-terminated string.
|
|
** fd = File descriptor of pertinent file.
|
|
*/
|
|
fputs(string,fd) char *string; int fd;
|
|
{while(*string)
|
|
OS_fputc(*string++,fd);
|
|
}
|
|
|
|
/*
|
|
** All character classification functions except isascii().
|
|
** Integer argument (c) must be in ASCII range (0-127) for
|
|
** dependable answers.
|
|
*/
|
|
|
|
#define ALNUM 1
|
|
#define ALPHA 2
|
|
#define CNTRL 4
|
|
#define DIGIT 8
|
|
#define GRAPH 16
|
|
#define LOWER 32
|
|
#define PRINT 64
|
|
#define PUNCT 128
|
|
#define BLANK 256
|
|
#define UPPER 512
|
|
#define XDIGIT 1024
|
|
|
|
int _is[128] =
|
|
{0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004,
|
|
0x004, 0x104, 0x104, 0x104, 0x104, 0x104, 0x004, 0x004,
|
|
0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004,
|
|
0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004,
|
|
0x140, 0x0D0, 0x0D0, 0x0D0, 0x0D0, 0x0D0, 0x0D0, 0x0D0,
|
|
0x0D0, 0x0D0, 0x0D0, 0x0D0, 0x0D0, 0x0D0, 0x0D0, 0x0D0,
|
|
0x459, 0x459, 0x459, 0x459, 0x459, 0x459, 0x459, 0x459,
|
|
0x459, 0x459, 0x0D0, 0x0D0, 0x0D0, 0x0D0, 0x0D0, 0x0D0,
|
|
0x0D0, 0x653, 0x653, 0x653, 0x653, 0x653, 0x653, 0x253,
|
|
0x253, 0x253, 0x253, 0x253, 0x253, 0x253, 0x253, 0x253,
|
|
0x253, 0x253, 0x253, 0x253, 0x253, 0x253, 0x253, 0x253,
|
|
0x253, 0x253, 0x253, 0x0D0, 0x0D0, 0x0D0, 0x0D0, 0x0D0,
|
|
0x0D0, 0x473, 0x473, 0x473, 0x473, 0x473, 0x473, 0x073,
|
|
0x073, 0x073, 0x073, 0x073, 0x073, 0x073, 0x073, 0x073,
|
|
0x073, 0x073, 0x073, 0x073, 0x073, 0x073, 0x073, 0x073,
|
|
0x073, 0x073, 0x073, 0x0D0, 0x0D0, 0x0D0, 0x0D0, 0x004
|
|
};
|
|
|
|
isalnum (c) int c; {return (_is[c] & ALNUM );} /* 'a'-'z', 'A'-'Z', '0'-'9' */
|
|
isalpha (c) int c; {return (_is[c] & ALPHA );} /* 'a'-'z', 'A'-'Z' */
|
|
iscntrl (c) int c; {return (_is[c] & CNTRL );} /* 0-31, 127 */
|
|
isdigit (c) int c; {return (_is[c] & DIGIT );} /* '0'-'9' */
|
|
isgraph (c) int c; {return (_is[c] & GRAPH );} /* '!'-'~' */
|
|
islower (c) int c; {return (_is[c] & LOWER );} /* 'a'-'z' */
|
|
isprint (c) int c; {return (_is[c] & PRINT );} /* ' '-'~' */
|
|
ispunct (c) int c; {return (_is[c] & PUNCT );} /* !alnum && !cntrl && !space */
|
|
isspace (c) int c; {return (_is[c] & BLANK );} /* HT, LF, VT, FF, CR, ' ' */
|
|
isupper (c) int c; {return (_is[c] & UPPER );} /* 'A'-'Z' */
|
|
isxdigit(c) int c; {return (_is[c] & XDIGIT);} /* '0'-'9', 'a'-'f', 'A'-'F' */
|
|
|
|
/*
|
|
** itoa(n,s) - Convert n to characters in s
|
|
*/
|
|
itoa(n,s) char *s; int n;
|
|
{int sign;
|
|
char *ptr;
|
|
|
|
ptr=s;
|
|
if((sign=n)<0) n=-n;
|
|
do
|
|
{*ptr++ =n%10+'0';
|
|
}while((n=n/10)>0);
|
|
if(sign<0) *ptr++='-';
|
|
*ptr='\0';
|
|
reverse(s);
|
|
}
|
|
|
|
/*
|
|
** itoab(n,s,b) - Convert "unsigned" n to characters in s using base b.
|
|
** NOTE: This is a non-standard function.
|
|
*/
|
|
itoab(n,s,b) int n; char *s; int b;
|
|
{char *ptr;
|
|
int lowbit;
|
|
ptr=s;
|
|
b >>= 1;
|
|
do
|
|
{lowbit=n&1;
|
|
n=(n>>1)&32767;
|
|
*ptr=((n%b)<<1)+lowbit;
|
|
if(*ptr<10) *ptr+='0';
|
|
else *ptr+=55;
|
|
++ptr;
|
|
}while(n/=b);
|
|
*ptr=0;
|
|
reverse(s);
|
|
}
|
|
|
|
/*
|
|
** itod -- convert nbr to signed decimal string of width sz
|
|
** right adjusted, blank filled; returns str
|
|
**
|
|
** if sz > 0 terminate with null byte
|
|
** if sz = 0 find end of string
|
|
** if sz < 0 use last byte for data
|
|
*/
|
|
itod(nbr,str,sz) int nbr; char str[]; int sz;
|
|
{char sgn;
|
|
|
|
if(nbr<0) {nbr=-nbr; sgn='-';}
|
|
else sgn=' ';
|
|
if(sz>0) str[--sz]=NULL;
|
|
else if(sz<0) sz=-sz;
|
|
else while(str[sz]!=NULL) ++sz;
|
|
while(sz)
|
|
{str[--sz]=(nbr%10+'0');
|
|
if((nbr=nbr/10)==0) break;
|
|
}
|
|
if(sz) str[--sz]=sgn;
|
|
while(sz>0) str[--sz]=' ';
|
|
return str;
|
|
}
|
|
|
|
/*
|
|
** itoo -- converts nbr to octal string of length sz
|
|
** right adjusted and blank filled, returns str
|
|
**
|
|
** if sz > 0 terminate with null byte
|
|
** if sz = 0 find end of string
|
|
** if sz < 0 use last byte for data
|
|
*/
|
|
itoo(nbr,str,sz) int nbr; char str[]; int sz;
|
|
{int digit;
|
|
|
|
if(sz>0) str[--sz]=0;
|
|
else if(sz<0) sz=-sz;
|
|
else while(str[sz]!=0) ++sz;
|
|
while(sz)
|
|
{digit=nbr&7;nbr=(nbr>>3)&8191;
|
|
str[--sz]=digit+48;
|
|
if(nbr==0) break;
|
|
}
|
|
while(sz) str[--sz]=' ';
|
|
return str;
|
|
}
|
|
|
|
/*
|
|
** itou -- convert nbr to unsigned decimal string of width sz
|
|
** right adjusted, blank filled; returns str
|
|
**
|
|
** if sz > 0 terminate with null byte
|
|
** if sz = 0 find end of string
|
|
** if sz < 0 use last byte for data
|
|
*/
|
|
itou(nbr,str,sz) int nbr; char str[]; int sz;
|
|
{int lowbit;
|
|
|
|
if(sz>0) str[--sz]=NULL;
|
|
else if(sz<0) sz=-sz;
|
|
else while(str[sz]!=NULL) ++sz;
|
|
while(sz)
|
|
{lowbit=nbr&1;
|
|
nbr=(nbr>>1)&32767; /* divide by 2 */
|
|
str[--sz]=((nbr%5)<<1)+lowbit+'0';
|
|
if((nbr=nbr/5)==0) break;
|
|
}
|
|
while(sz) str[--sz]=' ';
|
|
return str;
|
|
}
|
|
|
|
/*
|
|
** itox -- converts nbr to hex string of length sz
|
|
** right adjusted and blank filled, returns str
|
|
**
|
|
** if sz > 0 terminate with null byte
|
|
** if sz = 0 find end of string
|
|
** if sz < 0 use last byte for data
|
|
*/
|
|
|
|
itox(nbr,str,sz) int nbr; char str[]; int sz;
|
|
{int digit,offset;
|
|
|
|
if(sz>0) str[--sz]=0;
|
|
else if(sz<0) sz=-sz;
|
|
else while(str[sz]!=0) ++sz;
|
|
while(sz)
|
|
{digit=nbr&15;
|
|
nbr=nbr/16;
|
|
/*
|
|
nbr=(nbr>>4)&4095; // 268435455; // 0xFFFFFFF
|
|
*/
|
|
if(digit<10) offset=48;
|
|
else offset=55;
|
|
str[--sz]=digit+offset;
|
|
if(nbr==0) break;
|
|
}
|
|
while(sz) str[--sz]=' ';
|
|
return str;
|
|
}
|
|
|