kolibrios/programs/develop/scc/Libstd.c

441 lines
10 KiB
C
Raw Permalink Normal View History

#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;
}