# HG changeset patch # User Michael Pavone # Date 1660523857 25200 # Node ID d0129f19ca52c46041d7d353c90d7ccd7bb567a2 # Parent 935e684f2d58990b519404604682e6bc451e3b3f Add a printf command to the debugger diff -r 935e684f2d58 -r d0129f19ca52 debug.c --- a/debug.c Sun Aug 14 09:55:06 2022 -0700 +++ b/debug.c Sun Aug 14 17:37:37 2022 -0700 @@ -1127,7 +1127,7 @@ { uint32_t tmp_addr = addr; root->read_mem(root, &tmp_addr, 'b'); - char c = addr; + char c = tmp_addr; if (c < 0x20 || c > 0x7F) { break; } @@ -1142,6 +1142,109 @@ return 1; } +static uint8_t cmd_printf(debug_root *root, char *format, char *param) +{ + if (!param) { + fputs("printf requires at least one parameter\n", stderr); + return 1; + } + while (isblank(*param)) + { + ++param; + } + if (*param != '"') { + fprintf(stderr, "First parameter to printf must be a string, found '%s'\n", param); + return 1; + } + ++param; + char *fmt = strdup(param); + char *cur = param, *out = fmt; + while (*cur && *cur != '"') + { + if (*cur == '\\') { + switch (cur[1]) + { + case 't': + *(out++) = '\t'; + break; + case 'n': + *(out++) = '\n'; + break; + case 'r': + *(out++) = '\r'; + break; + case '\\': + *(out++) = '\\'; + break; + default: + fprintf(stderr, "Unsupported escape character %c in string %s\n", cur[1], fmt); + free(fmt); + return 1; + } + cur += 2; + } else { + *(out++) = *(cur++); + } + } + *out = 0; + ++cur; + param = cur; + cur = fmt; + char format_str[3] = {'%', 'd', 0}; + while (*cur) + { + if (*cur == '%') { + switch(cur[1]) + { + case 'x': + case 'X': + case 'c': + case 'd': + case 's': + break; + default: + fprintf(stderr, "Unsupported format character %c\n", cur[1]); + free(fmt); + return 1; + } + format_str[1] = cur[1]; + expr *arg = parse_expression(param, ¶m); + if (!arg) { + free(fmt); + return 1; + } + uint32_t val; + if (!eval_expr(root, arg, &val)) { + free(fmt); + return 1; + } + if (cur[1] == 's') { + char tmp[128]; + int j; + for (j = 0; j < sizeof(tmp)-1; j++, val++) + { + uint32_t addr = val; + root->read_mem(root, &addr, 'b'); + char c = addr; + if (c < 0x20 || c > 0x7F) { + break; + } + tmp[j] = c; + } + tmp[j] = 0; + printf(format_str, tmp); + } else { + printf(format_str, val); + } + cur += 2; + } else { + putchar(*cur); + ++cur; + } + } + return 1; +} + static uint8_t cmd_display(debug_root *root, char *format, int num_args, command_arg *args) { cmd_print(root, format, num_args, args); @@ -1694,6 +1797,16 @@ }, { .names = (const char *[]){ + "printf", NULL + }, + .usage = "printf FORMAT EXPRESSION...", + .desc = "Print a string with C-style formatting specifiers replaced with the value of the remaining arguments", + .raw_impl = cmd_printf, + .min_args = 1, + .max_args = -1 + }, + { + .names = (const char *[]){ "softreset", "sr", NULL }, .usage = "softreset",