Subversion Repositories HelenOS

Rev

Rev 4209 | Rev 4213 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4209 Rev 4210
Line 112... Line 112...
112
    printf_spec_t *ps)
112
    printf_spec_t *ps)
113
{
113
{
114
    return ps->write_utf32((void *) buf, size, ps->data);
114
    return ps->write_utf32((void *) buf, size, ps->data);
115
}
115
}
116
 
116
 
117
/** Print UTF-8 string without adding a newline.
117
/** Print string without adding newline.
118
 *
118
 *
119
 * @param str UTF-8 string to print.
119
 * @param str   String to print.
120
 * @param ps  Write function specification and support data.
120
 * @param ps    Write function specification and support data.
121
 *
121
 *
122
 * @return Number of UTF-8 characters printed.
122
 * @return Number of characters printed.
123
 *
123
 *
124
 */
124
 */
125
static int printf_putstr(const char *str, printf_spec_t *ps)
125
static int printf_putstr(const char *str, printf_spec_t *ps)
126
{
126
{
127
    if (str == NULL)
127
    if (str == NULL)
Line 236... Line 236...
236
    }
236
    }
237
   
237
   
238
    return (int) (counter + 1);
238
    return (int) (counter + 1);
239
}
239
}
240
 
240
 
241
/** Print UTF-8 string.
241
/** Format and print a string.
242
 *
242
 *
243
 * @param str       UTF-8 string to be printed.
243
 * @param str       String to be printed.
244
 * @param width     Width modifier.
244
 * @param width     Width modifier.
245
 * @param precision Precision modifier.
245
 * @param precision Precision modifier.
246
 * @param flags     Flags that modify the way the string is printed.
246
 * @param flags     Flags that modify the way the string is printed.
247
 *
247
 *
248
 * @return Number of UTF-8 characters printed, negative value on failure.
248
 * @return Number of characters printed, negative value on failure.
249
 */
249
 */
250
static int print_utf8(char *str, int width, unsigned int precision,
250
static int print_str(char *str, int width, unsigned int precision,
251
    uint32_t flags, printf_spec_t *ps)
251
    uint32_t flags, printf_spec_t *ps)
252
{
252
{
253
    if (str == NULL)
253
    if (str == NULL)
254
        return printf_putstr(nullstr, ps);
254
        return printf_putstr(nullstr, ps);
255
 
255
 
256
    /* Print leading spaces. */
256
    /* Print leading spaces. */
257
    count_t strw = str_length(str);
257
    count_t strw = str_length(str);
258
    if (precision == 0)
258
    if (precision == 0)
259
        precision = strw;
259
        precision = strw;
260
 
260
 
-
 
261
    /* Left padding */
261
    count_t counter = 0;
262
    count_t counter = 0;
262
    width -= precision;
263
    width -= precision;
263
    if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) {
264
    if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) {
264
        while (width-- > 0) {
265
        while (width-- > 0) {
265
            if (printf_putchar(' ', ps) == 1)
266
            if (printf_putchar(' ', ps) == 1)
266
                counter++;
267
                counter++;
267
        }
268
        }
268
    }
269
    }
269
 
270
 
-
 
271
    /* Part of @a str fitting into the alloted space. */
270
    int retval;
272
    int retval;
271
    size_t size = str_wsize(str, precision);
273
    size_t size = str_wsize(str, precision);
272
    if ((retval = printf_putnchars_utf8(str, size, ps)) < 0)
274
    if ((retval = printf_putnchars_utf8(str, size, ps)) < 0)
273
        return -counter;
275
        return -counter;
274
 
276
 
275
    counter += retval;
277
    counter += retval;
276
 
278
 
-
 
279
    /* Right padding */
277
    while (width-- > 0) {
280
    while (width-- > 0) {
278
        if (printf_putchar(' ', ps) == 1)
281
        if (printf_putchar(' ', ps) == 1)
279
            counter++;
282
            counter++;
280
    }
283
    }
281
 
284
 
282
    return ((int) counter);
285
    return ((int) counter);
283
 
286
 
284
}
287
}
285
 
288
 
286
/** Print UTF-32 string.
289
/** Format and print a wide string.
287
 *
290
 *
288
 * @param str       UTF-32 string to be printed.
291
 * @param wstr      Wide string to be printed.
289
 * @param width     Width modifier.
292
 * @param width     Width modifier.
290
 * @param precision Precision modifier.
293
 * @param precision Precision modifier.
291
 * @param flags     Flags that modify the way the string is printed.
294
 * @param flags     Flags that modify the way the string is printed.
292
 *
295
 *
293
 * @return Number of UTF-32 characters printed, negative value on failure.
296
 * @return      Number of characters printed, negative value
-
 
297
 *          on failure.
294
 */
