Subversion Repositories Kolibri OS

Rev

Rev 8687 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 8687 Rev 8718
Line 11... Line 11...
11
-%a
11
-%a
12
-can overflow unsigned as signed
12
-can overflow unsigned as signed
13
-radix point always '.', no LOCALEs
13
-radix point always '.', no LOCALEs
14
*/
14
*/
Line -... Line 15...
-
 
15
 
15
 
16
 
16
#include 
17
#include 
17
#include 
18
#include 
18
#include 
19
#include 
19
#include 
-
 
Line -... Line 20...
-
 
20
#include 
-
 
21
 
-
 
22
typedef int (*virtual_getc)(void *sp, const void *obj);
-
 
23
typedef void (*virtual_ungetc)(void *sp, int c, const void *obj);
-
 
24
 
-
 
25
enum flags_t
-
 
26
{
-
 
27
        flag_unsigned   = 0x02,
-
 
28
        flag_register   = 0x04,
-
 
29
        flag_plus       = 0x08,
-
 
30
        flag_left_just  = 0x10,
-
 
31
        flag_lead_zeros = 0x20,
-
 
32
        flag_space_plus = 0x40,
-
 
33
        flag_hash_sign  = 0x80,
-
 
34
        flag_point      = 0x100
20
#include "format_scan.h"
35
};
21
 
36
 
22
static int __try_parse_real(long double *real, int ch, const void *src, void *save, virtual_getc vgetc, virtual_ungetc vungetc)
37
int     try_parse_real(long double *real, int ch, const void *src, void *save, virtual_getc vgetc, virtual_ungetc vungetc)
23
// returns 1 if OK, -1 == EOF, -2 parse broken
38
// returns 1 if OK, -1 == EOF, -2 parse broken
24
{
39
{
Line 136... Line 151...
136
    *real *= pow(10,div);
151
    *real *= pow(10, div);
Line 137... Line 152...
137
 
152
 
138
    return 1;
153
    return 1;
Line 139... Line 154...
139
}
154
}
140
 
155
 
141
static int __try_parse_int(long long *digit, int ch, const void *src, void *save, virtual_getc vgetc, virtual_ungetc vungetc)
156
int     try_parse_int(long long *digit, int ch, const void *src, void *save, virtual_getc vgetc, virtual_ungetc vungetc)
Line 142... Line 157...
142
{
157
{
143
    int sign = 1, base = 10, have_digits = 0;
158
    int sign = 1, base = 10, have_digits = 0;
Line 206... Line 221...
206
        return -2;
221
        return -2;
207
}
222
}
Line 208... Line 223...
208
 
223
 
209
 
224
 
210
 
225
 
211
int _format_scan(const void *src, const char *fmt, va_list argp, virtual_getc vgetc, virtual_ungetc vungetc)
226
int format_scan(const void *src, const char *fmt, va_list argp, virtual_getc vgetc, virtual_ungetc vungetc)
212
{
227
{
213
    int         i;
228
    int                     i;
Line 361... Line 376...
361
            }
376
            }
362
            if (i < length) goto exit_me; // not enough chars
377
            if (i < length) goto exit_me; // not enough chars
363
            break;
378
            break;
364
        case 's':
379
        case 's':
365
            arg_str = va_arg(argp, char*);
380
            arg_str = va_arg(argp, char*);
366
            if (fmt1 == 0) length = STDIO_MAX_MEM;   // max string scan 4096
381
            if (fmt1 == 0) length = 4095;   // max string scan 4096
367
            else length = fmt1;
382
            else length = fmt1;
368
            for (i = 0; i < length; i++)
383
            for (i = 0; i < length; i++)
369
            {
384
            {
370
                *arg_str++ = ch;
385
                *arg_str++ = ch;
371
                ch = vgetc(&save, src);
386
                ch = vgetc(&save, src);
Line 373... Line 388...
373
            }
388
            }
374
            *arg_str++ = '\0';
389
            *arg_str++ = '\0';
375
            break;
390
            break;
376
        case 'd':   case 'i':   case 'u':
391
        case 'd':   case 'i':   case 'u':
377
        case 'o':   case 'p':   case 'x':
392
        case 'o':   case 'p':   case 'x':
378
            i = __try_parse_int(&digit, ch, src, &save, vgetc, vungetc);
393
            i = try_parse_int(&digit, ch, src, &save, vgetc, vungetc);
379
            if (i < 0) goto exit_me;
394
            if (i < 0) goto exit_me;
Line 380... Line 395...
380
 
395
 
381
            if (flag_long == 0) { arg_int = va_arg(argp, int*); *arg_int = (int)digit; } else
396
            if (flag_long == 0) { arg_int = va_arg(argp, int*); *arg_int = (int)digit; } else
382
            if (flag_long == 1) { arg_long = va_arg(argp, long*); *arg_long = (long)digit; } else
397
            if (flag_long == 1) { arg_long = va_arg(argp, long*); *arg_long = (long)digit; } else
383
            if (flag_long == 2) { arg_longlong = va_arg(argp, long long*); *arg_longlong = digit; }
398
            if (flag_long == 2) { arg_longlong = va_arg(argp, long long*); *arg_longlong = digit; }
384
            break;
399
            break;
385
        case 'a':   case 'A':   case 'f':   case 'F':
400
        case 'a':   case 'A':   case 'f':   case 'F':
386
        case 'e':   case 'E':
401
        case 'e':   case 'E':
387
        case 'g':   case 'G':
402
        case 'g':   case 'G':
388
            i = __try_parse_real(&real, ch, src, &save, vgetc, vungetc);
403
            i = try_parse_real(&real, ch, src, &save, vgetc, vungetc);
Line 389... Line 404...
389
            if (i < 0) goto exit_me;
404
            if (i < 0) goto exit_me;
390
 
405
 
391
            if (flag_long == 0) { arg_float = va_arg(argp, float*); *arg_float = (float)real; } else
406
            if (flag_long == 0) { arg_float = va_arg(argp, float*); *arg_float = (float)real; } else