Files
TempleOS-Rijn/LT/Compiler/SPrintF2.CPZ
T
2018-09-08 21:45:20 +02:00

1010 lines
25 KiB
Plaintext

void OutChar(I1 **addr_dst,I1 ch,I1 **addr_buf)
{
I8 i;
I1 *dst=*addr_dst,*buf;
if (addr_buf) {
buf=*addr_buf;
i=dst-buf;
if (i>=MSize(buf)) {
buf=MAlloc(i<<1+1);
MemCpy(buf,*addr_buf,i);
dst=buf+i;
*addr_buf=buf;
}
}
*dst++=ch;
*addr_dst=dst;
}
void OutStr(I1 *ptr,I1 **addr_buf,I1 *addr_dst,
I8 len,BoolU4 left_justify,BoolU4 truncate)
{
I8 i,j;
if (!ptr)
i=0;
else
i=StrLen(ptr);
if (truncate && i>len)
i=len;
if (left_justify) {
for (j=0;j<i;j++)
OutChar(addr_dst,*ptr++,addr_buf);
for (j=0;j<len-i;j++)
OutChar(addr_dst,CH_SPACE,addr_buf);
} else {
for (j=0;j<len-i;j++)
OutChar(addr_dst,CH_SPACE,addr_buf);
for (j=len-i;j<len;j++)
OutChar(addr_dst,*ptr++,addr_buf);
}
}
SysHashEntry *FindPSect(U8 *add,I8 *offset)
{
SysHashEntry *result=NULL,*temph;
SysHashTable *h=Fs->hash_table;
ClassStruct *tempc;
U8 i,best=0x8000,j;
if (!CheckPtr(add)) {
*offset=best;
return NULL;
}
while (h) {
for (i=0;i<=h->mask;i++) {
temph=h->body[i];
while (temph) {
if (temph->type&HTT_FUNCTION) {
tempc=temph;
j=tempc->executable_address;
} else
j=temph->user_data0;
j=add-j;
if (temph->type&(HTT_SYS_SYMBOL|HTT_FUNCTION)) {
if (j<best) {
best=j;
result=temph;
}
}
temph=temph->next;
}
}
h=h->next;
}
*offset=best;
return result;
}
void SPrintFPSect(I1 *buf,U8 add,U8 field_length)
{
U8 offset;
SysHashEntry *temph;
if (temph=FindPSect(add,&offset)) {
if (offset<=0xFFFF) {
if (field_length>5)
SPrintF(buf,"%*ts,%04X",field_length-5,temph->str,offset);
else
SPrintF(buf,"%s,%04X",temph->str,offset);
}
return;
}
if (field_length)
SPrintF(buf,"%*tX",field_length,add);
else
SPrintF(buf,"%X",add);
}
I1 *MSPrintFTime(LTDate ltdt,U8 sub_format)
{
LTDateStruct d;
switch (sub_format) {
case 1:
ToLTDateStruct(&d,ltdt+local_time_offset);
return MSPrintF("%02d:%02d",d.hours,d.minutes);
case 2:
ToLTDateStruct(&d,ltdt+local_time_offset);
if (d.hours>=12)
return MSPrintF("%02d:%02d:%02d pm",d.hours-12,d.minutes,d.seconds);
else
return MSPrintF("%02d:%02d:%02d am",d.hours,d.minutes,d.seconds);
case 3:
ToLTDateStruct(&d,ltdt+local_time_offset);
if (d.hours>=12)
return MSPrintF("%02d:%02d pm",d.hours-12,d.minutes);
else
return MSPrintF("%02d:%02d am",d.hours,d.minutes);
case 4:
ToLTDateStruct(&d,ltdt+local_time_offset);
if (d.hours>=12)
return MSPrintF("%02d:%02d:%02dp",d.hours-12,d.minutes,d.seconds);
else
return MSPrintF("%02d:%02d:%02da",d.hours,d.minutes,d.seconds);
case 5:
ToLTDateStruct(&d,ltdt+local_time_offset);
if (d.hours>=12)
return MSPrintF("%02d:%02dp",d.hours-12,d.minutes);
else
return MSPrintF("%02d:%02da",d.hours,d.minutes);
case 6:
ToLTDateStruct(&d,ltdt);
return MSPrintF("%dh %02dm",d.hours+ltdt.date*24,d.minutes);
case 7:
ToLTDateStruct(&d,ltdt);
return MSPrintF("%dh %02dm %02ds",d.hours+ltdt.date*24,d.minutes,d.seconds);
case 8:
ToLTDateStruct(&d,ltdt);
return MSPrintF("%dd %02dh %02dm",ltdt.date,d.hours,d.minutes);
case 9:
ToLTDateStruct(&d,ltdt);
return MSPrintF("%dd %02dh %02dm %02ds",ltdt.date,d.hours,d.minutes,d.seconds);
case 10:
ToLTDateStruct(&d,ltdt);
return MSPrintF("%dd %02dh %02dm %02d.%02ds",ltdt.date,d.hours,d.minutes,d.seconds,d.hundredths);
case 11:
ToLTDateStruct(&d,ltdt);
return MSPrintF("%dh %02dm %02d.%02ds",d.hours+ltdt.date*24,d.minutes,d.seconds,d.hundredths);
case 12:
ToLTDateStruct(&d,ltdt);
return MSPrintF("%d.%02d",60*((ltdt.date*24+d.hours)*60+d.minutes)+d.seconds,d.hundredths);
case 13:
ToLTDateStruct(&d,ltdt);
return MSPrintF("%02d:%02d.%02d",60*(ltdt.date*24+d.hours)+d.minutes,d.seconds,d.hundredths);
case 14:
ToLTDateStruct(&d,ltdt);
return MSPrintF("%02d:%02d:%02d.%02d",ltdt.date*24+d.hours,d.minutes,d.seconds,d.hundredths);
case 15:
ToLTDateStruct(&d,ltdt);
return MSPrintF("%dd %02dh %02dm %02d.%04ds",ltdt.date,d.hours,d.minutes,d.seconds,d.ten_thousandths);
case 16:
ToLTDateStruct(&d,ltdt);
return MSPrintF("%dh %02dm %02d.%04ds",d.hours+ltdt.date*24,d.minutes,d.seconds,d.ten_thousandths);
case 17:
ToLTDateStruct(&d,ltdt);
return MSPrintF("%d.%04d",60*((ltdt.date*24+d.hours)*60+d.minutes)+d.seconds,d.ten_thousandths);
case 18:
ToLTDateStruct(&d,ltdt);
return MSPrintF("%02d:%02d.%04d",60*(ltdt.date*24+d.hours)+d.minutes,d.seconds,d.ten_thousandths);
case 19:
ToLTDateStruct(&d,ltdt);
return MSPrintF("%02d:%02d:%02d.%04d",ltdt.date*24+d.hours,d.minutes,d.seconds,d.ten_thousandths);
default:
ToLTDateStruct(&d,ltdt+local_time_offset);
return MSPrintF("%02d:%02d:%02d",d.hours,d.minutes,d.seconds);
}
}
I1 *MSPrintFDate(LTDate dt,U8 sub_format)
{
LTDateStruct d;
ToLTDateStruct(&d,dt+local_time_offset);
switch (sub_format) {
case 1:
return MSPrintF("%02d/%02d",d.month,d.day_of_month);
case 2:
return MSPrintF("%3tZ %02d/%02d",d.day_of_week,"ST_DAYS_OF_WEEK",
d.month,d.day_of_month);
case 3:
return MSPrintF("%3tZ %02d/%02d/%02d",d.day_of_week,"ST_DAYS_OF_WEEK",
d.month,d.day_of_month,(d.year)%100);
case 4:
return MSPrintF("%02d/%02d/%d",d.month,d.day_of_month,d.year);
case 5:
return MSPrintF("%3tZ %02d/%02d/%d",d.day_of_week,"ST_DAYS_OF_WEEK",
d.month,d.day_of_month,d.year);
case 6:
return MSPrintF("%3tZ %02d",d.month-1,"ST_MONTHS",d.day_of_month);
case 7:
return MSPrintF("%3tZ, %3tZ %02d",d.day_of_week,"ST_DAYS_OF_WEEK",
d.month-1,"ST_MONTHS",d.day_of_month);
case 8:
return MSPrintF("%3tZ %02d,%04d",d.month-1,"ST_MONTHS",d.day_of_month,d.year);
case 9:
return MSPrintF("%3tZ, %3tZ %02d,%d",d.day_of_week,"ST_DAYS_OF_WEEK",
d.month-1,"ST_MONTHS",d.day_of_month,d.year);
case 10:
return MSPrintF("%Z %d",d.month-1,"ST_MONTHS",d.day_of_month);
case 11:
return MSPrintF("%Z, %Z %d",d.day_of_week,"ST_DAYS_OF_WEEK",
d.month-1,"ST_MONTHS",d.day_of_month);
case 12:
return MSPrintF("%Z %d,%d",d.month-1,"ST_MONTHS",d.day_of_month,d.year);
case 13:
return MSPrintF("%Z, %Z %d,%d",d.day_of_week,"ST_DAYS_OF_WEEK",
d.month-1,"ST_MONTHS",d.day_of_month,d.year);
case 14:
return MSPrintF("%02d/%02d/%02d",d.day_of_month,d.month,(d.year)%100);
case 15:
return MSPrintF("%02d/%02d",d.day_of_month,d.month);
case 16:
return MSPrintF("%3tZ %02d/%02d",d.day_of_week,"ST_DAYS_OF_WEEK",
d.day_of_month,d.month);
case 17:
return MSPrintF("%3tZ %02d/%02d/%02d",d.day_of_week,"ST_DAYS_OF_WEEK",
d.day_of_month,d.month,(d.year)%100);
case 18:
return MSPrintF("%02d/%02d/%d",d.day_of_month,d.month,d.year);
case 19:
return MSPrintF("%3tZ %02d/%02d/%d",d.day_of_week,"ST_DAYS_OF_WEEK",
d.day_of_month,d.month,d.year);
case 20:
return MSPrintF("%02d %3tZ",d.day_of_month,d.month-1,"ST_MONTHS");
case 21:
return MSPrintF("%3tZ, %02d %3tZ",d.day_of_week,"ST_DAYS_OF_WEEK",
d.day_of_month,d.month-1,"ST_MONTHS");
case 22:
return MSPrintF("%02d %3tZ,%04d",d.day_of_month,d.month-1,"ST_MONTHS",d.year);
case 23:
return MSPrintF("%3tZ, %02d %3tZ,%d",d.day_of_week,"ST_DAYS_OF_WEEK",
d.day_of_month,d.month-1,"ST_MONTHS",d.year);
case 24:
return MSPrintF("%d %Z",d.day_of_month,d.month-1,"ST_MONTHS");
case 25:
return MSPrintF("%Z, %d %Z",d.day_of_week,"ST_DAYS_OF_WEEK",
d.day_of_month,d.month-1,"ST_MONTHS");
case 26:
return MSPrintF("%d %Z,%d",d.day_of_month,d.month-1,"ST_MONTHS",d.year);
case 27:
return MSPrintF("%Z, %d %Z,%d",d.day_of_week,"ST_DAYS_OF_WEEK",
d.day_of_month,d.month-1,"ST_MONTHS",d.year);
case 28:
return MSPrintF("%02d/%02d/%02d",(d.year)%100,d.month,d.day_of_month);
case 29:
return MSPrintF("%d/%02d/%02d",d.year,d.month,d.day_of_month);
case 30:
return MSPrintF("%02d%02d%02d",(d.year)%100,d.month,d.day_of_month);
case 31:
return MSPrintF("%d%02d%02d",d.year,d.month,d.day_of_month);
case 32:
return MSPrintF("%02d%02d%02d",d.month,d.day_of_month,(d.year)%100);
case 33:
return MSPrintF("%02d%02d%d",d.month,d.day_of_month,d.year);
case 34:
return MSPrintF("%3tZ",d.day_of_week,"ST_DAYS_OF_WEEK");
case 35:
return MSPrintF("%Z",d.day_of_week,"ST_DAYS_OF_WEEK");
case 36:
return MSPrintF("%3tZ",d.month-1,"ST_MONTHS");
case 37:
return MSPrintF("%Z",d.month-1,"ST_MONTHS");
case 38:
return MSPrintF("%d %3tZ",d.year,d.month-1,"ST_MONTHS");
case 39:
return MSPrintF("%d %Z",d.year,d.month-1,"ST_MONTHS");
case 40:
return MSPrintF("%02d %3tZ",(d.year)%100,d.month-1,"ST_MONTHS");
case 41:
return MSPrintF("%02d %Z",(d.year)%100,d.month-1,"ST_MONTHS");
case 42:
return MSPrintF("%3tZ %d",d.month-1,"ST_MONTHS",d.year);
case 43:
return MSPrintF("%Z %d",d.month-1,"ST_MONTHS",d.year);
case 44:
return MSPrintF("%3tZ %02d",d.month-1,"ST_MONTHS",(d.year)%100);
case 45:
return MSPrintF("%Z %02d",d.month-1,"ST_MONTHS",(d.year)%100);
case 46:
return MSPrintF("%02d",(d.year)%100);
case 47:
return MSPrintF("%d",d.year);
default:
return MSPrintF("%02d/%02d/%02d",d.month,d.day_of_month,(d.year)%100);
}
}
#define TEMP_BUF_LEN 256
I1 *SPrintFJoin2(I1 *dst,I1 *src,I8 argc,I8 *argv)
{
I1 *ptr,**addr_buf,*buf,*addr_dst,
*temp1;
BoolU4 pad_zero,left_justify,truncate,neg,neg_e;
I8 i,ch,ch1,k,len,dec_len,sub_format;
U8 d,cur_param=0;
double dd,dd1;
I1 temp_buf[TEMP_BUF_LEN];
if (!src)
throw(EXCEPT_SPRINTF,0);
if (dst) {
addr_buf=NULL;
buf=dst;
} else {
buf=MAlloc(128);
addr_buf=&buf;
dst=buf;
}
addr_dst=&dst;
while (ch = *(src++)) {
if (ch=='%') {
if (*src=='-') {
left_justify=TRUE;
src++;
} else
left_justify=FALSE;
if (*src=='0') {
pad_zero=TRUE;
src++;
} else
pad_zero=FALSE;
len=0;
while (*src>='0' && *src<='9')
len=len*10+ *(src++)-'0';
if (*src=='*') {
src++;
if (cur_param>=argc)
throw(EXCEPT_SPRINTF,1);
len=argv[cur_param++];
}
dec_len=0;
if (*src=='.') {
src++;
while (*src>='0' && *src<='9')
dec_len=dec_len*10+ *(src++)-'0';
if (*src=='*') {
src++;
if (cur_param>=argc)
throw(EXCEPT_SPRINTF,1);
dec_len=argv[cur_param++];
}
}
if (*src=='t') {
src++;
truncate=TRUE;
} else
truncate=FALSE;
sub_format=0;
if (*src=='h') {
src++;
while (*src>='0' && *src<='9')
sub_format=sub_format*10+ *(src++)-'0';
if (*src=='*') {
src++;
if (cur_param>=argc)
throw(EXCEPT_SPRINTF,1);
sub_format=argv[cur_param++];
}
}
neg=FALSE;
k=0;
switch (*src++) {
case 's':
if (cur_param>=argc)
throw(EXCEPT_SPRINTF,1);
ptr=argv[cur_param++];
OutStr(ptr,addr_buf,addr_dst,len,left_justify,truncate);
break;
case 'S':
if (cur_param>=argc)
throw(EXCEPT_SPRINTF,1);
ptr=SysText(argv[cur_param++]);
OutStr(ptr,addr_buf,addr_dst,len,left_justify,truncate);
break;
case 'F':
if (cur_param>=argc)
throw(EXCEPT_SPRINTF,1);
ptr=ReadTextFile(argv[cur_param++]);
OutStr(ptr,addr_buf,addr_dst,len,left_justify,truncate);
Free(ptr);
break;
case 'Q':
if (cur_param>=argc)
throw(EXCEPT_SPRINTF,1);
if (ptr=argv[cur_param++])
while (ch=*ptr++) {
if (ch=='$$') {
OutChar(addr_dst,ch,addr_buf);
OutChar(addr_dst,ch,addr_buf);
} else if (ch==CH_LINE_FEED){
OutChar(addr_dst,'\\',addr_buf);
OutChar(addr_dst,'n',addr_buf);
} else if (ch==CH_CR){
OutChar(addr_dst,'\\',addr_buf);
OutChar(addr_dst,'r',addr_buf);
} else if (ch==CH_TAB){
OutChar(addr_dst,'\\',addr_buf);
OutChar(addr_dst,'t',addr_buf);
} else {
if (ch=='"' || ch=='\\')
OutChar(addr_dst,'\\',addr_buf);
if (ch>=CH_SHIFT_SPACE && ch<=0x7F)
OutChar(addr_dst,ch,addr_buf);
else {
OutChar(addr_dst,'\\',addr_buf);
OutChar(addr_dst,ch>>6&7+'0',addr_buf);
OutChar(addr_dst,ch>>3&7+'0',addr_buf);
OutChar(addr_dst,ch&7+'0',addr_buf);
}
}
}
break;
case 'q':
if (cur_param>=argc)
throw(EXCEPT_SPRINTF,1);
if (ptr=argv[cur_param++])
while (ch=*ptr++) {
ch1=*ptr;
if (ch=='\\') {
if (ch1=='n') {
OutChar(addr_dst,CH_LINE_FEED,addr_buf);
ptr++;
} else if (ch1=='r') {
OutChar(addr_dst,CH_CR,addr_buf);
ptr++;
} else if (ch1=='"') {
OutChar(addr_dst,'"',addr_buf);
ptr++;
} else if (ch1==0x27) { // "\'"
OutChar(addr_dst,0x27,addr_buf);
ptr++;
} else if (ch1=='\`') {
OutChar(addr_dst,'\`',addr_buf);
ptr++;
} else if (ch1=='\\') {
OutChar(addr_dst,'\\',addr_buf);
ptr++;
} else if (ch1=='t') {
OutChar(addr_dst,CH_TAB,addr_buf);
ptr++;
} else if (ch1>='0' && ch1<='7') {
i=ch1-'0';
ptr++;
do {
ch1=*ptr++;
if (ch1>='0' && ch1<='7')
i=i<<3+ch1-'0';
} while (ch1>='0' && ch1<='7');
OutChar(addr_dst,i,addr_buf);
} else
OutChar(addr_dst,ch,addr_buf);
} else if (ch=='$$' && ch1=='$$') {
OutChar(addr_dst,ch,addr_buf);
ptr++;
} else
OutChar(addr_dst,ch,addr_buf);
}
break;
case 'z':
if (cur_param+1>=argc)
throw(EXCEPT_SPRINTF,1);
ptr=PointAtListEntry(argv[cur_param],argv[cur_param+1]);
cur_param=cur_param+2;
OutStr(ptr,addr_buf,addr_dst,len,left_justify,truncate);
break;
case 'Z':
if (cur_param+1>=argc)
throw(EXCEPT_SPRINTF,1);
ptr=SysTextSub(argv[cur_param],argv[cur_param+1]);
cur_param=cur_param+2;
OutStr(ptr,addr_buf,addr_dst,len,left_justify,truncate);
break;
case 'c':
if (cur_param>=argc)
throw(EXCEPT_SPRINTF,1);
OutChar(addr_dst,argv[cur_param++],addr_buf);
break;
case 'C':
if (cur_param>=argc)
throw(EXCEPT_SPRINTF,1);
OutChar(addr_dst,ToUpper(argv[cur_param++]),addr_buf);
break;
case 'D':
if (cur_param>=argc)
throw(EXCEPT_SPRINTF,1);
temp1=MSPrintFDate(argv[cur_param++],sub_format);
OutStr(temp1,addr_buf,addr_dst,len,left_justify,truncate);
Free(temp1);
break;
case 'T':
if (cur_param>=argc)
throw(EXCEPT_SPRINTF,1);
temp1=MSPrintFTime(argv[cur_param++],sub_format);
OutStr(temp1,addr_buf,addr_dst,len,left_justify,truncate);
Free(temp1);
break;
case 'P':
if (cur_param>=argc)
throw(EXCEPT_SPRINTF,1);
if (truncate)
SPrintFPSect(temp_buf,argv[cur_param++],len);
else
SPrintFPSect(temp_buf,argv[cur_param++],0);
OutStr(temp_buf,addr_buf,addr_dst,len,left_justify,truncate);
break;
case 'd':
if (cur_param>=argc)
throw(EXCEPT_SPRINTF,1);
i=argv[cur_param++];
if (i<0) {
neg=TRUE;
i=-i;
}
while ((!k || i) && k<TEMP_BUF_LEN-16) {
temp_buf[k++]=i%10+'0';
i/=10;
}
out_num:
if (neg)
i=1;
else
i=0;
if (len>0) {
if (truncate && k+i>len)
k=len-i;
} else
len=0;
if (k<0)
k=0;
if (pad_zero)
for (;i<len-k;i++)
OutChar(addr_dst,'0',addr_buf);
else
for (;i<len-k;i++)
OutChar(addr_dst,32,addr_buf);
if (neg)
OutChar(addr_dst,'-',addr_buf);
for (i=k-1;i>=0;i--)
OutChar(addr_dst,temp_buf[i],addr_buf);
break;
case 'u':
if (cur_param>=argc)
throw(EXCEPT_SPRINTF,1);
d=argv[cur_param++];
while ((!k|| d) && k<TEMP_BUF_LEN-16) {
temp_buf[k++]=d%10+'0';
d/=10;
}
goto out_num;
case 'f':
if (cur_param>=argc)
throw(EXCEPT_SPRINTF,1);
dd=argv[cur_param++]><(double);
if (dd<0) {
neg=TRUE;
dd=-dd;
}
out_f:
if (i=dec_len)
dd*=Pow10(i);
dd=Round(dd);
while (i-- && k<TEMP_BUF_LEN-16) {
temp_buf[k++]=dd%10+'0';
dd=Floor(dd/10);
}
if (dec_len)
temp_buf[k++]='.';
do {
temp_buf[k++]=dd%10+'0';
dd=Floor(dd/10);
} while (dd && k<TEMP_BUF_LEN-16);
goto out_num;
case 'e':
if (!len) len=12;
if (cur_param>=argc)
throw(EXCEPT_SPRINTF,1);
dd=argv[cur_param++]><(double);
if (dd<0) {
neg=TRUE;
dd=-dd;
}
if (dd)
dd1=Floor(Log10(dd));
else
dd1=0;
out_e:
dd/=Pow10(dd1);
if (dd1<0) {
dd1=-dd1;
neg_e=TRUE;
} else
neg_e=FALSE;
if (dd) {
if (dd<1.0) {
dd*=10;
if (neg_e)
dd1+=1;
else
dd1-=1;
} else if (dd>=10.0) {
dd/=10;
if (neg_e)
dd1-=1;
else
dd1+=1;
}
}
i=3;
do {
temp_buf[k++]=dd1%10+'0';
dd1=Floor(dd1/10);
} while (dd1 && i--);
if (neg_e)
temp_buf[k++]='-';
temp_buf[k++]='e';
dec_len=len-k-neg-2;
goto out_f;
case 'g':
if (!len) len=12;
if (cur_param>=argc)
throw(EXCEPT_SPRINTF,1);
dd=argv[cur_param++]><(double);
if (dd<0) {
neg=TRUE;
dd=-dd;
}
if (dd)
dd1=Floor(Log10(dd));
else
dd1=0;
if (dd1>=(len-1-dec_len) || dd1<-(dec_len-1))
goto out_e;
else
goto out_f;
case 'n':
if (!len) len=12;
if (cur_param>=argc)
throw(EXCEPT_SPRINTF,1);
dd=argv[cur_param++]><(double);
if (dd<0) {
neg=TRUE;
dd=-dd;
}
if (dd)
dd1=3.0*Floor(Log10(dd)/3);
else
dd1=0;
out_n:
dd/=Pow10(dd1);
if (dd1<0) {
dd1=-dd1;
neg_e=TRUE;
} else
neg_e=FALSE;
if (dd) {
if (dd<1.0) {
dd*=1000;
if (neg_e)
dd1+=3;
else
dd1-=3;
} else if (dd>=1000.0) {
dd/=1000;
if (neg_e)
dd1-=3;
else
dd1+=3;
}
}
i=3;
do {
temp_buf[k++]=dd1%10+'0';
dd1=Floor(dd1/10);
} while (dd1 && i--);
if (neg_e)
temp_buf[k++]='-';
temp_buf[k++]='e';
dec_len=len-k-neg-2;
goto out_f;
case 'X':
if (cur_param>=argc)
throw(EXCEPT_SPRINTF,1);
d=argv[cur_param++];
while ((!k || d) && k<TEMP_BUF_LEN-16) {
temp_buf[k]=(d & 15)+'0';
if (temp_buf[k]>'9') temp_buf[k]+='A'-0x3A;
k++;
d>>=4;
}
goto out_num;
case 'x':
if (cur_param>=argc)
throw(EXCEPT_SPRINTF,1);
d=argv[cur_param++];
while ((!k || d) && k<TEMP_BUF_LEN-16) {
temp_buf[k]=(d & 15)+'0';
if (temp_buf[k]>'9') temp_buf[k]+='a'-0x3A;
k++;
d>>=4;
}
goto out_num;
case 'b':
if (cur_param>=argc)
throw(EXCEPT_SPRINTF,1);
d=argv[cur_param++];
while ((!k || d) && k<TEMP_BUF_LEN-16) {
temp_buf[k++]=(d&1)+'0';
d>>=1;
}
goto out_num;
case '%':
OutChar(addr_dst,'%',addr_buf);
break;
}
} else
OutChar(addr_dst,ch,addr_buf);
}
OutChar(addr_dst,0,addr_buf);
return buf;
}
double A2Double(I1 *src,I1 **end_ptr=NULL)
//ASCII string to double
{
I1 ch=*src++;
I8 i=0,j=0,k=0;
double d;
BoolU4 neg=FALSE;
while (ch==CH_SPACE||ch==CH_TAB||ch==CH_SHIFT_SPACE)
ch=*src++;
if (ch=='-') {
neg=TRUE;
ch=*src++;
}
while (TRUE) {
if (Bt(dec_numeric_bitmap,ch))
i=i*10+ch-'0';
else {
if (ch=='.' || ch=='e' || ch=='E') break;
d=i;
goto a2d_end;
}
ch=*src++;
}
if (ch=='.')
ch=*src++;
while (TRUE) {
if (Bt(dec_numeric_bitmap,ch)) {
j=j*10+ch-'0';
k++;
} else {
d=i+j*Pow10(-k);
if (ch=='e' || ch=='E') break;
goto a2d_end;
}
ch=*src++;
}
ch=*src++;
k=1;
if (ch=='-') {
k=-1;
ch=*src++;
}
j=0;
while (TRUE) {
if (Bt(dec_numeric_bitmap,ch))
j=j*10+ch-'0';
else {
d*=Pow10(j*k);
goto a2d_end;
}
ch=*src++;
}
a2d_end:
if (end_ptr) *end_ptr=src-1;
return (neg) ? -d:d;
}
/*
$FG,2$A2LTDate()
This routine recognizes the following formats:
1) "$FG,4$*+nnnn$FG,2$" "$FG,4$*-nnnnn$FG,2$"
2) $FG,4$mm/dd$FG,2$
3) $FG,4$mm/dd/yy$FG,2$
It also supports some functions
$FG,4$SM()$FG,2$ start of month
$FG,4$EM()$FG,2$ end of month
$FG,4$SM()$FG,2$ start of year
$FG,4$EY()$FG,2$ end of year
Full expressions are not implimented
but you can do stuff like $FG,4$SM(*-7)+3$FG,2$
and it will return the 3rd day after
the start of month for seven days before
today.
$FG$*/
LTDate A2LTDate(I1 *src2)
//ASCII date to LTDate
{
LTDate result=0;
LTDateStruct d,d1;
I1 *src=MStrUtil(src2,SU_REMOVE_SPACES|SU_TO_UPPER),
*v=NewStr(src),
*p1=src;
BoolU4 start_month=FALSE,end_month=FALSE;
BoolU4 start_year=FALSE,end_year=FALSE;
MemSet(&d,0,sizeof(LTDateStruct));
MemSet(&d1,0,sizeof(LTDateStruct));
if (!StrNCmp(p1,"SM(",3)) {
p1+=3;
start_month=TRUE;
} else if (!StrNCmp(p1,"EM(",3)) {
p1+=3;
end_month=TRUE;
} else if (!StrNCmp(p1,"SY(",3)) {
p1+=3;
start_year=TRUE;
} else if (!StrNCmp(p1,"EY(",3)) {
p1+=3;
end_year=TRUE;
}
if (*p1=='*') {
p1++;
if (*p1=='+' || *p1=='-')
result.date=AtoI(p1,10,&p1);
result+=GetCurTimeLTDate+local_time_offset;
} else {
RemoveFirstSeg(p1,"/",v); //Put month into v
d.month=AtoI(v);
if (Occurrences(p1,'/')) {
RemoveFirstSeg(p1,"/",v); //Put day into v leaving year in p1
d.day_of_month=AtoI(v);
d.year=AtoI(p1,10,&p1);
if (d.year<100) //if not 4 digit year
d.year+=2000;
} else {
d.day_of_month=AtoI(p1,10,&p1);
ToLTDateStruct(&d1,GetCurTimeLTDate+local_time_offset);
d.year=d1.year;
}
result=ToLTDate(&d);
}
if (*p1==')') p1++;
if (start_month)
result.date=FirstDayOfMonth(result.date);
else if (end_month)
result.date=LastDayOfMonth(result.date);
else if (start_year)
result.date=FirstDayOfYear(result.date);
else if (end_year)
result.date=LastDayOfYear(result.date);
if (*p1=='+' || *p1=='-')
result.date+=AtoI(p1);
Free(src);
Free(v);
return result-local_time_offset;
}
void GetFJoin2(I1 *src,I1 *fmt,I8i argc,I8i *argv)
//Pass pointer to data,
//For %s pass pointer to pointer (be careful because address
// of array is the same as array--create ptr to array and take address
{
I1 ch,*buf,*ptr,**pptr;
BoolU4 left_justify=FALSE;
I8 cur_param=0,i,j,k,len,*i_ptr,sub_format=0,dec_len;
double *d_ptr;
if (!fmt)
throw(EXCEPT_GETF,0);
while (ch = *(fmt++)) {
if (ch=='%') {
if (*fmt=='%') {
src++;
fmt++;
} else {
if (*fmt=='-') {
left_justify=TRUE;
fmt++;
} else
left_justify=FALSE;
len=0;
while (*fmt>='0' && *fmt<='9')
len=len*10+ (*(fmt++)-'0');
if (*fmt=='*') {
fmt++;
if (cur_param>=argc)
throw(EXCEPT_GETF,1);
len=argv[cur_param++];
}
ch=*(fmt++);
if (ch && !len) {
ptr=src;
while (*ptr && *ptr!=*fmt)
ptr++;
len=ptr-src;
} else {
if (ch=='.') {
dec_len=0;
while (*fmt>='0' && *fmt<='9')
dec_len=dec_len*10+ (*(fmt++)-'0');
if (*fmt=='*') {
fmt++;
if (cur_param>=argc)
throw(EXCEPT_GETF,1);
dec_len=argv[cur_param++];
}
ch=*(fmt++);
}
}
buf=MAlloc(len+1);
for (i=0;i<len;i++)
buf[i]=*(src++);
buf[i]=0;
switch (ch) {
case 's':
if (cur_param>=argc)
throw(EXCEPT_GETF,1);
pptr=argv[cur_param++];
StrCpy(*pptr,buf);
break;
case 'c':
if (cur_param>=argc)
throw(EXCEPT_GETF,1);
ptr=argv[cur_param++];
*ptr=*buf;
break;
case 'C':
if (cur_param>=argc)
throw(EXCEPT_GETF,1);
ptr=argv[cur_param++];
*ptr=ToUpper(*buf);
break;
case 'z':
if (cur_param+1>=argc)
throw(EXCEPT_GETF,1);
i_ptr=argv[cur_param++];
*i_ptr=MatchListEntry(buf,argv[cur_param++]);
break;
case 'Z':
if (cur_param+1>=argc)
throw(EXCEPT_GETF,1);
i_ptr=argv[cur_param++];
*i_ptr=MatchSysTextEntry(buf,argv[cur_param++]);
break;
case 'd':
if (cur_param>=argc)
throw(EXCEPT_GETF,1);
i_ptr=argv[cur_param++];
*i_ptr=0;
for (k=0;k<len;k++)
if (buf[k]!=32)
*i_ptr=(*i_ptr)*10+(buf[k]-'0');
break;
case 'X':
if (cur_param>=argc)
throw(EXCEPT_GETF,1);
i_ptr=argv[cur_param++];
*i_ptr=0;
for (k=0;k<len;k++)
if (buf[k]!=32) {
j=ToUpper(buf[k])-'0';
if (j>9) j=j-'A'+('9'+1);
*i_ptr=(*i_ptr<<4)+j;
}
break;
case 'b':
if (cur_param>=argc)
throw(EXCEPT_GETF,1);
i_ptr=argv[cur_param++];
*i_ptr=0;
for (k=0;k<len;k++)
if (buf[k]!=32)
*i_ptr=*i_ptr<<1+(buf[k]-'0');
break;
case 'e':
case 'f':
case 'g':
case 'n':
if (cur_param>=argc)
throw(EXCEPT_GETF,1);
d_ptr=argv[cur_param++];
*d_ptr=A2Double(buf);
break;
case 'D':
if (cur_param>=argc)
throw(EXCEPT_GETF,1);
i_ptr=argv[cur_param++];
*i_ptr=A2LTDate(buf);
break;
}
Free(buf);
}
} else
src++;
}
}