OpenCores
URL https://opencores.org/ocsvn/neorv32/neorv32/trunk

Subversion Repositories neorv32

[/] [neorv32/] [trunk/] [sw/] [example/] [coremark/] [ee_printf.c] - Diff between revs 38 and 65

Only display areas with differences | Details | Blame | View Log

Rev 38 Rev 65
/*
/*
Copyright 2018 Embedded Microprocessor Benchmark Consortium (EEMBC)
Copyright 2018 Embedded Microprocessor Benchmark Consortium (EEMBC)
 
 
Licensed under the Apache License, Version 2.0 (the "License");
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
You may obtain a copy of the License at
 
 
    http://www.apache.org/licenses/LICENSE-2.0
    http://www.apache.org/licenses/LICENSE-2.0
 
 
Unless required by applicable law or agreed to in writing, software
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
See the License for the specific language governing permissions and
limitations under the License.
limitations under the License.
*/
*/
 
 
/* Modified for the NEORV32 Processor - by Stephan Nolting */
/* Modified for the NEORV32 Processor - by Stephan Nolting */
 
 
#include <coremark.h>
#include <coremark.h>
#include <stdarg.h>
#include <stdarg.h>
 
 
#include <neorv32.h>
#include <neorv32.h>
 
 
#define ZEROPAD   (1 << 0) /* Pad with zero */
#define ZEROPAD   (1 << 0) /* Pad with zero */
#define SIGN      (1 << 1) /* Unsigned/signed long */
#define SIGN      (1 << 1) /* Unsigned/signed long */
#define PLUS      (1 << 2) /* Show plus */
#define PLUS      (1 << 2) /* Show plus */
#define SPACE     (1 << 3) /* Spacer */
#define SPACE     (1 << 3) /* Spacer */
#define LEFT      (1 << 4) /* Left justified */
#define LEFT      (1 << 4) /* Left justified */
#define HEX_PREP  (1 << 5) /* 0x */
#define HEX_PREP  (1 << 5) /* 0x */
#define UPPERCASE (1 << 6) /* 'ABCDEF' */
#define UPPERCASE (1 << 6) /* 'ABCDEF' */
 
 
#define is_digit(c) ((c) >= '0' && (c) <= '9')
#define is_digit(c) ((c) >= '0' && (c) <= '9')
 
 
static char *    digits       = "0123456789abcdefghijklmnopqrstuvwxyz";
static char *    digits       = "0123456789abcdefghijklmnopqrstuvwxyz";
static char *    upper_digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
static char *    upper_digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
static ee_size_t strnlen(const char *s, ee_size_t count);
static ee_size_t strnlen(const char *s, ee_size_t count);
 
 
static ee_size_t
static ee_size_t
strnlen(const char *s, ee_size_t count)
strnlen(const char *s, ee_size_t count)
{
{
    const char *sc;
    const char *sc;
    for (sc = s; *sc != '\0' && count--; ++sc)
    for (sc = s; *sc != '\0' && count--; ++sc)
        ;
        ;
    return sc - s;
    return sc - s;
}
}
 
 
static int
static int
skip_atoi(const char **s)
skip_atoi(const char **s)
{
{
    int i = 0;
    int i = 0;
    while (is_digit(**s))
    while (is_digit(**s))
        i = i * 10 + *((*s)++) - '0';
        i = i * 10 + *((*s)++) - '0';
    return i;
    return i;
}
}
 
 
static char *
static char *
number(char *str, long num, int base, int size, int precision, int type)
number(char *str, long num, int base, int size, int precision, int type)
{
{
    char  c, sign, tmp[66];
    char  c, sign, tmp[66];
    char *dig = digits;
    char *dig = digits;
    int   i;
    int   i;
 
 
    if (type & UPPERCASE)
    if (type & UPPERCASE)
        dig = upper_digits;
        dig = upper_digits;
    if (type & LEFT)
    if (type & LEFT)
        type &= ~ZEROPAD;
        type &= ~ZEROPAD;
    if (base < 2 || base > 36)
    if (base < 2 || base > 36)
        return 0;
        return 0;
 
 
    c    = (type & ZEROPAD) ? '0' : ' ';
    c    = (type & ZEROPAD) ? '0' : ' ';
    sign = 0;
    sign = 0;
    if (type & SIGN)
    if (type & SIGN)
    {
    {
        if (num < 0)
        if (num < 0)
        {
        {
            sign = '-';
            sign = '-';
            num  = -num;
            num  = -num;
            size--;
            size--;
        }
        }
        else if (type & PLUS)
        else if (type & PLUS)
        {
        {
            sign = '+';
            sign = '+';
            size--;
            size--;
        }
        }
        else if (type & SPACE)
        else if (type & SPACE)
        {
        {
            sign = ' ';
            sign = ' ';
            size--;
            size--;
        }
        }
    }
    }
 
 
    if (type & HEX_PREP)
    if (type & HEX_PREP)
    {
    {
        if (base == 16)
        if (base == 16)
            size -= 2;
            size -= 2;
        else if (base == 8)
        else if (base == 8)
            size--;
            size--;
    }
    }
 
 
    i = 0;
    i = 0;
 
 
    if (num == 0)
    if (num == 0)
        tmp[i++] = '0';
        tmp[i++] = '0';
    else
    else
    {
    {
        while (num != 0)
        while (num != 0)
        {
        {
            tmp[i++] = dig[((unsigned long)num) % (unsigned)base];
            tmp[i++] = dig[((unsigned long)num) % (unsigned)base];
            num      = ((unsigned long)num) / (unsigned)base;
            num      = ((unsigned long)num) / (unsigned)base;
        }
        }
    }
    }
 
 
    if (i > precision)
    if (i > precision)
        precision = i;
        precision = i;
    size -= precision;
    size -= precision;
    if (!(type & (ZEROPAD | LEFT)))
    if (!(type & (ZEROPAD | LEFT)))
        while (size-- > 0)
        while (size-- > 0)
            *str++ = ' ';
            *str++ = ' ';
    if (sign)
    if (sign)
        *str++ = sign;
        *str++ = sign;
 
 
    if (type & HEX_PREP)
    if (type & HEX_PREP)
    {
    {
        if (base == 8)
        if (base == 8)
            *str++ = '0';
            *str++ = '0';
        else if (base == 16)
        else if (base == 16)
        {
        {
            *str++ = '0';
            *str++ = '0';
            *str++ = digits[33];
            *str++ = digits[33];
        }
        }
    }
    }
 
 
    if (!(type & LEFT))
    if (!(type & LEFT))
        while (size-- > 0)
        while (size-- > 0)
            *str++ = c;
            *str++ = c;
    while (i < precision--)
    while (i < precision--)
        *str++ = '0';
        *str++ = '0';
    while (i-- > 0)
    while (i-- > 0)
        *str++ = tmp[i];
        *str++ = tmp[i];
    while (size-- > 0)
    while (size-- > 0)
        *str++ = ' ';
        *str++ = ' ';
 
 
    return str;
    return str;
}
}
 
 
static char *
static char *
eaddr(char *str, unsigned char *addr, int size, int precision, int type)
eaddr(char *str, unsigned char *addr, int size, int precision, int type)
{
{
    char  tmp[24];
    char  tmp[24];
    char *dig = digits;
    char *dig = digits;
    int   i, len;
    int   i, len;
 
 
    if (type & UPPERCASE)
    if (type & UPPERCASE)
        dig = upper_digits;
        dig = upper_digits;
    len = 0;
    len = 0;
    for (i = 0; i < 6; i++)
    for (i = 0; i < 6; i++)
    {
    {
        if (i != 0)
        if (i != 0)
            tmp[len++] = ':';
            tmp[len++] = ':';
        tmp[len++] = dig[addr[i] >> 4];
        tmp[len++] = dig[addr[i] >> 4];
        tmp[len++] = dig[addr[i] & 0x0F];
        tmp[len++] = dig[addr[i] & 0x0F];
    }
    }
 
 
    if (!(type & LEFT))
    if (!(type & LEFT))
        while (len < size--)
        while (len < size--)
            *str++ = ' ';
            *str++ = ' ';
    for (i = 0; i < len; ++i)
    for (i = 0; i < len; ++i)
        *str++ = tmp[i];
        *str++ = tmp[i];
    while (len < size--)
    while (len < size--)
        *str++ = ' ';
        *str++ = ' ';
 
 
    return str;
    return str;
}
}
 
 
static char *
static char *
iaddr(char *str, unsigned char *addr, int size, int precision, int type)
iaddr(char *str, unsigned char *addr, int size, int precision, int type)
{
{
    char tmp[24];
    char tmp[24];
    int  i, n, len;
    int  i, n, len;
 
 
    len = 0;
    len = 0;
    for (i = 0; i < 4; i++)
    for (i = 0; i < 4; i++)
    {
    {
        if (i != 0)
        if (i != 0)
            tmp[len++] = '.';
            tmp[len++] = '.';
        n = addr[i];
        n = addr[i];
 
 
        if (n == 0)
        if (n == 0)
            tmp[len++] = digits[0];
            tmp[len++] = digits[0];
        else
        else
        {
        {
            if (n >= 100)
            if (n >= 100)
            {
            {
                tmp[len++] = digits[n / 100];
                tmp[len++] = digits[n / 100];
                n          = n % 100;
                n          = n % 100;
                tmp[len++] = digits[n / 10];
                tmp[len++] = digits[n / 10];
                n          = n % 10;
                n          = n % 10;
            }
            }
            else if (n >= 10)
            else if (n >= 10)
            {
            {
                tmp[len++] = digits[n / 10];
                tmp[len++] = digits[n / 10];
                n          = n % 10;
                n          = n % 10;
            }
            }
 
 
            tmp[len++] = digits[n];
            tmp[len++] = digits[n];
        }
        }
    }
    }
 
 
    if (!(type & LEFT))
    if (!(type & LEFT))
        while (len < size--)
        while (len < size--)
            *str++ = ' ';
            *str++ = ' ';
    for (i = 0; i < len; ++i)
    for (i = 0; i < len; ++i)
        *str++ = tmp[i];
        *str++ = tmp[i];
    while (len < size--)
    while (len < size--)
        *str++ = ' ';
        *str++ = ' ';
 
 
    return str;
    return str;
}
}
 
 
#if HAS_FLOAT
#if HAS_FLOAT
 
 
char *      ecvtbuf(double arg, int ndigits, int *decpt, int *sign, char *buf);
char *      ecvtbuf(double arg, int ndigits, int *decpt, int *sign, char *buf);
char *      fcvtbuf(double arg, int ndigits, int *decpt, int *sign, char *buf);
char *      fcvtbuf(double arg, int ndigits, int *decpt, int *sign, char *buf);
static void ee_bufcpy(char *d, char *s, int count);
static void ee_bufcpy(char *d, char *s, int count);
 
 
void
void
ee_bufcpy(char *pd, char *ps, int count)
ee_bufcpy(char *pd, char *ps, int count)
{
{
    char *pe = ps + count;
    char *pe = ps + count;
    while (ps != pe)
    while (ps != pe)
        *pd++ = *ps++;
        *pd++ = *ps++;
}
}
 
 
static void
static void
parse_float(double value, char *buffer, char fmt, int precision)
parse_float(double value, char *buffer, char fmt, int precision)
{
{
    int   decpt, sign, exp, pos;
    int   decpt, sign, exp, pos;
    char *digits = NULL;
    char *digits = NULL;
    char  cvtbuf[80];
    char  cvtbuf[80];
    int   capexp = 0;
    int   capexp = 0;
    int   magnitude;
    int   magnitude;
 
 
    if (fmt == 'G' || fmt == 'E')
    if (fmt == 'G' || fmt == 'E')
    {
    {
        capexp = 1;
        capexp = 1;
        fmt += 'a' - 'A';
        fmt += 'a' - 'A';
    }
    }
 
 
    if (fmt == 'g')
    if (fmt == 'g')
    {
    {
        digits    = ecvtbuf(value, precision, &decpt, &sign, cvtbuf);
        digits    = ecvtbuf(value, precision, &decpt, &sign, cvtbuf);
        magnitude = decpt - 1;
        magnitude = decpt - 1;
        if (magnitude < -4 || magnitude > precision - 1)
        if (magnitude < -4 || magnitude > precision - 1)
        {
        {
            fmt = 'e';
            fmt = 'e';
            precision -= 1;
            precision -= 1;
        }
        }
        else
        else
        {
        {
            fmt = 'f';
            fmt = 'f';
            precision -= decpt;
            precision -= decpt;
        }
        }
    }
    }
 
 
    if (fmt == 'e')
    if (fmt == 'e')
    {
    {
        digits = ecvtbuf(value, precision + 1, &decpt, &sign, cvtbuf);
        digits = ecvtbuf(value, precision + 1, &decpt, &sign, cvtbuf);
 
 
        if (sign)
        if (sign)
            *buffer++ = '-';
            *buffer++ = '-';
        *buffer++ = *digits;
        *buffer++ = *digits;
        if (precision > 0)
        if (precision > 0)
            *buffer++ = '.';
            *buffer++ = '.';
        ee_bufcpy(buffer, digits + 1, precision);
        ee_bufcpy(buffer, digits + 1, precision);
        buffer += precision;
        buffer += precision;
        *buffer++ = capexp ? 'E' : 'e';
        *buffer++ = capexp ? 'E' : 'e';
 
 
        if (decpt == 0)
        if (decpt == 0)
        {
        {
            if (value == 0.0)
            if (value == 0.0)
                exp = 0;
                exp = 0;
            else
            else
                exp = -1;
                exp = -1;
        }
        }
        else
        else
            exp = decpt - 1;
            exp = decpt - 1;
 
 
        if (exp < 0)
        if (exp < 0)
        {
        {
            *buffer++ = '-';
            *buffer++ = '-';
            exp       = -exp;
            exp       = -exp;
        }
        }
        else
        else
            *buffer++ = '+';
            *buffer++ = '+';
 
 
        buffer[2] = (exp % 10) + '0';
        buffer[2] = (exp % 10) + '0';
        exp       = exp / 10;
        exp       = exp / 10;
        buffer[1] = (exp % 10) + '0';
        buffer[1] = (exp % 10) + '0';
        exp       = exp / 10;
        exp       = exp / 10;
        buffer[0] = (exp % 10) + '0';
        buffer[0] = (exp % 10) + '0';
        buffer += 3;
        buffer += 3;
    }
    }
    else if (fmt == 'f')
    else if (fmt == 'f')
    {
    {
        digits = fcvtbuf(value, precision, &decpt, &sign, cvtbuf);
        digits = fcvtbuf(value, precision, &decpt, &sign, cvtbuf);
        if (sign)
        if (sign)
            *buffer++ = '-';
            *buffer++ = '-';
        if (*digits)
        if (*digits)
        {
        {
            if (decpt <= 0)
            if (decpt <= 0)
            {
            {
                *buffer++ = '0';
                *buffer++ = '0';
                *buffer++ = '.';
                *buffer++ = '.';
                for (pos = 0; pos < -decpt; pos++)
                for (pos = 0; pos < -decpt; pos++)
                    *buffer++ = '0';
                    *buffer++ = '0';
                while (*digits)
                while (*digits)
                    *buffer++ = *digits++;
                    *buffer++ = *digits++;
            }
            }
            else
            else
            {
            {
                pos = 0;
                pos = 0;
                while (*digits)
                while (*digits)
                {
                {
                    if (pos++ == decpt)
                    if (pos++ == decpt)
                        *buffer++ = '.';
                        *buffer++ = '.';
                    *buffer++ = *digits++;
                    *buffer++ = *digits++;
                }
                }
            }
            }
        }
        }
        else
        else
        {
        {
            *buffer++ = '0';
            *buffer++ = '0';
            if (precision > 0)
            if (precision > 0)
            {
            {
                *buffer++ = '.';
                *buffer++ = '.';
                for (pos = 0; pos < precision; pos++)
                for (pos = 0; pos < precision; pos++)
                    *buffer++ = '0';
                    *buffer++ = '0';
            }
            }
        }
        }
    }
    }
 
 
    *buffer = '\0';
    *buffer = '\0';
}
}
 
 
static void
static void
decimal_point(char *buffer)
decimal_point(char *buffer)
{
{
    while (*buffer)
    while (*buffer)
    {
    {
        if (*buffer == '.')
        if (*buffer == '.')
            return;
            return;
        if (*buffer == 'e' || *buffer == 'E')
        if (*buffer == 'e' || *buffer == 'E')
            break;
            break;
        buffer++;
        buffer++;
    }
    }
 
 
    if (*buffer)
    if (*buffer)
    {
    {
        int n = strnlen(buffer, 256);
        int n = strnlen(buffer, 256);
        while (n > 0)
        while (n > 0)
        {
        {
            buffer[n + 1] = buffer[n];
            buffer[n + 1] = buffer[n];
            n--;
            n--;
        }
        }
 
 
        *buffer = '.';
        *buffer = '.';
    }
    }
    else
    else
    {
    {
        *buffer++ = '.';
        *buffer++ = '.';
        *buffer   = '\0';
        *buffer   = '\0';
    }
    }
}
}
 
 
static void
static void
cropzeros(char *buffer)
cropzeros(char *buffer)
{
{
    char *stop;
    char *stop;
 
 
    while (*buffer && *buffer != '.')
    while (*buffer && *buffer != '.')
        buffer++;
        buffer++;
    if (*buffer++)
    if (*buffer++)
    {
    {
        while (*buffer && *buffer != 'e' && *buffer != 'E')
        while (*buffer && *buffer != 'e' && *buffer != 'E')
            buffer++;
            buffer++;
        stop = buffer--;
        stop = buffer--;
        while (*buffer == '0')
        while (*buffer == '0')
            buffer--;
            buffer--;
        if (*buffer == '.')
        if (*buffer == '.')
            buffer--;
            buffer--;
        while (buffer != stop)
        while (buffer != stop)
            *++buffer = 0;
            *++buffer = 0;
    }
    }
}
}
 
 
static char *
static char *
flt(char *str, double num, int size, int precision, char fmt, int flags)
flt(char *str, double num, int size, int precision, char fmt, int flags)
{
{
    char tmp[80];
    char tmp[80];
    char c, sign;
    char c, sign;
    int  n, i;
    int  n, i;
 
 
    // Left align means no zero padding
    // Left align means no zero padding
    if (flags & LEFT)
    if (flags & LEFT)
        flags &= ~ZEROPAD;
        flags &= ~ZEROPAD;
 
 
    // Determine padding and sign char
    // Determine padding and sign char
    c    = (flags & ZEROPAD) ? '0' : ' ';
    c    = (flags & ZEROPAD) ? '0' : ' ';
    sign = 0;
    sign = 0;
    if (flags & SIGN)
    if (flags & SIGN)
    {
    {
        if (num < 0.0)
        if (num < 0.0)
        {
        {
            sign = '-';
            sign = '-';
            num  = -num;
            num  = -num;
            size--;
            size--;
        }
        }
        else if (flags & PLUS)
        else if (flags & PLUS)
        {
        {
            sign = '+';
            sign = '+';
            size--;
            size--;
        }
        }
        else if (flags & SPACE)
        else if (flags & SPACE)
        {
        {
            sign = ' ';
            sign = ' ';
            size--;
            size--;
        }
        }
    }
    }
 
 
    // Compute the precision value
    // Compute the precision value
    if (precision < 0)
    if (precision < 0)
        precision = 6; // Default precision: 6
        precision = 6; // Default precision: 6
 
 
    // Convert floating point number to text
    // Convert floating point number to text
    parse_float(num, tmp, fmt, precision);
    parse_float(num, tmp, fmt, precision);
 
 
    if ((flags & HEX_PREP) && precision == 0)
    if ((flags & HEX_PREP) && precision == 0)
        decimal_point(tmp);
        decimal_point(tmp);
    if (fmt == 'g' && !(flags & HEX_PREP))
    if (fmt == 'g' && !(flags & HEX_PREP))
        cropzeros(tmp);
        cropzeros(tmp);
 
 
    n = strnlen(tmp, 256);
    n = strnlen(tmp, 256);
 
 
    // Output number with alignment and padding
    // Output number with alignment and padding
    size -= n;
    size -= n;
    if (!(flags & (ZEROPAD | LEFT)))
    if (!(flags & (ZEROPAD | LEFT)))
        while (size-- > 0)
        while (size-- > 0)
            *str++ = ' ';
            *str++ = ' ';
    if (sign)
    if (sign)
        *str++ = sign;
        *str++ = sign;
    if (!(flags & LEFT))
    if (!(flags & LEFT))
        while (size-- > 0)
        while (size-- > 0)
            *str++ = c;
            *str++ = c;
    for (i = 0; i < n; i++)
    for (i = 0; i < n; i++)
        *str++ = tmp[i];
        *str++ = tmp[i];
    while (size-- > 0)
    while (size-- > 0)
        *str++ = ' ';
        *str++ = ' ';
 
 
    return str;
    return str;
}
}
 
 
#endif
#endif
 
 
static int
static int
ee_vsprintf(char *buf, const char *fmt, va_list args)
ee_vsprintf(char *buf, const char *fmt, va_list args)
{
{
    int           len;
    int           len;
    unsigned long num;
    unsigned long num;
    int           i, base;
    int           i, base;
    char *        str;
    char *        str;
    char *        s;
    char *        s;
 
 
    int flags; // Flags to number()
    int flags; // Flags to number()
 
 
    int field_width; // Width of output field
    int field_width; // Width of output field
    int precision;   // Min. # of digits for integers; max number of chars for
    int precision;   // Min. # of digits for integers; max number of chars for
                     // from string
                     // from string
    int qualifier;   // 'h', 'l', or 'L' for integer fields
    int qualifier;   // 'h', 'l', or 'L' for integer fields
 
 
    for (str = buf; *fmt; fmt++)
    for (str = buf; *fmt; fmt++)
    {
    {
        if (*fmt != '%')
        if (*fmt != '%')
        {
        {
            *str++ = *fmt;
            *str++ = *fmt;
            continue;
            continue;
        }
        }
 
 
        // Process flags
        // Process flags
        flags = 0;
        flags = 0;
    repeat:
    repeat:
        fmt++; // This also skips first '%'
        fmt++; // This also skips first '%'
        switch (*fmt)
        switch (*fmt)
        {
        {
            case '-':
            case '-':
                flags |= LEFT;
                flags |= LEFT;
                goto repeat;
                goto repeat;
            case '+':
            case '+':
                flags |= PLUS;
                flags |= PLUS;
                goto repeat;
                goto repeat;
            case ' ':
            case ' ':
                flags |= SPACE;
                flags |= SPACE;
                goto repeat;
                goto repeat;
            case '#':
            case '#':
                flags |= HEX_PREP;
                flags |= HEX_PREP;
                goto repeat;
                goto repeat;
            case '0':
            case '0':
                flags |= ZEROPAD;
                flags |= ZEROPAD;
                goto repeat;
                goto repeat;
        }
        }
 
 
        // Get field width
        // Get field width
        field_width = -1;
        field_width = -1;
        if (is_digit(*fmt))
        if (is_digit(*fmt))
            field_width = skip_atoi(&fmt);
            field_width = skip_atoi(&fmt);
        else if (*fmt == '*')
        else if (*fmt == '*')
        {
        {
            fmt++;
            fmt++;
            field_width = va_arg(args, int);
            field_width = va_arg(args, int);
            if (field_width < 0)
            if (field_width < 0)
            {
            {
                field_width = -field_width;
                field_width = -field_width;
                flags |= LEFT;
                flags |= LEFT;
            }
            }
        }
        }
 
 
        // Get the precision
        // Get the precision
        precision = -1;
        precision = -1;
        if (*fmt == '.')
        if (*fmt == '.')
        {
        {
            ++fmt;
            ++fmt;
            if (is_digit(*fmt))
            if (is_digit(*fmt))
                precision = skip_atoi(&fmt);
                precision = skip_atoi(&fmt);
            else if (*fmt == '*')
            else if (*fmt == '*')
            {
            {
                ++fmt;
                ++fmt;
                precision = va_arg(args, int);
                precision = va_arg(args, int);
            }
            }
            if (precision < 0)
            if (precision < 0)
                precision = 0;
                precision = 0;
        }
        }
 
 
        // Get the conversion qualifier
        // Get the conversion qualifier
        qualifier = -1;
        qualifier = -1;
        if (*fmt == 'l' || *fmt == 'L')
        if (*fmt == 'l' || *fmt == 'L')
        {
        {
            qualifier = *fmt;
            qualifier = *fmt;
            fmt++;
            fmt++;
        }
        }
 
 
        // Default base
        // Default base
        base = 10;
        base = 10;
 
 
        switch (*fmt)
        switch (*fmt)
        {
        {
            case 'c':
            case 'c':
                if (!(flags & LEFT))
                if (!(flags & LEFT))
                    while (--field_width > 0)
                    while (--field_width > 0)
                        *str++ = ' ';
                        *str++ = ' ';
                *str++ = (unsigned char)va_arg(args, int);
                *str++ = (unsigned char)va_arg(args, int);
                while (--field_width > 0)
                while (--field_width > 0)
                    *str++ = ' ';
                    *str++ = ' ';
                continue;
                continue;
 
 
            case 's':
            case 's':
                s = va_arg(args, char *);
                s = va_arg(args, char *);
                if (!s)
                if (!s)
                    s = "<NULL>";
                    s = "<NULL>";
                len = strnlen(s, precision);
                len = strnlen(s, precision);
                if (!(flags & LEFT))
                if (!(flags & LEFT))
                    while (len < field_width--)
                    while (len < field_width--)
                        *str++ = ' ';
                        *str++ = ' ';
                for (i = 0; i < len; ++i)
                for (i = 0; i < len; ++i)
                    *str++ = *s++;
                    *str++ = *s++;
                while (len < field_width--)
                while (len < field_width--)
                    *str++ = ' ';
                    *str++ = ' ';
                continue;
                continue;
 
 
            case 'p':
            case 'p':
                if (field_width == -1)
                if (field_width == -1)
                {
                {
                    field_width = 2 * sizeof(void *);
                    field_width = 2 * sizeof(void *);
                    flags |= ZEROPAD;
                    flags |= ZEROPAD;
                }
                }
                str = number(str,
                str = number(str,
                             (unsigned long)va_arg(args, void *),
                             (unsigned long)va_arg(args, void *),
                             16,
                             16,
                             field_width,
                             field_width,
                             precision,
                             precision,
                             flags);
                             flags);
                continue;
                continue;
 
 
            case 'A':
            case 'A':
                flags |= UPPERCASE;
                flags |= UPPERCASE;
 
 
            case 'a':
            case 'a':
                if (qualifier == 'l')
                if (qualifier == 'l')
                    str = eaddr(str,
                    str = eaddr(str,
                                va_arg(args, unsigned char *),
                                va_arg(args, unsigned char *),
                                field_width,
                                field_width,
                                precision,
                                precision,
                                flags);
                                flags);
                else
                else
                    str = iaddr(str,
                    str = iaddr(str,
                                va_arg(args, unsigned char *),
                                va_arg(args, unsigned char *),
                                field_width,
                                field_width,
                                precision,
                                precision,
                                flags);
                                flags);
                continue;
                continue;
 
 
            // Integer number formats - set up the flags and "break"
            // Integer number formats - set up the flags and "break"
            case 'o':
            case 'o':
                base = 8;
                base = 8;
                break;
                break;
 
 
            case 'X':
            case 'X':
                flags |= UPPERCASE;
                flags |= UPPERCASE;
 
 
            case 'x':
            case 'x':
                base = 16;
                base = 16;
                break;
                break;
 
 
            case 'd':
            case 'd':
            case 'i':
            case 'i':
                flags |= SIGN;
                flags |= SIGN;
 
 
            case 'u':
            case 'u':
                break;
                break;
 
 
#if HAS_FLOAT
#if HAS_FLOAT
 
 
            case 'f':
            case 'f':
                str = flt(str,
                str = flt(str,
                          va_arg(args, double),
                          va_arg(args, double),
                          field_width,
                          field_width,
                          precision,
                          precision,
                          *fmt,
                          *fmt,
                          flags | SIGN);
                          flags | SIGN);
                continue;
                continue;
 
 
#endif
#endif
 
 
            default:
            default:
                if (*fmt != '%')
                if (*fmt != '%')
                    *str++ = '%';
                    *str++ = '%';
                if (*fmt)
                if (*fmt)
                    *str++ = *fmt;
                    *str++ = *fmt;
                else
                else
                    --fmt;
                    --fmt;
                continue;
                continue;
        }
        }
 
 
        if (qualifier == 'l')
        if (qualifier == 'l')
            num = va_arg(args, unsigned long);
            num = va_arg(args, unsigned long);
        else if (flags & SIGN)
        else if (flags & SIGN)
            num = va_arg(args, int);
            num = va_arg(args, int);
        else
        else
            num = va_arg(args, unsigned int);
            num = va_arg(args, unsigned int);
 
 
        str = number(str, num, base, field_width, precision, flags);
        str = number(str, num, base, field_width, precision, flags);
    }
    }
 
 
    *str = '\0';
    *str = '\0';
    return str - buf;
    return str - buf;
}
}
 
 
void
void
uart_send_char(char c)
uart_send_char(char c)
{
{
//#error "You must implement the method uart_send_char to use this file!\n";
//#error "You must implement the method uart_send_char to use this file!\n";
    /*  Output of a char to a UART usually follows the following model:
    /*  Output of a char to a UART usually follows the following model:
            Wait until UART is ready
            Wait until UART is ready
            Write char to UART
            Write char to UART
            Wait until UART is done
            Wait until UART is done
 
 
            Or in code:
            Or in code:
            while (*UART_CONTROL_ADDRESS != UART_READY);
            while (*UART_CONTROL_ADDRESS != UART_READY);
            *UART_DATA_ADDRESS = c;
            *UART_DATA_ADDRESS = c;
            while (*UART_CONTROL_ADDRESS != UART_READY);
            while (*UART_CONTROL_ADDRESS != UART_READY);
 
 
            Check the UART sample code on your platform or the board
            Check the UART sample code on your platform or the board
       documentation.
       documentation.
    */
    */
 
 
  /* NEORV32-specific */
  /* NEORV32-specific */
  if (c == '\n') {
  if (c == '\n') {
    neorv32_uart_putc('\r');
    neorv32_uart0_putc('\r');
  }
  }
  neorv32_uart_putc(c);
  neorv32_uart0_putc(c);
}
}
 
 
int
int
ee_printf(const char *fmt, ...)
ee_printf(const char *fmt, ...)
{
{
    char    buf[256], *p;
    char    buf[256], *p;
    va_list args;
    va_list args;
    int     n = 0;
    int     n = 0;
 
 
    va_start(args, fmt);
    va_start(args, fmt);
    ee_vsprintf(buf, fmt, args);
    ee_vsprintf(buf, fmt, args);
    va_end(args);
    va_end(args);
    p = buf;
    p = buf;
    while (*p)
    while (*p)
    {
    {
        uart_send_char(*p);
        uart_send_char(*p);
        n++;
        n++;
        p++;
        p++;
    }
    }
 
 
    return n;
    return n;
}
}
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.