Changeset 11a4fbf in mainline


Ignore:
Timestamp:
2006-03-17T11:47:53Z (19 years ago)
Author:
Josef Cejka <malyzelenyhnus@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
e5a1f82f
Parents:
c05290e
Message:

Userspace printf was rewritten to support standard format. Not all needed features implemented yet.

Files:
7 edited

Legend:

Unmodified
Added
Removed
  • init/Makefile

    rc05290e r11a4fbf  
    3232LIBC_PREFIX = ../libc
    3333LIBIPC_PREFIX = ../libipc
     34SOFTINT_PREFIX = ../softint
    3435include $(LIBC_PREFIX)/Makefile.toolchain
    3536
  • init/init.c

    rc05290e r11a4fbf  
    4747        printf("Simple text.\n");
    4848        printf("Now insert '%s' string.\n","this");
    49         printf("We are brave enought to print numbers like %%d = '%d'\n", 0x123456);
    50         printf("And now... '%b' byte! '%w' word! '%W' Word! \n", 0x12, 0x1234, 0x1234);
    51         printf("'%Q' Q! Another '%q' q! \n", 0x1234567887654321ll, 0x1234567887654321ll);
    52         printf("'%Q' with 64bit value and '%p' with 32 bit value. \n", 0x1234567887654321ll, 0x12345678 );
    53         printf("'%Q' 64bit, '%p' 32bit, '%b' 8bit, '%w' 16bit, '%Q' 64bit and '%s' string.\n", 0x1234567887654321ll, 0x12345678, 0x12, 0x1234, 0x1234567887654321ull, "Lovely string" );
     49        printf("Signed formats on uns. numbers: '%d', '%+d', '% d', '%u' (,+, ,u)\n", 321, 321, 321, 321);
     50        printf("Signed formats on sig. numbers: '%d', '%+d', '% d', '%u' (,+, ,u)\n", -321, -321, -321, -321);
     51        printf("Signed with different sized: '%hhd', '%hd', '%d', '%ld', %lld;\n", -3, -32, -321, -32101l, -3210123ll);
     52        printf("And now... '%hhd' byte! '%hd' word! '%d' int! \n", 11, 11111, 1111111111);
     53        printf("Different bases: %#hx, %#hu, %#ho and %#hb\n", 123, 123, 123, 123);
     54        printf("Different bases signed: %#hx, %#hu, %#ho and %#hb\n", -123, -123, -123, -123);
     55        printf("'%llX' llX! Another '%llx' llx! \n", 0x1234567887654321ll, 0x1234567887654321ll);
     56        printf("'%llX' with 64bit value and '%x' with 32 bit value. \n", 0x1234567887654321ll, 0x12345678 );
     57        printf("'%llx' 64bit, '%x' 32bit, '%hhx' 8bit, '%hx' 16bit, '%llX' 64bit and '%s' string.\n", 0x1234567887654321ll, 0x12345678, 0x12, 0x1234, 0x1234567887654321ull, "Lovely string" );
    5458       
    5559        printf("Thats all, folks!\n");
     
    113117static void got_answer(void *private, int retval, ipc_data_t *data)
    114118{
    115         printf("Retval: %d...%s...%X, %X\n", retval, private,
     119        printf("Retval: %d...%s...%zX, %zX\n", retval, private,
    116120               IPC_GET_ARG1(*data), IPC_GET_ARG2(*data));
    117121}
     
    157161        printf("Asking 0 to connect to me...\n");
    158162        res = ipc_connect_to_me(0, 1, 2, &taskid);
    159         printf("Result: %d - taskid: %Q\n", res, taskid);
     163        printf("Result: %d - taskid: %llu\n", res, taskid);
    160164        for (i=0; i < 100; i++) {
    161165                printf("----------------\n");
     
    179183        printf("pinging.\n");
    180184        res = ipc_call_sync(res, NS_PING, 0xbeef,&result);
    181         printf("Retval: %d - received: %P\n", res, result);
     185        printf("Retval: %d - received: %zd\n", res, result);
    182186       
    183187}
  • libc/Makefile

    rc05290e r11a4fbf  
    3131
    3232LIBC_PREFIX = .
     33SOFTINT_PREFIX = ../softint
    3334
    3435## Setup toolchain
     
    3940## Sources
    4041#
     42
    4143
    4244GENERIC_SOURCES = \
  • libc/Makefile.toolchain

    rc05290e r11a4fbf  
    2929DEFS = -DARCH=$(ARCH)
    3030CFLAGS = -fno-builtin -Werror-implicit-function-declaration -Wmissing-prototypes -Werror -O3 -nostdlib -nostdinc -I$(LIBC_PREFIX)/include -I$(LIBC_PREFIX)/arch/$(ARCH)/include
    31 LFLAGS = -M
     31LFLAGS = -M -N $(SOFTINT_PREFIX)/softint.a
    3232AFLAGS =
     33
    3334
    3435## Setup platform configuration
  • libc/generic/io/print.c

    rc05290e r11a4fbf  
    3333#include <stdarg.h>
    3434
    35 #define __PRINTF_FLAG_PREFIX 0x00000001
    36 #define __PRINTF_FLAG_SIGNED 0x00000002
    37 
    38 static char digits[] = "0123456789abcdef";      /**< Hexadecimal characters */
    39 
    40 /** Print hexadecimal digits
    41  *
    42  * Print fixed count of hexadecimal digits from
    43  * the number num. The digits are printed in
    44  * natural left-to-right order starting with
    45  * the width-th digit.
    46  *
    47  * @param num   Number containing digits.
    48  * @param width Count of digits to print.
    49  *
    50  */
    51 static int print_fixed_hex(const uint64_t num, const int width, uint64_t flags)
    52 {
    53         int i;
    54         char buf[18]; /* 16 bytes for number + 2 for optionaly prefix */
    55         char *bptr;
    56        
    57         bptr = buf;
    58        
    59         if (flags & __PRINTF_FLAG_PREFIX) {
    60                 buf[0] = '0';
    61                 buf[1] = 'x';
    62                 bptr += 2;
    63         }
    64 
    65         for (i = width*8 - 4; i >= 0; i -= 4)
    66                 *bptr++ = digits[(num>>i) & 0xf];
    67         *bptr = '\0';
    68        
    69         return putstr(buf);     
    70 }
    71 
     35#define __PRINTF_FLAG_PREFIX            0x00000001      /* show prefixes 0x or 0*/
     36#define __PRINTF_FLAG_SIGNED            0x00000002      /* signed / unsigned number */
     37#define __PRINTF_FLAG_ZEROPADDED        0x00000004      /* print leading zeroes */
     38#define __PRINTF_FLAG_LEFTALIGNED       0x00000010      /* align to left */
     39#define __PRINTF_FLAG_SHOWPLUS          0x00000020      /* always show + sign */
     40#define __PRINTF_FLAG_SPACESIGN         0x00000040      /* print space instead of plus */
     41#define __PRINTF_FLAG_BIGCHARS          0x00000080      /* show big characters */
     42#define __PRINTF_FLAG_NEGATIVE          0x00000100      /* number has - sign */
     43
     44#define PRINT_NUMBER_BUFFER_SIZE        (64+5)          /* Buffer big enought for 64 bit number
     45                                                         * printed in base 2, sign, prefix and
     46                                                         * 0 to terminate string.. (last one is only for better testing
     47                                                         * end of buffer by zero-filling subroutine)
     48                                                         */
     49typedef enum {
     50        PrintfQualifierByte = 0,
     51        PrintfQualifierShort,
     52        PrintfQualifierInt,
     53        PrintfQualifierLong,
     54        PrintfQualifierLongLong,
     55        PrintfQualifierSizeT,
     56        PrintfQualifierPointer
     57} qualifier_t;
     58
     59static char digits_small[] = "0123456789abcdef";        /* Small hexadecimal characters */
     60static char digits_big[] = "0123456789ABCDEF";  /* Big hexadecimal characters */
    7261
    7362/** Print number in given base
     
    7766 *
    7867 * @param num  Number to print.
     68 * @param size not used, in future releases will be replaced with precision and width params
    7969 * @param base Base to print the number in (should
    8070 *             be in range 2 .. 16).
     71 * @param flags output modifiers
     72 * @return number of written characters or EOF
    8173 *
    8274 */
    83 static int print_number(const unsigned long num, const unsigned int base, uint64_t flags)
     75static int print_number(uint64_t num, size_t size, int base , uint64_t flags)
    8476{
    85         int val = num;
    86         char d[sizeof(unsigned long)*8+1];      /* this is good enough even for base == 2 */
    87         int i = sizeof(unsigned long)*8-1;
    88        
    89         /* FIXME: if signed, print sign */
    90        
    91         do {
    92                 d[i--] = digits[val % base];
    93         } while (val /= base);
    94        
    95         d[sizeof(unsigned long)*8] = 0;
    96 
    97         return putstr(&d[i + 1]);
     77        /* FIXME: This is only first version.
     78         * Printf does not have support for specification of size
     79         * and precision, so this function writes with parameters defined by
     80         * their type size.
     81         */
     82        char *digits = digits_small;
     83        char d[PRINT_NUMBER_BUFFER_SIZE];       /* this is good enough even for base == 2, prefix and sign */
     84        char *ptr = &d[PRINT_NUMBER_BUFFER_SIZE - 1];
     85       
     86        if (flags & __PRINTF_FLAG_BIGCHARS)
     87                digits = digits_big;   
     88       
     89        *ptr-- = 0; /* Put zero at end of string */
     90
     91        if (num == 0) {
     92                *ptr-- = '0';
     93        } else {
     94                do {
     95                        *ptr-- = digits[num % base];
     96                } while (num /= base);
     97        }
     98        if (flags & __PRINTF_FLAG_PREFIX) { /*FIXME*/
     99                switch(base) {
     100                        case 2: /* Binary formating is not standard, but usefull */
     101                                *ptr = 'b';
     102                                if (flags & __PRINTF_FLAG_BIGCHARS) *ptr = 'B';
     103                                ptr--;
     104                                *ptr-- = '0';
     105                                break;
     106                        case 8:
     107                                *ptr-- = 'o';
     108                                break;
     109                        case 16:
     110                                *ptr = 'x';
     111                                if (flags & __PRINTF_FLAG_BIGCHARS) *ptr = 'X';
     112                                ptr--;
     113                                *ptr-- = '0';
     114                                break;
     115                }
     116        }
     117       
     118        if (flags & __PRINTF_FLAG_SIGNED) {
     119                if (flags & __PRINTF_FLAG_NEGATIVE) {
     120                        *ptr-- = '-';
     121                } else if (flags & __PRINTF_FLAG_SHOWPLUS) {
     122                                *ptr-- = '+';
     123                        } else if (flags & __PRINTF_FLAG_SPACESIGN) {
     124                                        *ptr-- = ' ';
     125                                }
     126        }
     127
     128        /* Print leading zeroes */
     129
     130        if (flags & __PRINTF_FLAG_LEFTALIGNED) {
     131                flags &= ~__PRINTF_FLAG_ZEROPADDED;
     132        }
     133        if (flags & __PRINTF_FLAG_ZEROPADDED) {
     134                while (ptr != d ) {
     135                        *ptr-- = '0';
     136                }
     137        }
     138       
     139        return putstr(++ptr);
    98140}
    99141
     
    157199int printf(const char *fmt, ...)
    158200{
    159         int i = 0, j = 0;
    160         int counter, retval;
     201        int i = 0, j = 0; /* i is index of currently processed char from fmt, j is index to the first not printed nonformating character */
     202        int end;
     203        int counter; /* counter of printed characters */
     204        int retval; /* used to store return values from called functions */
    161205        va_list ap;
    162         char c;
    163 
     206        char c;
     207        qualifier_t qualifier;  /* type of argument */
     208        int base;       /* base in which will be parameter (numbers only) printed */
     209        uint64_t number; /* argument value */
     210        size_t  size; /* byte size of integer parameter */
    164211        uint64_t flags;
    165212       
     
    177224                                counter += retval;
    178225                        }
    179                        
    180                         j = ++i;
    181                        
     226               
     227                        j = i;
    182228                        /* parse modifiers */
    183229                        flags = 0;
    184                         /*switch (c = fmt[i]) {
    185                                 case '-':       
     230                        end = 0;
     231                       
     232                        do {
     233                                ++i;
     234                                switch (c = fmt[i]) {
     235                                        case '#': flags |= __PRINTF_FLAG_PREFIX; break;
     236                                        case '-': flags |= __PRINTF_FLAG_LEFTALIGNED; break;
     237                                        case '+': flags |= __PRINTF_FLAG_SHOWPLUS; break;
     238                                        case ' ': flags |= __PRINTF_FLAG_SPACESIGN; break;
     239                                        case '0': flags |= __PRINTF_FLAG_ZEROPADDED; break;
     240                                        default: end = 1;
     241                                };     
     242                               
     243                        } while (end == 0);     
     244                        /* TODO: width & '*' operator */
     245                        /* TODO: precision and '*' operator */ 
     246
     247                        switch (fmt[i++]) {
     248                                case 'h':       /* char or short */
     249                                        qualifier = PrintfQualifierShort;
     250                                        if (fmt[i] == 'h') {
     251                                                i++;
     252                                                qualifier = PrintfQualifierByte;
     253                                        }
     254                                        break;
     255                                case 'l':       /* long or long long*/
     256                                        qualifier = PrintfQualifierLong;
     257                                        if (fmt[i] == 'l') {
     258                                                i++;
     259                                                qualifier = PrintfQualifierLongLong;
     260                                        }
     261                                        break;
     262                                case 'z':       /* size_t */
     263                                        qualifier = PrintfQualifierSizeT;
     264                                        break;
     265                                default:
     266                                        qualifier = PrintfQualifierInt; /* default type */
     267                                        --i;
    186268                        }       
    187                         */
     269                       
     270                        base = 10;
     271
    188272                        switch (c = fmt[i]) {
    189 
    190                                 /* percentile itself */
    191                                 case '%':
    192                                         --j;    /* soon will be incremented back */
    193                                         break;
    194273
    195274                                /*
     
    202281                                       
    203282                                        counter += retval;
    204                                         break;
     283                                        j = i + 1;
     284                                        goto next_char;
    205285                                case 'c':
    206286                                        c = va_arg(ap, unsigned long);
     
    210290                                       
    211291                                        counter += retval;
    212                                         break;
    213 
    214                                 /*
    215                                 * Hexadecimal conversions with fixed width.
     292                                        j = i + 1;
     293                                        goto next_char;
     294
     295                                /*
     296                                 * Integer values
    216297                                */
    217                                 case 'P':
    218                                         flags |= __PRINTF_FLAG_PREFIX;
     298                                case 'P': /* pointer */
     299                                        flags |= __PRINTF_FLAG_BIGCHARS;
    219300                                case 'p':
    220                                         if ((retval = print_fixed_hex(va_arg(ap, unsigned long), sizeof(unsigned long), flags)) == EOF ) {
    221                                                 return -counter;
    222                                         };
    223 
    224                                         counter += retval;
    225                                         break;
    226                                 case 'Q':
    227                                         flags |= __PRINTF_FLAG_PREFIX;
    228                                 case 'q':
    229                                         if ((retval = print_fixed_hex(va_arg(ap, uint64_t), sizeof(uint64_t), flags)) == EOF ) {
    230                                                 return -counter;
    231                                         };
    232 
    233                                         counter += retval;
    234                                         break;
    235                                 case 'L':
    236                                         flags |= __PRINTF_FLAG_PREFIX;
    237                                 case 'l':
    238                                         if ((retval = print_fixed_hex(va_arg(ap, unsigned long), sizeof(uint32_t), flags)) == EOF ) {
    239                                                 return -counter;
    240                                         };
    241 
    242                                         counter += retval;
    243                                         break;
    244                                 case 'W':
    245                                         flags |= __PRINTF_FLAG_PREFIX;
    246                                 case 'w':
    247                                         if ((retval = print_fixed_hex(va_arg(ap, unsigned long), sizeof(uint16_t), flags)) == EOF ) {
    248                                                 return -counter;
    249                                         };
    250 
    251                                         counter += retval;
    252                                         break;
    253                                 case 'B':
    254                                         flags |= __PRINTF_FLAG_PREFIX;
    255                                 case 'b':
    256                                         if ((retval = print_fixed_hex(va_arg(ap, unsigned long), sizeof(uint8_t), flags)) == EOF ) {
    257                                                 return -counter;
    258                                         };
    259 
    260                                         counter += retval;
    261                                         break;
    262                                 /*
    263                                 * Decimal and hexadecimal conversions.
    264                                 */
     301                                        flags |= __PRINTF_FLAG_PREFIX;
     302                                        base = 16;
     303                                        qualifier = PrintfQualifierPointer;
     304                                        break; 
     305                                case 'b':
     306                                        base = 2;
     307                                        break;
     308                                case 'o':
     309                                        base = 8;
     310                                        break;
    265311                                case 'd':
    266312                                case 'i':
    267                                         flags |= __PRINTF_FLAG_SIGNED;
    268                                         if ((retval = print_number(va_arg(ap,unsigned long), 10, flags)) == EOF ) {
    269                                                 return -counter;
    270                                         };
    271 
    272                                         counter += retval;
    273                                         break;
     313                                        flags |= __PRINTF_FLAG_SIGNED; 
     314                                case 'u':
     315                                        break;
    274316                                case 'X':
    275                                         flags |= __PRINTF_FLAG_PREFIX;
     317                                        flags |= __PRINTF_FLAG_BIGCHARS;
    276318                                case 'x':
    277                                         if ((retval = print_number(va_arg(ap, unsigned long), 16, flags)) == EOF ) {
    278                                                 return -counter;
    279                                         };
    280 
    281                                         counter += retval;
    282                                         break;
     319                                        base = 16;
     320                                        break;
     321                                /* percentile itself */
     322                                case '%':
     323                                        j = i;
     324                                        goto next_char;
    283325                                /*
    284326                                * Bad formatting.
    285327                                */
    286328                                default:
     329                                        /* Unknown format
     330                                         *  now, the j is index of '%' so we will
     331                                         * print whole bad format sequence
     332                                         */
     333                                        goto next_char;         
     334                        }
     335               
     336               
     337                /* Print integers */
     338                        /* print number */
     339                        switch (qualifier) {
     340                                case PrintfQualifierByte:
     341                                        size = sizeof(unsigned char);
     342                                        number = (uint64_t)va_arg(ap, unsigned int);
     343                                        break;
     344                                case PrintfQualifierShort:
     345                                        size = sizeof(unsigned short);
     346                                        number = (uint64_t)va_arg(ap, unsigned int);
     347                                        break;
     348                                case PrintfQualifierInt:
     349                                        size = sizeof(unsigned int);
     350                                        number = (uint64_t)va_arg(ap, unsigned int);
     351                                        break;
     352                                case PrintfQualifierLong:
     353                                        size = sizeof(unsigned long);
     354                                        number = (uint64_t)va_arg(ap, unsigned long);
     355                                        break;
     356                                case PrintfQualifierLongLong:
     357                                        size = sizeof(unsigned long long);
     358                                        number = (uint64_t)va_arg(ap, unsigned long long);
     359                                        break;
     360                                case PrintfQualifierPointer:
     361                                        size = sizeof(void *);
     362                                        number = (uint64_t)(unsigned long)va_arg(ap, void *);
     363                                        break;
     364                                case PrintfQualifierSizeT:
     365                                        size = sizeof(size_t);
     366                                        number = (uint64_t)va_arg(ap, size_t);
     367                                        break;
     368                                default: /* Unknown qualifier */
    287369                                        return -counter;
     370                                       
    288371                        }
    289                         ++j;
     372                       
     373                        if (flags & __PRINTF_FLAG_SIGNED) {
     374                                if (number & (0x1 << (size*8 - 1))) {
     375                                        flags |= __PRINTF_FLAG_NEGATIVE;
     376                               
     377                                        if (size == sizeof(uint64_t)) {
     378                                                number = -((int64_t)number);
     379                                        } else {
     380                                                number = ~number;
     381                                                number &= (~((0xFFFFFFFFFFFFFFFFll) <<  (size * 8)));
     382                                                number++;
     383                                        }
     384                                }
     385                        }
     386
     387                        if ((retval = print_number(number, size, base, flags)) == EOF ) {
     388                                return -counter;
     389                        };
     390
     391                        counter += retval;
     392                        j = i + 1;
    290393                }       
     394next_char:
     395                       
    291396                ++i;
    292397        }
  • ns/Makefile

    rc05290e r11a4fbf  
    3232LIBC_PREFIX = ../libc
    3333LIBIPC_PREFIX = ../libipc
     34SOFTINT_PREFIX = ../softint
    3435include $(LIBC_PREFIX)/Makefile.toolchain
    3536
  • ns/ns.c

    rc05290e r11a4fbf  
    1818        while (1) {
    1919                callid = ipc_wait_for_call(&call, 0);
    20                 printf("Received call from: %P..%Q\n", &call.taskid,call.taskid);
     20                printf("Received call from: %P..%llX\n", &call.taskid,call.taskid);
    2121                switch (IPC_GET_METHOD(call.data)) {
    2222                case IPC_M_CONNECTTOME:
    23                         printf("Somebody wants to connect with phoneid %d...accepting\n", IPC_GET_ARG3(call.data));
     23                        printf("Somebody wants to connect with phoneid %zd...accepting\n", IPC_GET_ARG3(call.data));
    2424                        service = IPC_GET_ARG3(call.data);
    2525                        retval = 0;
    2626                        break;
    2727                case IPC_M_CONNECTMETO:
    28                         printf("Somebody wants to connect to: %d\n",
     28                        printf("Somebody wants to connect to: %zd\n",
    2929                               IPC_GET_ARG1(call.data));
    3030                        retval = 0;
     
    4343                        break;
    4444                default:
    45                         printf("Unknown method: %d\n", IPC_GET_METHOD(call.data));
     45                        printf("Unknown method: %zd\n", IPC_GET_METHOD(call.data));
    4646                        retval = ENOENT;
    4747                        break;
Note: See TracChangeset for help on using the changeset viewer.