Files
TempleOS-Rijn/Kernel/StrPrint.CPP
T
2018-09-08 21:46:09 +02:00

979 lines
19 KiB
C++

#define SPF_PAD_ZERO 0x001
#define SPF_LEFT_JUSTIFY 0x002
#define SPF_TRUNCATE 0x004
#define SPF_COMMA 0x008
#define SPF_DOLLAR 0x010
#define SPF_SLASH 0x020
#define SPF_QUESTION 0x040
#define SPF_AUX_FMT_NUM 0x080
#define SPF_DECIMAL 0x100
#define SPF_NEG 0x200
#define SPF_NEG_E 0x400
#define SPF_NEG_AUX_FMT_NUM 0x800
U0 SPutChar(U8 **_dst,U8 ch,U8 **_buf)
{
I64 i;
U8 *dst=*_dst,*buf;
if (_buf) {
buf=*_buf;
i=dst-buf;
if (i>=MSize(buf)) {
buf=MAlloc(i<<1+1);
MemCpy(buf,*_buf,i);
dst=buf+i;
*_buf=buf;
}
}
*dst++=ch;
*_dst=dst;
}
U0 OutStr(U8 *ptr,U8 **_buf,U8 **_dst,I64 len,I64 flags)
{
I64 i,j;
if (!ptr)
i=0;
else
i=StrLen(ptr);
if (flags&SPF_TRUNCATE && i>len)
i=len;
if (flags&SPF_LEFT_JUSTIFY) {
for (j=0;j<i;j++)
SPutChar(_dst,*ptr++,_buf);
for (j=0;j<len-i;j++)
SPutChar(_dst,CH_SPACE,_buf);
} else {
for (j=0;j<len-i;j++)
SPutChar(_dst,CH_SPACE,_buf);
for (j=len-i;j<len;j++)
SPutChar(_dst,*ptr++,_buf);
}
}
U8 *MPrintTime(CDate cdt)
{
CDateStruct ds;
Date2Struct(&ds,cdt+local_time_offset);
return MStrPrint("%02d:%02d:%02d",ds.hour,ds.min,ds.sec);
}
U8 *MPrintDate(CDate cdt)
{
CDateStruct ds;
Date2Struct(&ds,cdt+local_time_offset);
return MStrPrint("%02d/%02d/%02d",ds.mon,ds.day_of_mon,ds.year%100);
}
U8 *MPrintQ(U8 *ptr,I64 flags)
{
U8 **_buf,*buf,**_dst,*dst;
I64 ch;
buf=MAlloc(128);
_buf=&buf;
dst=buf;
_dst=&dst;
if (ptr)
while (ch=*ptr++) {
switch (ch) {
case '$$':
if (flags&SPF_DOLLAR) {
SPutChar(_dst,'\\',_buf);
SPutChar(_dst,'$$'>>6&7+'0',_buf);
SPutChar(_dst,'$$'>>3&7+'0',_buf);
SPutChar(_dst,'$$'&7+'0',_buf);
} else {
SPutChar(_dst,ch,_buf);
SPutChar(_dst,ch,_buf);
}
break;
case '%':
SPutChar(_dst,ch,_buf);
if (flags&SPF_SLASH)
SPutChar(_dst,ch,_buf);
break;
case '\n':
SPutChar(_dst,'\\',_buf);
SPutChar(_dst,'n',_buf);
break;
case '\r':
SPutChar(_dst,'\\',_buf);
SPutChar(_dst,'r',_buf);
break;
case '\t':
SPutChar(_dst,'\\',_buf);
SPutChar(_dst,'t',_buf);
break;
case '"':
case '\\':
SPutChar(_dst,'\\',_buf);
SPutChar(_dst,ch,_buf);
break;
default:
if (CH_SHIFT_SPACE<=ch<=0x7F) {
SPutChar(_dst,ch,_buf);
} else {
SPutChar(_dst,'\\',_buf);
SPutChar(_dst,ch>>6&7+'0',_buf);
SPutChar(_dst,ch>>3&7+'0',_buf);
SPutChar(_dst,ch&7+'0',_buf);
}
}
}
SPutChar(_dst,0,_buf);
return buf;
}
U8 *MPrintq(U8 *ptr,I64 flags)
{
U8 **_buf,*buf,**_dst,*dst;
I64 i,ch,ch1;
buf=MAlloc(128);
_buf=&buf;
dst=buf;
_dst=&dst;
if (ptr)
while (ch=*ptr++) {
ch1=*ptr;
switch (ch) {
case '\\':
switch (ch1) {
sub_switch_start:
case 'n':
SPutChar(_dst,'\n',_buf);
break;
case 'r':
SPutChar(_dst,'\r',_buf);
break;
case '"':
SPutChar(_dst,'"',_buf);
break;
case '\'':
SPutChar(_dst,'\'',_buf);
break;
case '\`':
SPutChar(_dst,'\`',_buf);
break;
case '\\':
SPutChar(_dst,'\\',_buf);
break;
case 't':
SPutChar(_dst,'\t',_buf);
break;
sub_switch_end:
ptr++;
break;
sub_switch_start:
case 'x':
case 'X':
i=0;
ptr++;
while (TRUE) {
ch1=ToUpper(*ptr++);
if (Bt(chars_bitmap_hex_numeric,ch1)) {
if (ch1<='9')
i=i<<4+ch1-'0';
else
i=i<<4+ch1-'A'+10;
} else
break;
}
break;
case 'b':
case 'B':
i=0;
ptr++;
while (TRUE) {
ch1=*ptr++;
if ('0'<=ch1<='1')
i=i<<1+ch1-'0';
else
break;
}
break;
case 'o':
case 'O':
i=0;
ptr++;
goto sq_octal;
case '0'...'7':
i=ch1-'0';
ptr++;
sq_octal:
while (TRUE) {
ch1=*ptr++;
if ('0'<=ch1<='7')
i=i<<3+ch1-'0';
else
break;
}
break;
sub_switch_end:
SPutChar(_dst,i,_buf);
ptr--;
break;
default:
SPutChar(_dst,ch,_buf);
}
break;
case '$$':
SPutChar(_dst,ch,_buf);
if (ch1=='$$')
ptr++;
break;
case '%':
SPutChar(_dst,ch,_buf);
if (flags&SPF_SLASH && ch1=='%')
ptr++;
break;
default:
SPutChar(_dst,ch,_buf);
}
}
SPutChar(_dst,0,_buf);
return buf;
}
U8 *sys_pos_powers_lets=" KMGTPEZY",
*sys_neg_powers_lets=" mænpfazy",
*sys_pos_powers_lst="kilo\0mega\0giga\0tera\0peta\0exa\0zetta\0yotta\0",
*sys_neg_powers_lst="milli\0micro\0nano\0pico\0femto\0atto\0zepto\0yocto\0";
#define TEMP_BUF_LEN 256
#define SLOP 8
U8 *StrPrintJoin(U8 *dst,U8 *src,I64 argc,I64 *argv)
{/*$LK,"Print(\"\") Fmt Strings",A="FI:::/Doc/Print.TXT"$
In float formatting, do not exceed 18-digits
before or after the decimal point
because the numbers before and after
the decimal point are stored
in 64-bits. Use exponentiated forms
to avoid this.
*/
I64 i,j,l,ch,k,k0,n,n0,len,dec_len,flags,
aux_fmt_num,comma_cnt,comma_fmt_cnt,cur_arg=0;
U64 m;
F64 d,d1;
U8 *ptr,**_buf,*buf,**_dst,temp_buf[TEMP_BUF_LEN],temp_buf2[TEMP_BUF_LEN*2];
if (!src)
throw('StrPrint');
if (dst) {
_buf=NULL;
buf=dst;
} else {
buf=MAlloc(128);
_buf=&buf;
dst=buf;
}
_dst=&dst;
while (ch = *src++) {
if (ch=='%') {
flags=0;
if (*src=='-') {
flags|=SPF_LEFT_JUSTIFY;
src++;
}
if (*src=='0') {
flags|=SPF_PAD_ZERO;
src++;
}
len=0;
while ('0'<=*src<='9')
len=len*10+ *src++ -'0';
if (*src=='*') {
src++;
if (cur_arg>=argc)
throw('StrPrint');
len=argv[cur_arg++];
}
dec_len=0;
if (*src=='.') {
src++;
while ('0'<=*src<='9')
dec_len=dec_len*10+ *src++ -'0';
if (*src=='*') {
src++;
if (cur_arg>=argc)
throw('StrPrint');
dec_len=argv[cur_arg++];
}
flags|=SPF_DECIMAL;
}
aux_fmt_num=0;
while (TRUE) {
switch (*src) {
sub_switch_start:
case '$$':
flags|=SPF_DOLLAR;
break;
case '/':
flags|=SPF_SLASH;
break;
case ',':
flags|=SPF_COMMA;
break;
case 't':
flags|=SPF_TRUNCATE;
break;
case 'l': //harmless
break;
sub_switch_end:
src++;
break;
case 'h':
src++;
flags|=SPF_AUX_FMT_NUM;
if (*src=='?') {
src++;
flags|=SPF_QUESTION;
} else {
if (*src=='*') {
src++;
if (cur_arg>=argc)
throw('StrPrint');
aux_fmt_num=argv[cur_arg++];
} else {
if (*src=='-') {
src++;
flags|=SPF_NEG_AUX_FMT_NUM;
}
while ('0'<=*src<='9')
aux_fmt_num=aux_fmt_num*10+ *src++ -'0';
if (flags&SPF_NEG_AUX_FMT_NUM)
aux_fmt_num=-aux_fmt_num;
}
}
break;
default:
goto sp_arg;
}
}
sp_arg:
k=0;
switch (*src++) {
sub_switch_start:
case 'F':
if (cur_arg>=argc)
throw('StrPrint');
ptr=FileRead(argv[cur_arg++]);
break;
case 'Q':
if (cur_arg>=argc)
throw('StrPrint');
ptr=MPrintQ(argv[cur_arg++],flags);
break;
case 'q':
if (cur_arg>=argc)
throw('StrPrint');
ptr=MPrintq(argv[cur_arg++],flags);
break;
case 'D':
if (cur_arg>=argc)
throw('StrPrint');
ptr=MPrintDate(argv[cur_arg++]);
break;
case 'T':
if (cur_arg>=argc)
throw('StrPrint');
ptr=MPrintTime(argv[cur_arg++]);
break;
sub_switch_end:
OutStr(ptr,_buf,_dst,len,flags);
Free(ptr);
break;
sub_switch_start:
case 's':
if (cur_arg>=argc)
throw('StrPrint');
ptr=argv[cur_arg++];
break;
case 'S':
if (cur_arg>=argc)
throw('StrPrint');
ptr=Define(argv[cur_arg++]);
break;
case 'z':
if (cur_arg+1>=argc)
throw('StrPrint');
ptr=LstSub(argv[cur_arg],argv[cur_arg+1]);
cur_arg=cur_arg+2;
break;
case 'Z':
if (cur_arg+1>=argc)
throw('StrPrint');
ptr=DefineSub(argv[cur_arg],argv[cur_arg+1]);
cur_arg=cur_arg+2;
break;
sub_switch_end:
OutStr(ptr,_buf,_dst,len,flags);
break;
sub_switch_start:
case 'c':
if (cur_arg>=argc)
throw('StrPrint');
temp_buf[0](I64)=argv[cur_arg++];
temp_buf[8]=0;
break;
case 'C':
if (cur_arg>=argc)
throw('StrPrint');
temp_buf[0](I64)=argv[cur_arg++];
temp_buf[8]=0;
ptr=temp_buf;
while (*ptr) {
*ptr=ToUpper(*ptr);
ptr++;
}
break;
sub_switch_end:
if (!(flags&SPF_AUX_FMT_NUM))
aux_fmt_num=1;
while (aux_fmt_num-->0)
OutStr(temp_buf,_buf,_dst,len,flags);
break;
case 'p':
if (cur_arg>=argc)
throw('StrPrint');
if (flags&SPF_TRUNCATE)
StrPrintPSect(temp_buf,argv[cur_arg++],len);
else
StrPrintPSect(temp_buf,argv[cur_arg++],0);
OutStr(temp_buf,_buf,_dst,len,flags);
break;
case 'P':
if (cur_arg>=argc)
throw('StrPrint');
if (flags&SPF_TRUNCATE)
StrPrintPSect(temp_buf,argv[cur_arg],len);
else
StrPrintPSect(temp_buf,argv[cur_arg],0);
if (!IsRaw || !_buf) {
StrPrint(temp_buf2,"$$LK,\"%s\",A=\"AD:0x%X\"$$",temp_buf,argv[cur_arg]);
OutStr(temp_buf2,_buf,_dst,len,flags);
} else
OutStr(temp_buf,_buf,_dst,len,flags);
cur_arg++;
break;
case 'd':
if (cur_arg>=argc)
throw('StrPrint');
m=argv[cur_arg++];
if (m(I64)<0) {
flags|=SPF_NEG;
m=-m;
}
sp_out_dec:
if (flags&SPF_AUX_FMT_NUM) {
if (!len) len=12;
d=m;
goto sp_out_eng;
}
if (flags&SPF_COMMA) {
comma_fmt_cnt=comma_cnt=3;
do {
temp_buf[k++]=ModU64(&m,10)+'0';
if (!m) break;
if (!--comma_cnt) {
temp_buf[k++]=',';
comma_cnt=3;
}
} while (k<TEMP_BUF_LEN-SLOP);
sp_out_comma_num:
if (flags&SPF_NEG)
i=1;
else
i=0;
if (len<0)
len=0;
if (flags&SPF_TRUNCATE && k+i>len)
k=len-i;
if (k<0)
k=0;
if (flags&SPF_PAD_ZERO) {
if (flags&SPF_NEG)
SPutChar(_dst,'-',_buf);
comma_cnt=(len-k-i+comma_fmt_cnt-comma_cnt+1)%(comma_fmt_cnt+1)+1;
for (;i<len-k;i++) {
if (!--comma_cnt) {
SPutChar(_dst,',',_buf);
comma_cnt=comma_fmt_cnt;
if (++i>=len-k)
break;
}
SPutChar(_dst,'0',_buf);
}
} else {
for (;i<len-k;i++)
SPutChar(_dst,CH_SPACE,_buf);
if (flags&SPF_NEG)
SPutChar(_dst,'-',_buf);
}
} else {
do {
temp_buf[k++]=ModU64(&m,10)+'0';
if (!m) break;
} while (k<TEMP_BUF_LEN-SLOP);
sp_out_num:
if (flags&SPF_NEG)
i=1;
else
i=0;
if (len<0)
len=0;
if (flags&SPF_TRUNCATE && k+i>len)
k=len-i;
if (k<0)
k=0;
if (flags&SPF_PAD_ZERO) {
if (flags&SPF_NEG)
SPutChar(_dst,'-',_buf);
for (;i<len-k;i++)
SPutChar(_dst,'0',_buf);
} else {
for (;i<len-k;i++)
SPutChar(_dst,CH_SPACE,_buf);
if (flags&SPF_NEG)
SPutChar(_dst,'-',_buf);
}
}
for (i=k-1;i>=0;i--)
SPutChar(_dst,temp_buf[i],_buf);
break;
case 'u':
if (cur_arg>=argc)
throw('StrPrint');
m=argv[cur_arg++];
goto sp_out_dec;
case 'f':
if (cur_arg>=argc)
throw('StrPrint');
d=argv[cur_arg++](F64);
if (d<0) {
flags|=SPF_NEG;
d=-d;
}
if (d==ì) {
sp_out_inf:
if (flags&SPF_NEG)
i=1;
else
i=0;
k=1;
if (len<0)
len=0;
if (flags&SPF_TRUNCATE && k+i>len)
k=len-i;
if (k<0)
k=0;
for (;i<len-k;i++)
SPutChar(_dst,CH_SPACE,_buf);
if (flags&SPF_NEG)
SPutChar(_dst,'-',_buf);
for (i=0;i<k;i++)
SPutChar(_dst,'ì',_buf);
break;
}
sp_out_f:
if (dec_len<0)
dec_len=0;
n=Log10(d);
if (i=dec_len) {
if (flags&SPF_COMMA)
i=i-i/4;
if (n+i>17) {
n+=i-17;
d*=Pow10I64(i-n);
} else {
n=0;
d*=Pow10I64(i);
}
i=dec_len;
} else if (n>17) {
n-=17;
d*=Pow10I64(-n);
} else
n=0;
m=Round(d);
if (flags&SPF_COMMA) {
comma_cnt=i&3;
while (i-- && k<TEMP_BUF_LEN-SLOP) {
if (i>2 && !comma_cnt--) {
temp_buf[k++]=',';
comma_cnt=2;
if (!--i) break;
}
if (n) {
n--;
temp_buf[k++]='0';
} else
temp_buf[k++]=ModU64(&m,10)+'0';
if (!i) break;
}
} else {
while (i-- && k<TEMP_BUF_LEN-SLOP) {
if (n) {
n--;
temp_buf[k++]='0';
} else
temp_buf[k++]=ModU64(&m,10)+'0';
}
}
if (dec_len)
temp_buf[k++]='.';
if (flags&SPF_COMMA) {
comma_cnt=3;
do {
if (n) {
n--;
temp_buf[k++]='0';
} else
temp_buf[k++]=ModU64(&m,10)+'0';
if (!m) break;
if (!--comma_cnt) {
temp_buf[k++]=',';
comma_cnt=3;
}
} while (k<TEMP_BUF_LEN-SLOP);
} else {
do {
if (n) {
n--;
temp_buf[k++]='0';
} else
temp_buf[k++]=ModU64(&m,10)+'0';
if (!m) break;
} while (k<TEMP_BUF_LEN-SLOP);
}
goto sp_out_num;
case 'e':
if (!len) len=12;
flags|=SPF_TRUNCATE;
if (cur_arg>=argc)
throw('StrPrint');
d=argv[cur_arg++](F64);
if (d<0) {
flags|=SPF_NEG;
d=-d;
}
if (d==ì) goto sp_out_inf;
if (d)
n=Floor(Log10(d));
else
n=0;
sp_out_e:
d/=Pow10I64(n);
k0=k;
for (l=0;l<2;l++) {
n0=n;
if (n<0) {
n=-n;
flags|=SPF_NEG_E;
} else
flags&=~SPF_NEG_E;
i=3;
do temp_buf[k++]=ModU64(&n,10)+'0';
while (n && i--);
if (flags&SPF_NEG_E)
temp_buf[k++]='-';
temp_buf[k++]='e';
dec_len=len-k-2;
if (flags&SPF_NEG)
dec_len--;
if (d) {
d1=d+Pow10I64(-dec_len)/2;
if (d1<1.0) {
d*=10;
n=n0-1;
k=k0;
} else if (d1>=10) {
d/=10;
n=n0+1;
k=k0;
} else
break;
} else
break;
}
goto sp_out_f;
case 'g':
if (!len) len=12;
flags|=SPF_TRUNCATE;
if (cur_arg>=argc)
throw('StrPrint');
d=argv[cur_arg++](F64);
if (d<0) {
flags|=SPF_NEG;
d=-d;
}
if (d==ì) goto sp_out_inf;
if (d)
n=Floor(Log10(d));
else
n=0;
if (n>=len-1-dec_len || n<-(dec_len-1))
goto sp_out_e;
else
goto sp_out_f;
case 'n':
if (!len) len=12;
flags|=SPF_TRUNCATE;
if (cur_arg>=argc)
throw('StrPrint');
d=argv[cur_arg++](F64);
if (d<0) {
flags|=SPF_NEG;
d=-d;
}
sp_out_eng: //Engineering notation
if (d==ì) goto sp_out_inf;
if (d)
n=FloorI64(Floor(Log10(d)),3);
else
n=0;
d/=Pow10I64(n);
if (n<0) {
n=-n;
flags|=SPF_NEG_E;
}
if (flags&SPF_AUX_FMT_NUM && -24<=n<=24) {
if (flags&SPF_QUESTION) {
if (flags&SPF_NEG_E)
i=-n/3;
else
i=n/3;
j=0;
} else {
if (flags&SPF_NEG_E)
j=-n-aux_fmt_num;
else
j=n-aux_fmt_num;
d*=Pow10I64(j);
i=aux_fmt_num/3;
}
if (i<0)
temp_buf[k++]=sys_neg_powers_lets[-i];
else if (i>0)
temp_buf[k++]=sys_pos_powers_lets[i];
else if (len!=0)
temp_buf[k++]=CH_SPACE;
if (!(flags&SPF_DECIMAL)) {
dec_len=len-k-2;
if (flags&SPF_NEG)
dec_len--;
if (j>0) {
if (flags&SPF_COMMA)
dec_len-=4*j/3;
else
dec_len-=j;
}
d1=d+Pow10I64(-dec_len+1)/2;
if (d1>=10) {
dec_len--;
if (d1>=100)
dec_len--;
}
}
} else {
i=3;
do temp_buf[k++]=ModU64(&n,10)+'0';
while (n && i--);
if (flags&SPF_NEG_E)
temp_buf[k++]='-';
temp_buf[k++]='e';
if (!dec_len) {
dec_len=len-k-2;
if (flags&SPF_NEG)
dec_len--;
d1=d+Pow10I64(-dec_len+1)/2;
if (d1>=10) {
dec_len--;
if (d1>=100)
dec_len--;
}
}
}
if (flags&SPF_COMMA) {
if (len && dec_len>0 && !(dec_len&3))
temp_buf[k++]=',';
dec_len-=dec_len/4;
}
goto sp_out_f;
case 'X':
if (cur_arg>=argc)
throw('StrPrint');
m=argv[cur_arg++];
if (flags&SPF_COMMA) {
comma_fmt_cnt=comma_cnt=4;
do {
temp_buf[k]= m&15 +'0';
if (temp_buf[k]>'9') temp_buf[k]+='A'-0x3A;
k++;
m>>=4;
if (!m) break;
if (!--comma_cnt) {
temp_buf[k++]=',';
comma_cnt=4;
}
} while (k<TEMP_BUF_LEN-SLOP);
goto sp_out_comma_num;
} else {
do {
temp_buf[k]= m&15 +'0';
if (temp_buf[k]>'9') temp_buf[k]+='A'-0x3A;
k++;
m>>=4;
} while (m && k<TEMP_BUF_LEN-SLOP);
goto sp_out_num;
}
case 'x':
if (cur_arg>=argc)
throw('StrPrint');
m=argv[cur_arg++];
if (flags&SPF_COMMA) {
comma_fmt_cnt=comma_cnt=4;
do {
temp_buf[k]= m&15 +'0';
if (temp_buf[k]>'9') temp_buf[k]+='a'-0x3A;
k++;
m>>=4;
if (!m) break;
if (!--comma_cnt) {
temp_buf[k++]=',';
comma_cnt=4;
}
} while (k<TEMP_BUF_LEN-SLOP);
goto sp_out_comma_num;
} else {
do {
temp_buf[k]= m&15 +'0';
if (temp_buf[k]>'9') temp_buf[k]+='a'-0x3A;
k++;
m>>=4;
} while (m && k<TEMP_BUF_LEN-SLOP);
goto sp_out_num;
}
case 'b':
case 'B':
if (cur_arg>=argc)
throw('StrPrint');
m=argv[cur_arg++];
if (flags&SPF_COMMA) {
comma_fmt_cnt=comma_cnt=4;
do {
temp_buf[k++]= m&1 +'0';
m>>=1;
if (!m) break;
if (!--comma_cnt) {
temp_buf[k++]=',';
comma_cnt=4;
}
} while (k<TEMP_BUF_LEN-SLOP);
goto sp_out_comma_num;
} else {
do {
temp_buf[k++]= m&1 +'0';
m>>=1;
} while (m && k<TEMP_BUF_LEN-SLOP);
goto sp_out_num;
}
case 'o':
case 'O':
if (cur_arg>=argc)
throw('StrPrint');
m=argv[cur_arg++];
if (flags&SPF_COMMA) {
comma_fmt_cnt=comma_cnt=3;
do {
temp_buf[k++]= m&7 +'0';
m>>=3;
if (!m) break;
if (!--comma_cnt) {
temp_buf[k++]=',';
comma_cnt=3;
}
} while (k<TEMP_BUF_LEN-SLOP);
goto sp_out_comma_num;
} else {
do {
temp_buf[k++]= m&7 +'0';
m>>=3;
} while (m && k<TEMP_BUF_LEN-SLOP);
goto sp_out_num;
}
case '%':
SPutChar(_dst,'%',_buf);
break;
}
} else
SPutChar(_dst,ch,_buf);
}
SPutChar(_dst,0,_buf);
return buf;
}
U8 *StrPrint(U8 *dst,U8 *fmt,...)
{//See $LK,"StrPrintJoin",A="MN:StrPrintJoin"$().
return StrPrintJoin(dst,fmt,argc,argv);
}
U8 *CatPrint(U8 *_dst,U8 *fmt,...)
{//StrCat(). See $LK,"StrPrintJoin",A="MN:StrPrintJoin"$().
U8 *dst=_dst;
while (*dst)
dst++;
StrPrintJoin(dst,fmt,argc,argv);
return _dst;
}
U0 Print(U8 *fmt,...)
{//$LK,"Print(\"\") Fmt Strings",A="FI:::/Doc/Print.TXT"$. See $LK,"StrPrintJoin",A="MN:StrPrintJoin"$().
U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
PutS(buf);
Free(buf);
}
U8 *MStrPrint(U8 *fmt,...)
{//MAlloc StrPrint. See $LK,"StrPrintJoin",A="MN:StrPrintJoin"$().
U8 *result,*buf=StrPrintJoin(NULL,fmt,argc,argv);
result=StrNew(buf);
Free(buf);
return result;
}
U0 PrintErr(U8 *fmt,...)
{//Print "Err:" and msg in blinking red.
U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
GetOutOfDollar;
ST_ERR_ST "%s",buf;
Free(buf);
}
U0 PrintWarn(U8 *fmt,...)
{//Print "Warn:" and msg in blinking red.
U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
GetOutOfDollar;
ST_WARN_ST "%s",buf;
Free(buf);
}