|
|
Copyright © 1985,2006 Helmut O.B. Schellong
#if defined(F_catstr) && !defined(DF_catstr) && !defined(catstr)
# define DF_catstr
fSTATIC int catstr(BYTE *S0, const BYTE *S1, ...)
{
BYTE *s;
if (s=S0, s) {
if (!S1) while (*s) ++s;
else { const BYTE *sa=S1; va_list a;
va_start(a,S1);
do while (!!(*s=*sa)) ++s,++sa;
while (sa=va_arg(a,BYTE*), sa);
va_end(a);
}
}
return (int)(s-S0);
}
#endif
Verkettet Strings ab S1, Zielpuffer ist S0.
#if defined(F_catstrn) && !defined(DF_catstrn) && !defined(catstrn)
# define DF_catstrn
#if defined(BSH_H) && !defined(catstrnEXIT)
# define catstrnEXIT() bsh_Err(E_LIMIT, "Ziel-Puffer");
#endif
#if !defined(catstrnEXIT)
# define catstrnEXIT() write(2, "*** LIMIT: Ziel-Puffer ***\r\n", 28), exit(64);
#endif
fSTATIC int catstrn(int n, BYTE *S0, const BYTE *S1, ...)
{
BYTE *s;
if (s=S0, s&&n>0) { const BYTE *sa; va_list a;
va_start(a,S1);
for (sa=S1; sa; ++n,sa=va_arg(a,BYTE*)) {
while (n-- >0 && !!(*s=*sa)) ++s,++sa;
if (n<0) {
va_end(a);
catstrnEXIT();
return n;
}
}
va_end(a);
}
return (int)(s-S0);
}
#endif
Fast wie catstr(). Mit zusätzlicher Prüfung der Zielpuffergröße.
#if defined(F_printi) && !defined(DF_printi) && !defined(printi)
# define DF_printi
# include <stdarg.h>
fSTATIC int printi(const BYTE *F, ...)
{
BYTE buf[4*1024];
va_list ap;
int r, fd;
if (!F) return -1;
va_start(ap,F);
if (F[0]=='%'&&F[1]=='H') {
F+=2; fd=va_arg(ap,int);
if (fd<0) { va_end(ap); return -1; }
}
else fd=1;
r= sprinti(buf, "\004%B%F%V", sizeof(buf), F, ap);
va_end(ap);
if (r>0) write(fd, buf, r);
return r;
}
#endif
Ähnelt printf(). Verarbeitet nur Integer.
#if defined(F_sprinti) && !defined(DF_sprinti) && !defined(sprinti)
# define DF_sprinti
#if defined(BSH_H) && !defined(sprintiEXIT)
# define sprintiEXIT() bsh_Err(E_LIMIT, "Ziel-Puffer");
#endif
#if !defined(sprintiEXIT)
# define sprintiEXIT() write(2, "*** LIMIT: Ziel-Puffer ***\r\n", 28), exit(64);
#endif
# include <stdarg.h>
# define LINKS 1
# define VPLUS 2
# define VLEER 4
# define V0X 8
# define VNULL 16
# define GLEIT 32
# define LCUT 64
# define ISWI 512
# define ISPR 1024
# define LENH 2048
# define LENL 4096
# define LENLL 0x4000
# define NOINT 0x2000
# define CENTR 0x8000u
# define NEGAT 128
# define XUPP 256
fSTATIC int sprinti(BYTE *buf, const BYTE *f, ...)
{
BYTE *b;
int blen=(1<<30)-1;
va_list ap, ap0;
if (!(b=buf)||!f) return -1;
va_start(ap,f); va_copy(ap0,ap);
if (f[0]==4&&f[1]=='%'&&f[2]=='B'&&f[3]=='%'&&f[4]=='F'&&f[5]=='%'&&f[6]=='V') {
blen= (int)va_arg(ap0,size_t);
f = va_arg(ap0,BYTE*);
ap = va_arg(ap0,va_list);
}
else if (f[0]=='%'&&f[1]=='B') f+=2, blen=(int)va_arg(ap,size_t);
va_end(ap0);
if (blen<=0||blen==1&&(*b=0,1)) { va_end(ap); return 0; }
while (*f) { BYTE ns[132], fs[4]; BYTE *s;
UNS flg, z; int l, w, p;
if (*f!='%' || f[1]=='%'&&(++f,1) || f[1]==0) {
if (blen<=1) va_end(ap), sprintiEXIT();
*b++= *f++; --blen; continue;
}
for (s=0,++f,w=p=0,flg=z=0; z<=4&&*f; ++z) {
switch (z) {
case 0:
NXTF:;
switch (*f) {
case '-': flg|= LINKS; break;
case '+': flg|= VPLUS; break;
case ' ': flg|= VLEER; break;
case '#': flg|= V0X; break;
case '0': flg|= VNULL; break;
case ',': flg|= GLEIT; break;
case '|': flg|= LCUT; break;
case ':': flg|= CENTR; break;
default : continue;
}
++f; goto NXTF;
case 1:
if (*f=='*') flg|=ISWI, ++f, w= va_arg(ap,int);
else if (DIGIT(*f)) { flg|=ISWI;
w= atoi_F(f);
while (DIGIT(*f)) ++f;
}
if (w<0) w=-w, flg|=LINKS;
if (*f!='.') { z=3-1; continue; }
break;
case 2:
if (DIGIT(*f)||*f=='*') { flg|=ISPR;
if (*f=='*') p= va_arg(ap,int), ++f;
else { p= atoi_F(f);
while (DIGIT(*f)) ++f; }
}
else continue;
z=3;
case 3:
if (*f=='h') { flg|=LENH; break; }
if (*f=='l') { flg|= f[1]=='l'?(++f,LENLL):LENL; break; }
continue;
case 4:
switch (s=ns,l=0, *f) { INT8 sv; UNS8 uv;
case 'i':
case 'd': if (flg&LENLL) sv= va_arg(ap,INT8);
else if (flg&LENL)
sv= va_arg(ap,INT4);
else if (flg&LENH)
sv= va_arg(ap,INT);
else sv= va_arg(ap,INT);
if (sv<0L) sv=-sv, flg|=NEGAT;
if (flg&LENLL) l=ulltoa_F(ns, sv);
else if (flg&LENL)
l= ultoa_F(ns, (UNS4)sv);
else if (flg&LENH)
l= utoa_F(ns, (UNS)sv);
else l= utoa_F(ns, (UNS)sv);
break;
case 'u':
if (flg&LENLL) l=ulltoa_F(ns, va_arg(ap,UNS8));
else if (flg&LENL)
l= ultoa_F(ns, va_arg(ap,UNS4));
else if (flg&LENH)
l= utoa_F(ns, va_arg(ap,UNS));
else l= utoa_F(ns, va_arg(ap,UNS));
break;
case 'x':
case 'X':
case 'b': if (flg&LENLL) uv= va_arg(ap,UNS8);
else if (flg&LENL)
uv= va_arg(ap,UNS4);
else if (flg&LENH)
uv= va_arg(ap,UNS);
else uv= va_arg(ap,UNS);
if (*f=='b') l= ulltob_F(ns, uv);
else l= ulltoh_F(ns, uv);
if (*f=='X') toupp_F(ns), flg|=XUPP;
break;
case 'n': *( va_arg(ap,int*) )= (int)(b-buf);
flg|=NOINT; s=0;
break;
case 's': s= va_arg(ap,BYTE*);
if (!s) s="(null)";
while (s[l]) ++l;
flg|=NOINT;
break;
case 'c': ns[0]= (BYTE)va_arg(ap,int);
flg|=NOINT; l=1;
break;
default : z=0; goto FERR;
}
break;
default: continue;
}
++f;
}
/*for-z*/
FERR:;
if (s&&z==5) { int lfs, l0, wfill, sp,spv;
BYTE *f0;
spv=sp=wfill=l0=lfs=0;
if (!(flg&NEGAT)) {
if (flg& VPLUS) fs[0]='+', lfs=1;
if (flg& VLEER) fs[0]=' ', lfs=1;
}
else fs[0]='-', ++lfs;
if (flg& V0X) fs[lfs++]='0', fs[lfs++]= flg&XUPP?'X':'x';
if ((flg&(GLEIT|NOINT|ISPR))==(GLEIT|ISPR)) {
if (f0=s,z=p, p>l) z=l, sp=p-l;
for (s+=l ; z; --s,--z) s[sp]= s[-1];
for (*s='.',z=sp; z; --z) s[z ]= '0';
if (p=l+=sp+1, s==f0) ++p;
s=f0; sp=0;
}
if (!(flg&NOINT)) { if (flg&ISPR&&p>l) l0=p-l; }
else { if (flg&ISPR&&l>p) l =p ; }
if ((flg&(LCUT|ISWI))==(LCUT|ISWI) && lfs+l0+l>w) {
if (l0 =w-(lfs+l ), l0 <0) l0 =0;
if (lfs=w-(l +l0), lfs<0) lfs=0;
if (l =w-(lfs+l0), l <0) l =0;
}
if (flg&ISWI) wfill= w - (lfs+l0+l);
if (wfill>0) {
if (flg&VNULL) l0+=wfill;
else if (flg&CENTR) spv=wfill>>1, sp=wfill-spv;
else if (flg&LINKS) sp =wfill;
else spv=wfill;
}
blen-= spv+lfs+l0+l+sp;
if (blen<1) va_end(ap), sprintiEXIT();
while (spv>0) *b++=' ', --spv;
for (z=0; lfs>0; --lfs) *b++= fs[z++];
while (l0 >0) *b++='0', --l0;
while (l >0) *b++= *s++, --l;
while (sp >0) *b++=' ', --sp;
}
}
va_end(ap);
*b=0;
return b-buf;
}
#undef LINKS
#undef VPLUS
#undef VLEER
#undef V0X
#undef VNULL
#undef GLEIT
#undef LCUT
#undef ISWI
#undef ISPR
#undef LENH
#undef LENL
#undef LENLL
#undef NOINT
#undef CENTR
#undef NEGAT
#undef XUPP
#undef DIGIT
#undef LOWER
#endif