Ignore:
Timestamp:
Nov 4, 2007, 3:16:40 AM (16 years ago)
Author:
Bruno Cornec
Message:

Update to busybox 1.7.2

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/2.2.5/mindi-busybox/coreutils/printf.c

    r821 r1765  
    3131   %b = print an argument string, interpreting backslash escapes
    3232
    33    The `format' argument is re-used as many times as necessary
     33   The 'format' argument is re-used as many times as necessary
    3434   to convert all of the given arguments.
    3535
     
    3939//   19990508 Busy Boxed! Dave Cinege
    4040
    41 #include <unistd.h>
    42 #include <stdio.h>
    43 #include <sys/types.h>
    44 #include <string.h>
    45 #include <errno.h>
    46 #include <stdlib.h>
    47 #include <fcntl.h>
    48 #include <ctype.h>
    49 #include <assert.h>
    50 #include "busybox.h"
    51 
    52 static int print_formatted (char *format, int argc, char **argv);
    53 static void print_direc (char *start, size_t length,
    54             int field_width, int precision, char *argument);
    55 
    56 typedef int (*converter)(char *arg, void *result);
    57 static void multiconvert(char *arg, void *result, converter convert)
    58 {
    59     char s[16];
     41#include "libbb.h"
     42
     43typedef void (*converter)(const char *arg, void *result);
     44
     45static void multiconvert(const char *arg, void *result, converter convert)
     46{
     47    char s[sizeof(int)*3 + 2];
     48
    6049    if (*arg == '"' || *arg == '\'') {
    61         sprintf(s,"%d",(unsigned)*(++arg));
    62         arg=s;
    63     }
    64     if(convert(arg,result)) fprintf(stderr, "%s", arg);
    65 }
    66 
    67 static unsigned long xstrtoul(char *arg)
     50        sprintf(s, "%d", (unsigned char)arg[1]);
     51        arg = s;
     52    }
     53    convert(arg, result);
     54    /* if there was conversion error, print unconverted string */
     55    if (errno)
     56        fputs(arg, stderr);
     57}
     58
     59static void conv_strtoul(const char *arg, void *result)
     60{
     61    *(unsigned long*)result = bb_strtoul(arg, NULL, 0);
     62}
     63static void conv_strtol(const char *arg, void *result)
     64{
     65    *(long*)result = bb_strtol(arg, NULL, 0);
     66}
     67static void conv_strtod(const char *arg, void *result)
     68{
     69    char *end;
     70    /* Well, this one allows leading whitespace... so what */
     71    /* What I like much less is that "-" is accepted too! :( */
     72    *(double*)result = strtod(arg, &end);
     73    if (end[0]) errno = ERANGE;
     74}
     75
     76static unsigned long my_xstrtoul(const char *arg)
    6877{
    6978    unsigned long result;
    70 
    71     multiconvert(arg,&result, (converter)safe_strtoul);
     79    multiconvert(arg, &result, conv_strtoul);
    7280    return result;
    7381}
    7482
    75 static long xstrtol(char *arg)
     83static long my_xstrtol(const char *arg)
    7684{
    7785    long result;
    78     multiconvert(arg, &result, (converter)safe_strtol);
     86    multiconvert(arg, &result, conv_strtol);
    7987    return result;
    8088}
    8189
    82 static double xstrtod(char *arg)
     90static double my_xstrtod(const char *arg)
    8391{
    8492    double result;
    85     multiconvert(arg, &result, (converter)safe_strtod);
     93    multiconvert(arg, &result, conv_strtod);
    8694    return result;
    8795}
     
    100108}
    101109
    102 int printf_main(int argc, char **argv)
    103 {
    104     char *format;
    105     int args_used;
    106 
    107     if (argc <= 1 || **(argv + 1) == '-') {
    108         bb_show_usage();
    109     }
    110 
    111     format = argv[1];
    112     argc -= 2;
    113     argv += 2;
    114 
    115     do {
    116         args_used = print_formatted(format, argc, argv);
    117         argc -= args_used;
    118         argv += args_used;
    119     }
    120     while (args_used > 0 && argc > 0);
    121 
    122 /*
    123   if (argc > 0)
    124     fprintf(stderr, "excess args ignored");
    125 */
    126 
    127     return EXIT_SUCCESS;
     110static void print_direc(char *start, size_t length, int field_width, int precision,
     111        const char *argument)
     112{
     113    char *p;        /* Null-terminated copy of % directive. */
     114
     115    p = xmalloc((unsigned) (length + 1));
     116    strncpy(p, start, length);
     117    p[length] = 0;
     118
     119    switch (p[length - 1]) {
     120    case 'd':
     121    case 'i':
     122        if (field_width < 0) {
     123            if (precision < 0)
     124                printf(p, my_xstrtol(argument));
     125            else
     126                printf(p, precision, my_xstrtol(argument));
     127        } else {
     128            if (precision < 0)
     129                printf(p, field_width, my_xstrtol(argument));
     130            else
     131                printf(p, field_width, precision, my_xstrtol(argument));
     132        }
     133        break;
     134    case 'o':
     135    case 'u':
     136    case 'x':
     137    case 'X':
     138        if (field_width < 0) {
     139            if (precision < 0)
     140                printf(p, my_xstrtoul(argument));
     141            else
     142                printf(p, precision, my_xstrtoul(argument));
     143        } else {
     144            if (precision < 0)
     145                printf(p, field_width, my_xstrtoul(argument));
     146            else
     147                printf(p, field_width, precision, my_xstrtoul(argument));
     148        }
     149        break;
     150    case 'f':
     151    case 'e':
     152    case 'E':
     153    case 'g':
     154    case 'G':
     155        if (field_width < 0) {
     156            if (precision < 0)
     157                printf(p, my_xstrtod(argument));
     158            else
     159                printf(p, precision, my_xstrtod(argument));
     160        } else {
     161            if (precision < 0)
     162                printf(p, field_width, my_xstrtod(argument));
     163            else
     164                printf(p, field_width, precision, my_xstrtod(argument));
     165        }
     166        break;
     167    case 'c':
     168        printf(p, *argument);
     169        break;
     170    case 's':
     171        if (field_width < 0) {
     172            if (precision < 0)
     173                printf(p, argument);
     174            else
     175                printf(p, precision, argument);
     176        } else {
     177            if (precision < 0)
     178                printf(p, field_width, argument);
     179            else
     180                printf(p, field_width, precision, argument);
     181        }
     182        break;
     183    }
     184
     185    free(p);
    128186}
    129187
    130188/* Print the text in FORMAT, using ARGV (with ARGC elements) for
    131    arguments to any `%' directives.
     189   arguments to any '%' directives.
    132190   Return the number of elements of ARGV used.  */
    133191
    134192static int print_formatted(char *format, int argc, char **argv)
    135193{
    136     int save_argc = argc;       /* Preserve original value.  */
    137     char *f;                    /* Pointer into `format'.  */
    138     char *direc_start;          /* Start of % directive.  */
    139     size_t direc_length;        /* Length of % directive.  */
    140     int field_width;            /* Arg to first '*', or -1 if none.  */
    141     int precision;              /* Arg to second '*', or -1 if none.  */
     194    int save_argc = argc;   /* Preserve original value.  */
     195    char *f;                /* Pointer into 'format'.  */
     196    char *direc_start;      /* Start of % directive.  */
     197    size_t direc_length;    /* Length of % directive.  */
     198    int field_width;        /* Arg to first '*', or -1 if none.  */
     199    int precision;          /* Arg to second '*', or -1 if none.  */
    142200
    143201    for (f = format; *f; ++f) {
     
    167225                ++direc_length;
    168226                if (argc > 0) {
    169                     field_width = xstrtoul(*argv);
     227                    field_width = my_xstrtoul(*argv);
    170228                    ++argv;
    171229                    --argc;
    172230                } else
    173231                    field_width = 0;
    174             } else
     232            } else {
    175233                while (isdigit(*f)) {
    176234                    ++f;
    177235                    ++direc_length;
    178236                }
     237            }
    179238            if (*f == '.') {
    180239                ++f;
     
    184243                    ++direc_length;
    185244                    if (argc > 0) {
    186                         precision = xstrtoul(*argv);
     245                        precision = my_xstrtoul(*argv);
    187246                        ++argv;
    188247                        --argc;
     
    200259            }
    201260            /*
    202                if (!strchr ("diouxXfeEgGcs", *f))
    203                fprintf(stderr, "%%%c: invalid directive", *f);
    204              */
     261            if (!strchr ("diouxXfeEgGcs", *f))
     262            fprintf(stderr, "%%%c: invalid directive", *f);
     263            */
    205264            ++direc_length;
    206265            if (argc > 0) {
     
    213272                            precision, "");
    214273            break;
    215 
    216274        case '\\':
    217275            if (*++f == 'c')
     
    220278            f--;
    221279            break;
    222 
    223280        default:
    224281            putchar(*f);
     
    229286}
    230287
    231 static void
    232 print_direc(char *start, size_t length, int field_width, int precision,
    233             char *argument)
    234 {
    235     char *p;                    /* Null-terminated copy of % directive. */
    236 
    237     p = xmalloc((unsigned) (length + 1));
    238     strncpy(p, start, length);
    239     p[length] = 0;
    240 
    241     switch (p[length - 1]) {
    242     case 'd':
    243     case 'i':
    244         if (field_width < 0) {
    245             if (precision < 0)
    246                 printf(p, xstrtol(argument));
    247             else
    248                 printf(p, precision, xstrtol(argument));
    249         } else {
    250             if (precision < 0)
    251                 printf(p, field_width, xstrtol(argument));
    252             else
    253                 printf(p, field_width, precision, xstrtol(argument));
    254         }
    255         break;
    256 
    257     case 'o':
    258     case 'u':
    259     case 'x':
    260     case 'X':
    261         if (field_width < 0) {
    262             if (precision < 0)
    263                 printf(p, xstrtoul(argument));
    264             else
    265                 printf(p, precision, xstrtoul(argument));
    266         } else {
    267             if (precision < 0)
    268                 printf(p, field_width, xstrtoul(argument));
    269             else
    270                 printf(p, field_width, precision, xstrtoul(argument));
    271         }
    272         break;
    273 
    274     case 'f':
    275     case 'e':
    276     case 'E':
    277     case 'g':
    278     case 'G':
    279         if (field_width < 0) {
    280             if (precision < 0)
    281                 printf(p, xstrtod(argument));
    282             else
    283                 printf(p, precision, xstrtod(argument));
    284         } else {
    285             if (precision < 0)
    286                 printf(p, field_width, xstrtod(argument));
    287             else
    288                 printf(p, field_width, precision, xstrtod(argument));
    289         }
    290         break;
    291 
    292     case 'c':
    293         printf(p, *argument);
    294         break;
    295 
    296     case 's':
    297         if (field_width < 0) {
    298             if (precision < 0)
    299                 printf(p, argument);
    300             else
    301                 printf(p, precision, argument);
    302         } else {
    303             if (precision < 0)
    304                 printf(p, field_width, argument);
    305             else
    306                 printf(p, field_width, precision, argument);
    307         }
    308         break;
    309     }
    310 
    311     free(p);
    312 }
     288int printf_main(int argc, char **argv);
     289int printf_main(int argc, char **argv)
     290{
     291    char *format;
     292    int args_used;
     293
     294    if (argc <= 1 || argv[1][0] == '-') {
     295        bb_show_usage();
     296    }
     297
     298    format = argv[1];
     299    argc -= 2;
     300    argv += 2;
     301
     302    do {
     303        args_used = print_formatted(format, argc, argv);
     304        argc -= args_used;
     305        argv += args_used;
     306    } while (args_used > 0 && argc > 0);
     307
     308/*  if (argc > 0)
     309        fprintf(stderr, "excess args ignored");
     310*/
     311
     312    return EXIT_SUCCESS;
     313}
Note: See TracChangeset for help on using the changeset viewer.