298
 */
295
static int print_utf32(wchar_t *wstr, int width, unsigned int precision,
299
static int print_wstr(wchar_t *wstr, int width, unsigned int precision,
296
    uint32_t flags, printf_spec_t *ps)
300
    uint32_t flags, printf_spec_t *ps)
297
{
301
{
298
    if (wstr == NULL)
302
    if (wstr == NULL)
299
        return printf_putstr(nullstr, ps);
303
        return printf_putstr(nullstr, ps);
300
 
304
 
301
    /* Print leading spaces. */
305
    /* Print leading spaces. */
302
    size_t strw = wstr_length(wstr);
306
    size_t strw = wstr_length(wstr);
303
    if (precision == 0)
307
    if (precision == 0)
304
        precision = strw;
308
        precision = strw;
305
 
309
 
-
 
310
    /* Left padding */
306
    count_t counter = 0;
311
    count_t counter = 0;
307
    width -= precision;
312
    width -= precision;
308
    if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) {
313
    if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) {
309
        while (width-- > 0) {
314
        while (width-- > 0) {
310
            if (printf_putchar(' ', ps) == 1)
315
            if (printf_putchar(' ', ps) == 1)
311
                counter++;
316
                counter++;
312
        }
317
        }
313
    }
318
    }
314
 
319
 
-
 
320
    /* Part of @a wstr fitting into the alloted space. */
315
    int retval;
321
    int retval;
316
    size_t size = wstr_wlength(wstr, precision) * sizeof(wchar_t);
322
    size_t size = wstr_wlength(wstr, precision) * sizeof(wchar_t);
317
    if ((retval = printf_putnchars_utf32(wstr, size, ps)) < 0)
323
    if ((retval = printf_putnchars_utf32(wstr, size, ps)) < 0)
318
        return -counter;
324
        return -counter;
319
 
325
 
320
    counter += retval;
326
    counter += retval;
321
 
327
 
-
 
328
    /* Right padding */
322
    while (width-- > 0) {
329
    while (width-- > 0) {
323
        if (printf_putchar(' ', ps) == 1)
330
        if (printf_putchar(' ', ps) == 1)
324
            counter++;
331
            counter++;
325
    }
332
    }
326
 
333
 
Line 414... Line 421...
414
    if (flags & __PRINTF_FLAG_ZEROPADDED) {
421
    if (flags & __PRINTF_FLAG_ZEROPADDED) {
415
        if ((precision == 0) && (width > size))
422
        if ((precision == 0) && (width > size))
416
            precision = width - size + number_size;
423
            precision = width - size + number_size;
417
    }
424
    }
418
   
425
   
419
    /* Print leading spaces */
426
    /* Print leading spaces. */
420
    if (number_size > precision) {
427
    if (number_size > precision) {
421
        /* Print the whole number, not only a part */
428
        /* Print the whole number, not only a part. */
422
        precision = number_size;
429
        precision = number_size;
423
    }
430
    }
424
   
431
   
425
    width -= precision + size - number_size;
432
    width -= precision + size - number_size;
426
    count_t counter = 0;
433
    count_t counter = 0;
Line 430... Line 437...
430
            if (printf_putchar(' ', ps) == 1)
437
            if (printf_putchar(' ', ps) == 1)
431
                counter++;
438
                counter++;
432
        }
439
        }
433
    }
440
    }
434
   
441
   
435
    /* Print sign */
442
    /* Print sign. */
436
    if (sgn) {
443
    if (sgn) {
437
        if (printf_putchar(sgn, ps) == 1)
444
        if (printf_putchar(sgn, ps) == 1)
438
            counter++;
445
            counter++;
439
    }
446
    }
440
   
447
   
441
    /* Print prefix */
448
    /* Print prefix. */
442
    if (flags & __PRINTF_FLAG_PREFIX) {
449
    if (flags & __PRINTF_FLAG_PREFIX) {
443
        switch(base) {
450
        switch(base) {
444
        case 2:
451
        case 2:
445
            /* Binary formating is not standard, but usefull */
452
            /* Binary formating is not standard, but usefull */
446
            if (printf_putchar('0', ps) == 1)
453
            if (printf_putchar('0', ps) == 1)
Line 469... Line 476...
469
            }
476
            }
470
            break;
477
            break;
471
        }
478
        }
