From cfc0102d28c38691516638f0489f4d4374b3043f Mon Sep 17 00:00:00 2001 From: Ivan Baravy Date: Sun, 29 May 2022 19:17:00 +0400 Subject: [PATCH] Use optparse library --- README | 9 + getopt.c | 220 ---------- getopt.h | 53 --- makefile | 4 +- optparse.c | 2 + optparse.h | 403 +++++++++++++++++ shell.c | 1169 +++++++++++++++++++++++++------------------------ shell.h | 8 +- test/makefile | 2 +- umka_os.c | 9 +- umka_shell.c | 77 ++-- 11 files changed, 1061 insertions(+), 895 deletions(-) delete mode 100644 getopt.c delete mode 100644 getopt.h create mode 100644 optparse.c create mode 100644 optparse.h diff --git a/README b/README index e13f8ff..d13f130 100644 --- a/README +++ b/README @@ -108,3 +108,12 @@ Links & Acknowledgements [2] LodePNG by Lode Vandevenne https://lodev.org/lodepng/ + +[3] Optparse by Christopher Wellons + https://github.com/skeeto/optparse + +[4] Universal TUN/TAP device driver by Maxim Krasnyansky and others + https://www.kernel.org/doc/html/v5.12/networking/tuntap.html + +[5] Bestline by Justine Tunney + https://github.com/jart/bestline diff --git a/getopt.c b/getopt.c deleted file mode 100644 index 21a27fe..0000000 --- a/getopt.c +++ /dev/null @@ -1,220 +0,0 @@ -#include -#include -#include -#include "getopt.h" - -#ifdef _WIN32 - -char *optarg; -int optind=1, opterr=1, optopt, __optpos, optreset=0; - -#define optpos __optpos - -static void __getopt_msg(const char *a, const char *b, const char *c, size_t l) -{ - FILE *f = stderr; -#if !defined(WIN32) && !defined(_WIN32) - flockfile(f); -#endif - fputs(a, f); - fwrite(b, strlen(b), 1, f); - fwrite(c, 1, l, f); - fputc('\n', f); -#if !defined(WIN32) && !defined(_WIN32) - funlockfile(f); -#endif -} - -int getopt(int argc, char * const argv[], const char *optstring) -{ - int i, c, d; - int k, l; - char *optchar; - - if (!optind || optreset) { - optreset = 0; - __optpos = 0; - optind = 1; - } - - if (optind >= argc || !argv[optind]) - return -1; - - if (argv[optind][0] != '-') { - if (optstring[0] == '-') { - optarg = argv[optind++]; - return 1; - } - return -1; - } - - if (!argv[optind][1]) - return -1; - - if (argv[optind][1] == '-' && !argv[optind][2]) - return optind++, -1; - - if (!optpos) optpos++; - c = argv[optind][optpos], k = 1; - optchar = argv[optind]+optpos; - optopt = c; - optpos += k; - - if (!argv[optind][optpos]) { - optind++; - optpos = 0; - } - - if (optstring[0] == '-' || optstring[0] == '+') - optstring++; - - i = 0; - d = 0; - do { - d = optstring[i], l = 1; - if (l>0) i+=l; else i++; - } while (l && d != c); - - if (d != c) { - if (optstring[0] != ':' && opterr) - __getopt_msg(argv[0], ": unrecognized option: ", optchar, k); - return '?'; - } - if (optstring[i] == ':') { - if (optstring[i+1] == ':') optarg = 0; - else if (optind >= argc) { - if (optstring[0] == ':') return ':'; - if (opterr) __getopt_msg(argv[0], - ": option requires an argument: ", - optchar, k); - return '?'; - } - if (optstring[i+1] != ':' || optpos) { - optarg = argv[optind++] + optpos; - optpos = 0; - } - } - return c; -} - -static void permute(char *const *argv, int dest, int src) -{ - char **av = (char **)argv; - char *tmp = av[src]; - int i; - for (i=src; i>dest; i--) - av[i] = av[i-1]; - av[dest] = tmp; -} - -static int __getopt_long_core(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx, int longonly) -{ - optarg = 0; - if (longopts && argv[optind][0] == '-' && - ((longonly && argv[optind][1] && argv[optind][1] != '-') || - (argv[optind][1] == '-' && argv[optind][2]))) - { - int colon = optstring[optstring[0]=='+'||optstring[0]=='-']==':'; - int i, cnt, match = -1; - char *opt; - for (cnt=i=0; longopts[i].name; i++) { - const char *name = longopts[i].name; - opt = argv[optind]+1; - if (*opt == '-') opt++; - for (; *name && *name == *opt; name++, opt++); - if (*opt && *opt != '=') continue; - match = i; - if (!*name) { - cnt = 1; - break; - } - cnt++; - } - if (cnt==1) { - i = match; - optind++; - optopt = longopts[i].val; - if (*opt == '=') { - if (!longopts[i].has_arg) { - if (colon || !opterr) - return '?'; - __getopt_msg(argv[0], - ": option does not take an argument: ", - longopts[i].name, - strlen(longopts[i].name)); - return '?'; - } - optarg = opt+1; - } else if (longopts[i].has_arg == required_argument) { - if (!(optarg = argv[optind])) { - if (colon) return ':'; - if (!opterr) return '?'; - __getopt_msg(argv[0], - ": option requires an argument: ", - longopts[i].name, - strlen(longopts[i].name)); - return '?'; - } - optind++; - } - if (idx) *idx = i; - if (longopts[i].flag) { - *longopts[i].flag = longopts[i].val; - return 0; - } - return longopts[i].val; - } - if (argv[optind][1] == '-') { - if (!colon && opterr) - __getopt_msg(argv[0], cnt ? - ": option is ambiguous: " : - ": unrecognized option: ", - argv[optind]+2, - strlen(argv[optind]+2)); - optind++; - return '?'; - } - } - return getopt(argc, argv, optstring); -} - -static int __getopt_long(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx, int longonly) -{ - int ret, skipped, resumed; - if (!optind || optreset) { - optreset = 0; - __optpos = 0; - optind = 1; - } - if (optind >= argc || !argv[optind]) return -1; - skipped = optind; - if (optstring[0] != '+' && optstring[0] != '-') { - int i; - for (i=optind; ; i++) { - if (i >= argc || !argv[i]) return -1; - if (argv[i][0] == '-' && argv[i][1]) break; - } - optind = i; - } - resumed = optind; - ret = __getopt_long_core(argc, argv, optstring, longopts, idx, longonly); - if (resumed > skipped) { - int i, cnt = optind-resumed; - for (i=0; ierrmsg[p++] = *msg++; + while (*sep) + options->errmsg[p++] = *sep++; + while (p < sizeof(options->errmsg) - 2 && *data) + options->errmsg[p++] = *data++; + options->errmsg[p++] = '\''; + options->errmsg[p++] = '\0'; + return '?'; +} + +OPTPARSE_API +void +optparse_init(struct optparse *options, char **argv) +{ + options->argv = argv; + options->permute = 1; + options->optind = 1; + options->subopt = 0; + options->optarg = 0; + options->errmsg[0] = '\0'; +} + +static int +optparse_is_dashdash(const char *arg) +{ + return arg != 0 && arg[0] == '-' && arg[1] == '-' && arg[2] == '\0'; +} + +static int +optparse_is_shortopt(const char *arg) +{ + return arg != 0 && arg[0] == '-' && arg[1] != '-' && arg[1] != '\0'; +} + +static int +optparse_is_longopt(const char *arg) +{ + return arg != 0 && arg[0] == '-' && arg[1] == '-' && arg[2] != '\0'; +} + +static void +optparse_permute(struct optparse *options, int index) +{ + char *nonoption = options->argv[index]; + int i; + for (i = index; i < options->optind - 1; i++) + options->argv[i] = options->argv[i + 1]; + options->argv[options->optind - 1] = nonoption; +} + +static int +optparse_argtype(const char *optstring, char c) +{ + int count = OPTPARSE_NONE; + if (c == ':') + return -1; + for (; *optstring && c != *optstring; optstring++); + if (!*optstring) + return -1; + if (optstring[1] == ':') + count += optstring[2] == ':' ? 2 : 1; + return count; +} + +OPTPARSE_API +int +optparse(struct optparse *options, const char *optstring) +{ + int type; + char *next; + char *option = options->argv[options->optind]; + options->errmsg[0] = '\0'; + options->optopt = 0; + options->optarg = 0; + if (option == 0) { + return -1; + } else if (optparse_is_dashdash(option)) { + options->optind++; /* consume "--" */ + return -1; + } else if (!optparse_is_shortopt(option)) { + if (options->permute) { + int index = options->optind++; + int r = optparse(options, optstring); + optparse_permute(options, index); + options->optind--; + return r; + } else { + return -1; + } + } + option += options->subopt + 1; + options->optopt = option[0]; + type = optparse_argtype(optstring, option[0]); + next = options->argv[options->optind + 1]; + switch (type) { + case -1: { + char str[2] = {0, 0}; + str[0] = option[0]; + options->optind++; + return optparse_error(options, OPTPARSE_MSG_INVALID, str); + } + case OPTPARSE_NONE: + if (option[1]) { + options->subopt++; + } else { + options->subopt = 0; + options->optind++; + } + return option[0]; + case OPTPARSE_REQUIRED: + options->subopt = 0; + options->optind++; + if (option[1]) { + options->optarg = option + 1; + } else if (next != 0) { + options->optarg = next; + options->optind++; + } else { + char str[2] = {0, 0}; + str[0] = option[0]; + options->optarg = 0; + return optparse_error(options, OPTPARSE_MSG_MISSING, str); + } + return option[0]; + case OPTPARSE_OPTIONAL: + options->subopt = 0; + options->optind++; + if (option[1]) + options->optarg = option + 1; + else + options->optarg = 0; + return option[0]; + } + return 0; +} + +OPTPARSE_API +char * +optparse_arg(struct optparse *options) +{ + char *option = options->argv[options->optind]; + options->subopt = 0; + if (option != 0) + options->optind++; + return option; +} + +static int +optparse_longopts_end(const struct optparse_long *longopts, int i) +{ + return !longopts[i].longname && !longopts[i].shortname; +} + +static void +optparse_from_long(const struct optparse_long *longopts, char *optstring) +{ + char *p = optstring; + int i; + for (i = 0; !optparse_longopts_end(longopts, i); i++) { + if (longopts[i].shortname && longopts[i].shortname < 127) { + int a; + *p++ = longopts[i].shortname; + for (a = 0; a < (int)longopts[i].argtype; a++) + *p++ = ':'; + } + } + *p = '\0'; +} + +/* Unlike strcmp(), handles options containing "=". */ +static int +optparse_longopts_match(const char *longname, const char *option) +{ + const char *a = option, *n = longname; + if (longname == 0) + return 0; + for (; *a && *n && *a != '='; a++, n++) + if (*a != *n) + return 0; + return *n == '\0' && (*a == '\0' || *a == '='); +} + +/* Return the part after "=", or NULL. */ +static char * +optparse_longopts_arg(char *option) +{ + for (; *option && *option != '='; option++); + if (*option == '=') + return option + 1; + else + return 0; +} + +static int +optparse_long_fallback(struct optparse *options, + const struct optparse_long *longopts, + int *longindex) +{ + int result; + char optstring[96 * 3 + 1]; /* 96 ASCII printable characters */ + optparse_from_long(longopts, optstring); + result = optparse(options, optstring); + if (longindex != 0) { + *longindex = -1; + if (result != -1) { + int i; + for (i = 0; !optparse_longopts_end(longopts, i); i++) + if (longopts[i].shortname == options->optopt) + *longindex = i; + } + } + return result; +} + +OPTPARSE_API +int +optparse_long(struct optparse *options, + const struct optparse_long *longopts, + int *longindex) +{ + int i; + char *option = options->argv[options->optind]; + if (option == 0) { + return -1; + } else if (optparse_is_dashdash(option)) { + options->optind++; /* consume "--" */ + return -1; + } else if (optparse_is_shortopt(option)) { + return optparse_long_fallback(options, longopts, longindex); + } else if (!optparse_is_longopt(option)) { + if (options->permute) { + int index = options->optind++; + int r = optparse_long(options, longopts, longindex); + optparse_permute(options, index); + options->optind--; + return r; + } else { + return -1; + } + } + + /* Parse as long option. */ + options->errmsg[0] = '\0'; + options->optopt = 0; + options->optarg = 0; + option += 2; /* skip "--" */ + options->optind++; + for (i = 0; !optparse_longopts_end(longopts, i); i++) { + const char *name = longopts[i].longname; + if (optparse_longopts_match(name, option)) { + char *arg; + if (longindex) + *longindex = i; + options->optopt = longopts[i].shortname; + arg = optparse_longopts_arg(option); + if (longopts[i].argtype == OPTPARSE_NONE && arg != 0) { + return optparse_error(options, OPTPARSE_MSG_TOOMANY, name); + } if (arg != 0) { + options->optarg = arg; + } else if (longopts[i].argtype == OPTPARSE_REQUIRED) { + options->optarg = options->argv[options->optind]; + if (options->optarg == 0) + return optparse_error(options, OPTPARSE_MSG_MISSING, name); + else + options->optind++; + } + return options->optopt; + } + } + return optparse_error(options, OPTPARSE_MSG_INVALID, option); +} + +#endif /* OPTPARSE_IMPLEMENTATION */ +#endif /* OPTPARSE_H */ diff --git a/shell.c b/shell.c index 5fdb8ae..d190349 100644 --- a/shell.c +++ b/shell.c @@ -36,7 +36,9 @@ #include #endif -#include "getopt.h" +#include "shell.h" +#include "optparse.h" +//#include "bestline.h" #include "vdisk.h" #include "vnet.h" #include "umka.h" @@ -55,8 +57,7 @@ #define DEFAULT_READDIR_ENCODING UTF8 #define DEFAULT_PATH_ENCODING UTF8 -FILE *fin, *fout; - +char prompt_line[2*PATH_MAX]; char cur_dir[PATH_MAX] = "/"; const char *last_dir = cur_dir; bool cur_dir_changed = true; @@ -65,7 +66,7 @@ char cmd_buf[FGETS_BUF_LEN]; typedef struct { char *name; - void (*func) (int, char **); + void (*func) (struct shell_ctx *, int, char **); } func_table_t; const char *f70_status_name[] = { @@ -118,12 +119,12 @@ convert_f70_file_attr(uint32_t attr, char s[KF_ATTR_CNT+1]) { } static void -print_f70_status(f7080ret_t *r, int use_ebx) { - fprintf(fout, "status = %d %s", r->status, get_f70_status_name(r->status)); +print_f70_status(struct shell_ctx *ctx, f7080ret_t *r, int use_ebx) { + fprintf(ctx->fout, "status = %d %s", r->status, get_f70_status_name(r->status)); if (use_ebx && (r->status == ERROR_SUCCESS || r->status == ERROR_END_OF_FILE)) - fprintf(fout, ", count = %d", r->count); - fputc('\n', fout); + fprintf(ctx->fout, ", count = %d", r->count); + fputc('\n', ctx->fout); } static bool @@ -135,48 +136,48 @@ parse_uintmax(const char *str, uintmax_t *res) { } static bool -parse_uint32(const char *str, uint32_t *res) { +parse_uint32(struct shell_ctx *ctx, const char *str, uint32_t *res) { uintmax_t x; if (parse_uintmax(str, &x) && x <= UINT32_MAX) { *res = (uint32_t)x; return true; } else { - perror("invalid number"); + fprintf(ctx->fout, "invalid number: %s\n", str); return false; } } static bool -parse_uint64(const char *str, uint64_t *res) { +parse_uint64(struct shell_ctx *ctx, const char *str, uint64_t *res) { uintmax_t x; if (parse_uintmax(str, &x) && x <= UINT64_MAX) { *res = x; return true; } else { - perror("invalid number"); + fprintf(ctx->fout, "invalid number: %s\n", str); return false; } } static void -print_bytes(uint8_t *x, size_t len) { +print_bytes(struct shell_ctx *ctx, uint8_t *x, size_t len) { for (size_t i = 0; i < len; i++) { if (i % PRINT_BYTES_PER_LINE == 0 && i != 0) { - fputc('\n', fout); + fputc('\n', ctx->fout); } - fprintf(fout, "%2.2x", x[i]); + fprintf(ctx->fout, "%2.2x", x[i]); } - fputc('\n', fout); + fputc('\n', ctx->fout); } static void -print_hash(uint8_t *x, size_t len) { - hash_context ctx; - hash_oneshot(&ctx, x, len); +print_hash(struct shell_ctx *ctx, uint8_t *x, size_t len) { + hash_context hash; + hash_oneshot(&hash, x, len); for (size_t i = 0; i < HASH_SIZE; i++) { - fprintf(fout, "%2.2x", ctx.hash[i]); + fprintf(ctx->fout, "%2.2x", hash.hash[i]); } - fputc('\n', fout); + fputc('\n', ctx->fout); } void *host_load_file(const char *fname) { @@ -205,7 +206,7 @@ get_last_dir(const char *path) { } static void -prompt() { +prompt(struct shell_ctx *ctx) { if (cur_dir_changed) { if (umka_initialized) { COVERAGE_ON(); @@ -215,35 +216,59 @@ prompt() { last_dir = get_last_dir(cur_dir); cur_dir_changed = false; } - fprintf(fout, "%s> ", last_dir); - fflush(fout); + fprintf(ctx->fout, "%s> ", last_dir); + fflush(ctx->fout); +} +/* +static void +completion(const char *buf, bestlineCompletions *lc) { + if (buf[0] == 'h') { + bestlineAddCompletion(lc,"hello"); + bestlineAddCompletion(lc,"hello there"); + } } -static int -next_line(int is_tty, int block) { - if (is_tty) { - prompt(); +static char * +hints(const char *buf, const char **ansi1, const char **ansi2) { + if (!strcmp(buf,"hello")) { + *ansi1 = "\033[35m"; + *ansi2 = "\033[39m"; + return " World"; } + return NULL; +} +*/ +static int +next_line(struct shell_ctx *ctx, int is_tty) { + if (is_tty) { + prompt(ctx); + } + return fgets(cmd_buf, FGETS_BUF_LEN, ctx->fin) != NULL; // TODO: Cleanup #ifdef _WIN32 - return fgets(cmd_buf, FGETS_BUF_LEN, fin) != NULL; + return fgets(cmd_buf, FGETS_BUF_LEN, ctx->fin) != NULL; #else - if (block) { - return fgets(cmd_buf, FGETS_BUF_LEN, fin) != NULL; - } else { - fd_set readfds; -// FD_ZERO(&readfds); - memset(&readfds, 0, sizeof(readfds)); - FD_SET(fileno(fin), &readfds); - struct timeval timeout = {.tv_sec = 0, .tv_usec = 0}; - int sr = select(fileno(fin)+1, &readfds, NULL, NULL, &timeout); - cmd_buf[0] = '\0'; - if (sr > 0) { - fgets(cmd_buf, FGETS_BUF_LEN, fin); - } - return 1; + fd_set readfds; +// FD_ZERO(&readfds); + memset(&readfds, 0, sizeof(readfds)); + FD_SET(fileno(ctx->fin), &readfds); + struct timeval timeout = {.tv_sec = 0, .tv_usec = 0}; + int sr = select(fileno(ctx->fin)+1, &readfds, NULL, NULL, &timeout); + cmd_buf[0] = '\0'; + if (sr > 0) { + fgets(cmd_buf, FGETS_BUF_LEN, ctx->fin); } + return 1; #endif +/* + sprintf(prompt_line, "%s> ", last_dir); + char *line = bestlineRaw(prompt_line, fileno(ctx->fin), fileno(ctx->fout)); + if (line) { + strcpy(cmd_buf, line); + bestlineFree(line); + } + return line != NULL; +*/ } static int @@ -254,13 +279,13 @@ split_args(char *s, char **argv) { } static void -shell_send_scancode(int argc, char **argv) { +shell_send_scancode(struct shell_ctx *ctx, int argc, char **argv) { const char *usage = \ "usage: send_scancode ...\n" " code dec or hex number\n"; if (argc < 2) { - fputs(usage, fout); + fputs(usage, ctx->fout); return; } argc -= 1; @@ -274,20 +299,20 @@ shell_send_scancode(int argc, char **argv) { argc--; argv++; } else { - fprintf(fout, "not an integer: %s\n", argv[0]); - fputs(usage, fout); + fprintf(ctx->fout, "not an integer: %s\n", argv[0]); + fputs(usage, ctx->fout); return; } } } static void -shell_umka_init(int argc, char **argv) { +shell_umka_init(struct shell_ctx *ctx, int argc, char **argv) { const char *usage = \ "usage: umka_init\n"; (void)argv; if (argc < 0) { - fputs(usage, fout); + fputs(usage, ctx->fout); return; } COVERAGE_ON(); @@ -296,7 +321,7 @@ shell_umka_init(int argc, char **argv) { } static void -shell_umka_set_boot_params(int argc, char **argv) { +shell_umka_set_boot_params(struct shell_ctx *ctx, int argc, char **argv) { const char *usage = \ "usage: umka_set_boot_params [--x_res ] [--y_res ]\n" " --x_res screen width\n" @@ -318,8 +343,8 @@ shell_umka_set_boot_params(int argc, char **argv) { argv += 2; continue; } else { - fprintf(fout, "bad option: %s\n", argv[0]); - fputs(usage, fout); + fprintf(ctx->fout, "bad option: %s\n", argv[0]); + fputs(usage, ctx->fout); return; } } @@ -327,12 +352,12 @@ shell_umka_set_boot_params(int argc, char **argv) { } static void -shell_i40(int argc, char **argv) { +shell_i40(struct shell_ctx *ctx, int argc, char **argv) { const char *usage = \ "usage: i40 [ebx [ecx [edx [esi [edi [ebp]]]]]]...\n" " see '/kernel/docs/sysfuncs.txt' for details\n"; if (argc < 2 || argc > 8) { - fputs(usage, fout); + fputs(usage, ctx->fout); return; } pushad_t regs = {0, 0, 0, 0, 0, 0, 0, 0}; @@ -346,51 +371,51 @@ shell_i40(int argc, char **argv) { COVERAGE_ON(); umka_i40(®s); COVERAGE_OFF(); - fprintf(fout, "eax = %8.8x %" PRIu32 " %" PRIi32 "\n" + fprintf(ctx->fout, "eax = %8.8x %" PRIu32 " %" PRIi32 "\n" "ebx = %8.8x %" PRIu32 " %" PRIi32 "\n", regs.eax, regs.eax, (int32_t)regs.eax, regs.ebx, regs.ebx, (int32_t)regs.ebx); } static void -disk_list_partitions(disk_t *d) { +disk_list_partitions(struct shell_ctx *ctx, disk_t *d) { for (size_t i = 0; i < d->num_partitions; i++) { - fprintf(fout, "/%s/%d: ", d->name, i+1); + fprintf(ctx->fout, "/%s/%d: ", d->name, i+1); if (d->partitions[i]->fs_user_functions == xfs_user_functions) { - fputs("xfs\n", fout); + fputs("xfs\n", ctx->fout); } else if (d->partitions[i]->fs_user_functions == ext_user_functions) { - fputs("ext\n", fout); + fputs("ext\n", ctx->fout); } else if (d->partitions[i]->fs_user_functions == fat_user_functions) { - fputs("fat\n", fout); + fputs("fat\n", ctx->fout); } else if (d->partitions[i]->fs_user_functions == exfat_user_functions) { - fputs("exfat\n", fout); + fputs("exfat\n", ctx->fout); } else if (d->partitions[i]->fs_user_functions == ntfs_user_functions) { - fputs("ntfs\n", fout); + fputs("ntfs\n", ctx->fout); } else { - fputs("???\n", fout); + fputs("???\n", ctx->fout); } } } static void -shell_ramdisk_init(int argc, char **argv) { +shell_ramdisk_init(struct shell_ctx *ctx, int argc, char **argv) { const char *usage = \ "usage: ramdisk_init \n" " absolute or relative path\n"; if (argc != 2) { - fputs(usage, fout); + fputs(usage, ctx->fout); return; } const char *fname = argv[1]; FILE *f = fopen(fname, "rb"); if (!f) { - fprintf(fout, "[!] can't open file '%s': %s\n", fname, strerror(errno)); + fprintf(ctx->fout, "[!] can't open file '%s': %s\n", fname, strerror(errno)); return; } fseek(f, 0, SEEK_END); size_t fsize = ftell(f); if (fsize > 2880*512) { - fprintf(fout, "[!] file '%s' is too big, max size is 1474560 bytes\n", + fprintf(ctx->fout, "[!] file '%s' is too big, max size is 1474560 bytes\n", fname); return; } @@ -400,18 +425,18 @@ shell_ramdisk_init(int argc, char **argv) { COVERAGE_ON(); void *ramdisk = kos_ramdisk_init(); COVERAGE_OFF(); - disk_list_partitions(ramdisk); + disk_list_partitions(ctx, ramdisk); } static void -shell_disk_add(int argc, char **argv) { +shell_disk_add(struct shell_ctx *ctx, int argc, char **argv) { const char *usage = \ "usage: disk_add [option]...\n" " absolute or relative path\n" " disk name, e.g. hd0 or rd\n" " -c cache size size of disk cache in bytes\n"; if (argc < 3) { - fputs(usage, fout); + fputs(usage, ctx->fout); return; } size_t cache_size = 0; @@ -427,7 +452,7 @@ shell_disk_add(int argc, char **argv) { adjust_cache_size = 1; break; default: - fputs(usage, fout); + fputs(usage, ctx->fout); return; } } @@ -441,17 +466,17 @@ shell_disk_add(int argc, char **argv) { COVERAGE_ON(); disk_media_changed(vdisk, 1); COVERAGE_OFF(); - disk_list_partitions(vdisk); + disk_list_partitions(ctx, vdisk); return; } } - fprintf(fout, "umka: can't add file '%s' as disk '%s'\n", file_name, + fprintf(ctx->fout, "umka: can't add file '%s' as disk '%s'\n", file_name, disk_name); return; } static void -disk_del_by_name(const char *name) { +disk_del_by_name(struct shell_ctx *ctx, const char *name) { for(disk_t *d = disk_list.next; d != &disk_list; d = d->next) { if (!strcmp(d->name, name)) { COVERAGE_ON(); @@ -460,29 +485,29 @@ disk_del_by_name(const char *name) { return; } } - fprintf(fout, "umka: can't find disk '%s'\n", name); + fprintf(ctx->fout, "umka: can't find disk '%s'\n", name); } static void -shell_disk_del(int argc, char **argv) { +shell_disk_del(struct shell_ctx *ctx, int argc, char **argv) { const char *usage = \ "usage: disk_del \n" " name disk name, i.e. rd or hd0\n"; if (argc != 2) { - fputs(usage, fout); + fputs(usage, ctx->fout); return; } const char *name = argv[1]; - disk_del_by_name(name); + disk_del_by_name(ctx, name); return; } static void -shell_pwd(int argc, char **argv) { +shell_pwd(struct shell_ctx *ctx, int argc, char **argv) { const char *usage = \ "usage: pwd\n"; if (argc != 1) { - fputs(usage, fout); + fputs(usage, ctx->fout); return; } (void)argv; @@ -491,11 +516,11 @@ shell_pwd(int argc, char **argv) { COVERAGE_ON(); umka_sys_get_cwd(cur_dir, PATH_MAX); COVERAGE_OFF(); - fprintf(fout, "%s%s%s\n", quote, cur_dir, quote); + fprintf(ctx->fout, "%s%s%s\n", quote, cur_dir, quote); } static void -shell_set_pixel(int argc, char **argv) { +shell_set_pixel(struct shell_ctx *ctx, int argc, char **argv) { const char *usage = \ "usage: set_pixel [-i]\n" " x x window coordinate\n" @@ -503,7 +528,7 @@ shell_set_pixel(int argc, char **argv) { " color argb in hex\n" " -i inverted color\n"; if (argc < 4) { - fputs(usage, fout); + fputs(usage, ctx->fout); return; } size_t x = strtoul(argv[1], NULL, 0); @@ -516,7 +541,7 @@ shell_set_pixel(int argc, char **argv) { } static void -shell_write_text(int argc, char **argv) { +shell_write_text(struct shell_ctx *ctx, int argc, char **argv) { const char *usage = \ "usage: write_text " " " @@ -532,7 +557,7 @@ shell_write_text(int argc, char **argv) { " length length of the string if it is non-asciiz\n" " bg_color_or_buf argb or pointer\n"; if (argc != 12) { - fputs(usage, fout); + fputs(usage, ctx->fout); return; } size_t x = strtoul(argv[1], NULL, 0); @@ -554,24 +579,24 @@ shell_write_text(int argc, char **argv) { } static void -shell_get_key(int argc, char **argv) { +shell_get_key(struct shell_ctx *ctx, int argc, char **argv) { (void)argv; const char *usage = \ "usage: get_key\n"; if (argc > 1) { - fputs(usage, fout); + fputs(usage, ctx->fout); return; } - fprintf(fout, "0x%8.8" PRIx32 "\n", umka_get_key()); + fprintf(ctx->fout, "0x%8.8" PRIx32 "\n", umka_get_key()); } static void -shell_dump_key_buff(int argc, char **argv) { +shell_dump_key_buff(struct shell_ctx *ctx, int argc, char **argv) { const char *usage = \ "usage: dump_key_buff [count]\n" " count how many items to dump (all by default)\n"; if (argc > 2) { - fputs(usage, fout); + fputs(usage, ctx->fout); return; } int count = INT_MAX; @@ -579,18 +604,18 @@ shell_dump_key_buff(int argc, char **argv) { count = strtol(argv[1], NULL, 0); } for (int i = 0; i < count && i < kos_key_count; i++) { - fprintf(fout, "%3i 0x%2.2x 0x%2.2x\n", i, kos_key_buff[i], + fprintf(ctx->fout, "%3i 0x%2.2x 0x%2.2x\n", i, kos_key_buff[i], kos_key_buff[120+2+i]); } } static void -shell_dump_win_stack(int argc, char **argv) { +shell_dump_win_stack(struct shell_ctx *ctx, int argc, char **argv) { const char *usage = \ "usage: dump_win_stack [count]\n" " count how many items to dump\n"; if (argc > 2) { - fputs(usage, fout); + fputs(usage, ctx->fout); return; } int depth = 5; @@ -598,17 +623,17 @@ shell_dump_win_stack(int argc, char **argv) { depth = strtol(argv[1], NULL, 0); } for (int i = 0; i < depth; i++) { - fprintf(fout, "%3i: %3u\n", i, kos_win_stack[i]); + fprintf(ctx->fout, "%3i: %3u\n", i, kos_win_stack[i]); } } static void -shell_dump_win_pos(int argc, char **argv) { +shell_dump_win_pos(struct shell_ctx *ctx, int argc, char **argv) { const char *usage = \ "usage: dump_win_pos [count]\n" " count how many items to dump\n"; if (argc < 1) { - fputs(usage, fout); + fputs(usage, ctx->fout); return; } int depth = 5; @@ -616,36 +641,36 @@ shell_dump_win_pos(int argc, char **argv) { depth = strtol(argv[1], NULL, 0); } for (int i = 0; i < depth; i++) { - fprintf(fout, "%3i: %3u\n", i, kos_win_pos[i]); + fprintf(ctx->fout, "%3i: %3u\n", i, kos_win_pos[i]); } } static void -shell_dump_win_map(int argc, char **argv) { +shell_dump_win_map(struct shell_ctx *ctx, int argc, char **argv) { // TODO: area const char *usage = \ "usage: dump_win_map\n"; (void)argv; if (argc < 0) { - fputs(usage, fout); + fputs(usage, ctx->fout); return; } for (size_t y = 0; y < kos_display.height; y++) { for (size_t x = 0; x < kos_display.width; x++) { - fputc(kos_display.win_map[y * kos_display.width + x] + '0', fout); + fputc(kos_display.win_map[y * kos_display.width + x] + '0', ctx->fout); } - fputc('\n', fout); + fputc('\n', ctx->fout); } } static void -shell_dump_appdata(int argc, char **argv) { +shell_dump_appdata(struct shell_ctx *ctx, int argc, char **argv) { const char *usage = \ "usage: dump_appdata [-p]\n" " index index into appdata array to dump\n" " -p print fields that are pointers\n"; if (argc < 2) { - fputs(usage, fout); + fputs(usage, ctx->fout); return; } int show_pointers = 0; @@ -654,60 +679,60 @@ shell_dump_appdata(int argc, char **argv) { show_pointers = 1; } appdata_t *a = kos_slot_base + idx; - fprintf(fout, "app_name: %s\n", a->app_name); + fprintf(ctx->fout, "app_name: %s\n", a->app_name); if (show_pointers) { - fprintf(fout, "process: %p\n", (void*)a->process); - fprintf(fout, "fpu_state: %p\n", (void*)a->fpu_state); - fprintf(fout, "exc_handler: %p\n", (void*)a->exc_handler); + fprintf(ctx->fout, "process: %p\n", (void*)a->process); + fprintf(ctx->fout, "fpu_state: %p\n", (void*)a->fpu_state); + fprintf(ctx->fout, "exc_handler: %p\n", (void*)a->exc_handler); } - fprintf(fout, "except_mask: %" PRIx32 "\n", a->except_mask); + fprintf(ctx->fout, "except_mask: %" PRIx32 "\n", a->except_mask); if (show_pointers) { - fprintf(fout, "pl0_stack: %p\n", (void*)a->pl0_stack); - fprintf(fout, "cursor: %p\n", (void*)a->cursor); - fprintf(fout, "fd_ev: %p\n", (void*)a->fd_ev); - fprintf(fout, "bk_ev: %p\n", (void*)a->bk_ev); - fprintf(fout, "fd_obj: %p\n", (void*)a->fd_obj); - fprintf(fout, "bk_obj: %p\n", (void*)a->bk_obj); - fprintf(fout, "saved_esp: %p\n", (void*)a->saved_esp); + fprintf(ctx->fout, "pl0_stack: %p\n", (void*)a->pl0_stack); + fprintf(ctx->fout, "cursor: %p\n", (void*)a->cursor); + fprintf(ctx->fout, "fd_ev: %p\n", (void*)a->fd_ev); + fprintf(ctx->fout, "bk_ev: %p\n", (void*)a->bk_ev); + fprintf(ctx->fout, "fd_obj: %p\n", (void*)a->fd_obj); + fprintf(ctx->fout, "bk_obj: %p\n", (void*)a->bk_obj); + fprintf(ctx->fout, "saved_esp: %p\n", (void*)a->saved_esp); } - fprintf(fout, "dbg_state: %u\n", a->dbg_state); - fprintf(fout, "cur_dir: %s\n", a->cur_dir); - fprintf(fout, "draw_bgr_x: %u\n", a->draw_bgr_x); - fprintf(fout, "draw_bgr_y: %u\n", a->draw_bgr_y); - fprintf(fout, "event_mask: %" PRIx32 "\n", a->event_mask); - fprintf(fout, "tid: %" PRId32 "\n", a->tid); - fprintf(fout, "state: 0x%" PRIx8 "\n", a->state); - fprintf(fout, "wnd_number: %" PRIu8 "\n", a->wnd_number); - fprintf(fout, "terminate_protection: %u\n", a->terminate_protection); - fprintf(fout, "keyboard_mode: %u\n", a->keyboard_mode); - fprintf(fout, "captionEncoding: %u\n", a->captionEncoding); - fprintf(fout, "exec_params: %s\n", a->exec_params); - fprintf(fout, "wnd_caption: %s\n", a->wnd_caption); - fprintf(fout, "wnd_clientbox (ltwh): %u %u %u %u\n", a->wnd_clientbox.left, + fprintf(ctx->fout, "dbg_state: %u\n", a->dbg_state); + fprintf(ctx->fout, "cur_dir: %s\n", a->cur_dir); + fprintf(ctx->fout, "draw_bgr_x: %u\n", a->draw_bgr_x); + fprintf(ctx->fout, "draw_bgr_y: %u\n", a->draw_bgr_y); + fprintf(ctx->fout, "event_mask: %" PRIx32 "\n", a->event_mask); + fprintf(ctx->fout, "tid: %" PRId32 "\n", a->tid); + fprintf(ctx->fout, "state: 0x%" PRIx8 "\n", a->state); + fprintf(ctx->fout, "wnd_number: %" PRIu8 "\n", a->wnd_number); + fprintf(ctx->fout, "terminate_protection: %u\n", a->terminate_protection); + fprintf(ctx->fout, "keyboard_mode: %u\n", a->keyboard_mode); + fprintf(ctx->fout, "captionEncoding: %u\n", a->captionEncoding); + fprintf(ctx->fout, "exec_params: %s\n", a->exec_params); + fprintf(ctx->fout, "wnd_caption: %s\n", a->wnd_caption); + fprintf(ctx->fout, "wnd_clientbox (ltwh): %u %u %u %u\n", a->wnd_clientbox.left, a->wnd_clientbox.top, a->wnd_clientbox.width, a->wnd_clientbox.height); - fprintf(fout, "priority: %u\n", a->priority); + fprintf(ctx->fout, "priority: %u\n", a->priority); - fprintf(fout, "in_schedule: prev"); + fprintf(ctx->fout, "in_schedule: prev"); if (show_pointers) { - fprintf(fout, " %p", (void*)a->in_schedule.prev); + fprintf(ctx->fout, " %p", (void*)a->in_schedule.prev); } - fprintf(fout, " (%u), next", + fprintf(ctx->fout, " (%u), next", (appdata_t*)a->in_schedule.prev - kos_slot_base); if (show_pointers) { - fprintf(fout, " %p", (void*)a->in_schedule.next); + fprintf(ctx->fout, " %p", (void*)a->in_schedule.next); } - fprintf(fout, " (%u)\n", + fprintf(ctx->fout, " (%u)\n", (appdata_t*)a->in_schedule.next - kos_slot_base); } static void -shell_switch_to_thread(int argc, char **argv) { +shell_switch_to_thread(struct shell_ctx *ctx, int argc, char **argv) { const char *usage = \ "usage: switch_to_thread \n" " thread id to switch to\n"; if (argc != 2) { - fputs(usage, fout); + fputs(usage, ctx->fout); return; } uint8_t tid = strtoul(argv[1], NULL, 0); @@ -716,40 +741,40 @@ shell_switch_to_thread(int argc, char **argv) { } static void -shell_get(int argc, char **argv) { +shell_get(struct shell_ctx *ctx, int argc, char **argv) { const char *usage = \ "usage: get \n" " variable to get\n"; if (argc != 2) { - fputs(usage, fout); + fputs(usage, ctx->fout); return; } const char *var = argv[1]; if (!strcmp(var, "redraw_background")) { - fprintf(fout, "%i\n", kos_redraw_background); + fprintf(ctx->fout, "%i\n", kos_redraw_background); } else if (!strcmp(var, "key_count")) { - fprintf(fout, "%i\n", kos_key_count); + fprintf(ctx->fout, "%i\n", kos_key_count); } else if (!strcmp(var, "syslang")) { - fprintf(fout, "%i\n", kos_syslang); + fprintf(ctx->fout, "%i\n", kos_syslang); } else if (!strcmp(var, "keyboard")) { - fprintf(fout, "%i\n", kos_keyboard); + fprintf(ctx->fout, "%i\n", kos_keyboard); } else if (!strcmp(var, "keyboard_mode")) { - fprintf(fout, "%i\n", kos_keyboard_mode); + fprintf(ctx->fout, "%i\n", kos_keyboard_mode); } else { - fprintf(fout, "no such variable: %s\n", var); - fputs(usage, fout); + fprintf(ctx->fout, "no such variable: %s\n", var); + fputs(usage, ctx->fout); return; } } static void -shell_set(int argc, char **argv) { +shell_set(struct shell_ctx *ctx, int argc, char **argv) { const char *usage = \ "usage: set \n" " variable to set\n" " decimal or hex value\n"; if (argc != 3) { - fputs(usage, fout); + fputs(usage, ctx->fout); return; } const char *var = argv[1]; @@ -763,28 +788,28 @@ shell_set(int argc, char **argv) { } else if (!strcmp(var, "keyboard_mode")) { kos_keyboard_mode = value; } else { - fprintf(fout, "bad option: %s\n", argv[1]); - fputs(usage, fout); + fprintf(ctx->fout, "bad option: %s\n", argv[1]); + fputs(usage, ctx->fout); return; } } static void -shell_new_sys_thread(int argc, char **argv) { +shell_new_sys_thread(struct shell_ctx *ctx, int argc, char **argv) { // FIXME const char *usage = \ "usage: new_sys_thread\n"; if (!argc) { - fputs(usage, fout); + fputs(usage, ctx->fout); return; } (void)argv; size_t tid = umka_new_sys_threads(0, NULL, NULL); - fprintf(fout, "tid: %u\n", tid); + fprintf(ctx->fout, "tid: %u\n", tid); } static void -shell_mouse_move(int argc, char **argv) { +shell_mouse_move(struct shell_ctx *ctx, int argc, char **argv) { const char *usage = \ "usage: mouse_move [-l] [-m] [-r] [-x {+|-|=}]" "[-y {+|-|=}] [-h {+|-}] [-v {+|-}]\n" @@ -796,7 +821,7 @@ shell_mouse_move(int argc, char **argv) { " -h scroll horizontally\n" " -v scroll vertically\n"; if (!argc) { - fputs(usage, fout); + fputs(usage, ctx->fout); return; } int lbheld = 0, mbheld = 0, rbheld = 0, xabs = 0, yabs = 0; @@ -826,7 +851,7 @@ shell_mouse_move(int argc, char **argv) { xmoving = -strtol(optarg, NULL, 0); break; default: - fputs(usage, fout); + fputs(usage, ctx->fout); return; } break; @@ -842,26 +867,26 @@ shell_mouse_move(int argc, char **argv) { ymoving = -strtol(optarg, NULL, 0); break; default: - fputs(usage, fout); + fputs(usage, ctx->fout); return; } break; case 'h': if ((optarg[0] != '+') && (optarg[0] != '-')) { - fputs(usage, fout); + fputs(usage, ctx->fout); return; } hscroll = strtol(optarg, NULL, 0); break; case 'v': if ((optarg[0] != '+') && (optarg[0] != '-')) { - fputs(usage, fout); + fputs(usage, ctx->fout); return; } vscroll = strtol(optarg, NULL, 0); break; default: - fputs(usage, fout); + fputs(usage, ctx->fout); return; } } @@ -872,12 +897,12 @@ shell_mouse_move(int argc, char **argv) { } static void -shell_process_info(int argc, char **argv) { +shell_process_info(struct shell_ctx *ctx, int argc, char **argv) { const char *usage = \ "usage: process_info \n" " pid process id to dump, -1 for self\n"; if (argc != 2) { - fputs(usage, fout); + fputs(usage, ctx->fout); return; } process_information_t info; @@ -885,24 +910,24 @@ shell_process_info(int argc, char **argv) { COVERAGE_ON(); umka_sys_process_info(pid, &info); COVERAGE_OFF(); - fprintf(fout, "cpu_usage: %u\n", info.cpu_usage); - fprintf(fout, "window_stack_position: %u\n", info.window_stack_position); - fprintf(fout, "window_stack_value: %u\n", info.window_stack_value); - fprintf(fout, "process_name: %s\n", info.process_name); - fprintf(fout, "memory_start: 0x%.8" PRIx32 "\n", info.memory_start); - fprintf(fout, "used_memory: %u (0x%x)\n", info.used_memory, + fprintf(ctx->fout, "cpu_usage: %u\n", info.cpu_usage); + fprintf(ctx->fout, "window_stack_position: %u\n", info.window_stack_position); + fprintf(ctx->fout, "window_stack_value: %u\n", info.window_stack_value); + fprintf(ctx->fout, "process_name: %s\n", info.process_name); + fprintf(ctx->fout, "memory_start: 0x%.8" PRIx32 "\n", info.memory_start); + fprintf(ctx->fout, "used_memory: %u (0x%x)\n", info.used_memory, info.used_memory); - fprintf(fout, "pid: %u\n", info.pid); - fprintf(fout, "box: %u %u %u %u\n", info.box.left, info.box.top, + fprintf(ctx->fout, "pid: %u\n", info.pid); + fprintf(ctx->fout, "box: %u %u %u %u\n", info.box.left, info.box.top, info.box.width, info.box.height); - fprintf(fout, "slot_state: %u\n", info.slot_state); - fprintf(fout, "client_box: %u %u %u %u\n", info.client_box.left, + fprintf(ctx->fout, "slot_state: %u\n", info.slot_state); + fprintf(ctx->fout, "client_box: %u %u %u %u\n", info.client_box.left, info.client_box.top, info.client_box.width, info.client_box.height); - fprintf(fout, "wnd_state: 0x%.2" PRIx8 "\n", info.wnd_state); + fprintf(ctx->fout, "wnd_state: 0x%.2" PRIx8 "\n", info.wnd_state); } static void -shell_display_number(int argc, char **argv) { +shell_display_number(struct shell_ctx *ctx, int argc, char **argv) { const char *usage = \ "usage: display_number " " " @@ -922,7 +947,7 @@ shell_display_number(int argc, char **argv) { " scale_factor 0 = x1, ..., 7 = x8\n" " bg_color_or_buf depending on flags fill_bg and draw_to_buf\n"; if (argc != 15) { - fputs(usage, fout); + fputs(usage, ctx->fout); return; } int is_pointer = strtoul(argv[1], NULL, 0); @@ -952,14 +977,14 @@ shell_display_number(int argc, char **argv) { } static void -shell_set_window_colors(int argc, char **argv) { +shell_set_window_colors(struct shell_ctx *ctx, int argc, char **argv) { const char *usage = \ "usage: set_window_colors " " " " \n" " * all colors are in hex\n"; if (argc != (1 + sizeof(system_colors_t)/4)) { - fputs(usage, fout); + fputs(usage, ctx->fout); return; } system_colors_t colors; @@ -979,11 +1004,11 @@ shell_set_window_colors(int argc, char **argv) { } static void -shell_get_window_colors(int argc, char **argv) { +shell_get_window_colors(struct shell_ctx *ctx, int argc, char **argv) { const char *usage = \ "usage: get_window_colors\n"; if (argc != 1) { - fputs(usage, fout); + fputs(usage, ctx->fout); return; } (void)argv; @@ -992,40 +1017,40 @@ shell_get_window_colors(int argc, char **argv) { COVERAGE_ON(); umka_sys_get_window_colors(&colors); COVERAGE_OFF(); - fprintf(fout, "0x%.8" PRIx32 " frame\n", colors.frame); - fprintf(fout, "0x%.8" PRIx32 " grab\n", colors.grab); - fprintf(fout, "0x%.8" PRIx32 " work_3d_dark\n", colors.work_3d_dark); - fprintf(fout, "0x%.8" PRIx32 " work_3d_light\n", colors.work_3d_light); - fprintf(fout, "0x%.8" PRIx32 " grab_text\n", colors.grab_text); - fprintf(fout, "0x%.8" PRIx32 " work\n", colors.work); - fprintf(fout, "0x%.8" PRIx32 " work_button\n", colors.work_button); - fprintf(fout, "0x%.8" PRIx32 " work_button_text\n", + fprintf(ctx->fout, "0x%.8" PRIx32 " frame\n", colors.frame); + fprintf(ctx->fout, "0x%.8" PRIx32 " grab\n", colors.grab); + fprintf(ctx->fout, "0x%.8" PRIx32 " work_3d_dark\n", colors.work_3d_dark); + fprintf(ctx->fout, "0x%.8" PRIx32 " work_3d_light\n", colors.work_3d_light); + fprintf(ctx->fout, "0x%.8" PRIx32 " grab_text\n", colors.grab_text); + fprintf(ctx->fout, "0x%.8" PRIx32 " work\n", colors.work); + fprintf(ctx->fout, "0x%.8" PRIx32 " work_button\n", colors.work_button); + fprintf(ctx->fout, "0x%.8" PRIx32 " work_button_text\n", colors.work_button_text); - fprintf(fout, "0x%.8" PRIx32 " work_text\n", colors.work_text); - fprintf(fout, "0x%.8" PRIx32 " work_graph\n", colors.work_graph); + fprintf(ctx->fout, "0x%.8" PRIx32 " work_text\n", colors.work_text); + fprintf(ctx->fout, "0x%.8" PRIx32 " work_graph\n", colors.work_graph); } static void -shell_get_skin_height(int argc, char **argv) { +shell_get_skin_height(struct shell_ctx *ctx, int argc, char **argv) { const char *usage = \ "usage: get_skin_height\n"; if (argc != 1) { - fputs(usage, fout); + fputs(usage, ctx->fout); return; } (void)argv; COVERAGE_ON(); uint32_t skin_height = umka_sys_get_skin_height(); COVERAGE_OFF(); - fprintf(fout, "%" PRIu32 "\n", skin_height); + fprintf(ctx->fout, "%" PRIu32 "\n", skin_height); } static void -shell_get_screen_area(int argc, char **argv) { +shell_get_screen_area(struct shell_ctx *ctx, int argc, char **argv) { const char *usage = \ "usage: get_screen_area\n"; if (argc != 1) { - fputs(usage, fout); + fputs(usage, ctx->fout); return; } (void)argv; @@ -1033,14 +1058,14 @@ shell_get_screen_area(int argc, char **argv) { COVERAGE_ON(); umka_sys_get_screen_area(&wa); COVERAGE_OFF(); - fprintf(fout, "%" PRIu32 " left\n", wa.left); - fprintf(fout, "%" PRIu32 " top\n", wa.top); - fprintf(fout, "%" PRIu32 " right\n", wa.right); - fprintf(fout, "%" PRIu32 " bottom\n", wa.bottom); + fprintf(ctx->fout, "%" PRIu32 " left\n", wa.left); + fprintf(ctx->fout, "%" PRIu32 " top\n", wa.top); + fprintf(ctx->fout, "%" PRIu32 " right\n", wa.right); + fprintf(ctx->fout, "%" PRIu32 " bottom\n", wa.bottom); } static void -shell_set_screen_area(int argc, char **argv) { +shell_set_screen_area(struct shell_ctx *ctx, int argc, char **argv) { const char *usage = \ "usage: set_screen_area \n" " left left x coord\n" @@ -1048,7 +1073,7 @@ shell_set_screen_area(int argc, char **argv) { " right right x coord (not length!)\n" " bottom bottom y coord\n"; if (argc != 5) { - fputs(usage, fout); + fputs(usage, ctx->fout); return; } rect_t wa; @@ -1062,11 +1087,11 @@ shell_set_screen_area(int argc, char **argv) { } static void -shell_get_skin_margins(int argc, char **argv) { +shell_get_skin_margins(struct shell_ctx *ctx, int argc, char **argv) { const char *usage = \ "usage: get_skin_margins\n"; if (argc != 1) { - fputs(usage, fout); + fputs(usage, ctx->fout); return; } (void)argv; @@ -1074,19 +1099,19 @@ shell_get_skin_margins(int argc, char **argv) { COVERAGE_ON(); umka_sys_get_skin_margins(&wa); COVERAGE_OFF(); - fprintf(fout, "%" PRIu32 " left\n", wa.left); - fprintf(fout, "%" PRIu32 " top\n", wa.top); - fprintf(fout, "%" PRIu32 " right\n", wa.right); - fprintf(fout, "%" PRIu32 " bottom\n", wa.bottom); + fprintf(ctx->fout, "%" PRIu32 " left\n", wa.left); + fprintf(ctx->fout, "%" PRIu32 " top\n", wa.top); + fprintf(ctx->fout, "%" PRIu32 " right\n", wa.right); + fprintf(ctx->fout, "%" PRIu32 " bottom\n", wa.bottom); } static void -shell_set_button_style(int argc, char **argv) { +shell_set_button_style(struct shell_ctx *ctx, int argc, char **argv) { const char *usage = \ "usage: set_button_style