Ignore:
Timestamp:
May 28, 2015, 3:34:23 PM (9 years ago)
Author:
laurent
Message:

Try

File:
1 edited

Legend:

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

    r558 r580  
    142142{
    143143    int ret;                    // return value from the syscall
     144    enum TModifiers {NO_MOD, L_MOD, LL_MOD} modifiers;
    144145
    145146printf_text:
     
    164165        {
    165166            format++;
     167            modifiers = NO_MOD;
    166168            goto printf_arguments;
    167169        }
     
    173175
    174176    {
    175         char buf[20];
     177        char buf[30];
    176178        char * pbuf;
    177179        unsigned int len = 0;
    178180        static const char HexaTab[] = "0123456789ABCDEF";
    179181        unsigned int i;
     182       
     183        /* Ignored fields : width and precision */
     184        for (; *format >= '0' && *format <= '9'; format++);
    180185
    181186        switch (*format++)
    182187        {
     188            case ('%'):
    183189            case ('c'):             /* char conversion */
    184190            {
    185191                int val = va_arg( *args, int );
     192                if (modifiers != NO_MOD) goto return_error; //Modifiers have no meaning
     193               
    186194                len = 1;
    187195                buf[0] = val;
     
    189197                break;
    190198            }
    191             case ('d'):             /* 32 bits decimal signed integer */
     199            case ('d'):             /* decimal signed integer */
    192200            {
    193201                int val = va_arg( *args, int );
     202               
     203                if (modifiers == LL_MOD) goto return_error; //64 bits not supported
     204               
    194205                if (val < 0)
    195206                {
     
    211222                break;
    212223            }
    213             case ('u'):             /* 32 bits decimal unsigned integer */
     224            case ('u'):             /* decimal unsigned integer */
    214225            {
    215                 unsigned int val = va_arg( *args, unsigned int );
    216                 for(i = 0; i < 10; i++)
    217                 {
    218                     buf[9 - i] = HexaTab[val % 10];
    219                     if (!(val /= 10)) break;
    220                 }
    221                 len =  i + 1;
    222                 pbuf = &buf[9 - i];
    223                 break;
     226                if (modifiers != LL_MOD) //32 bits integer
     227                {
     228                    unsigned int val = va_arg( *args, unsigned int );
     229                    for(i = 0; i < 10; i++)
     230                    {
     231                        buf[9 - i] = HexaTab[val % 10];
     232                        if (!(val /= 10)) break;
     233                    }
     234                    len =  i + 1;
     235                    pbuf = &buf[9 - i];
     236                    break;
     237                }
     238                //64 bits : base 10 unsupported : continue to hexa
    224239            }
    225             case ('x'):             /* 32 bits hexadecimal integer */
     240            case ('x'):
     241            case ('X'):             /* hexadecimal integer */
    226242            {
    227                 unsigned int val = va_arg( *args, unsigned int );
    228                 ret = sys_call(SYSCALL_TTY_WRITE,
    229                                (unsigned int)"0x",
    230                                2,
    231                                channel,
    232                                0);
    233                 if (ret != 2) goto return_error;       
    234                 for(i = 0; i < 8; i++)
    235                 {
    236                     buf[7 - i] = HexaTab[val % 16];
    237                     if (!(val /= 16))  break;
    238                 }
    239                 len =  i + 1;
    240                 pbuf = &buf[7 - i];
    241                 break;
    242             }
    243             case ('l'):            /* 64 bits hexadecimal unsigned */
    244             {
    245                 unsigned long long val = va_arg( *args, unsigned long long );
     243                unsigned long long val;
     244                int imax;
     245               
     246                if (modifiers == LL_MOD) //64 bits
     247                {
     248                    val = va_arg( *args, unsigned long long);
     249                   
     250                    if (*(format-1) == 'u' && (!(val & 0xFFFFFFFF00000000))) //if asked to print in base 10, can do only if it fits in 32 bits
     251                    {
     252                        unsigned int uintv = (unsigned int) val;
     253                       
     254                        for(i = 0; i < 10; i++)
     255                        {
     256                            buf[9 - i] = HexaTab[uintv % 10];
     257                            if (!(uintv /= 10)) break;
     258                        }
     259                        len =  i + 1;
     260                        pbuf = &buf[9 - i];
     261                        break;
     262                    }
     263                   
     264                    imax = 16;
     265                }
     266                else //32 bits
     267                {
     268                    val = va_arg( *args, unsigned int);
     269                    imax = 8;
     270                }
     271               
    246272                ret = sys_call(SYSCALL_TTY_WRITE,
    247273                               (unsigned int)"0x",
     
    250276                               0);
    251277                if (ret != 2) goto return_error;
    252                 for(i = 0; i < 16; i++)
    253                 {
    254                     buf[15 - i] = HexaTab[val % 16];
     278               
     279                for(i = 0; i < imax; i++)
     280                {
     281                    buf[(imax-1) - i] = HexaTab[val % 16];
    255282                    if (!(val /= 16))  break;
    256283                }
    257284                len =  i + 1;
    258                 pbuf = &buf[15 - i];
     285                pbuf = &buf[(imax-1) - i];
    259286                break;
    260287            }
     
    262289            {
    263290                char* str = va_arg( *args, char* );
     291               
     292                if (modifiers != NO_MOD) goto return_error; //Modifiers have no meaning
     293               
    264294                while (str[len])
    265295                {
     
    269299                break;
    270300            }
     301            case ('e'):
     302            case ('f'):
     303            case ('g'):             /* IEEE754 64 bits */
     304            {
     305               
     306                double vald = va_arg( *args, double);
     307               
     308                unsigned long long
     309                    val = *(unsigned long long*)&vald, //get ieee754 without conversion
     310                    digits = val & 0xFFFFFFFFFFFFF;    //get mantissa
     311               
     312                unsigned int
     313                    base = (unsigned int)((val & 0x7FF0000000000000) >> 52), //get exposant
     314                    intp = (unsigned int)vald,         //get integer part of the float
     315                    decp;
     316               
     317                int isvalue = 0;
     318               
     319                if (base == 0x7FF) //special value
     320                {
     321                    if (digits & 0xFFFFFFFFFFFFF)
     322                    {
     323                        /* Not a Number */
     324                        buf[0] = 'N';
     325                        buf[1] = 'a';
     326                        buf[2] = 'N';
     327                        len = 3;
     328                        pbuf = buf;
     329                    }
     330                    else
     331                    {
     332                        /* inf */
     333                        buf[0] = (val & 0x8000000000000000) ? '-' : '+';
     334                        buf[1] = 'i';
     335                        buf[2] = 'n';
     336                        buf[3] = 'f';
     337                        len = 4;
     338                        pbuf = buf;
     339                    }
     340                    break;
     341                }
     342               
     343                if (val & 0x8000000000000000)
     344                {
     345                    /* negative */
     346                    ret = sys_call(SYSCALL_TTY_WRITE,
     347                                (unsigned int)"-",
     348                                1,
     349                                channel,
     350                                0);
     351                    if (ret != 1) goto return_error;
     352                    vald = vald * -1;
     353                }
     354                else
     355                {
     356                    /* positive */
     357                    ret = sys_call(SYSCALL_TTY_WRITE,
     358                                (unsigned int)"+",
     359                                1,
     360                                channel,
     361                                0);
     362                    if (ret != 1) goto return_error;
     363                }
     364               
     365                if (vald > 0xFFFFFFFF)
     366                {
     367                    /* overflow */
     368                    buf[0] = 'B';
     369                    buf[1] = 'I';
     370                    buf[2] = 'G';
     371                    len = 3;
     372                    pbuf = buf;
     373                    break;
     374                }
     375               
     376                vald -= (double)intp;
     377                decp = (unsigned int)(vald * 100000000);
     378               
     379                for(i = 0; i < 10; i++)
     380                {
     381                    if ((!isvalue) && (intp % 10)) isvalue = 1;
     382                    buf[9 - i] = HexaTab[intp % 10];
     383                    if (!(intp /= 10)) break;
     384                }
     385                pbuf = &buf[9 - i];
     386                len = i+11;
     387                buf[10] = '.';
     388               
     389                for(i = 0; i < 9; i++)
     390                {
     391                    if ((!isvalue) && (decp % 10)) isvalue = 1;
     392                    buf[19 - i] = HexaTab[decp % 10];
     393                    decp /= 10;
     394                }
     395               
     396                if (!isvalue)
     397                {
     398                    if (vald != 0)
     399                    {
     400                        /* underflow */
     401                        buf[0] = 'T';
     402                        buf[1] = 'I';
     403                        buf[2] = 'N';
     404                        buf[3] = 'Y';
     405                        len = 4;
     406                        pbuf = buf;
     407                    }
     408                }
     409
     410                break;
     411            }
     412            case ('l'):
     413                switch (modifiers)
     414                {
     415                    case NO_MOD:
     416                        modifiers = L_MOD;
     417                        goto printf_arguments;
     418                   
     419                    case L_MOD:
     420                        modifiers = LL_MOD;
     421                        goto printf_arguments;
     422                   
     423                    default:
     424                        goto return_error;
     425                }
     426
     427            /* Ignored fields : width and precision */
     428            case ('.'): goto printf_arguments;
     429               
    271430            default:
    272431                goto return_error;
Note: See TracChangeset for help on using the changeset viewer.