summaryrefslogtreecommitdiff
path: root/tests/printf.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/printf.c')
-rw-r--r--tests/printf.c164
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;
+}