1,213 → 1,230 |
/* |
function for format output to the string |
|
Siemargl update formats as http://www.cplusplus.com/reference/cstdio/printf/, no wchar though |
http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap05.html is used too |
%g explain https://support.microsoft.com/en-us/kb/43392 |
|
todo: |
-%e |
-simplify justifying |
-fix %o, %x |
-fix precision in %g |
-%a |
-NAN, INF |
-%n nothing printed |
-%17.18f digits maximum format |
%C as w_char L'x' |
*/ |
|
#include <kolibrisys.h> |
|
//#include <kolibrisys.h> |
#include <string.h> |
#include <stdio.h> |
//#include <ctype.h> |
#include <ctype.h> |
#include <math.h> |
#include <stdarg.h> |
|
int formatted_double_to_string(long double number,int format1,int format2,char *s) |
enum flags_t |
{ |
double n; |
double nbefor; |
double nafter; |
double v,v2; |
long intdigit; |
long beforpointdigit; |
long div; |
flag_unsigned = 0x02, |
flag_register = 0x04, |
flag_plus = 0x08, |
flag_left_just = 0x10, |
flag_lead_zeros = 0x20, |
flag_space_plus = 0x40, |
flag_hash_sign = 0x80, |
flag_point = 0x100 |
}; |
|
int formatted_double_to_string_scientific(long double number, int format1, int format2, char *s, int flags) |
{ |
strcpy(s, "%e not implemented yet, sorry"); |
return strlen(s); |
} |
|
int formatted_double_to_string(long double number, int format1, int format2, char *s, int flags) |
{ |
long double nafter, beforpointdigit; |
long long intdigit, mul; |
int div; |
int i; |
int pos; |
int size; |
char* size; |
int fmt1; |
int fmt2; |
long mul; |
char buf[200]; |
char buf[100], *pbuf = buf; |
char buf_low[50], *pbuf_lo = buf_low; |
|
size=(int)s; |
n=(double)number; |
if (n<0) {*s='-';s++;n=-n;} |
if((flags & flag_point) == 0) format2 = 6; // default prec if no point spec |
|
fmt1=format1; |
size = s; |
if (number < 0) {*s++ = '-'; number = -number; } |
else |
{ |
if (flags & flag_plus) *s++ = '+'; else |
if (flags & flag_space_plus) *s++ = ' '; |
} |
|
fmt1 = 1; |
fmt2=format2; |
if (fmt2>18) {fmt2=18;} //maximum of size long long type |
if (fmt2 > 18) fmt2 = 18; //maximum size of long long type |
|
//clear array befor output |
for(i=0;i<=200;i++) {buf[i]=0;} |
beforpointdigit = floor(number + 0.00000000000001); |
nafter = number - beforpointdigit; |
|
if ((fmt1>=0) && (n<1)) |
{ //formatted output if 0<=n<1 |
//print part of number before point |
mul=1; |
for(i=0;i<fmt2;i++) |
{n=n*10;mul=mul*10;} |
|
n=n*10; |
n=ceil(n); |
intdigit=floor(n); |
//intdigit=n; |
intdigit=(intdigit/10); |
|
pos=0; |
mul=mul/10; |
for(i=0;i<fmt2-1;i++) |
for(i = 0; i < sizeof buf - 1; i++) |
{ |
div=intdigit/mul; |
buf[pos]=(char)div; |
pos++; |
intdigit=intdigit-div*mul; |
mul=mul/10; |
if (mul==1) break; |
mul *= 10; |
if ((beforpointdigit/mul) < 1.0) { fmt1 = i + 1; break; } |
} |
buf[pos]=(char)intdigit; |
*s='0';s++; |
*s='.';s++; |
for(i=0;i<format2;i++) |
if (i == sizeof buf - 1 || fmt1 > 17) |
{ |
if ((buf[i]>=0) && (buf[i]<=9)) {*s='0'+buf[i];} |
else {*s='0';} |
s++; |
strcpy(s, "[too big number for %f, %a]"); |
return strlen(s); |
} |
} |
else |
{ //if n>=1 |
//v=floorf(n+0.00000000000001); |
beforpointdigit=floor(n+0.00000000000001); |
//beforpointdigit=n; |
nbefor=beforpointdigit; |
nafter=n-nbefor; |
|
//print part of number befor point |
mul=1; |
for(i=0;i<200-2;i++) |
mul /= 10; |
while(mul > 1) |
{ |
mul=mul*10; |
if ((beforpointdigit/mul)==0) {fmt1=i+1;break;} |
} |
|
pos=0; |
mul=mul/10; |
for(i=0;i<fmt1-1;i++) |
{ |
div=beforpointdigit/mul; |
buf[pos]=(char)div; |
pos++; |
*pbuf++ = (char)div + '0'; |
beforpointdigit=beforpointdigit-div*mul; |
mul=mul/10; |
if (mul==1) break; |
mul /= 10; |
} |
buf[pos]=(char)beforpointdigit; |
*pbuf++=(char)beforpointdigit + '0'; |
|
for(i=0;i<fmt1;i++) |
{ |
if ((buf[i]>=0) && (buf[i]<=9)) {*s='0'+buf[i];} |
s++; |
} |
|
//print part of number after point |
mul=1; |
for(i=0;i<fmt2;i++) |
{nafter=nafter*10;mul=mul*10;} |
|
{ |
nafter=nafter*10; |
nafter=ceil(nafter); |
intdigit=floor(nafter); |
//intdigit=nafter; |
intdigit=intdigit/10; |
mul *= 10; |
} |
|
pos=0; |
mul=mul/10; |
intdigit = roundl(nafter); |
|
mul /= 10; |
for(i=0;i<fmt2-1;i++) |
{ |
div=intdigit/mul; |
buf[pos]=(char)div; |
pos++; |
*pbuf_lo++=(char)div + '0'; |
intdigit=intdigit-div*mul; |
mul=mul/10; |
mul /= 10; |
if (mul==1) break; |
} |
buf[pos]=(char)intdigit; |
*s='.';s++; |
for(i=0;i<format2;i++) |
*pbuf_lo++ = (char)intdigit + '0'; |
|
|
memcpy(s, buf, pbuf - buf); s += pbuf - buf; |
if (roundl(nafter) != 0 || fmt2 != 0) |
{ |
if ((buf[i]>=0) && (buf[i]<=9)) {*s='0'+buf[i];} |
else {*s='0';} |
s++; |
*s++ = '.'; |
memcpy(s, buf_low, pbuf_lo - buf_low); s += pbuf_lo - buf_low; |
} else if (flags & flag_hash_sign) |
*s++ = '.'; |
|
// right justifiyng and forward zeros |
div = (s - size); |
if ((flags & flag_left_just) == 0 && div < format1) |
{ |
pbuf = size; |
if ((flags & flag_lead_zeros) != 0) |
if (*pbuf == '+' || *pbuf == '-' || *pbuf == ' ') { pbuf++; div--; } // sign already at place |
for (i = 0; i < div; i++) |
size[format1 - i - 1] = pbuf[div - 1 - i]; |
for (i = 0; i < format1 - div - (pbuf - size); i++) |
if (flags & flag_lead_zeros) |
pbuf[i] = '0'; |
else |
pbuf[i] = ' '; |
|
return format1; |
} |
|
return s - size; |
} |
size=(int)s-size; |
return(size); |
} |
|
int formatted_long_to_string(long long number,int fmt1,char *s) |
int formatted_long_to_string(long long number, int format1, int prec, char *s, int flags) |
{ |
int i; |
int pos; |
int fmt; |
int size; |
int difference_pos; |
long digit; |
long mul; |
long div; |
char buf[200]; |
char* size = s; |
long long digit; |
long long mul; |
int div; |
char buf[100], *pbuf = buf; |
|
//clear array befor output |
for(i=0;i<200;i++) {buf[i]=0;} |
if (number == -9223372036854775807LL - 1) // overflow all our math, cant minus this |
{ |
strcpy(buf, "9223372036854775808"); |
pbuf += 19; |
*s++ = '-'; |
goto verybig; |
} |
|
if (flags & flag_point) flags &= ~flag_lead_zeros; // conflicting flags |
|
if (number < 0) {*s++ = '-'; number = -number; } |
else |
{ |
if (flags & flag_plus) *s++ = '+'; else |
if (flags & flag_space_plus) *s++ = ' '; |
} |
|
digit=number; |
|
size=(int)s; |
if (digit<0) {*s='-';s++;digit=-digit;} |
if (digit==0) {*s='0';s++;goto end;} |
mul = (digit < 0) ? -1 : 1; |
|
mul=1; |
for(i=0;i<200-2;i++) |
for(i = 0; i < sizeof buf - 2; i++) |
{ |
mul=mul*10; |
if ((digit/mul)==0) {fmt=i+1;break;} |
if (digit / mul < 10) { fmt = i + 1; break; } |
mul *= 10; |
} |
|
difference_pos=i+1; |
// add leading zeros |
for(i = 0; i < prec - fmt; i++) *pbuf++ = '0'; |
|
pos=0; |
mul=mul/10; |
for(i=0;i<fmt-1;i++) |
{ |
div=digit/mul; |
buf[pos]=(char)div; |
pos++; |
*pbuf++ = (char)div + '0'; |
digit=digit-div*mul; |
mul=mul/10; |
if (mul==1) break; |
mul /= 10; |
if (mul == 1 || mul == -1) break; |
} |
buf[pos]=(char)digit; |
*pbuf++ = (char)digit + '0'; |
|
if (fmt1>=difference_pos) fmt=fmt1; |
else |
fmt=difference_pos; |
verybig: |
memcpy(s, buf, pbuf - buf); s += pbuf - buf; |
|
for(i=0;i<fmt;i++) |
// right justifiyng and forward zeros |
div = (s - size); |
if ((flags & flag_left_just) == 0 && div < format1) |
{ |
if (i<difference_pos) |
{ |
if ((buf[i]>=0) && (buf[i]<=9)) {*s='0'+buf[i];} |
} |
pbuf = size; |
if ((flags & flag_lead_zeros) != 0) |
if (*pbuf == '+' || *pbuf == '-' || *pbuf == ' ') { pbuf++; div--; } // sign already at place |
for (i = 0; i < div; i++) |
size[format1 - i - 1] = pbuf[div - 1 - i]; |
for (i = 0; i < format1 - div - (pbuf - size); i++) |
if (flags & flag_lead_zeros) |
pbuf[i] = '0'; |
else |
{ |
*s=' '; |
pbuf[i] = ' '; |
|
return format1; |
} |
s++; |
|
return s - size; |
} |
end: |
size=(int)s-size; |
return(size); |
} |
|
int formatted_hex_to_string(long long number,int fmt1,char flag_register,char *s) |
int formatted_hex_to_string(long long number, int fmt1, char *s, int flags) |
{ |
long n; |
int i,pos; |
int fmt; |
// int fmt; |
long size; |
int difference_pos; |
char xdigs_lower[16]="0123456789abcdef"; |
262,11 → 279,11 |
return(size); |
} |
|
int formatted_octa_to_string(long long number,int fmt1,char flag_register,char *s) |
int formatted_octa_to_string(long long number, int fmt1, char *s, int flags) |
{ |
long n; |
int i,pos; |
int fmt; |
// int fmt; |
long size; |
int difference_pos; |
char xdigs_lower[16]="012345678"; |
311,28 → 328,24 |
return(size); |
} |
|
//int vsnprintf (char * s, size_t n, const char * format, va_list arg ); |
int format_print(char *dest, size_t maxlen,const char *fmt0, va_list argp) |
{ |
int i,j,k; |
int i; |
int length; |
int fmt1,fmt2,stepen; |
int fmt1, fmt2; // width, precision |
size_t pos,posc; |
long long intdigit; |
long double doubledigit; |
float floatdigit; |
const char *fmt,*fmtc; |
char *s; |
// float floatdigit; |
const char *fmt, *fmtc; // first point to %, fmtc points to specifier |
char *s; // pointer to current dest char |
char *str; |
char buffmt1[30]; |
char buffmt2[30]; |
char buf[1024]; |
char format_flag; |
char flag_point; |
char flag_noformat; |
char flag_long; |
char flag_unsigned; |
char flag_register; |
char flag_plus; |
char buf[200]; // buffer for current argument value print representation |
int format_flag; |
int flag_long; // 2 = long double or long long int or wchar |
int *point_to_n = NULL; |
int flags; // parsed flags |
|
fmt=fmt0; |
s=dest; |
339,386 → 352,201 |
pos=0; |
while(pos<maxlen) |
{ |
if (*fmt=='%') |
if (*fmt != '%') // usual char |
{ |
if ('\0' == (*s++ = *fmt++)) break; |
pos++; |
continue; |
} |
|
if (*(fmt+1)=='%') |
if (*(fmt + 1) == '%') // %% |
{ |
*s='%'; |
s++; |
fmt=fmt+2; |
pos++; |
goto exit_check; |
*s++ = '%'; pos++; |
fmt += 2; |
continue; |
} |
//checking to containg format in the string |
fmtc=fmt; |
posc=pos; |
|
flags = 0; |
format_flag=0; |
flag_long=0; |
flag_unsigned=0; |
flag_register=0; |
flag_plus=0; |
while((*fmtc!='\0') || (*fmtc!=0)) |
flag_long = 0; // 2 = long double or long long int or wchar |
|
while(*fmtc != '\0' && !format_flag) // searching end of format |
{ |
fmtc++; |
posc++; |
fmtc++; posc++; |
switch(*fmtc) |
{ |
case 'c': |
case 'C': |
case 'a': |
format_flag=1; |
flags |= flag_unsigned; |
break; |
case 'd': |
case 'D': |
case 'i': |
case 'I': |
case 'A': |
format_flag=1; |
flags |= flag_unsigned | flag_register; |
break; |
case 'e': |
case 'c': case 'd': case 'i': case 'e': case 'f': case 'g': case 's': case 'n': |
format_flag=1; |
break; |
case 'E': |
case 'E': case 'F': case 'G': |
format_flag=1; |
flag_long=1; |
flags |= flag_register; |
break; |
case 'f': |
format_flag=1; |
break; |
case 'F': |
format_flag=1; |
flag_long=1; |
break; |
case 'g': |
format_flag=1; |
break; |
case 'G': |
format_flag=1; |
flag_long=1; |
break; |
case 'l': |
flag_long=1; |
flag_long = flag_long ? 2 : 1; // ll.eq.L |
break; |
case 'L': |
flag_long=2; |
break; |
case 'o': |
case 'o': case 'u': case 'x': case 'p': |
format_flag=1; |
flags |= flag_unsigned; |
break; |
case 's': |
case 'S': |
case 'X': case 'P': |
format_flag=1; |
flags |= flag_unsigned | flag_register; |
break; |
case 'u': |
case 'U': |
format_flag=1; |
flag_unsigned=1; |
case '+': |
flags |= flag_plus; |
break; |
case 'x': |
case 'p': |
format_flag=1; |
case '-': |
flags |= flag_left_just; |
break; |
case 'X': |
case 'P': |
flag_register=1; |
format_flag=1; |
case ' ': // space |
flags |= flag_space_plus; |
break; |
case 'z': |
case 'Z': |
format_flag=1; |
flag_unsigned=1; |
case '#': |
flags |= flag_hash_sign; |
break; |
case '+': |
flag_plus=1; |
case '*': case '.': // just skip |
break; |
|
default:; |
default: |
if(isdigit(*fmtc)) break; |
strncpy(dest, "print format error - in % invalid char found", maxlen); |
return -1; // non format char found - user error |
} |
if ((*fmtc=='%') || (*fmtc==' ')) break; |
if (format_flag==1) break; |
} |
|
if (format_flag==0) |
{ |
*s=*fmt; |
fmt++; |
s++; |
pos++; |
strncpy(dest, "print format error - % without format specifier", maxlen); |
return -1; // format char not found - user error |
} |
else |
{ |
if ((posc-pos)==1) |
{//simbols % and format simbol near tothere(for example %c ) |
fmt=fmtc+1; |
switch(*fmtc) |
{ |
case 'c': |
case 'C': |
if ((pos+1)<=maxlen) |
{ |
//*s=(int)va_arg(argp,char*); |
*s=*((char *)argp); |
argp=argp+4; |
*s++;pos++; |
} |
break; |
case 's': |
case 'S': |
str=va_arg(argp,char*); |
length=strlen(str); |
if (pos + length > maxlen) |
length = maxlen - pos; |
memcpy(s,str,length); |
s=s+length;pos=pos+length; |
break; |
case 'd': |
case 'D': |
case 'i': |
case 'I': |
if (flag_long==0) {intdigit=va_arg(argp,int);} |
if (flag_long==1) {intdigit=va_arg(argp,long);} |
if (flag_long==2) {intdigit=va_arg(argp,long long);} |
//intdigit=*((long*)argp); |
//argp=argp+4; |
if ((intdigit>0) && (flag_plus==1) && (pos+1<=maxlen)) |
{ |
*s='+'; |
s++; |
pos++; |
} |
length=formatted_long_to_string(intdigit,0,buf); |
if (pos + length > maxlen) |
length = maxlen - pos; |
memcpy(s,buf,length); |
s=s+length;pos=pos+length; |
break; |
case 'o': |
if (flag_long==0) {intdigit=va_arg(argp,int);} |
if (flag_long==1) {intdigit=va_arg(argp,long);} |
if (flag_long==2) {intdigit=va_arg(argp,long long);} |
//intdigit=*((long int *)argp); |
//argp=argp+4; |
|
length=formatted_octa_to_string(intdigit,0,flag_register,buf); |
if (pos + length > maxlen) |
length = maxlen - pos; |
memcpy(s,buf,length); |
s=s+length;pos=pos+length; |
break; |
case 'u': |
case 'U': |
if (flag_long==0) {intdigit=va_arg(argp,int);} |
if (flag_long==1) {intdigit=va_arg(argp,long int);} |
if (flag_long==2) {intdigit=va_arg(argp,long long);} |
|
if (flag_unsigned==1) { |
if (intdigit<0) {intdigit=-intdigit;} |
} |
|
length=formatted_long_to_string(intdigit,0,buf); |
if (pos + length > maxlen) |
length = maxlen - pos; |
memcpy(s,buf,length); |
s=s+length;pos=pos+length; |
break; |
case 'p': |
case 'P': |
case 'x': |
case 'X': |
if (flag_long==0) {intdigit=va_arg(argp,int);} |
if (flag_long==1) {intdigit=va_arg(argp,long);} |
if (flag_long==2) {intdigit=va_arg(argp,long long);} |
//intdigit=*((long int *)argp); |
//argp=argp+4; |
|
length=formatted_hex_to_string(intdigit,0,flag_register,buf); |
if (pos + length > maxlen) |
length = maxlen - pos; |
memcpy(s,buf,length); |
s=s+length;pos=pos+length; |
break; |
case 'z': |
case 'Z': |
intdigit=va_arg(argp,size_t); |
|
if (flag_unsigned==1) { |
if (intdigit<0) {intdigit=-intdigit;} |
} |
|
length=formatted_long_to_string(intdigit,0,buf); |
if (pos + length > maxlen) |
length = maxlen - pos; |
memcpy(s,buf,length); |
s=s+length;pos=pos+length; |
break; |
default:; |
|
} |
} |
else |
fmt1 = 0; |
fmt2 = 0; |
if (posc - pos > 1) // try to read width, precision |
{ |
fmt++; |
flag_point=0; |
flag_noformat=0; |
fmt1=0; |
fmt2=0; |
j=0; |
k=0; |
for(i=pos+1;i<posc;i++) |
{ |
switch(*fmt) |
{ |
case '0': |
case '1': |
case '2': |
case '3': |
case '4': |
case '5': |
case '6': |
case '7': |
case '8': |
case '9': |
if(fmt1 == 0 && (flags & flag_point) == 0) flags |= flag_lead_zeros; |
case '1': case '2': case '3': case '4': |
case '5': case '6': case '7': case '8': case '9': |
if ((flags & flag_point) == 0) |
fmt1 = fmt1 * 10 + (*fmt -'0'); |
else |
fmt2 = fmt2 * 10 + (*fmt -'0'); |
break; |
case '*': |
if (flag_point==0) |
{ |
buffmt1[j]=*fmt-'0'; |
j++; |
} |
fmt1 = va_arg(argp, int); |
else |
{ |
buffmt2[k]=*fmt-'0'; |
k++; |
} |
fmt2 = va_arg(argp, int); |
break; |
case '.': |
flag_point=1; |
flags |= flag_point; |
break; |
case 'l': |
case 'L': |
case 'l': case 'L': case '+': // valid chars - skip |
case '-': case ' ': case '#': |
break; |
case '+': |
break; |
default:flag_noformat=1; |
default: // must be error |
strncpy(dest, "print format error - %width.precision", maxlen); |
return -1; // format char not found - user error |
} |
if (flag_noformat==1) break; |
fmt++; |
} |
if (flag_noformat==0) |
{ |
stepen=1; |
for(i=j-1;i>=0;i--) |
{ |
fmt1=fmt1+buffmt1[i]*stepen; |
stepen=stepen*10; |
} |
stepen=1; |
for(i=k-1;i>=0;i--) |
{ |
fmt2=fmt2+buffmt2[i]*stepen; |
stepen=stepen*10; |
} |
|
// do real work - format arguments values |
|
length = 0; |
switch(*fmtc) |
{ |
case 'f': |
case 'F': |
if (flag_long==0) {doubledigit=va_arg(argp,double);} |
if (flag_long>=1) {doubledigit=va_arg(argp,long double);} |
//doubledigit=*((double *)argp); |
//sargp=argp+8; |
length=formatted_double_to_string(doubledigit,fmt1,fmt2,buf); |
if ((pos+length)<maxlen) |
{ |
memcpy(s,buf,length); |
s=s+length;pos=pos+length; |
} |
case 'n': |
point_to_n = va_arg(argp, int*); |
break; |
case 'd': |
case 'D': |
case 'i': |
case 'I': |
if (flag_long==0) {intdigit=va_arg(argp,int);} |
if (flag_long==1) {intdigit=va_arg(argp,long);} |
if (flag_long==2) {intdigit=va_arg(argp,long long);} |
|
if ((intdigit>0) && (flag_plus==1) && (pos+1<maxlen)) |
case 'c': |
if (pos + 1 <= maxlen) |
{ |
*s='+'; |
s++; |
pos++; |
buf[0] = (char)va_arg(argp, int); |
length = 1; |
} |
length=formatted_long_to_string(intdigit,fmt1,buf); |
if ((pos+length)<maxlen) |
{ |
memcpy(s,buf,length); |
s=s+length;pos=pos+length; |
} |
break; |
case 's': // special case - without buf |
str = va_arg(argp, char*); |
length = strlen(str); |
if ((flags & flag_point) && (length > fmt2)) length = fmt2; // cut by precision |
if (pos + length > maxlen) length = maxlen - pos; |
memcpy(s, str ,length); |
s += length; |
pos += length; |
break; |
case 'd': case 'i': case 'u': case 'U': |
if (flag_long == 0) intdigit = va_arg(argp, int); else |
if (flag_long == 1) intdigit = va_arg(argp, long); else |
if (flag_long == 2) intdigit = va_arg(argp, long long); |
length = formatted_long_to_string(intdigit, fmt1, fmt2, buf, flags); |
break; |
case 'o': |
if (flag_long==0) {intdigit=va_arg(argp,int);} |
if (flag_long==1) {intdigit=va_arg(argp,long);} |
if (flag_long==2) {intdigit=va_arg(argp,long long);} |
length=formatted_octa_to_string(intdigit,fmt1,flag_register,buf); |
if ((pos+length)<maxlen) |
{ |
memcpy(s,buf,length); |
s=s+length;pos=pos+length; |
} |
if (flag_long == 0) intdigit = va_arg(argp, int); else |
if (flag_long == 1) intdigit = va_arg(argp, long); else |
if (flag_long == 2) intdigit = va_arg(argp, long long); |
length = formatted_octa_to_string(intdigit, fmt1, buf, flags); |
break; |
case 'u': |
case 'U': |
if (flag_long==0) {intdigit=va_arg(argp,int);} |
if (flag_long==1) {intdigit=va_arg(argp,long int);} |
if (flag_long==2) {intdigit=va_arg(argp,long long);} |
|
if (flag_unsigned==1) { |
if (intdigit<0) {intdigit=-intdigit;} |
} |
|
length=formatted_long_to_string(intdigit,fmt1,buf); |
if ((pos+length)<maxlen) |
{ |
memcpy(s,buf,length); |
s=s+length;pos=pos+length; |
} |
case 'p': case 'P': case 'x': case 'X': |
if (flag_long == 0) intdigit = va_arg(argp, int); else |
if (flag_long == 1) intdigit = va_arg(argp, long); else |
if (flag_long == 2) intdigit = va_arg(argp, long long); |
length=formatted_hex_to_string(intdigit, fmt1, buf, flags); |
break; |
case 'x': |
case 'X': |
if (flag_long==0) {intdigit=va_arg(argp,int);} |
if (flag_long==1) {intdigit=va_arg(argp,long int);} |
if (flag_long==2) {intdigit=va_arg(argp,long long);} |
length=formatted_hex_to_string(intdigit,fmt1,flag_register,buf); |
if ((pos+length)<maxlen) |
case 'a': case 'A': case 'f': case 'F': |
if (flag_long <= 1) doubledigit = va_arg(argp, double); else |
if (flag_long == 2) doubledigit = va_arg(argp, long double); |
length = formatted_double_to_string(doubledigit, fmt1, fmt2, buf, flags); |
break; |
case 'e': case 'E': |
if (flag_long <= 1) doubledigit = va_arg(argp, double); else |
if (flag_long == 2) doubledigit = va_arg(argp, long double); |
length = formatted_double_to_string_scientific(doubledigit, fmt1, fmt2, buf, flags); |
break; |
case 'g': case 'G': |
//prec special case, this is just workaround |
if (flag_long <= 1) doubledigit = va_arg(argp, double); else |
if (flag_long == 2) doubledigit = va_arg(argp, long double); |
length = formatted_double_to_string(doubledigit, fmt1, fmt2, buf, flags); |
i = formatted_double_to_string_scientific(doubledigit, fmt1, fmt2, buf + sizeof buf / 2, flags); |
if(length > i) |
{ |
memcpy(s,buf,length); |
s=s+length;pos=pos+length; |
memcpy(buf, buf + sizeof buf / 2, i); |
length = i; |
} |
break; |
case 'z': |
case 'Z': |
intdigit=va_arg(argp,size_t); |
|
if (flag_unsigned==1) { |
if (intdigit<0) {intdigit=-intdigit;} |
} |
|
length=formatted_long_to_string(intdigit,fmt1,buf); |
if ((pos+length)<maxlen) |
if (*fmtc != 's' && length > 0) // skip multiple string copying |
{ |
if (pos + length > maxlen) length = maxlen - pos; |
memcpy(s,buf,length); |
s=s+length;pos=pos+length; |
s += length; |
pos += length; |
} |
break; |
default:; |
} |
} |
fmt=fmtc+1; |
} |
} |
} |
else |
{ |
if (!(*s++ = *fmt++)) break; |
pos++; |
} |
exit_check:; |
} |
|
if (point_to_n) *point_to_n = pos; |
return(pos); |
} |