Changeset 771 for soft/giet_vm/giet_libs


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.

Location:
soft/giet_vm/giet_libs
Files:
4 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
  • soft/giet_vm/giet_libs/stdio.h

    r759 r771  
    6868#define SYSCALL_FAT_MMAP             0x2D
    6969#define SYSCALL_FAT_MUNMAP           0x2E
    70 //                                   0x2F
     70#define SYSCALL_FAT_DUMP             0x2F
    7171
    7272#define SYSCALL_NIC_ALLOC            0x30
     
    420420                            unsigned int  length );
    421421
     422extern int giet_fat_dump( unsigned int type,
     423                          char*        pathname,
     424                          unsigned int block_id );
     425
    422426//////////////////////////////////////////////////////////////////////////
    423427//                    Miscelaneous system calls
  • soft/giet_vm/giet_libs/stdlib.c

    r647 r771  
    77
    88#include <stdlib.h>
     9#include <stdio.h>
     10#include <stdarg.h>
    911
    1012/////////////////////////
     
    147149}
    148150
     151
     152//////////////////////////////////////////
     153unsigned int xprintf( char*        string,
     154                      unsigned int length,
     155                      char*        format,
     156                      va_list*     args )
     157{
     158    unsigned int ps = 0;    // write pointer to the string buffer
     159
     160#define TO_STREAM(x) do { string[ps] = (x); ps++; if(ps==length) return -1; } while(0);
     161
     162xprintf_text:
     163
     164    while ( *format != 0 )
     165    {
     166
     167        if (*format == '%')   // copy argument to string
     168        {
     169            format++;
     170            goto xprintf_arguments;
     171        }
     172        else                  // copy one char to string
     173        {
     174            TO_STREAM( *format );
     175            format++;
     176        }
     177    }
     178
     179    return ps;
     180
     181xprintf_arguments:
     182
     183    {
     184        char              buf[30];    // buffer to display one number
     185        char *            pbuf;       // pointer on first char to display
     186        unsigned int      len = 0;    // number of char to display
     187        static const char HexaTab[] = "0123456789ABCDEF";
     188        unsigned int      i;
     189       
     190        // Ignore fields width and precision
     191        for ( ; *format >= '0' && *format <= '9'; format++ );
     192
     193        switch (*format)
     194        {
     195            case ('c'):             // char conversion
     196            {
     197                int val = va_arg( *args, int );
     198                buf[0] = val;
     199                pbuf   = buf;
     200                len    = 1;
     201                break;
     202            }
     203            case ('d'):             // decimal signed integer
     204            {
     205                int val = va_arg( *args, int );
     206                if (val < 0)
     207                {
     208                    TO_STREAM( '-' );
     209                    val = -val;
     210                }
     211                for(i = 0; i < 10; i++)
     212                {
     213
     214                    buf[9 - i] = HexaTab[val % 10];
     215                    if (!(val /= 10)) break;
     216                }
     217                len =  i + 1;
     218                pbuf = &buf[9 - i];
     219                break;
     220            }
     221            case ('u'):             // decimal unsigned integer
     222            {
     223                unsigned int val = va_arg( *args, unsigned int );
     224                for(i = 0; i < 10; i++)
     225                {
     226                    buf[9 - i] = HexaTab[val % 10];
     227                    if (!(val /= 10)) break;
     228                }
     229                len =  i + 1;
     230                pbuf = &buf[9 - i];
     231                break;
     232            }
     233            case ('x'):             // 32 bits hexadecimal
     234            case ('l'):             // 64 bits hexadecimal
     235            {
     236                unsigned int       imax;
     237                unsigned long long val;
     238               
     239                if ( *format == 'l' )   // 64 bits
     240                {
     241                    val = va_arg( *args, unsigned long long);
     242                    imax = 16;
     243                }
     244                else                    // 32 bits
     245                {
     246                    val = va_arg( *args, unsigned int);
     247                    imax = 8;
     248                }
     249               
     250                TO_STREAM( '0' );
     251                TO_STREAM( 'x' );
     252               
     253                for(i = 0; i < imax; i++)
     254                {
     255                    buf[(imax-1) - i] = HexaTab[val % 16];
     256                    if (!(val /= 16))  break;
     257                }
     258                len =  i + 1;
     259                pbuf = &buf[(imax-1) - i];
     260                break;
     261            }
     262            case ('s'):             /* string */
     263            {
     264                char* str = va_arg( *args, char* );
     265                while (str[len]) { len++; }
     266                pbuf = str;
     267                break;
     268            }
     269            case ('e'):
     270            case ('f'):
     271            case ('g'):             // IEEE754 64 bits
     272            {
     273                union
     274                {
     275                    double d;
     276                    unsigned long long ull;
     277                } val;
     278               
     279                val.d = va_arg( *args, double );
     280               
     281                unsigned long long digits;
     282                digits = val.ull & 0xFFFFFFFFFFFFFULL;    // mantisse
     283               
     284                unsigned int base;
     285                base = (unsigned int)((val.ull & 0x7FF0000000000000ULL) >> 52); // exp
     286
     287                unsigned int intp;
     288                intp = (unsigned int)val.d;         // integer part
     289
     290                unsigned int decp;                  // decimal part
     291               
     292                int isvalue = 0;
     293               
     294                if (base == 0x7FF) // special values
     295                {
     296                    if (digits & 0xFFFFFFFFFFFFFULL)  // Not a Number
     297                    {
     298                        buf[0] = 'N';
     299                        buf[1] = 'a';
     300                        buf[2] = 'N';
     301                        len = 3;
     302                        pbuf = buf;
     303                    }
     304                    else                              // infinite
     305                    {
     306                        /* inf */
     307                        buf[0] = (val.ull & 0x8000000000000000ULL) ? '-' : '+';
     308                        buf[1] = 'i';
     309                        buf[2] = 'n';
     310                        buf[3] = 'f';
     311                        len = 4;
     312                        pbuf = buf;
     313                    }
     314                    break;
     315                }
     316               
     317                if (val.ull & 0x8000000000000000ULL)  // negative
     318                {
     319                    TO_STREAM( '-' );
     320                    val.d = val.d * -1;
     321                }
     322                else                                  // positive
     323                {
     324                    TO_STREAM( '+' );
     325                }
     326               
     327                if (val.d > 0xFFFFFFFF)              // overflow
     328                {
     329                    buf[0] = 'B';
     330                    buf[1] = 'I';
     331                    buf[2] = 'G';
     332                    len = 3;
     333                    pbuf = buf;
     334                    break;
     335                }
     336               
     337                val.d -= (double)intp;
     338                decp = (unsigned int)(val.d * 1000000000);
     339               
     340                for(i = 0; i < 10; i++)
     341                {
     342                    if ((!isvalue) && (intp % 10)) isvalue = 1;
     343                    buf[9 - i] = HexaTab[intp % 10];
     344                    if (!(intp /= 10)) break;
     345                }
     346                pbuf = &buf[9 - i];
     347                len = i+11;
     348                buf[10] = '.';
     349               
     350                for(i = 0; i < 9; i++)
     351                {
     352                    if ((!isvalue) && (decp % 10)) isvalue = 1;
     353                    buf[19 - i] = HexaTab[decp % 10];
     354                    decp /= 10;
     355                }
     356               
     357                if (!isvalue)
     358                {
     359                    if (val.d != 0)                   // underflow
     360                    {
     361                        buf[0] = 'T';
     362                        buf[1] = 'I';
     363                        buf[2] = 'N';
     364                        buf[3] = 'Y';
     365                        len = 4;
     366                        pbuf = buf;
     367                    }
     368                }
     369
     370                break;
     371            }
     372                   
     373            default:       // unsupported argument type
     374            {
     375                return -1;
     376            }
     377        }  // end switch on  argument type
     378
     379        format++;
     380
     381        // copy argument to string
     382        for( i = 0 ; i < len ; i++ )
     383        {
     384            TO_STREAM( pbuf[i] );
     385        }
     386       
     387        goto xprintf_text;
     388    }
     389} // end xprintf()
     390
     391///////////////////////////////////////////
     392unsigned int snprintf( char*        string,
     393                       unsigned int length,
     394                       char*        format, ... )
     395{
     396    va_list      args;
     397    unsigned int count;
     398
     399    va_start( args, format );
     400    count = xprintf( string , length , format , &args );
     401    va_end( args );
     402
     403    if ( count == 0xFFFFFFFF ) giet_pthread_exit("error in snprintf()");
     404    else string[count] = 0;
     405
     406    return count;
     407}
    149408// Local Variables:
    150409// tab-width: 4
  • soft/giet_vm/giet_libs/stdlib.h

    r681 r771  
    55// Copyright (c) UPMC-LIP6
    66///////////////////////////////////////////////////////////////////////////////////
     7
     8#include <stdarg.h>
    79
    810#ifndef _STDLIB_H
     
    6062              char* source );
    6163
     64///////////////////////////////////////////////////////////////////////////////////////
     65// This user function build a formated string.
     66// It analyse the <format> argument and uses the other arguments to returns
     67// a formated string in the <string> buffer.
     68// The <length> define the destination buffer size (bytes).
     69// It returns the number of written characters in case of success.
     70// It returns 0xFFFFFFFF in case of error (illegal format, or buffer overflow).
     71///////////////////////////////////////////////////////////////////////////////////////
     72unsigned int snprintf( char*        string,
     73                       unsigned int length,
     74                       char*        format, ... );
     75
     76///////////////////////////////////////////////////////////////////////////////////////
     77// This service function is called by:
     78// - giet_fat_fprintf()
     79// - giet_tty_printf()
     80// - snprintf()
     81///////////////////////////////////////////////////////////////////////////////////////
     82unsigned int xprintf( char*        string,
     83                      unsigned int length,
     84                      char*        format,
     85                      va_list*     args );
     86               
     87
     88
    6289#endif
     90
    6391
    6492// Local Variables:
Note: See TracChangeset for help on using the changeset viewer.