~rdoering/ubuntu/karmic/erlang/fix-535090

« back to all changes in this revision

Viewing changes to erts/lib_src/common/erl_printf_format.c

  • Committer: Bazaar Package Importer
  • Author(s): Sergei Golovan
  • Date: 2009-02-15 16:42:52 UTC
  • mfrom: (3.1.2 squeeze)
  • Revision ID: james.westby@ubuntu.com-20090215164252-q5x4rcf8a5pbesb1
Tags: 1:12.b.5-dfsg-2
Upload to unstable after lenny is released.

Show diffs side-by-side

added added

removed removed

Lines of Context:
53
53
#include <limits.h>
54
54
#include "erl_printf_format.h"
55
55
 
 
56
#include "sys.h"
 
57
#undef ASSERT
 
58
 
56
59
#ifdef DEBUG
57
60
#include <assert.h>
58
61
#define ASSERT(X) assert(X)
128
131
static char blanks[] = "                                ";
129
132
static char hex[] = "0123456789abcdef";
130
133
static char heX[] = "0123456789ABCDEF";
131
 
static int xtab[] = { 0, 10, 11, 12, 13, 14, 15,
132
 
                      0, 0, 0, 0, 0, 0, 0, 0, 0, 
133
 
                      0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
134
 
                      0, 0, 0, 0, 0, 0 };
135
 
#define HEX(c) xtab[(c) & 0x1f]
136
134
 
137
135
#define FMT(fn,arg,buf,len,count) do { \
138
136
    int res__ = (fn)((arg),(buf),(len)); \
329
327
    char format_str[7];
330
328
    char sbuf[32];
331
329
    char *bufp;
332
 
    double dexp = log10(val);
333
 
    int exp = (int) dexp;
 
330
    double dexp;
 
331
    int exp;
334
332
    size_t max_size = 1;
335
333
    size_t size;
336
334
    int new_fmt = fmt;
 
335
    int fpe_was_unmasked;
 
336
 
 
337
    fpe_was_unmasked = erts_block_fpe();
 
338
 
 
339
    dexp = log10(val);
 
340
    exp = (int) dexp;
337
341
 
338
342
    new_fmt &= ~FMTF_sgn;
339
343
    new_fmt &= ~FMTF_blk;
398
402
        break;
399
403
    }
400
404
    default:
401
 
        return -EINVAL;
 
405
        res = -EINVAL;
 
406
        goto out;
402
407
    }
403
408
 
404
409
    format_str[fi++] = '\0';
410
415
        bufp = sbuf;
411
416
    else {
412
417
        bufp = (char *) malloc(sizeof(char)*max_size);
413
 
        if (!bufp)
414
 
            return -ENOMEM;
 
418
        if (!bufp) {
 
419
            res = -ENOMEM;
 
420
            goto out;
 
421
        }
415
422
    }
416
423
 
417
424
    size = sprintf(bufp, format_str, precision, val);
418
425
    if (size < 0) {
419
426
        if (errno > 0)
420
 
            return -errno;
421
 
        return -EIO;
 
427
            res = -errno;
 
428
        else
 
429
            res = -EIO;
 
430
        goto out;
422
431
    }
423
432
 
424
433
    ASSERT(max_size >= size);
428
437
    if (bufp != sbuf)
429
438
        free((void *) bufp);
430
439
 
 
440
 out:
 
441
    erts_unblock_fpe_conditional(fpe_was_unmasked);
431
442
    return res;
432
443
}
433
444
 
434
 
 
435
 
static char* fmtq(char* ptr, int* buf)
436
 
{
437
 
    int c;
438
 
 
439
 
    switch((c=*ptr++)) {
440
 
    case 'n': c = '\n'; break;
441
 
    case 'r': c = '\r'; break;
442
 
    case 't': c = '\t'; break;
443
 
    case 'v': c = '\v'; break;
444
 
    case 'b': c = '\b'; break;
445
 
    case 'f': c = '\f'; break;
446
 
    case 'x':
447
 
        if (isxdigit((int) *ptr)) {
448
 
            c = HEX(*ptr);
449
 
            ptr++;
450
 
            if (isxdigit((int) *ptr)) {
451
 
                c = (c << 4) | HEX(*ptr);
452
 
                ptr++;
453
 
                if (isxdigit((int) *ptr)) {
454
 
                    c = (c << 4) | HEX(*ptr);
455
 
                    ptr++;
456
 
                }
457
 
            }
458
 
        }
459
 
        break;
460
 
    case '0': case '1': case '2': case '3': case '4':
461
 
    case '5': case '6': case '7':
462
 
        c = c - '0';
463
 
        if ((*ptr >= 0) && (*ptr <= 7)) {
464
 
            c = (c << 3) | (*ptr - '0');
465
 
            ptr++;
466
 
            if ((*ptr >= 0) && (*ptr <= 7)) {
467
 
                c = (c << 3) | (*ptr - '0');
468
 
                ptr++;
469
 
            }
470
 
        }
471
 
        break;
472
 
    }
473
 
    *buf = c;
474
 
    return ptr;
475
 
}
476
 
 
477
445
int erts_printf_format(fmtfn_t fn, void* arg, char* fmt, va_list ap)
478
446
{
479
447
    char* ptr0 = fmt;
491
459
        if (res < 0)
492
460
            return res;
493
461
 
494
 
        if (*ptr == '\\') {
495
 
            int wc;
496
 
            char c;
497
 
            if ((n=ptr-ptr0))
498
 
                FMT(fn,arg,ptr0,n,count);
499
 
            ptr++;
500
 
            ptr0 = ptr = fmtq(ptr, &wc);
501
 
            c = wc & 0xff;
502
 
            FMT(fn,arg,&c,1,count);
503
 
        }
504
 
        else if (*ptr == '%') {
 
462
        if (*ptr == '%') {
505
463
            if ((n=ptr-ptr0))
506
464
                FMT(fn,arg,ptr0,n,count);
507
465
            ptr++;