Ignore:
Timestamp:
2007-10-05T05:16:18Z (17 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
c4e75ea
Parents:
f7fad5a
Message:

Remove duplicit implementation of strlen() in kernel, rename is_digit(),
is_white() and co. to their standard names (e.g. isdigit(), isspace()) and
remove duplicit implementation of isdigit(). Fix cstyle in kernel printf()
implementation.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/src/printf/printf_core.c

    rf7fad5a rdb25906  
    4040#include <print.h>
    4141#include <arch/arg.h>
     42#include <macros.h>
     43#include <func.h>
    4244#include <arch.h>
    4345
    44 #define __PRINTF_FLAG_PREFIX            0x00000001      /**< show prefixes 0x or 0*/
    45 #define __PRINTF_FLAG_SIGNED            0x00000002      /**< signed / unsigned number */
    46 #define __PRINTF_FLAG_ZEROPADDED        0x00000004      /**< print leading zeroes */
    47 #define __PRINTF_FLAG_LEFTALIGNED       0x00000010      /**< align to left */
    48 #define __PRINTF_FLAG_SHOWPLUS          0x00000020      /**< always show + sign */
    49 #define __PRINTF_FLAG_SPACESIGN         0x00000040      /**< print space instead of plus */
    50 #define __PRINTF_FLAG_BIGCHARS          0x00000080      /**< show big characters */
    51 #define __PRINTF_FLAG_NEGATIVE          0x00000100      /**< number has - sign */
    52 
    53 #define PRINT_NUMBER_BUFFER_SIZE        (64+5)          /**< Buffer big enought for 64 bit number
    54                                                          * printed in base 2, sign, prefix and
    55                                                          * 0 to terminate string.. (last one is only for better testing
    56                                                          * end of buffer by zero-filling subroutine)*/
     46/** show prefixes 0x or 0 */
     47#define __PRINTF_FLAG_PREFIX            0x00000001
     48/** signed / unsigned number */
     49#define __PRINTF_FLAG_SIGNED            0x00000002
     50/** print leading zeroes */
     51#define __PRINTF_FLAG_ZEROPADDED        0x00000004
     52/** align to left */
     53#define __PRINTF_FLAG_LEFTALIGNED       0x00000010
     54/** always show + sign */
     55#define __PRINTF_FLAG_SHOWPLUS          0x00000020
     56/** print space instead of plus */
     57#define __PRINTF_FLAG_SPACESIGN         0x00000040
     58/** show big characters */
     59#define __PRINTF_FLAG_BIGCHARS          0x00000080
     60/** number has - sign */
     61#define __PRINTF_FLAG_NEGATIVE          0x00000100
     62
     63/**
     64 * Buffer big enough for 64-bit number printed in base 2, sign, prefix and 0
     65 * to terminate string... (last one is only for better testing end of buffer by
     66 * zero-filling subroutine)
     67 */
     68#define PRINT_NUMBER_BUFFER_SIZE        (64 + 5)       
    5769
    5870/** Enumeration of possible arguments types.
     
    6880} qualifier_t;
    6981
    70 static char digits_small[] = "0123456789abcdef";        /**< Small hexadecimal characters */
    71 static char digits_big[] = "0123456789ABCDEF";  /**< Big hexadecimal characters */
    72 
    73 /** Checks c for a digit.
    74  * @param c One character.
    75  * @return nonzero if c is from interval '0 to '9'.
    76  */
    77 static inline int isdigit(int c)
    78 {
    79         return ((c >= '0' )&&( c <= '9'));
    80 }
    81 
    82 /** Compute length of given zero terminated string.
    83  * @param str Pointer to valid string.
    84  * @return string length without trailing zero.
    85  */
    86 static unative_t strlen(const char *str)
    87 {
    88         unative_t counter = 0;
    89 
    90         while (str[counter] != 0) {
    91                 counter++;
    92         }
    93 
    94         return counter;
    95 }
    96 
    97 /** Print count chars from buffer without adding newline
    98  * @param buf Buffer with size at least count bytes - NULL pointer NOT allowed!
    99  * @param count
    100  * @param ps output method and its data
    101  * @return number of printed characters
    102  */
    103 static int printf_putnchars(const char * buf, size_t count, struct printf_spec *ps)
     82static char digits_small[] = "0123456789abcdef";
     83static char digits_big[] = "0123456789ABCDEF";
     84
     85/** Print one or more characters without adding newline.
     86 *
     87 * @param buf           Buffer with size at least count bytes. NULL pointer is
     88 *                      not allowed!
     89 * @param count         Number of characters to print.
     90 * @param ps            Output method and its data.
     91 * @return              Number of characters printed.
     92 */
     93static int printf_putnchars(const char * buf, size_t count,
     94    struct printf_spec *ps)
    10495{
    10596        return ps->write((void *)buf, count, ps->data);
    10697}
    10798
    108 /** Print string without added newline
    109  * @param str string to print
    110  * @param ps write function specification and support data
    111  * @return number of printed characters
     99/** Print a string without adding a newline.
     100 *
     101 * @param str           String to print.
     102 * @param ps            Write function specification and support data.
     103 * @return              Number of characters printed.
    112104 */
    113105static int printf_putstr(const char * str, struct printf_spec *ps)
     
    116108       
    117109        if (str == NULL) {
    118                 return printf_putnchars("(NULL)", 6, ps);
     110                char *nullstr = "(NULL)";
     111                return printf_putnchars(nullstr, strlen(nullstr), ps);
    119112        }
    120113
     
    124117}
    125118
    126 /** Print one character to output
    127  * @param c one character
    128  * @param ps output method
    129  * @return number of printed characters
     119/** Print one character.
     120 *
     121 * @param c             Character to be printed.
     122 * @param ps            Output method.
     123 *
     124 * @return              Number of characters printed.
    130125 */
    131126static int printf_putchar(int c, struct printf_spec *ps)
     
    136131}
    137132
    138 /** Print one formatted character
    139  * @param c character to print
    140  * @param width
    141  * @param flags
    142  * @return number of printed characters, negative value on fail
     133/** Print one formatted character.
     134 *
     135 * @param c             Character to print.
     136 * @param width         Width modifier.
     137 * @param flags         Flags that change the way the character is printed.
     138 *
     139 * @return              Number of characters printed, negative value on failure.
    143140 */
    144141static int print_char(char c, int width, uint64_t flags, struct printf_spec *ps)
     
    147144       
    148145        if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) {
    149                 while (--width > 0) {   /* one space is consumed by character itself hence predecrement */
     146                while (--width > 0) {
     147                        /*
     148                         * One space is consumed by the character itself, hence
     149                         * the predecrement.
     150                         */
    150151                        if (printf_putchar(' ', ps) > 0)       
    151152                                ++counter;
     
    156157                counter++;
    157158
    158         while (--width > 0) { /* one space is consumed by character itself hence predecrement */
     159        while (--width > 0) {
     160                        /*
     161                         * One space is consumed by the character itself, hence
     162                         * the predecrement.
     163                         */
    159164                if (printf_putchar(' ', ps) > 0)
    160165                        ++counter;
     
    164169}
    165170
    166 /** Print one string
    167  * @param s string
    168  * @param width
    169  * @param precision
    170  * @param flags
    171  * @return number of printed characters or negative value on fail
    172  */
    173                                                
    174 static int print_string(char *s, int width, int precision, uint64_t flags, struct printf_spec *ps)
     171/** Print string.
     172 *
     173 * @param s             String to be printed.
     174 * @param width         Width modifier.
     175 * @param precision     Precision modifier.
     176 * @param flags         Flags that modify the way the string is printed.
     177 *
     178 * @return              Number of characters printed, negative value on failure.
     179 */
     180static int print_string(char *s, int width, int precision, uint64_t flags,
     181    struct printf_spec *ps)
    175182{
    176183        int counter = 0;
     
    198205        }
    199206
    200         if ((retval = printf_putnchars(s, size < precision ? size : precision,
    201             ps)) < 0) {
     207        if ((retval = printf_putnchars(s, min(size, precision), ps)) < 0) {
    202208                return -counter;
    203209        }
     
    213219
    214220
    215 /** Print number in given base
    216  *
    217  * Print significant digits of a number in given
    218  * base.
    219  *
    220  * @param num  Number to print.
    221  * @param width
    222  * @param precision
    223  * @param base Base to print the number in (should
    224  *             be in range 2 .. 16).
    225  * @param flags output modifiers
    226  * @return number of written characters or EOF
    227  *
    228  */
    229 static int print_number(uint64_t num, int width, int precision, int base , uint64_t flags, struct printf_spec *ps)
     221/** Print a number in a given base.
     222 *
     223 * Print significant digits of a number in given base.
     224 *
     225 * @param num           Number to print.
     226 * @param widt          Width modifier.h
     227 * @param precision     Precision modifier.
     228 * @param base          Base to print the number in (must be between 2 and 16).
     229 * @param flags         Flags that modify the way the number is printed.       
     230 *
     231 * @return              Number of characters printed.
     232 *
     233 */
     234static int print_number(uint64_t num, int width, int precision, int base,
     235    uint64_t flags, struct printf_spec *ps)
    230236{
    231237        char *digits = digits_small;
    232         char d[PRINT_NUMBER_BUFFER_SIZE];       /* this is good enough even for base == 2, prefix and sign */
     238        char d[PRINT_NUMBER_BUFFER_SIZE];
    233239        char *ptr = &d[PRINT_NUMBER_BUFFER_SIZE - 1];
    234         int size = 0; /* size of number with all prefixes and signs */
    235         int number_size; /* size of plain number */
     240        int size = 0;           /* size of number with all prefixes and signs */
     241        int number_size;        /* size of plain number */
    236242        char sgn;
    237243        int retval;
     
    255261        number_size = size;
    256262
    257         /* Collect sum of all prefixes/signs/... to calculate padding and leading zeroes */
     263        /*
     264         * Collect the sum of all prefixes/signs/... to calculate padding and
     265         * leading zeroes.
     266         */
    258267        if (flags & __PRINTF_FLAG_PREFIX) {
    259268                switch(base) {
     
    276285                        size++;
    277286                } else if (flags & __PRINTF_FLAG_SHOWPLUS) {
    278                                 sgn = '+';
    279                                 size++;
    280                         } else if (flags & __PRINTF_FLAG_SPACESIGN) {
    281                                         sgn = ' ';
    282                                         size++;
    283                                 }
     287                        sgn = '+';
     288                        size++;
     289                } else if (flags & __PRINTF_FLAG_SPACESIGN) {
     290                        sgn = ' ';
     291                        size++;
     292                }
    284293        }
    285294
     
    288297        }
    289298
    290         /* if number is leftaligned or precision is specified then zeropadding is ignored */
     299        /*
     300         * If the number is leftaligned or precision is specified then
     301         * zeropadding is ignored.
     302         */
    291303        if (flags & __PRINTF_FLAG_ZEROPADDED) {
    292304                if ((precision == 0) && (width > size)) {
     
    296308
    297309        /* print leading spaces */
    298         if (number_size > precision) /* We must print whole number not only a part */
     310        if (number_size > precision) {
     311                /* print the whole number not only a part */
    299312                precision = number_size;
     313        }
    300314
    301315        width -= precision + size - number_size;
     
    375389/** Print formatted string.
    376390 *
    377  * Print string formatted according to the fmt parameter
    378  * and variadic arguments. Each formatting directive
    379  * must have the following form:
     391 * Print string formatted according to the fmt parameter and variadic arguments.
     392 * Each formatting directive must have the following form:
    380393 *
    381394 *      \% [ FLAGS ] [ WIDTH ] [ .PRECISION ] [ TYPE ] CONVERSION
    382395 *
    383396 * FLAGS:@n
    384  *      - "#" Force to print prefix.
    385  *      For conversion \%o the prefix is 0, for \%x and \%X prefixes are 0x and 0X
    386  *      and for conversion \%b the prefix is 0b.
     397 *      - "#"   Force to print prefix.For \%o conversion, the prefix is 0, for
     398 *              \%x and \%X prefixes are 0x and 0X and for conversion \%b the
     399 *              prefix is 0b.
    387400 *
    388401 *      - "-"   Align to left.
     
    390403 *      - "+"   Print positive sign just as negative.
    391404 *
    392  *      - " "   If the printed number is positive and "+" flag is not set, print space in
    393  *      place of sign.
    394  *
    395  *      - "0"   Print 0 as padding instead of spaces. Zeroes are placed between sign and the
    396  *      rest of the number. This flag is ignored if "-" flag is specified.
     405 *      - " "   If the printed number is positive and "+" flag is not set,
     406 *              print space in place of sign.
     407 *
     408 *      - "0"   Print 0 as padding instead of spaces. Zeroes are placed between
     409 *              sign and the rest of the number. This flag is ignored if "-"
     410 *              flag is specified.
    397411 *
    398412 * WIDTH:@n
    399  *      - Specify minimal width of printed argument. If it is bigger, width is ignored.
    400  * If width is specified with a "*" character instead of number, width is taken from
    401  * parameter list. And integer parameter is expected before parameter for processed
    402  * conversion specification. If this value is negative its absolute value is taken
    403  * and the "-" flag is set.
     413 *      - Specify the minimal width of a printed argument. If it is bigger,
     414 *      width is ignored. If width is specified with a "*" character instead of
     415 *      number, width is taken from parameter list. And integer parameter is
     416 *      expected before parameter for processed conversion specification. If
     417 *      this value is negative its absolute value is taken and the "-" flag is
     418 *      set.
    404419 *
    405420 * PRECISION:@n
    406421 *      - Value precision. For numbers it specifies minimum valid numbers.
    407  * Smaller numbers are printed with leading zeroes. Bigger numbers are not affected.
    408  * Strings with more than precision characters are cut off.
    409  * Just as with width, an "*" can be used used instead of a number.
    410  * An integer value is then expected in parameters. When both width and precision
    411  * are specified using "*", the first parameter is used for width and the second one
    412  * for precision.
     422 *      Smaller numbers are printed with leading zeroes. Bigger numbers are not
     423 *      affected. Strings with more than precision characters are cut off. Just
     424 *      as with width, an "*" can be used used instead of a number. An integer
     425 *      value is then expected in parameters. When both width and precision are
     426 *      specified using "*", the first parameter is used for width and the
     427 *      second one for precision.
    413428 *
    414429 * TYPE:@n
     
    426441 *      - c     Print single character.
    427442 *
    428  *      - s     Print zero terminated string. If a NULL value is passed as value, "(NULL)" is printed instead.
     443 *      - s     Print zero terminated string. If a NULL value is passed as
     444 *              value, "(NULL)" is printed instead.
    429445 *
    430  *      - P, p  Print value of a pointer. Void * value is expected and it is printed in hexadecimal notation with prefix
    431  *      (as with \%#X / \%#x for 32bit or \%#X / \%#x for 64bit long pointers).
    432  *
    433  *      - b     Print value as unsigned binary number. Prefix is not printed by default. (Nonstandard extension.)
     446 *      - P, p  Print value of a pointer. Void * value is expected and it is
     447 *              printed in hexadecimal notation with prefix (as with \%#X / \%#x
     448 *              for 32-bit or \%#X / \%#x for 64-bit long pointers).
     449 *
     450 *      - b     Print value as unsigned binary number. Prefix is not printed by
     451 *              default. (Nonstandard extension.)
    434452 *
    435  *      - o     Print value as unsigned octal number. Prefix is not printed by default.
    436  *
    437  *      - d,i   Print signed decimal number. There is no difference between d and i conversion.
     453 *      - o     Print value as unsigned octal number. Prefix is not printed by
     454 *              default.
     455 *
     456 *      - d, i  Print signed decimal number. There is no difference between d
     457 *              and i conversion.
    438458 *
    439459 *      - u     Print unsigned decimal number.
    440460 *
    441  *      - X, x  Print hexadecimal number with upper- or lower-case. Prefix is not printed by default.
     461 *      - X, x  Print hexadecimal number with upper- or lower-case. Prefix isi
     462 *              not printed by default.
    442463 *
    443  * All other characters from fmt except the formatting directives
    444  * are printed in verbatim.
    445  *
    446  * @param fmt Formatting NULL terminated string.
    447  * @return Number of printed characters or negative value on failure.
     464 * All other characters from fmt except the formatting directives are printed in
     465 * verbatim.
     466 *
     467 * @param fmt           Formatting NULL terminated string.
     468 * @return              Number of characters printed, negative value on failure.
    448469 */
    449470int printf_core(const char *fmt, struct printf_spec *ps, va_list ap)
    450471{
    451         int i = 0, j = 0; /**< i is index of currently processed char from fmt, j is index to the first not printed nonformating character */
     472        int i = 0; /* index of the currently processed char from fmt */
     473        int j = 0; /* index to the first not printed nonformating character */
    452474        int end;
    453         int counter; /**< counter of printed characters */
    454         int retval; /**< used to store return values from called functions */
     475        int counter; /* counter of printed characters */
     476        int retval; /* used to store return values from called functions */
    455477        char c;
    456         qualifier_t qualifier;  /* type of argument */
    457         int base;       /**< base in which will be parameter (numbers only) printed */
    458         uint64_t number; /**< argument value */
    459         size_t  size; /**< byte size of integer parameter */
     478        qualifier_t qualifier; /* type of argument */
     479        int base; /* base in which a numeric parameter will be printed */
     480        uint64_t number; /* argument value */
     481        size_t  size; /* byte size of integer parameter */
    460482        int width, precision;
    461483        uint64_t flags;
     
    468490                        /* print common characters if any processed */ 
    469491                        if (i > j) {
    470                                 if ((retval = printf_putnchars(&fmt[j], (size_t)(i - j), ps)) < 0) { /* error */
     492                                if ((retval = printf_putnchars(&fmt[j],
     493                                    (size_t)(i - j), ps)) < 0) { /* error */
    471494                                        counter = -counter;
    472495                                        goto out;
     
    483506                                ++i;
    484507                                switch (c = fmt[i]) {
    485                                 case '#': flags |= __PRINTF_FLAG_PREFIX; break;
    486                                 case '-': flags |= __PRINTF_FLAG_LEFTALIGNED; break;
    487                                 case '+': flags |= __PRINTF_FLAG_SHOWPLUS; break;
    488                                 case ' ': flags |= __PRINTF_FLAG_SPACESIGN; break;
    489                                 case '0': flags |= __PRINTF_FLAG_ZEROPADDED; break;
    490                                 default: end = 1;
     508                                case '#':
     509                                        flags |= __PRINTF_FLAG_PREFIX;
     510                                        break;
     511                                case '-':
     512                                        flags |= __PRINTF_FLAG_LEFTALIGNED;
     513                                        break;
     514                                case '+':
     515                                        flags |= __PRINTF_FLAG_SHOWPLUS;
     516                                        break;
     517                                case ' ':
     518                                        flags |= __PRINTF_FLAG_SPACESIGN;
     519                                        break;
     520                                case '0':
     521                                        flags |= __PRINTF_FLAG_ZEROPADDED;
     522                                        break;
     523                                default:
     524                                        end = 1;
    491525                                };     
    492526                               
     
    501535                                }
    502536                        } else if (fmt[i] == '*') {
    503                                 /* get width value from argument list*/
     537                                /* get width value from argument list */
    504538                                i++;
    505539                                width = (int)va_arg(ap, int);
    506540                                if (width < 0) {
    507                                         /* negative width means to set '-' flag */
     541                                        /* negative width sets '-' flag */
    508542                                        width *= -1;
    509543                                        flags |= __PRINTF_FLAG_LEFTALIGNED;
     
    521555                                        }
    522556                                } else if (fmt[i] == '*') {
    523                                         /* get precision value from argument list*/
     557                                        /*
     558                                         * Get precision value from the argument
     559                                         * list.
     560                                         */
    524561                                        i++;
    525562                                        precision = (int)va_arg(ap, int);
    526563                                        if (precision < 0) {
    527                                                 /* negative precision means to ignore it */
     564                                                /* ignore negative precision */
    528565                                                precision = 0;
    529566                                        }
     
    532569
    533570                        switch (fmt[i++]) {
    534                         /** TODO: unimplemented qualifiers:
     571                        /** @todo unimplemented qualifiers:
    535572                         * t ptrdiff_t - ISO C 99
    536573                         */
     
    553590                                break;
    554591                        default:
    555                                 qualifier = PrintfQualifierInt; /* default type */
     592                                /* default type */
     593                                qualifier = PrintfQualifierInt;
    556594                                --i;
    557595                        }       
     
    565603                        */
    566604                        case 's':
    567                                 if ((retval = print_string(va_arg(ap, char*), width, precision, flags, ps)) < 0) {
     605                                if ((retval = print_string(va_arg(ap, char *),
     606                                    width, precision, flags, ps)) < 0) {
    568607                                        counter = -counter;
    569608                                        goto out;
     
    575614                        case 'c':
    576615                                c = va_arg(ap, unsigned int);
    577                                 if ((retval = print_char(c, width, flags, ps)) < 0) {
     616                                retval = print_char(c, width, flags, ps);
     617                                if (retval < 0) {
    578618                                        counter = -counter;
    579619                                        goto out;
     
    618658                         */
    619659                        default:
    620                                 /* Unknown format
    621                                  * now, j is index of '%' so we will
    622                                  * print whole bad format sequence
     660                                /*
     661                                 * Unknown format. Now, j is the index of '%'
     662                                 * so we will print whole bad format sequence.
    623663                                 */
    624664                                goto next_char;         
     
    647687                        case PrintfQualifierLongLong:
    648688                                size = sizeof(unsigned long long);
    649                                 number = (uint64_t)va_arg(ap, unsigned long long);
     689                                number = (uint64_t)va_arg(ap,
     690                                    unsigned long long);
    650691                                break;
    651692                        case PrintfQualifierPointer:
    652693                                size = sizeof(void *);
    653                                 number = (uint64_t)(unsigned long)va_arg(ap, void *);
     694                                number = (uint64_t)(unsigned long)va_arg(ap,
     695                                    void *);
    654696                                break;
    655697                        case PrintfQualifierNative:
     
    663705                       
    664706                        if (flags & __PRINTF_FLAG_SIGNED) {
    665                                 if (number & (0x1 << (size*8 - 1))) {
     707                                if (number & (0x1 << (size * 8 - 1))) {
    666708                                        flags |= __PRINTF_FLAG_NEGATIVE;
    667709                               
     
    670712                                        } else {
    671713                                                number = ~number;
    672                                                 number &= (~((0xFFFFFFFFFFFFFFFFll) <<  (size * 8)));
     714                                                number &=
     715                                                    ~(0xFFFFFFFFFFFFFFFFll <<
     716                                                    (size * 8));
    673717                                                number++;
    674718                                        }
     
    676720                        }
    677721
    678                         if ((retval = print_number(number, width, precision, base, flags, ps)) < 0) {
     722                        if ((retval = print_number(number, width, precision,
     723                            base, flags, ps)) < 0) {
    679724                                counter = -counter;
    680725                                goto out;
    681                         };
     726                        }
    682727
    683728                        counter += retval;
     
    690735       
    691736        if (i > j) {
    692                 if ((retval = printf_putnchars(&fmt[j], (unative_t)(i - j), ps)) < 0) { /* error */
     737                if ((retval = printf_putnchars(&fmt[j], (unative_t)(i - j),
     738                    ps)) < 0) { /* error */
    693739                        counter = -counter;
    694740                        goto out;
Note: See TracChangeset for help on using the changeset viewer.