|
|
|
@ -75,6 +75,97 @@ m3ApiRawFunction(m3_libc_print)
|
|
|
|
|
m3ApiReturn(i_size);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static
|
|
|
|
|
void internal_itoa(int n, char s[], int radix)
|
|
|
|
|
{
|
|
|
|
|
static char const HEXDIGITS[0x10] = {
|
|
|
|
|
'0', '1', '2', '3', '4', '5', '6', '7',
|
|
|
|
|
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
int i, j, sign;
|
|
|
|
|
char c;
|
|
|
|
|
|
|
|
|
|
if ((sign = n) < 0) { n = -n; }
|
|
|
|
|
i = 0;
|
|
|
|
|
do {
|
|
|
|
|
s[i++] = HEXDIGITS[n % radix];
|
|
|
|
|
} while ((n /= radix) > 0);
|
|
|
|
|
|
|
|
|
|
if (sign < 0) { s[i++] = '-'; }
|
|
|
|
|
s[i] = '\0';
|
|
|
|
|
|
|
|
|
|
// reverse
|
|
|
|
|
for (i = 0, j = strlen(s)-1; i<j; i++, j--) {
|
|
|
|
|
c = s[i];
|
|
|
|
|
s[i] = s[j];
|
|
|
|
|
s[j] = c;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m3ApiRawFunction(m3_libc_printf)
|
|
|
|
|
{
|
|
|
|
|
m3ApiReturnType (int32_t)
|
|
|
|
|
|
|
|
|
|
m3ApiGetArgMem (const char*, i_fmt)
|
|
|
|
|
m3ApiGetArgMem (u32*, i_args)
|
|
|
|
|
|
|
|
|
|
m3ApiCheckMem(i_fmt, 1);
|
|
|
|
|
|
|
|
|
|
size_t fmt_len = strlen(i_fmt);
|
|
|
|
|
m3ApiCheckMem(i_fmt, fmt_len+1);
|
|
|
|
|
|
|
|
|
|
FILE* file = stdout;
|
|
|
|
|
|
|
|
|
|
int32_t length = 0;
|
|
|
|
|
char ch;
|
|
|
|
|
while ((ch = *i_fmt++)) {
|
|
|
|
|
if ( '%' != ch ) {
|
|
|
|
|
putc(ch, file);
|
|
|
|
|
length++;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
ch = *i_fmt++;
|
|
|
|
|
switch (ch) {
|
|
|
|
|
case '%': {
|
|
|
|
|
fputc('%', file);
|
|
|
|
|
length++;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 'c': {
|
|
|
|
|
m3ApiCheckMem(i_args, sizeof(int));
|
|
|
|
|
char char_temp = *i_args++;
|
|
|
|
|
fputc(char_temp, file);
|
|
|
|
|
length++;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 'd':
|
|
|
|
|
case 'x': {
|
|
|
|
|
m3ApiCheckMem(i_args, sizeof(int));
|
|
|
|
|
int int_temp = *i_args++;
|
|
|
|
|
char buffer[32] = { 0, };
|
|
|
|
|
internal_itoa(int_temp, buffer, (ch == 'x') ? 16 : 10);
|
|
|
|
|
fputs(buffer, file);
|
|
|
|
|
length += strlen(buffer);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 's': {
|
|
|
|
|
m3ApiCheckMem(i_args, sizeof(int));
|
|
|
|
|
const char* string_temp = m3ApiOffsetToPtr(*i_args++);
|
|
|
|
|
size_t string_len = strlen(string_temp);
|
|
|
|
|
|
|
|
|
|
m3ApiCheckMem(string_temp, string_len+1);
|
|
|
|
|
|
|
|
|
|
fputs(string_temp, file);
|
|
|
|
|
length += string_len;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m3ApiReturn(length);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m3ApiRawFunction(m3_libc_clock_ms)
|
|
|
|
|
{
|
|
|
|
|
m3ApiReturnType (uint32_t)
|
|
|
|
@ -128,6 +219,7 @@ _ (SuppressLookupFailure (m3_LinkRawFunction (module, env, "_memcpy",
|
|
|
|
|
_ (SuppressLookupFailure (m3_LinkRawFunction (module, env, "_abort", "v()", &m3_libc_abort)));
|
|
|
|
|
_ (SuppressLookupFailure (m3_LinkRawFunction (module, env, "_exit", "v(i)", &m3_libc_exit)));
|
|
|
|
|
_ (SuppressLookupFailure (m3_LinkRawFunction (module, env, "clock_ms", "i()", &m3_libc_clock_ms)));
|
|
|
|
|
_ (SuppressLookupFailure (m3_LinkRawFunction (module, env, "printf", "i(**)", &m3_libc_printf)));
|
|
|
|
|
|
|
|
|
|
_catch:
|
|
|
|
|
return result;
|
|
|
|
|