diff options
Diffstat (limited to 'tests/printf.c')
| -rw-r--r-- | tests/printf.c | 164 |
1 files changed, 164 insertions, 0 deletions
diff --git a/tests/printf.c b/tests/printf.c new file mode 100644 index 0000000..fc0d68d --- /dev/null +++ b/tests/printf.c @@ -0,0 +1,164 @@ +char out_buf[4096]; +int out_pos = 0; + +int buf_putc(char c) { + out_buf[out_pos] = c; + out_pos++; + if (out_pos >= 4096) { + syscall(1, 1, out_buf, out_pos); + out_pos = 0; + } + return 1; +} + +int buf_flush() { + if (out_pos > 0) { + syscall(1, 1, out_buf, out_pos); + out_pos = 0; + } + return 0; +} + + +int my_strlen(char *s) { + int n = 0; + while (s[n] != 0) { n++; } + return n; +} + +int print_str(char *s) { + int i = 0; + while (s[i] != 0) { buf_putc(s[i]); i++; } + return i; +} + + +int print_int(int n) { + char tmp[24]; + int len = 0; + int neg = n < 0; + if (neg) { buf_putc('-'); n = -n; } + if (n == 0) { buf_putc('0'); return neg + 1; } + while (n > 0) { + tmp[len] = (char)('0' + n % 10); + n = n / 10; + len++; + } + + int i = len - 1; + while (i >= 0) { buf_putc(tmp[i]); i--; } + return neg + len; +} + + +int print_hex(int n) { + char hex[16] = {'0','1','2','3','4','5','6','7', + '8','9','a','b','c','d','e','f'}; + if (n == 0) { buf_putc('0'); return 1; } + char tmp[18]; + int len = 0; + int u = n; + while (u != 0) { + tmp[len] = hex[u & 15]; + u = u / 16; + len++; + } + int i = len - 1; + while (i >= 0) { buf_putc(tmp[i]); i--; } + return len; +} + + +int my_printf(char *fmt, int a, int b, int c) { + int arg_idx = 0; + int i = 0; + int total = 0; + while (fmt[i] != 0) { + if (fmt[i] != '%') { + buf_putc(fmt[i]); + total++; + i++; + continue; + } + i++; /* skip '%' */ + int arg = arg_idx == 0 ? a : (arg_idx == 1 ? b : c); + arg_idx++; + if (fmt[i] == 'd') { + total += print_int(arg); + } else if (fmt[i] == 's') { + total += print_str((char*)arg); + } else if (fmt[i] == 'c') { + buf_putc((char)arg); + total++; + } else if (fmt[i] == 'x') { + total += print_hex(arg); + } else if (fmt[i] == '%') { + buf_putc('%'); + total++; + arg_idx--; /* %% doesn't consume an arg */ + } else { + buf_putc('%'); buf_putc(fmt[i]); + total += 2; + } + i++; + } + return total; +} + + +int fact(int n) { + return n <= 1 ? 1 : n * fact(n - 1); +} + +int fib(int n) { + if (n <= 1) return n; + return fib(n - 1) + fib(n - 2); +} + +int main() { + my_printf("=== JIT printf demo ===\n", 0, 0, 0); + + my_printf("Hello, %s!\n", "world", 0, 0); + my_printf("int: %d neg: %d\n", 42, -7, 0); + my_printf("hex: 0x%x\n", 255, 0, 0); + my_printf("char: %c\n", 'A', 0, 0); + my_printf("percent: 100%%\n", 0, 0, 0); + + my_printf("\nFactorials:\n", 0, 0, 0); + int i = 1; + while (i <= 8) { + my_printf(" %d! = %d\n", i, fact(i), 0); + i++; + } + + my_printf("\nFibonacci:\n ", 0, 0, 0); + i = 0; + while (i < 10) { + my_printf("%d ", fib(i), 0, 0); + i++; + } + my_printf("\n", 0, 0, 0); + + + my_printf("\nCountdown: ", 0, 0, 0); + int n = 5; + do { + my_printf("%d ", n, 0, 0); + n--; + } while (n > 0); + my_printf("\n", 0, 0, 0); + + + my_printf("Odd 1-9: ", 0, 0, 0); + i = 0; + while (i < 10) { + i++; + if (i % 2 == 0) continue; + my_printf("%d ", i, 0, 0); + if (i == 9) break; + } + my_printf("\n", 0, 0, 0); + + buf_flush(); + return 0; +} |
