Ignore:
Timestamp:
Feb 3, 2016, 9:57:40 AM (9 years ago)
Author:
alain
Message:

Introducing the generic xprintf() function, called by the various *printf() functions.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • soft/giet_vm/giet_libs/stdio.c

    r767 r771  
    88#include <stdarg.h>
    99#include <stdio.h>
     10#include <stdlib.h>
    1011#include <giet_config.h>
    11 
    12 /////////////////////////////////////////////////////////////////////////////////////
    13 // This function is called by both the giet_tty_printf() and
    14 // the giet_fat_printf() system calls.
    15 // It analyse the <format> and <args> arguments and returns a byte stream
    16 // in the <stream> buffer. The TO_STREAM macro checks buffer overflow.
    17 // It returns number of written bytes in case of success.
    18 // It returns 0xFFFFFFFF in case of error (illegal format, or buffer overflow).
    19 /////////////////////////////////////////////////////////////////////////////////////
    20 
    21 #define TO_STREAM(x) do { stream[ps] = (x); ps++; if(ps==maxlen) return -1; } while(0);
    22 
    23 static unsigned int xprintf( char*        stream,
    24                              unsigned int maxlen,
    25                              char*        format,
    26                              va_list*     args)
    27 {
    28     unsigned int ps = 0;    // write pointer to the stream buffer
    29 
    30 xprintf_text:
    31 
    32     while ( *format != 0 )
    33     {
    34 
    35         if (*format == '%')   // copy argument to stream
    36         {
    37             format++;
    38             goto xprintf_arguments;
    39         }
    40         else                  // copy one char to stream
    41         {
    42             TO_STREAM( *format );
    43             format++;
    44         }
    45     }
    46 
    47     return ps;
    48 
    49 xprintf_arguments:
    50 
    51     {
    52         char              buf[30];    // buffer to display one number
    53         char *            pbuf;       // pointer on first char to display
    54         unsigned int      len = 0;    // number of char to display
    55         static const char HexaTab[] = "0123456789ABCDEF";
    56         unsigned int      i;
    57        
    58         // Ignore fields width and precision
    59         for ( ; *format >= '0' && *format <= '9'; format++ );
    60 
    61         switch (*format)
    62         {
    63             case ('c'):             // char conversion
    64             {
    65                 int val = va_arg( *args, int );
    66                 buf[0] = val;
    67                 pbuf   = buf;
    68                 len    = 1;
    69                 break;
    70             }
    71             case ('d'):             // decimal signed integer
    72             {
    73                 int val = va_arg( *args, int );
    74                 if (val < 0)
    75                 {
    76                     TO_STREAM( '-' );
    77                     val = -val;
    78                 }
    79                 for(i = 0; i < 10; i++)
    80                 {
    81 
    82                     buf[9 - i] = HexaTab[val % 10];
    83                     if (!(val /= 10)) break;
    84                 }
    85                 len =  i + 1;
    86                 pbuf = &buf[9 - i];
    87                 break;
    88             }
    89             case ('u'):             // decimal unsigned integer
    90             {
    91                 unsigned int val = va_arg( *args, unsigned int );
    92                 for(i = 0; i < 10; i++)
    93                 {
    94                     buf[9 - i] = HexaTab[val % 10];
    95                     if (!(val /= 10)) break;
    96                 }
    97                 len =  i + 1;
    98                 pbuf = &buf[9 - i];
    99                 break;
    100             }
    101             case ('x'):             // 32 bits hexadecimal
    102             case ('l'):             // 64 bits hexadecimal
    103             {
    104                 unsigned int       imax;
    105                 unsigned long long val;
    106                
    107                 if ( *format == 'l' )   // 64 bits
    108                 {
    109                     val = va_arg( *args, unsigned long long);
    110                     imax = 16;
    111                 }
    112                 else                    // 32 bits
    113                 {
    114                     val = va_arg( *args, unsigned int);
    115                     imax = 8;
    116                 }
    117                
    118                 TO_STREAM( '0' );
    119                 TO_STREAM( 'x' );
    120                
    121                 for(i = 0; i < imax; i++)
    122                 {
    123                     buf[(imax-1) - i] = HexaTab[val % 16];
    124                     if (!(val /= 16))  break;
    125                 }
    126                 len =  i + 1;
    127                 pbuf = &buf[(imax-1) - i];
    128                 break;
    129             }
    130             case ('s'):             /* string */
    131             {
    132                 char* str = va_arg( *args, char* );
    133                 while (str[len]) { len++; }
    134                 pbuf = str;
    135                 break;
    136             }
    137             case ('e'):
    138             case ('f'):
    139             case ('g'):             // IEEE754 64 bits
    140             {
    141                 union
    142                 {
    143                     double d;
    144                     unsigned long long ull;
    145                 } val;
    146                
    147                 val.d = va_arg( *args, double );
    148                
    149                 unsigned long long digits;
    150                 digits = val.ull & 0xFFFFFFFFFFFFFULL;    // mantisse
    151                
    152                 unsigned int base;
    153                 base = (unsigned int)((val.ull & 0x7FF0000000000000ULL) >> 52); // exp
    154 
    155                 unsigned int intp;
    156                 intp = (unsigned int)val.d;         // integer part
    157 
    158                 unsigned int decp;                  // decimal part
    159                
    160                 int isvalue = 0;
    161                
    162                 if (base == 0x7FF) // special values
    163                 {
    164                     if (digits & 0xFFFFFFFFFFFFFULL)  // Not a Number
    165                     {
    166                         buf[0] = 'N';
    167                         buf[1] = 'a';
    168                         buf[2] = 'N';
    169                         len = 3;
    170                         pbuf = buf;
    171                     }
    172                     else                              // infinite
    173                     {
    174                         /* inf */
    175                         buf[0] = (val.ull & 0x8000000000000000ULL) ? '-' : '+';
    176                         buf[1] = 'i';
    177                         buf[2] = 'n';
    178                         buf[3] = 'f';
    179                         len = 4;
    180                         pbuf = buf;
    181                     }
    182                     break;
    183                 }
    184                
    185                 if (val.ull & 0x8000000000000000ULL)  // negative
    186                 {
    187                     TO_STREAM( '-' );
    188                     val.d = val.d * -1;
    189                 }
    190                 else                                  // positive
    191                 {
    192                     TO_STREAM( '+' );
    193                 }
    194                
    195                 if (val.d > 0xFFFFFFFF)              // overflow
    196                 {
    197                     buf[0] = 'B';
    198                     buf[1] = 'I';
    199                     buf[2] = 'G';
    200                     len = 3;
    201                     pbuf = buf;
    202                     break;
    203                 }
    204                
    205                 val.d -= (double)intp;
    206                 decp = (unsigned int)(val.d * 1000000000);
    207                
    208                 for(i = 0; i < 10; i++)
    209                 {
    210                     if ((!isvalue) && (intp % 10)) isvalue = 1;
    211                     buf[9 - i] = HexaTab[intp % 10];
    212                     if (!(intp /= 10)) break;
    213                 }
    214                 pbuf = &buf[9 - i];
    215                 len = i+11;
    216                 buf[10] = '.';
    217                
    218                 for(i = 0; i < 9; i++)
    219                 {
    220                     if ((!isvalue) && (decp % 10)) isvalue = 1;
    221                     buf[19 - i] = HexaTab[decp % 10];
    222                     decp /= 10;
    223                 }
    224                
    225                 if (!isvalue)
    226                 {
    227                     if (val.d != 0)                   // underflow
    228                     {
    229                         buf[0] = 'T';
    230                         buf[1] = 'I';
    231                         buf[2] = 'N';
    232                         buf[3] = 'Y';
    233                         len = 4;
    234                         pbuf = buf;
    235                     }
    236                 }
    237 
    238                 break;
    239             }
    240                    
    241             default:       // unsupported argument type
    242             {
    243                 return -1;
    244             }
    245         }  // end switch on  argument type
    246 
    247         format++;
    248 
    249         // copy argument to stream
    250         for( i = 0 ; i < len ; i++ )
    251         {
    252             TO_STREAM( pbuf[i] );
    253         }
    254        
    255         goto xprintf_text;
    256     }
    257 
    258 } // end xprintf()
    25912
    26013
     
    503256{
    504257    va_list      args;
    505     char         stream[4096];
     258    char         string[4096];
    506259    unsigned int length;
    507260
    508261    va_start( args, format );
    509     length = xprintf( stream, 4096, format, &args );
     262    length = xprintf( string , 4096 , format , &args );
    510263    va_end( args );
    511264
     
    513266   
    514267    if ( sys_call( SYSCALL_TTY_WRITE,
    515                    (unsigned int)stream,   // buffer address
     268                   (unsigned int)string,   // buffer address
    516269                   length,                 // number of characters
    517270                   0xFFFFFFFF,             // channel index from thread context
     
    1092845{
    1093846    va_list      args;
    1094     char         stream[4096];
     847    char         string[4096];
    1095848    unsigned int count;
    1096849
    1097850    va_start( args, format );
    1098 
    1099     count = xprintf( stream, 4096, format, &args );
     851    count = xprintf( string , 4096 , format , &args );
    1100852    va_end( args );
    1101853
     
    1104856    return sys_call( SYSCALL_FAT_WRITE,
    1105857                     fd_id,
    1106                      (unsigned int)stream,
     858                     (unsigned int)string,
    1107859                     count,
    1108860                     0 );      // no physical addressing required
     
    1143895}
    1144896
     897///////////////////////////////////////
     898int giet_fat_dump( unsigned int type,
     899                   char*        pathname,
     900                   unsigned int block_id )
     901{
     902    return sys_call( SYSCALL_FAT_DUMP,
     903                     type,
     904                     (unsigned int)pathname,
     905                     block_id,
     906                     0 );
     907
     908}
     909
     910
    1145911//////////////////////////////////////////////////////////////////////////////////
    1146912//                      Miscellaneous system calls
Note: See TracChangeset for help on using the changeset viewer.