472
    }
479
    }
473
   
480
   
474
    /* Print leading zeroes */
481
    /* Print leading zeroes. */
475
    precision -= number_size;
482
    precision -= number_size;
476
    while (precision-- > 0) {
483
    while (precision-- > 0) {
477
        if (printf_putchar('0', ps) == 1)
484
        if (printf_putchar('0', ps) == 1)
478
            counter++;
485
            counter++;
479
    }
486
    }
480
   
487
   
481
    /* Print the number itself */
488
    /* Print the number itself. */
482
    int retval;
489
    int retval;
483
    if ((retval = printf_putstr(++ptr, ps)) > 0)
490
    if ((retval = printf_putstr(++ptr, ps)) > 0)
484
        counter += retval;
491
        counter += retval;
485
   
492
   
486
    /* Print tailing spaces */
493
    /* Print tailing spaces. */
487
   
494
   
488
    while (width-- > 0) {
495
    while (width-- > 0) {
489
        if (printf_putchar(' ', ps) == 1)
496
        if (printf_putchar(' ', ps) == 1)
490
            counter++;
497
            counter++;
491
    }
498
    }
Line 573... Line 580...
573
 *  - u Print unsigned decimal number.
580
 *  - u Print unsigned decimal number.
574
 *
581
 *
575
 *  - X, x Print hexadecimal number with upper- or lower-case. Prefix is
582
 *  - X, x Print hexadecimal number with upper- or lower-case. Prefix is
576
 *         not printed by default.
583
 *         not printed by default.
577
 *
584
 *
578
 * All other characters from fmt except the formatting directives are printed in
585
 * All other characters from fmt except the formatting directives are printed
579
 * verbatim.
586
 * verbatim.
580
 *
587
 *
581
 * @param fmt Formatting NULL terminated string (UTF-8 or plain ASCII).
588
 * @param fmt Format string.
582
 *
-
 
583
 * @return Number of UTF-8 characters printed, negative value on failure.
589
 * @return Number of characters printed, negative value on failure.
584
 *
590
 *
585
 */
591
 */
586
int printf_core(const char *fmt, printf_spec_t *ps, va_list ap)
592
int printf_core(const char *fmt, printf_spec_t *ps, va_list ap)
587
{
593
{
588
    size_t i = 0;  /* Index of the currently processed character from fmt */
594
    size_t i = 0;  /* Index of the currently processed character from fmt */
589
    size_t nxt = 0;
595
    size_t nxt = 0;
590
    size_t j = 0;  /* Index to the first not printed nonformating character */
596
    size_t j = 0;  /* Index to the first not printed nonformating character */
591
   
597
   
592
    wchar_t uc;           /* Current UTF-32 character decoded from fmt */
598
    wchar_t uc;           /* Current character decoded from fmt */
593
    count_t counter = 0;  /* Number of UTF-8 characters printed */
599
    count_t counter = 0;  /* Number of characters printed */
594
    int retval;           /* Return values from nested functions */
600
    int retval;           /* Return values from nested functions */
595
   
601
   
596
    while (true) {
602
    while (true) {
597
        i = nxt;
603
        i = nxt;
598
        uc = chr_decode(fmt, &nxt, UTF8_NO_LIMIT);
604
        uc = chr_decode(fmt, &nxt, UTF8_NO_LIMIT);
Line 735... Line 741...
735
            /*
741
            /*
736
             * String and character conversions.
742
             * String and character conversions.
737
             */
743
             */
738
            case 's':
744
            case 's':
739
                if (qualifier == PrintfQualifierLong)
745
                if (qualifier == PrintfQualifierLong)
740
                    retval = print_utf32(va_arg(ap, wchar_t *), width, precision, flags, ps);
746
                    retval = print_wstr(va_arg(ap, wchar_t *), width, precision, flags, ps);
741
                else
747
                else
742
                    retval = print_utf8(va_arg(ap, char *), width, precision, flags, ps);
748
                    retval = print_str(va_arg(ap, char *), width, precision, flags, ps);
743
               
749
               
744
                if (retval < 0) {
750
                if (retval < 0) {
745
                    counter = -counter;
751
                    counter = -counter;
746
                    goto out;
752
                    goto out;
747
                }
753
                }