Subversion Repositories Kolibri OS

Rev

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;