This commit is contained in:
Aurora Wright 2017-05-07 23:18:26 +02:00
parent e8d4a98c7b
commit c746326eb3
4 changed files with 224 additions and 352 deletions

View File

@ -188,9 +188,9 @@ void detectAndProcessExceptionDumps(void)
drawFormattedString(false, 10 + 10 * SPACING_X + 3 * i * SPACING_X, posYBottom, COLOR_WHITE, "%02X", *stackDump); drawFormattedString(false, 10 + 10 * SPACING_X + 3 * i * SPACING_X, posYBottom, COLOR_WHITE, "%02X", *stackDump);
} }
char folderPath[36], char folderPath[12],
path[36], path[36],
fileName[] = "crash_dump_00010000.dmp"; fileName[24];
sprintf(folderPath, "dumps/arm%u", dumpHeader->processor); sprintf(folderPath, "dumps/arm%u", dumpHeader->processor);
findDumpFile(folderPath, fileName); findDumpFile(folderPath, fileName);

View File

@ -1,9 +1,3 @@
// TuxSH's changes: add support for 64-bit numbers, remove floating-point code
// TODO! fix left-padding handling with > 10 characters.
#include "fmt.h"
#include "strings.h"
/* File : barebones/ee_printf.c /* File : barebones/ee_printf.c
This file contains an implementation of ee_printf that only requires a method to output a char to a UART without pulling in library code. This file contains an implementation of ee_printf that only requires a method to output a char to a UART without pulling in library code.
@ -37,52 +31,35 @@ This code is based on a file that contains the following:
*/ */
//#include <coremark.h> /* TuxSH's changes: add support for 64-bit numbers, remove floating-point code
//#include <stdarg.h> TODO! fix left-padding handling with > 10 characters. */
#define ZEROPAD (1<<0) /* Pad with zero */ #include "fmt.h"
#define SIGN (1<<1) /* Unsigned/signed long */ #include "strings.h"
#define PLUS (1<<2) /* Show plus */
#define SPACE (1<<3) /* Spacer */
#define LEFT (1<<4) /* Left justified */
#define HEX_PREP (1<<5) /* 0x */
#define UPPERCASE (1<<6) /* 'ABCDEF' */
#define is_digit(c) ((c) >= '0' && (c) <= '9') #define ZEROPAD (1<<0) //Pad with zero
#define SIGN (1<<1) //Unsigned/signed long
#define PLUS (1<<2) //Show plus
#define SPACE (1<<3) //Spacer
#define LEFT (1<<4) //Left justified
#define HEX_PREP (1<<5) //0x
#define UPPERCASE (1<<6) //'ABCDEF'
static char *lower_digits = "0123456789abcdefghijklmnopqrstuvwxyz"; #define IS_DIGIT(c) ((c) >= '0' && (c) <= '9')
static char *upper_digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
/* static u32 skipAtoi(const char **s)
static size_t strnlen(const char *s, size_t count);
static size_t strnlen(const char *s, size_t count)
{ {
const char *sc; u32 i = 0;
for (sc = s; *sc != '\0' && count--; ++sc); while(IS_DIGIT(**s)) i = i * 10 + *((*s)++) - '0';
return sc - s;
}
*/
static int ee_skip_atoi(const char **s)
{
int i = 0;
while (is_digit(**s)) i = i*10 + *((*s)++) - '0';
return i; return i;
} }
static char *ee_number(char *str, long long num, int base, int size, int precision, int type) static char *processNumber(char *str, s64 num, bool isHex, s32 size, s32 precision, u32 type)
{ {
char c, sign, tmp[66];
char *dig = lower_digits;
int i;
if (type & UPPERCASE) dig = upper_digits;
if(type & LEFT) type &= ~ZEROPAD; if(type & LEFT) type &= ~ZEROPAD;
if (base < 2 || base > 36) return 0;
c = (type & ZEROPAD) ? '0' : ' '; char sign = 0;
sign = 0;
if(type & SIGN) if(type & SIGN)
{ {
if(num < 0) if(num < 0)
@ -103,24 +80,24 @@ static char *ee_number(char *str, long long num, int base, int size, int precisi
} }
} }
if (type & HEX_PREP) if(type & HEX_PREP && isHex) size -= 2;
{
if (base == 16)
size -= 2;
else if (base == 8)
size--;
}
i = 0; static const char *lowerDigits = "0123456789abcdef",
*upperDigits = "0123456789ABCDEF";
if (num == 0) s32 i = 0;
tmp[i++] = '0'; char tmp[66],
c = (type & ZEROPAD) ? '0' : ' ';
const char *dig = (type & UPPERCASE) ? upperDigits : lowerDigits;
if(num == 0) tmp[i++] = '0';
else else
{ {
while (num != 0) while (num != 0)
{ {
tmp[i++] = dig[(unsigned long long)num % (unsigned long long)base]; u64 base = isHex ? 16ULL : 10ULL;
num = (long long)((unsigned long long)num / (unsigned long long) base); tmp[i++] = dig[(u64)num % base];
num = (s64)((u64)num / base);
} }
} }
@ -129,15 +106,10 @@ static char *ee_number(char *str, long long num, int base, int size, int precisi
if(!(type & (ZEROPAD | LEFT))) while(size-- > 0) *str++ = ' '; if(!(type & (ZEROPAD | LEFT))) while(size-- > 0) *str++ = ' ';
if(sign) *str++ = sign; if(sign) *str++ = sign;
if (type & HEX_PREP) if(type & HEX_PREP && isHex)
{
if (base == 8)
*str++ = '0';
else if (base == 16)
{ {
*str++ = '0'; *str++ = '0';
*str++ = lower_digits[33]; *str++ = 'x';
}
} }
if(!(type & LEFT)) while(size-- > 0) *str++ = c; if(!(type & LEFT)) while(size-- > 0) *str++ = c;
@ -148,80 +120,9 @@ static char *ee_number(char *str, long long num, int base, int size, int precisi
return str; return str;
} }
static char *eaddr(char *str, unsigned char *addr, int size, int precision __attribute__((unused)), int type) u32 vsprintf(char *buf, const char *fmt, va_list args)
{ {
char tmp[24];
char *dig = lower_digits;
int i, len;
if (type & UPPERCASE) dig = upper_digits;
len = 0;
for (i = 0; i < 6; i++)
{
if (i != 0) tmp[len++] = ':';
tmp[len++] = dig[addr[i] >> 4];
tmp[len++] = dig[addr[i] & 0x0F];
}
if (!(type & LEFT)) while (len < size--) *str++ = ' ';
for (i = 0; i < len; ++i) *str++ = tmp[i];
while (len < size--) *str++ = ' ';
return str;
}
static char *iaddr(char *str, unsigned char *addr, int size, int precision __attribute__((unused)), int type)
{
char tmp[24];
int i, n, len;
len = 0;
for (i = 0; i < 4; i++)
{
if (i != 0) tmp[len++] = '.';
n = addr[i];
if (n == 0)
tmp[len++] = lower_digits[0];
else
{
if (n >= 100)
{
tmp[len++] = lower_digits[n / 100];
n = n % 100;
tmp[len++] = lower_digits[n / 10];
n = n % 10;
}
else if (n >= 10)
{
tmp[len++] = lower_digits[n / 10];
n = n % 10;
}
tmp[len++] = lower_digits[n];
}
}
if (!(type & LEFT)) while (len < size--) *str++ = ' ';
for (i = 0; i < len; ++i) *str++ = tmp[i];
while (len < size--) *str++ = ' ';
return str;
}
static int ee_vsprintf(char *buf, const char *fmt, va_list args)
{
int len;
long long num;
int i, base;
char *str; char *str;
char *s;
int flags; // Flags to number()
int field_width; // Width of output field
int precision; // Min. # of digits for integers; max number of chars for from string
int qualifier; // 'h', 'l', or 'L' for integer fields
int qualifier2;
for(str = buf; *fmt; fmt++) for(str = buf; *fmt; fmt++)
{ {
@ -232,115 +133,102 @@ static int ee_vsprintf(char *buf, const char *fmt, va_list args)
} }
//Process flags //Process flags
flags = 0; u32 flags = 0; //Flags to number()
repeat: bool loop = false;
fmt++; // This also skips first '%'
switch (*fmt) while(!loop)
{ {
case '-': flags |= LEFT; goto repeat; switch(*++fmt)
case '+': flags |= PLUS; goto repeat; {
case ' ': flags |= SPACE; goto repeat; case '-': flags |= LEFT; break;
case '#': flags |= HEX_PREP; goto repeat; case '+': flags |= PLUS; break;
case '0': flags |= ZEROPAD; goto repeat; case ' ': flags |= SPACE; break;
case '#': flags |= HEX_PREP; break;
case '0': flags |= ZEROPAD; break;
default: loop = true; break;
}
} }
//Get field width //Get field width
field_width = -1; s32 fieldWidth = -1; //Width of output field
if (is_digit(*fmt)) if(IS_DIGIT(*fmt)) fieldWidth = skipAtoi(&fmt);
field_width = ee_skip_atoi(&fmt);
else if(*fmt == '*') else if(*fmt == '*')
{ {
fmt++; fmt++;
field_width = va_arg(args, int);
if (field_width < 0) fieldWidth = va_arg(args, s32);
if(fieldWidth < 0)
{ {
field_width = -field_width; fieldWidth = -fieldWidth;
flags |= LEFT; flags |= LEFT;
} }
} }
//Get the precision //Get the precision
precision = -1; s32 precision = -1; //Min. # of digits for integers; max number of chars for from string
if(*fmt == '.') if(*fmt == '.')
{ {
++fmt; fmt++;
if (is_digit(*fmt))
precision = ee_skip_atoi(&fmt); if(IS_DIGIT(*fmt)) precision = skipAtoi(&fmt);
else if(*fmt == '*') else if(*fmt == '*')
{ {
++fmt; fmt++;
precision = va_arg(args, int); precision = va_arg(args, s32);
} }
if(precision < 0) precision = 0; if(precision < 0) precision = 0;
} }
//Get the conversion qualifier //Get the conversion qualifier
qualifier = qualifier2 = -1; bool isLongLong = false;
if(*fmt == 'L') if(*fmt == 'l')
qualifier = *fmt++;
else if (*fmt == 'l')
{ {
qualifier = *fmt++; if(*++fmt == 'l')
if(*fmt == 'l') qualifier2 = *fmt++; {
fmt++;
isLongLong = true;
} }
else if (*fmt == 'h')
{
qualifier = *fmt++;
if(*fmt == 'h') qualifier2 = *fmt++;
} }
//Default base //Default base
base = 10; bool isHex = false;
switch(*fmt) switch(*fmt)
{ {
case 'c': case 'c':
if (!(flags & LEFT)) while (--field_width > 0) *str++ = ' '; if(!(flags & LEFT)) while(--fieldWidth > 0) *str++ = ' ';
*str++ = (unsigned char) va_arg(args, int); *str++ = (u8)va_arg(args, s32);
while (--field_width > 0) *str++ = ' '; while(--fieldWidth > 0) *str++ = ' ';
continue; continue;
case 's': case 's':
s = va_arg(args, char *); {
char *s = va_arg(args, char *);
if(!s) s = "<NULL>"; if(!s) s = "<NULL>";
if(precision != -1) u32 len = (precision != -1) ? strnlen(s, precision) : strlen(s);
len = strnlen(s, precision); if(!(flags & LEFT)) while((s32)len < fieldWidth--) *str++ = ' ';
else for(u32 i = 0; i < len; i++) *str++ = *s++;
len = strlen(s); while((s32)len < fieldWidth--) *str++ = ' ';
if (!(flags & LEFT)) while (len < field_width--) *str++ = ' ';
for (i = 0; i < len; ++i) *str++ = *s++;
while (len < field_width--) *str++ = ' ';
continue; continue;
}
case 'p': case 'p':
if (field_width == -1) if(fieldWidth == -1)
{ {
field_width = 2 * sizeof(void *); fieldWidth = 8;
flags |= ZEROPAD; flags |= ZEROPAD;
} }
str = ee_number(str, (unsigned long) va_arg(args, void *), 16, field_width, precision, flags); str = processNumber(str, (s64)va_arg(args, u32), true, fieldWidth, precision, flags);
continue;
case 'A':
flags |= UPPERCASE;
case 'a':
if (qualifier == 'l')
str = eaddr(str, va_arg(args, unsigned char *), field_width, precision, flags);
else
str = iaddr(str, va_arg(args, unsigned char *), field_width, precision, flags);
continue; continue;
//Integer number formats - set up the flags and "break" //Integer number formats - set up the flags and "break"
case 'o':
base = 8;
break;
case 'X': case 'X':
flags |= UPPERCASE; flags |= UPPERCASE;
case 'x': case 'x':
base = 16; isHex = true;
break; break;
case 'd': case 'd':
@ -352,60 +240,36 @@ repeat:
default: default:
if(*fmt != '%') *str++ = '%'; if(*fmt != '%') *str++ = '%';
if (*fmt) if(*fmt) *str++ = *fmt;
*str++ = *fmt; else fmt--;
else
--fmt;
continue; continue;
} }
// bugfixes here: s64 num;
if(flags & SIGN) if(flags & SIGN)
{ {
if (qualifier == 'l' && qualifier2 == 'l') if(isLongLong) num = va_arg(args, s64);
num = va_arg(args, long long int); else num = va_arg(args, s32);
else if(qualifier == 'l')
num = va_arg(args, long int);
/* else if(qualifier == 'h' && qualifier == 'h')
num = va_arg(args, signed char);
else if(qualifier == 'h')
num = va_arg(args, short);*/
else
num = va_arg(args, int);
} }
else else
{ {
if (qualifier == 'l' && qualifier2 == 'l') if(isLongLong) num = va_arg(args, u64);
num = va_arg(args, unsigned long long int); else num = va_arg(args, u32);
else if(qualifier == 'l')
num = va_arg(args, unsigned long int);
/* else if(qualifier == 'h' && qualifier == 'h')
num = va_arg(args, unsigned char);
else if(qualifier == 'h')
num = va_arg(args, unsigned short);*/
else
num = va_arg(args, unsigned int);
} }
str = ee_number(str, num, base, field_width, precision, flags); str = processNumber(str, num, isHex, fieldWidth, precision, flags);
} }
*str = '\0'; *str = 0;
return str - buf; return str - buf;
} }
int vsprintf(char *buf, const char *fmt, va_list args) u32 sprintf(char *buf, const char *fmt, ...)
{ {
return ee_vsprintf(buf, fmt, args);
}
int sprintf(char *buf, const char *fmt, ...)
{
int n = 0;
va_list args; va_list args;
va_start(args, fmt); va_start(args, fmt);
n = ee_vsprintf(buf, fmt, args); u32 res = vsprintf(buf, fmt, args);
va_end(args); va_end(args);
return n; return res;
} }

View File

@ -2,5 +2,5 @@
#include "memory.h" #include "memory.h"
#include <stdarg.h> #include <stdarg.h>
int vsprintf(char *buf, const char *fmt, va_list args); u32 vsprintf(char *buf, const char *fmt, va_list args);
int sprintf(char *buf, const char *fmt, ...); u32 sprintf(char *buf, const char *fmt, ...);

View File

@ -35,6 +35,14 @@ typedef volatile u8 vu8;
typedef volatile u16 vu16; typedef volatile u16 vu16;
typedef volatile u32 vu32; typedef volatile u32 vu32;
typedef volatile u64 vu64; typedef volatile u64 vu64;
typedef int8_t s8;
typedef int16_t s16;
typedef int32_t s32;
typedef int64_t s64;
typedef volatile s8 vs8;
typedef volatile s16 vs16;
typedef volatile s32 vs32;
typedef volatile s64 vs64;
#include "3dsheaders.h" #include "3dsheaders.h"