Rev 6412 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 6412 | Rev 6424 | ||
---|---|---|---|
Line 1... | Line 1... | ||
1 | /* |
1 | /* |
2 | function for format output to the string |
2 | function for format output to the string |
- | 3 | ||
- | 4 | Siemargl update formats as http://www.cplusplus.com/reference/cstdio/printf/, no wchar though |
|
- | 5 | http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap05.html is used too |
|
- | 6 | %g explain https://support.microsoft.com/en-us/kb/43392 |
|
- | 7 | ||
- | 8 | todo: |
|
- | 9 | -%e |
|
- | 10 | -simplify justifying |
|
- | 11 | -fix %o, %x |
|
- | 12 | -fix precision in %g |
|
- | 13 | -%a |
|
- | 14 | -NAN, INF |
|
- | 15 | -%n nothing printed |
|
- | 16 | -%17.18f digits maximum format |
|
- | 17 | %C as w_char L'x' |
|
3 | */ |
18 | */ |
Line -... | Line 19... | ||
- | 19 | ||
4 | 20 | ||
5 | #include |
21 | //#include |
6 | #include |
22 | #include |
7 | #include |
23 | #include |
8 | //#include |
24 | #include |
- | 25 | #include |
|
- | 26 | #include |
|
- | 27 | ||
- | 28 | enum flags_t |
|
- | 29 | { |
|
- | 30 | flag_unsigned = 0x02, |
|
- | 31 | flag_register = 0x04, |
|
- | 32 | flag_plus = 0x08, |
|
- | 33 | flag_left_just = 0x10, |
|
- | 34 | flag_lead_zeros = 0x20, |
|
- | 35 | flag_space_plus = 0x40, |
|
- | 36 | flag_hash_sign = 0x80, |
|
- | 37 | flag_point = 0x100 |
|
- | 38 | }; |
|
- | 39 | ||
- | 40 | int formatted_double_to_string_scientific(long double number, int format1, int format2, char *s, int flags) |
|
- | 41 | { |
|
- | 42 | strcpy(s, "%e not implemented yet, sorry"); |
|
- | 43 | return strlen(s); |
|
Line 9... | Line 44... | ||
9 | #include |
44 | } |
10 | 45 | ||
11 | int formatted_double_to_string(long double number,int format1,int format2,char *s) |
- | |
12 | { |
- | |
13 | double n; |
46 | int formatted_double_to_string(long double number, int format1, int format2, char *s, int flags) |
14 | double nbefor; |
- | |
15 | double nafter; |
47 | { |
16 | double v,v2; |
- | |
17 | long intdigit; |
48 | long double nafter, beforpointdigit; |
18 | long beforpointdigit; |
49 | long long intdigit, mul; |
19 | long div; |
- | |
20 | int i; |
50 | int div; |
21 | int pos; |
51 | int i; |
22 | int size; |
52 | char* size; |
23 | int fmt1; |
53 | int fmt1; |
24 | int fmt2; |
54 | int fmt2; |
Line -... | Line 55... | ||
- | 55 | char buf[100], *pbuf = buf; |
|
- | 56 | char buf_low[50], *pbuf_lo = buf_low; |
|
25 | long mul; |
57 | |
- | 58 | if((flags & flag_point) == 0) format2 = 6; // default prec if no point spec |
|
26 | char buf[200]; |
59 | |
- | 60 | size = s; |
|
- | 61 | if (number < 0) {*s++ = '-'; number = -number; } |
|
27 | 62 | else |
|
- | 63 | { |
|
Line 28... | Line 64... | ||
28 | size=(int)s; |
64 | if (flags & flag_plus) *s++ = '+'; else |
29 | n=(double)number; |
65 | if (flags & flag_space_plus) *s++ = ' '; |
30 | if (n<0) {*s='-';s++;n=-n;} |
66 | } |
Line 31... | Line 67... | ||
31 | 67 | ||
32 | fmt1=format1; |
68 | fmt1 = 1; |
Line 33... | Line -... | ||
33 | fmt2=format2; |
- | |
34 | if (fmt2>18) {fmt2=18;} //maximum of size long long type |
69 | fmt2 = format2; |
35 | 70 | if (fmt2 > 18) fmt2 = 18; //maximum size of long long type |
|
36 | //clear array befor output |
- | |
37 | for(i=0;i<=200;i++) {buf[i]=0;} |
- | |
38 | - | ||
39 | if ((fmt1>=0) && (n<1)) |
- | |
40 | { //formatted output if 0<=n<1 |
- | |
41 | mul=1; |
- | |
42 | for(i=0;i |
- | |
43 | {n=n*10;mul=mul*10;} |
- | |
44 | - | ||
45 | n=n*10; |
- | |
46 | n=ceil(n); |
- | |
47 | intdigit=floor(n); |
71 | |
48 | //intdigit=n; |
72 | beforpointdigit = floor(number + 0.00000000000001); |
49 | intdigit=(intdigit/10); |
- | |
50 | - | ||
51 | pos=0; |
73 | nafter = number - beforpointdigit; |
52 | mul=mul/10; |
74 | |
53 | for(i=0;i |
- | |
54 | { |
- | |
55 | div=intdigit/mul; |
75 | //print part of number before point |
56 | buf[pos]=(char)div; |
- | |
57 | pos++; |
- | |
58 | intdigit=intdigit-div*mul; |
- | |
59 | mul=mul/10; |
76 | mul = 1; |
60 | if (mul==1) break; |
77 | for(i = 0; i < sizeof buf - 1; i++) |
61 | } |
- | |
62 | buf[pos]=(char)intdigit; |
78 | { |
63 | *s='0';s++; |
79 | mul *= 10; |
64 | *s='.';s++; |
- | |
65 | for(i=0;i |
80 | if ((beforpointdigit/mul) < 1.0) { fmt1 = i + 1; break; } |
66 | { |
- | |
67 | if ((buf[i]>=0) && (buf[i]<=9)) {*s='0'+buf[i];} |
- | |
68 | else {*s='0';} |
- | |
69 | s++; |
- | |
70 | } |
- | |
71 | } |
- | |
72 | else |
- | |
Line 73... | Line -... | ||
73 | { //if n>=1 |
- | |
74 | //v=floorf(n+0.00000000000001); |
- | |
75 | beforpointdigit=floor(n+0.00000000000001); |
- | |
76 | //beforpointdigit=n; |
81 | } |
77 | nbefor=beforpointdigit; |
- | |
78 | nafter=n-nbefor; |
- | |
79 | 82 | if (i == sizeof buf - 1 || fmt1 > 17) |
|
80 | //print part of number befor point |
- | |
81 | mul=1; |
- | |
82 | for(i=0;i<200-2;i++) |
- | |
83 | { |
- | |
84 | mul=mul*10; |
83 | { |
85 | if ((beforpointdigit/mul)==0) {fmt1=i+1;break;} |
84 | strcpy(s, "[too big number for %f, %a]"); |
86 | } |
85 | return strlen(s); |
87 | - | ||
88 | pos=0; |
86 | } |
89 | mul=mul/10; |
- | |
90 | for(i=0;i |
- | |
91 | { |
87 | |
92 | div=beforpointdigit/mul; |
- | |
93 | buf[pos]=(char)div; |
- | |
94 | pos++; |
- | |
95 | beforpointdigit=beforpointdigit-div*mul; |
- | |
96 | mul=mul/10; |
- | |
97 | if (mul==1) break; |
- | |
98 | } |
88 | mul /= 10; |
- | 89 | while(mul > 1) |
|
Line 99... | Line 90... | ||
99 | buf[pos]=(char)beforpointdigit; |
90 | { |
100 | 91 | div = beforpointdigit / mul; |
|
101 | for(i=0;i |
92 | *pbuf++ = (char)div + '0'; |
102 | { |
93 | beforpointdigit = beforpointdigit - div * mul; |
103 | if ((buf[i]>=0) && (buf[i]<=9)) {*s='0'+buf[i];} |
- | |
104 | s++; |
94 | mul /= 10; |
105 | } |
95 | } |
106 | - | ||
107 | //print part of number after point |
96 | *pbuf++=(char)beforpointdigit + '0'; |
108 | mul=1; |
- | |
Line 109... | Line 97... | ||
109 | for(i=0;i |
97 | |
- | 98 | //print part of number after point |
|
110 | {nafter=nafter*10;mul=mul*10;} |
99 | mul = 1; |
111 | 100 | for(i = 0; i < fmt2; i++) |
|
112 | nafter=nafter*10; |
101 | { |
113 | nafter=ceil(nafter); |
102 | nafter = nafter*10; |
114 | intdigit=floor(nafter); |
103 | mul *= 10; |
115 | //intdigit=nafter; |
- | |
116 | intdigit=intdigit/10; |
104 | } |
117 | 105 | ||
118 | pos=0; |
106 | intdigit = roundl(nafter); |
119 | mul=mul/10; |
107 | |
120 | for(i=0;i |
108 | mul /= 10; |
- | 109 | for(i = 0; i < fmt2 - 1; i++) |
|
- | 110 | { |
|
121 | { |
111 | div = intdigit / mul; |
122 | div=intdigit/mul; |
112 | *pbuf_lo++=(char)div + '0'; |
123 | buf[pos]=(char)div; |
113 | intdigit = intdigit - div * mul; |
- | 114 | mul /= 10; |
|
- | 115 | if (mul == 1) break; |
|
- | 116 | } |
|
- | 117 | *pbuf_lo++ = (char)intdigit + '0'; |
|
- | 118 | ||
- | 119 | ||
- | 120 | memcpy(s, buf, pbuf - buf); s += pbuf - buf; |
|
- | 121 | if (roundl(nafter) != 0 || fmt2 != 0) |
|
- | 122 | { |
|
- | 123 | *s++ = '.'; |
|
- | 124 | memcpy(s, buf_low, pbuf_lo - buf_low); s += pbuf_lo - buf_low; |
|
- | 125 | } else if (flags & flag_hash_sign) |
|
- | 126 | *s++ = '.'; |
|
124 | pos++; |
127 | |
- | 128 | // right justifiyng and forward zeros |
|
125 | intdigit=intdigit-div*mul; |
129 | div = (s - size); |
126 | mul=mul/10; |
130 | if ((flags & flag_left_just) == 0 && div < format1) |
127 | if (mul==1) break; |
131 | { |
- | 132 | pbuf = size; |
|
Line -... | Line 133... | ||
- | 133 | if ((flags & flag_lead_zeros) != 0) |
|
128 | } |
134 | if (*pbuf == '+' || *pbuf == '-' || *pbuf == ' ') { pbuf++; div--; } // sign already at place |
129 | buf[pos]=(char)intdigit; |
- | |
- | 135 | for (i = 0; i < div; i++) |
|
130 | *s='.';s++; |
136 | size[format1 - i - 1] = pbuf[div - 1 - i]; |
131 | for(i=0;i |
137 | for (i = 0; i < format1 - div - (pbuf - size); i++) |
Line 132... | Line 138... | ||
132 | { |
138 | if (flags & flag_lead_zeros) |
133 | if ((buf[i]>=0) && (buf[i]<=9)) {*s='0'+buf[i];} |
139 | pbuf[i] = '0'; |
134 | else {*s='0';} |
140 | else |
135 | s++; |
- | |
136 | } |
141 | pbuf[i] = ' '; |
137 | 142 | ||
138 | } |
143 | return format1; |
139 | size=(int)s-size; |
144 | } |
140 | return(size); |
145 | |
- | 146 | return s - size; |
|
- | 147 | } |
|
- | 148 | ||
- | 149 | int formatted_long_to_string(long long number, int format1, int prec, char *s, int flags) |
|
- | 150 | { |
|
- | 151 | int i; |
|
141 | } |
152 | int fmt; |
142 | 153 | char* size = s; |
|
- | 154 | long long digit; |
|
- | 155 | long long mul; |
|
- | 156 | int div; |
|
- | 157 | char buf[100], *pbuf = buf; |
|
- | 158 | ||
- | 159 | if (number == -9223372036854775807LL - 1) // overflow all our math, cant minus this |
|
- | 160 | { |
|
- | 161 | strcpy(buf, "9223372036854775808"); |
|
- | 162 | pbuf += 19; |
|
- | 163 | *s++ = '-'; |
|
Line 143... | Line -... | ||
143 | int formatted_long_to_string(long long number,int fmt1,char *s) |
- | |
144 | { |
- | |
145 | int i; |
164 | goto verybig; |
Line 146... | Line -... | ||
146 | int pos; |
- | |
147 | int fmt; |
- | |
148 | int size; |
165 | } |
Line 149... | Line -... | ||
149 | int difference_pos; |
- | |
150 | long digit; |
166 | |
151 | long mul; |
167 | if (flags & flag_point) flags &= ~flag_lead_zeros; // conflicting flags |
152 | long div; |
168 | |
153 | char buf[200]; |
169 | if (number < 0) {*s++ = '-'; number = -number; } |
154 | 170 | else |
|
Line 155... | Line 171... | ||
155 | //clear array befor output |
171 | { |
- | 172 | if (flags & flag_plus) *s++ = '+'; else |
|
Line 156... | Line -... | ||
156 | for(i=0;i<200;i++) {buf[i]=0;} |
- | |
157 | digit=number; |
- | |
158 | 173 | if (flags & flag_space_plus) *s++ = ' '; |
|
159 | size=(int)s; |
174 | } |
160 | if (digit<0) {*s='-';s++;digit=-digit;} |
175 | |
161 | if (digit==0) {*s='0';s++;goto end;} |
176 | digit = number; |
162 | - | ||
163 | mul=1; |
177 | |
164 | for(i=0;i<200-2;i++) |
178 | mul = (digit < 0) ? -1 : 1; |
165 | { |
179 | |
166 | mul=mul*10; |
180 | for(i = 0; i < sizeof buf - 2; i++) |
167 | if ((digit/mul)==0) {fmt=i+1;break;} |
181 | { |
Line 168... | Line -... | ||
168 | } |
- | |
169 | 182 | if (digit / mul < 10) { fmt = i + 1; break; } |
|
170 | difference_pos=i+1; |
183 | mul *= 10; |
Line -... | Line 184... | ||
- | 184 | } |
|
171 | 185 | ||
- | 186 | // add leading zeros |
|
- | 187 | for(i = 0; i < prec - fmt; i++) *pbuf++ = '0'; |
|
172 | pos=0; |
188 | |
173 | mul=mul/10; |
189 | for(i = 0; i < fmt - 1; i++) |
- | 190 | { |
|
174 | for(i=0;i |
191 | div = digit / mul; |
175 | { |
192 | *pbuf++ = (char)div + '0'; |
- | 193 | digit = digit - div * mul; |
|
- | 194 | mul /= 10; |
|
176 | div=digit/mul; |
195 | if (mul == 1 || mul == -1) break; |
177 | buf[pos]=(char)div; |
196 | } |
178 | pos++; |
- | |
179 | digit=digit-div*mul; |
197 | *pbuf++ = (char)digit + '0'; |
180 | mul=mul/10; |
- | |
- | 198 | ||
181 | if (mul==1) break; |
199 | verybig: |
182 | } |
200 | memcpy(s, buf, pbuf - buf); s += pbuf - buf; |
183 | buf[pos]=(char)digit; |
201 | |
184 | - | ||
185 | if (fmt1>=difference_pos) fmt=fmt1; |
202 | // right justifiyng and forward zeros |
186 | else |
203 | div = (s - size); |
Line 187... | Line 204... | ||
187 | fmt=difference_pos; |
204 | if ((flags & flag_left_just) == 0 && div < format1) |
188 | 205 | { |
|
189 | for(i=0;i |
206 | pbuf = size; |
190 | { |
207 | if ((flags & flag_lead_zeros) != 0) |
191 | if (i |
208 | if (*pbuf == '+' || *pbuf == '-' || *pbuf == ' ') { pbuf++; div--; } // sign already at place |
192 | { |
209 | for (i = 0; i < div; i++) |
193 | if ((buf[i]>=0) && (buf[i]<=9)) {*s='0'+buf[i];} |
210 | size[format1 - i - 1] = pbuf[div - 1 - i]; |
194 | } |
211 | for (i = 0; i < format1 - div - (pbuf - size); i++) |
195 | else |
212 | if (flags & flag_lead_zeros) |
196 | { |
213 | pbuf[i] = '0'; |
Line 260... | Line 277... | ||
260 | } |
277 | } |
261 | end:size=(int)s-size; |
278 | end:size=(int)s-size; |
262 | return(size); |
279 | return(size); |
263 | } |
280 | } |
Line 264... | Line 281... | ||
264 | 281 | ||
265 | int formatted_octa_to_string(long long number,int fmt1,char flag_register,char *s) |
282 | int formatted_octa_to_string(long long number, int fmt1, char *s, int flags) |
266 | { |
283 | { |
267 | long n; |
284 | long n; |
268 | int i,pos; |
285 | int i,pos; |
269 | int fmt; |
286 | // int fmt; |
270 | long size; |
287 | long size; |
271 | int difference_pos; |
288 | int difference_pos; |
272 | char xdigs_lower[16]="012345678"; |
289 | char xdigs_lower[16]="012345678"; |
Line 309... | Line 326... | ||
309 | } |
326 | } |
310 | end:size=(int)s-size; |
327 | end:size=(int)s-size; |
311 | return(size); |
328 | return(size); |
312 | } |
329 | } |
Line -... | Line 330... | ||
- | 330 | ||
313 | 331 | //int vsnprintf (char * s, size_t n, const char * format, va_list arg ); |
|
314 | int format_print(char *dest, size_t maxlen,const char *fmt0, va_list argp) |
332 | int format_print(char *dest, size_t maxlen, const char *fmt0, va_list argp) |
315 | { |
333 | { |
316 | int i,j,k; |
334 | int i; |
317 | int length; |
335 | int length; |
318 | int fmt1,fmt2,stepen; |
336 | int fmt1, fmt2; // width, precision |
319 | size_t pos,posc; |
337 | size_t pos, posc; |
320 | long long intdigit; |
338 | long long intdigit; |
321 | long double doubledigit; |
339 | long double doubledigit; |
322 | float floatdigit; |
340 | // float floatdigit; |
323 | const char *fmt,*fmtc; |
341 | const char *fmt, *fmtc; // first point to %, fmtc points to specifier |
324 | char *s; |
342 | char *s; // pointer to current dest char |
325 | char *str; |
- | |
326 | char buffmt1[30]; |
343 | char *str; |
327 | char buffmt2[30]; |
- | |
328 | char buf[1024]; |
344 | char buf[200]; // buffer for current argument value print representation |
329 | char format_flag; |
- | |
330 | char flag_point; |
345 | int format_flag; |
331 | char flag_noformat; |
346 | int flag_long; // 2 = long double or long long int or wchar |
332 | char flag_long; |
- | |
333 | char flag_unsigned; |
347 | int *point_to_n = NULL; |
334 | char flag_register; |
- | |
Line 335... | Line 348... | ||
335 | char flag_plus; |
348 | int flags; // parsed flags |
336 | 349 | ||
337 | fmt=fmt0; |
350 | fmt = fmt0; |
338 | s=dest; |
351 | s = dest; |
339 | pos=0; |
352 | pos = 0; |
340 | while(pos |
353 | while(pos < maxlen) |
341 | { |
354 | { |
- | 355 | if (*fmt != '%') // usual char |
|
- | 356 | { |
|
- | 357 | if ('\0' == (*s++ = *fmt++)) break; |
|
- | 358 | pos++; |
|
Line 342... | Line 359... | ||
342 | if (*fmt=='%') |
359 | continue; |
343 | { |
360 | } |
344 | - | ||
345 | if (*(fmt+1)=='%') |
361 | |
346 | { |
362 | if (*(fmt + 1) == '%') // %% |
347 | *s='%'; |
363 | { |
348 | s++; |
- | |
349 | fmt=fmt+2; |
364 | *s++ = '%'; pos++; |
350 | pos++; |
365 | fmt += 2; |
351 | goto exit_check; |
366 | continue; |
352 | } |
367 | } |
- | 368 | //checking to containg format in the string |
|
- | 369 | fmtc = fmt; |
|
353 | //checking to containg format in the string |
370 | posc = pos; |
354 | fmtc=fmt; |
- | |
355 | posc=pos; |
- | |
356 | format_flag=0; |
371 | |
357 | flag_long=0; |
- | |
- | 372 | flags = 0; |
|
358 | flag_unsigned=0; |
373 | format_flag = 0; |
359 | flag_register=0; |
374 | flag_long = 0; // 2 = long double or long long int or wchar |
360 | flag_plus=0; |
- | |
361 | while((*fmtc!='\0') || (*fmtc!=0)) |
375 | |
362 | { |
376 | while(*fmtc != '\0' && !format_flag) // searching end of format |
363 | fmtc++; |
377 | { |
364 | posc++; |
- | |
365 | switch(*fmtc) |
- | |
366 | { |
- | |
367 | case 'c': |
- | |
368 | case 'C': |
378 | fmtc++; posc++; |
369 | format_flag=1; |
- | |
370 | break; |
- | |
371 | case 'd': |
- | |
372 | case 'D': |
379 | switch( *fmtc ) |
- | 380 | { |
|
373 | case 'i': |
381 | case 'a': |
374 | case 'I': |
382 | format_flag = 1; |
375 | format_flag=1; |
383 | flags |= flag_unsigned; |
- | 384 | break; |
|
376 | break; |
385 | case 'A': |
377 | case 'e': |
386 | format_flag = 1; |
378 | format_flag=1; |
387 | flags |= flag_unsigned | flag_register; |
379 | break; |
- | |
380 | case 'E': |
388 | break; |
381 | format_flag=1; |
389 | case 'c': case 'd': case 'i': case 'e': case 'f': case 'g': case 's': case 'n': |
382 | flag_long=1; |
390 | format_flag = 1; |
383 | break; |
- | |
384 | case 'f': |
- | |
385 | format_flag=1; |
- | |
386 | break; |
- | |
387 | case 'F': |
391 | break; |
388 | format_flag=1; |
- | |
389 | flag_long=1; |
- | |
390 | break; |
- | |
391 | case 'g': |
- | |
392 | format_flag=1; |
- | |
393 | break; |
- | |
394 | case 'G': |
392 | case 'E': case 'F': case 'G': |
395 | format_flag=1; |
393 | format_flag = 1; |
396 | flag_long=1; |
394 | flags |= flag_register; |
397 | break; |
395 | break; |
398 | case 'l': |
396 | case 'l': |
399 | flag_long=1; |
397 | flag_long = flag_long ? 2 : 1; // ll.eq.L |
400 | break; |
398 | break; |
401 | case 'L': |
399 | case 'L': |
402 | flag_long=2; |
400 | flag_long = 2; |
- | 401 | break; |
|
403 | break; |
402 | case 'o': case 'u': case 'x': case 'p': |
404 | case 'o': |
- | |
405 | format_flag=1; |
403 | format_flag = 1; |
406 | break; |
404 | flags |= flag_unsigned; |
- | 405 | break; |
|
407 | case 's': |
406 | case 'X': case 'P': |
408 | case 'S': |
- | |
409 | format_flag=1; |
407 | format_flag = 1; |
410 | break; |
408 | flags |= flag_unsigned | flag_register; |
411 | case 'u': |
- | |
412 | case 'U': |
409 | break; |
413 | format_flag=1; |
410 | case '+': |
414 | flag_unsigned=1; |
411 | flags |= flag_plus; |
415 | break; |
- | |
416 | case 'x': |
412 | break; |
417 | case 'p': |
413 | case '-': |
418 | format_flag=1; |
414 | flags |= flag_left_just; |
419 | break; |
- | |
420 | case 'X': |
- | |
421 | case 'P': |
415 | break; |
422 | flag_register=1; |
- | |
423 | format_flag=1; |
416 | case ' ': // space |
424 | break; |
- | |
425 | case 'z': |
417 | flags |= flag_space_plus; |
426 | case 'Z': |
418 | break; |
427 | format_flag=1; |
419 | case '#': |
428 | flag_unsigned=1; |
- | |
429 | break; |
420 | flags |= flag_hash_sign; |
430 | case '+': |
- | |
- | 421 | break; |
|
431 | flag_plus=1; |
422 | case '*': case '.': // just skip |
- | 423 | break; |
|
- | 424 | default: |
|
432 | break; |
425 | if(isdigit(*fmtc)) break; |
433 | - | ||
434 | default:; |
- | |
435 | } |
426 | strncpy(dest, "print format error - in % invalid char found", maxlen); |
Line 436... | Line 427... | ||
436 | if ((*fmtc=='%') || (*fmtc==' ')) break; |
427 | return -1; // non format char found - user error |
437 | if (format_flag==1) break; |
428 | } |
438 | } |
- | |
439 | - | ||
440 | if (format_flag==0) |
- | |
441 | { |
- | |
442 | *s=*fmt; |
- | |
443 | fmt++; |
- | |
444 | s++; |
- | |
445 | pos++; |
- | |
446 | } |
429 | } |
447 | else |
- | |
448 | { |
- | |
449 | if ((posc-pos)==1) |
- | |
450 | {//simbols % and format simbol near tothere(for example %c ) |
- | |
451 | fmt=fmtc+1; |
430 | |
452 | switch(*fmtc) |
- | |
453 | { |
- | |
454 | case 'c': |
- | |
455 | case 'C': |
- | |
456 | if ((pos+1)<=maxlen) |
- | |
457 | { |
- | |
458 | //*s=(int)va_arg(argp,char*); |
431 | if (format_flag == 0) |
459 | *s=*((char *)argp); |
- | |
460 | argp=argp+4; |
- | |
461 | *s++;pos++; |
- | |
462 | } |
- | |
463 | break; |
- | |
464 | case 's': |
- | |
465 | case 'S': |
- | |
466 | str=va_arg(argp,char*); |
- | |
467 | length=strlen(str); |
- | |
468 | if (pos + length > maxlen) |
- | |
469 | length = maxlen - pos; |
- | |
470 | memcpy(s,str,length); |
- | |
471 | s=s+length;pos=pos+length; |
- | |
472 | break; |
- | |
473 | case 'd': |
- | |
474 | case 'D': |
- | |
475 | case 'i': |
- | |
476 | case 'I': |
- | |
477 | if (flag_long==0) {intdigit=va_arg(argp,int);} |
- | |
478 | if (flag_long==1) {intdigit=va_arg(argp,long);} |
- | |
479 | if (flag_long==2) {intdigit=va_arg(argp,long long);} |
- | |
480 | //intdigit=*((long*)argp); |
- | |
481 | //argp=argp+4; |
- | |
482 | if ((intdigit>0) && (flag_plus==1) && (pos+1<=maxlen)) |
- | |
483 | { |
- | |
484 | *s='+'; |
- | |
485 | s++; |
- | |
486 | pos++; |
- | |
487 | } |
- | |
488 | length=formatted_long_to_string(intdigit,0,buf); |
- | |
489 | if (pos + length > maxlen) |
- | |
490 | length = maxlen - pos; |
- | |
491 | memcpy(s,buf,length); |
- | |
492 | s=s+length;pos=pos+length; |
- | |
493 | break; |
- | |
494 | case 'o': |
- | |
495 | if (flag_long==0) {intdigit=va_arg(argp,int);} |
- | |
496 | if (flag_long==1) {intdigit=va_arg(argp,long);} |
- | |
497 | if (flag_long==2) {intdigit=va_arg(argp,long long);} |
- | |
498 | //intdigit=*((long int *)argp); |
- | |
499 | //argp=argp+4; |
- | |
500 | - | ||
501 | length=formatted_octa_to_string(intdigit,0,flag_register,buf); |
- | |
502 | if (pos + length > maxlen) |
- | |
503 | length = maxlen - pos; |
- | |
504 | memcpy(s,buf,length); |
- | |
505 | s=s+length;pos=pos+length; |
- | |
506 | break; |
- | |
507 | case 'u': |
- | |
508 | case 'U': |
- | |
509 | if (flag_long==0) {intdigit=va_arg(argp,int);} |
- | |
510 | if (flag_long==1) {intdigit=va_arg(argp,long int);} |
- | |
511 | if (flag_long==2) {intdigit=va_arg(argp,long long);} |
- | |
512 | - | ||
513 | if (flag_unsigned==1) { |
- | |
514 | if (intdigit<0) {intdigit=-intdigit;} |
- | |
515 | } |
- | |
516 | - | ||
517 | length=formatted_long_to_string(intdigit,0,buf); |
- | |
518 | if (pos + length > maxlen) |
- | |
519 | length = maxlen - pos; |
- | |
520 | memcpy(s,buf,length); |
- | |
521 | s=s+length;pos=pos+length; |
- | |
522 | break; |
- | |
523 | case 'p': |
- | |
524 | case 'P': |
- | |
525 | case 'x': |
- | |
526 | case 'X': |
- | |
527 | if (flag_long==0) {intdigit=va_arg(argp,int);} |
- | |
528 | if (flag_long==1) {intdigit=va_arg(argp,long);} |
- | |
529 | if (flag_long==2) {intdigit=va_arg(argp,long long);} |
- | |
530 | //intdigit=*((long int *)argp); |
- | |
531 | //argp=argp+4; |
- | |
532 | - | ||
533 | length=formatted_hex_to_string(intdigit,0,flag_register,buf); |
- | |
534 | if (pos + length > maxlen) |
- | |
535 | length = maxlen - pos; |
- | |
536 | memcpy(s,buf,length); |
- | |
537 | s=s+length;pos=pos+length; |
- | |
538 | break; |
- | |
539 | case 'z': |
- | |
540 | case 'Z': |
- | |
541 | intdigit=va_arg(argp,size_t); |
- | |
542 | - | ||
543 | if (flag_unsigned==1) { |
- | |
544 | if (intdigit<0) {intdigit=-intdigit;} |
- | |
545 | } |
- | |
546 | - | ||
547 | length=formatted_long_to_string(intdigit,0,buf); |
- | |
548 | if (pos + length > maxlen) |
- | |
549 | length = maxlen - pos; |
- | |
Line 550... | Line -... | ||
550 | memcpy(s,buf,length); |
- | |
551 | s=s+length;pos=pos+length; |
- | |
552 | break; |
- | |
553 | default:; |
- | |
554 | - | ||
555 | } |
- | |
556 | } |
- | |
557 | else |
432 | { |
558 | { |
433 | strncpy(dest, "print format error - % without format specifier", maxlen); |
559 | fmt++; |
434 | return -1; // format char not found - user error |
- | 435 | } |
|
560 | flag_point=0; |
436 | |
561 | flag_noformat=0; |
437 | fmt1 = 0; |
562 | fmt1=0; |
438 | fmt2 = 0; |
563 | fmt2=0; |
439 | if (posc - pos > 1) // try to read width, precision |
564 | j=0; |
440 | { |
565 | k=0; |
441 | fmt++; |
566 | for(i=pos+1;i |
442 | for(i = pos + 1; i < posc; i++) |
567 | { |
443 | { |
568 | switch(*fmt) |
444 | switch(*fmt) |
569 | { |
445 | { |
570 | case '0': |
446 | case '0': |
571 | case '1': |
447 | if(fmt1 == 0 && (flags & flag_point) == 0) flags |= flag_lead_zeros; |
572 | case '2': |
448 | case '1': case '2': case '3': case '4': |
573 | case '3': |
449 | case '5': case '6': case '7': case '8': case '9': |
574 | case '4': |
450 | if ((flags & flag_point) == 0) |
575 | case '5': |
451 | fmt1 = fmt1 * 10 + (*fmt -'0'); |
576 | case '6': |
- | |
577 | case '7': |
- | |
578 | case '8': |
- | |
579 | case '9': |
452 | else |
580 | if (flag_point==0) |
453 | fmt2 = fmt2 * 10 + (*fmt -'0'); |
581 | { |
- | |
582 | buffmt1[j]=*fmt-'0'; |
- | |
583 | j++; |
- | |
584 | } |
454 | break; |
585 | else |
455 | case '*': |
586 | { |
456 | if (flag_point == 0) |
587 | buffmt2[k]=*fmt-'0'; |
457 | fmt1 = va_arg(argp, int); |
588 | k++; |
458 | else |
589 | } |
459 | fmt2 = va_arg(argp, int); |
590 | break; |
460 | break; |
591 | case '.': |
461 | case '.': |
592 | flag_point=1; |
462 | flags |= flag_point; |
593 | break; |
463 | break; |
594 | case 'l': |
464 | case 'l': case 'L': case '+': // valid chars - skip |
595 | case 'L': |
465 | case '-': case ' ': case '#': |
596 | break; |
- | |
597 | case '+': |
466 | break; |
598 | break; |
467 | default: // must be error |
599 | default:flag_noformat=1; |
- | |
600 | } |
- | |
601 | if (flag_noformat==1) break; |
- | |
602 | fmt++; |
- | |
603 | } |
- | |
604 | if (flag_noformat==0) |
- | |
605 | { |
- | |
606 | stepen=1; |
- | |
607 | for(i=j-1;i>=0;i--) |
- | |
608 | { |
- | |
609 | fmt1=fmt1+buffmt1[i]*stepen; |
- | |
610 | stepen=stepen*10; |
- | |
611 | } |
- | |
612 | stepen=1; |
468 | strncpy(dest, "print format error - %width.precision", maxlen); |
- | 469 | return -1; // format char not found - user error |
|
- | 470 | } |
|
- | 471 | fmt++; |
|
- | 472 | } |
|
613 | for(i=k-1;i>=0;i--) |
473 | } |
614 | { |
474 | |
615 | fmt2=fmt2+buffmt2[i]*stepen; |
- | |
616 | stepen=stepen*10; |
475 | // do real work - format arguments values |
617 | } |
- | |
618 | switch(*fmtc) |
- | |
619 | { |
- | |
620 | case 'f': |
- | |
621 | case 'F': |
- | |
622 | if (flag_long==0) {doubledigit=va_arg(argp,double);} |
- | |
623 | if (flag_long>=1) {doubledigit=va_arg(argp,long double);} |
- | |
624 | //doubledigit=*((double *)argp); |
- | |
625 | //sargp=argp+8; |
- | |
626 | length=formatted_double_to_string(doubledigit,fmt1,fmt2,buf); |
476 | |
627 | if ((pos+length) |
477 | length = 0; |
628 | { |
- | |
629 | memcpy(s,buf,length); |
- | |
630 | s=s+length;pos=pos+length; |
- | |
631 | } |
478 | switch(*fmtc) |
632 | break; |
- | |
633 | case 'd': |
- | |
634 | case 'D': |
- | |
635 | case 'i': |
- | |
636 | case 'I': |
- | |
637 | if (flag_long==0) {intdigit=va_arg(argp,int);} |
- | |
638 | if (flag_long==1) {intdigit=va_arg(argp,long);} |
- | |
639 | if (flag_long==2) {intdigit=va_arg(argp,long long);} |
- | |
640 | - | ||
641 | if ((intdigit>0) && (flag_plus==1) && (pos+1 |
479 | { |
642 | { |
- | |
643 | *s='+'; |
- | |
644 | s++; |
480 | case 'n': |
645 | pos++; |
481 | point_to_n = va_arg(argp, int*); |
646 | } |
482 | break; |
647 | length=formatted_long_to_string(intdigit,fmt1,buf); |
483 | case 'c': |
648 | if ((pos+length) |
484 | if (pos + 1 <= maxlen) |
649 | { |
485 | { |
650 | memcpy(s,buf,length); |
- | |
651 | s=s+length;pos=pos+length; |
486 | buf[0] = (char)va_arg(argp, int); |
652 | } |
- | |
653 | break; |
487 | length = 1; |
654 | case 'o': |
488 | } |
655 | if (flag_long==0) {intdigit=va_arg(argp,int);} |
489 | break; |
656 | if (flag_long==1) {intdigit=va_arg(argp,long);} |
490 | case 's': // special case - without buf |
657 | if (flag_long==2) {intdigit=va_arg(argp,long long);} |
491 | str = va_arg(argp, char*); |
658 | length=formatted_octa_to_string(intdigit,fmt1,flag_register,buf); |
492 | length = strlen(str); |
659 | if ((pos+length) |
493 | if ((flags & flag_point) && (length > fmt2)) length = fmt2; // cut by precision |
660 | { |
- | |
661 | memcpy(s,buf,length); |
494 | if (pos + length > maxlen) length = maxlen - pos; |
662 | s=s+length;pos=pos+length; |
495 | memcpy(s, str ,length); |
663 | } |
496 | s += length; |
664 | break; |
497 | pos += length; |
665 | case 'u': |
- | |
666 | case 'U': |
- | |
667 | if (flag_long==0) {intdigit=va_arg(argp,int);} |
- | |
668 | if (flag_long==1) {intdigit=va_arg(argp,long int);} |
- | |
669 | if (flag_long==2) {intdigit=va_arg(argp,long long);} |
- | |
670 | 498 | break; |
|
671 | if (flag_unsigned==1) { |
- | |
672 | if (intdigit<0) {intdigit=-intdigit;} |
- | |
673 | } |
- | |
674 | - | ||
675 | length=formatted_long_to_string(intdigit,fmt1,buf); |
- | |
676 | if ((pos+length) |
499 | case 'd': case 'i': case 'u': case 'U': |
- | 500 | if (flag_long == 0) intdigit = va_arg(argp, int); else |
|
677 | { |
501 | if (flag_long == 1) intdigit = va_arg(argp, long); else |
- | 502 | if (flag_long == 2) intdigit = va_arg(argp, long long); |
|
- | 503 | length = formatted_long_to_string(intdigit, fmt1, fmt2, buf, flags); |
|
- | 504 | break; |
|
- | 505 | case 'o': |
|
678 | memcpy(s,buf,length); |
506 | if (flag_long == 0) intdigit = va_arg(argp, int); else |
679 | s=s+length;pos=pos+length; |
507 | if (flag_long == 1) intdigit = va_arg(argp, long); else |
680 | } |
508 | if (flag_long == 2) intdigit = va_arg(argp, long long); |
681 | break; |
509 | length = formatted_octa_to_string(intdigit, fmt1, buf, flags); |
682 | case 'x': |
510 | break; |
- | 511 | case 'p': case 'P': case 'x': case 'X': |
|
- | 512 | if (flag_long == 0) intdigit = va_arg(argp, int); else |
|
683 | case 'X': |
513 | if (flag_long == 1) intdigit = va_arg(argp, long); else |
684 | if (flag_long==0) {intdigit=va_arg(argp,int);} |
514 | if (flag_long == 2) intdigit = va_arg(argp, long long); |
685 | if (flag_long==1) {intdigit=va_arg(argp,long int);} |
515 | length=formatted_hex_to_string(intdigit, fmt1, buf, flags); |
- | 516 | break; |
|
- | 517 | case 'a': case 'A': case 'f': case 'F': |
|
- | 518 | if (flag_long <= 1) doubledigit = va_arg(argp, double); else |
|
- | 519 | if (flag_long == 2) doubledigit = va_arg(argp, long double); |
|
- | 520 | length = formatted_double_to_string(doubledigit, fmt1, fmt2, buf, flags); |
|
- | 521 | break; |
|
- | 522 | case 'e': case 'E': |
|
- | 523 | if (flag_long <= 1) doubledigit = va_arg(argp, double); else |
|
- | 524 | if (flag_long == 2) doubledigit = va_arg(argp, long double); |
|
686 | if (flag_long==2) {intdigit=va_arg(argp,long long);} |
525 | length = formatted_double_to_string_scientific(doubledigit, fmt1, fmt2, buf, flags); |
- | 526 | break; |
|
- | 527 | case 'g': case 'G': |
|
- | 528 | //prec special case, this is just workaround |
|
- | 529 | if (flag_long <= 1) doubledigit = va_arg(argp, double); else |
|
- | 530 | if (flag_long == 2) doubledigit = va_arg(argp, long double); |
|
- | 531 | length = formatted_double_to_string(doubledigit, fmt1, fmt2, buf, flags); |
|
687 | length=formatted_hex_to_string(intdigit,fmt1,flag_register,buf); |
532 | i = formatted_double_to_string_scientific(doubledigit, fmt1, fmt2, buf + sizeof buf / 2, flags); |
688 | if ((pos+length) |
533 | if(length > i) |
689 | { |
- | |
690 | memcpy(s,buf,length); |
- | |
691 | s=s+length;pos=pos+length; |
- | |
692 | } |
- | |
693 | break; |
- | |
694 | case 'z': |
- | |
695 | case 'Z': |
534 | { |
696 | intdigit=va_arg(argp,size_t); |
- | |
697 | - | ||
698 | if (flag_unsigned==1) { |
535 | memcpy(buf, buf + sizeof buf / 2, i); |
699 | if (intdigit<0) {intdigit=-intdigit;} |
536 | length = i; |
- | 537 | } |
|
700 | } |
538 | break; |
701 | - | ||
702 | length=formatted_long_to_string(intdigit,fmt1,buf); |
539 | } |
703 | if ((pos+length) |
- | |
704 | { |
- | |
705 | memcpy(s,buf,length); |
540 | if (*fmtc != 's' && length > 0) // skip multiple string copying |
706 | s=s+length;pos=pos+length; |
541 | { |
707 | } |
542 | if (pos + length > maxlen) length = maxlen - pos; |
708 | break; |
543 | memcpy(s, buf, length); |
709 | default:; |
- | |
710 | } |
- | |
711 | } |
- | |
712 | fmt=fmtc+1; |
- | |
713 | } |
- | |
- | 544 | s += length; |
|
714 | } |
545 | pos += length; |
715 | } |
- | |
716 | else |
- | |
717 | { |
- | |
718 | if (!(*s++ = *fmt++)) break; |
546 | } |
719 | pos++; |
547 | fmt = fmtc + 1; |