From 37ddf81b563a8e57a03be38ee07876b5be844ac9 Mon Sep 17 00:00:00 2001 From: Bobby Bingham Date: Sat, 1 Aug 2015 12:03:41 -0500 Subject: simplify parameter handling --- src/satmkboot.c | 150 +++++++++++++++++++------------------------------------- 1 file changed, 51 insertions(+), 99 deletions(-) (limited to 'src') diff --git a/src/satmkboot.c b/src/satmkboot.c index 3b71fe5..83b4f03 100644 --- a/src/satmkboot.c +++ b/src/satmkboot.c @@ -15,8 +15,8 @@ static struct systemid sysid = { .version = "V0.001", .reldate = "20000101", .device = "CD-1/1 ", - .regions = " ", - .peripherals = " ", + .regions = "JTUBKAEL ", + .peripherals = "J ", .padding1 = " ", .title = "TEST TITLE ", .bootsize = 0xe00, @@ -118,17 +118,6 @@ fail: return -1; } -static int append_symbol(char *list, size_t size, char symbol) -{ - for (size_t i = 0; i < size; i++) { - if (list[i] == ' ') - list[i] = symbol; - if (list[i] == symbol) - return 0; - } - return -1; -} - static void print_symbols(FILE *fp, int width, const struct symbolname *symbols) { for (; symbols->symbol; symbols++) { @@ -153,111 +142,81 @@ static void usage(const char *progname) fprintf(stderr, "\t%-*s%s\n", width, "-s slave_stack", "Slave stack address (default 0x06001000)"); } -#define ERR_UNKNOWN_OPTION 0 -#define ERR_MISSING_OPTION 1 -#define ERR_DUPLICATE_INPUT 2 -#define ERR_DUPLICATE_OUTPUT 3 -#define ERR_REGION_OVERFLOW 4 -#define ERR_PERIPHERAL_OVERFLOW 5 -#define ERR_DUPLICATE_MASTER 6 -#define ERR_DUPLICATE_SLAVE 7 -#define ERR_INVALID_MASTER 8 -#define ERR_INVALID_SLAVE 9 - -static const char *errmsgs[] = { - "Unknown extra argument", - "Missing required option", - "Duplicate -i parameter", - "Duplicate -o parameter", - "Too many regions specified (max 10)", - "Too many peripherals specified (max 16)", - "Duplicate -m parameter", - "Duplicate -s parameter", - "Invalid master stack address", - "Invalid slave stack address", -}; - -static int show_arg_error(const char *progname, int prev_errors, int error) -{ - if (!(prev_errors & 1 << error)) - fprintf(stderr, "%s: %s\n", progname, errmsgs[error]); - return prev_errors | 1 << error; -} - -static void process_symbols(const char *progname, char *list, size_t size, const char *arg, int *errors, int overflow) +static int process_symbols(const char *progname, char *list, size_t size, const char *arg) { - for (; *arg; arg++) { - if (append_symbol(list, size, *arg)) { - *errors = show_arg_error(progname, *errors, overflow); - return; - } - } + while (size-- && *arg) *list++ = *arg++; + while (size--) *list++ = ' '; + return *arg; } -static int process_address(const char *progname, uint32_t *addr, const char *arg, int *errors, int bad_addr) +static int process_address(const char *progname, uint32_t *addr, const char *arg) { char *end; errno = 0; unsigned long val = strtoul(arg, &end, 16); - if (end == arg || *end || errno || val > (uint32_t)-1) { - *errors = show_arg_error(progname, *errors, bad_addr); - return 0; - } - + if (end == arg || *end || errno || val > (uint32_t)-1) return 1; *addr = val; - return 1; + return 0; } +#define FLAG_o (1U << 3) + static int process_args(int argc, char **argv) { - int errors = 0, fail = 0, help = 0; - int opt; - - int have_master = 0; - int have_slave = 0; + uint32_t seen = 0; + int opt, fail = 0; extern char *optarg; extern int optind, optopt; - while ((opt = getopt(argc, argv, "hi:o:p:r:m:s:")) != -1) { + static const char *optpat = "hi:o:p:r:m:s:"; + while ((opt = getopt(argc, argv, optpat)) != -1) { + uint32_t flag = opt == '?' ? 0 : 1U << strchr(optpat, opt) - optpat; + if (seen & flag) { + fprintf(stderr, "%s: Duplicate option -%c\n", argv[0], opt); + fail = 1; + continue; + } + seen |= flag; + switch (opt) { case 'h': - help = 1; - break; + usage(argv[0]); + return 1; case 'i': - if (ipfile) - errors = show_arg_error(argv[0], errors, ERR_DUPLICATE_INPUT); - else - ipfile = optarg; + ipfile = optarg; break; case 'o': - if (outfile) - errors = show_arg_error(argv[0], errors, ERR_DUPLICATE_OUTPUT); - else - outfile = optarg; + outfile = optarg; break; case 'm': - if (have_master) - errors = show_arg_error(argv[0], errors, ERR_DUPLICATE_MASTER); - else - have_master = process_address(argv[0], &sysid.stack_master, optarg, &errors, ERR_INVALID_MASTER); + if (process_address(argv[0], &sysid.stack_master, optarg)) { + fprintf(stderr, "%s: Invalid master stack\n", argv[0]); + fail = 1; + } break; case 's': - if (have_slave) - errors = show_arg_error(argv[0], errors, ERR_DUPLICATE_SLAVE); - else - have_slave = process_address(argv[0], &sysid.stack_slave, optarg, &errors, ERR_INVALID_SLAVE); + if (process_address(argv[0], &sysid.stack_slave, optarg)) { + fprintf(stderr, "%s: Invalid slave stack\n", argv[0]); + fail = 1; + } break; case 'p': - process_symbols(argv[0], sysid.peripherals, sizeof sysid.peripherals, optarg, &errors, ERR_PERIPHERAL_OVERFLOW); + if (process_symbols(argv[0], sysid.peripherals, sizeof sysid.peripherals, optarg)) { + fprintf(stderr, "%s: Too many peripherals specified (max 16)\n", argv[0]); + fail = 1; + } break; case 'r': - process_symbols(argv[0], sysid.regions, sizeof sysid.regions, optarg, &errors, ERR_REGION_OVERFLOW); + if (process_symbols(argv[0], sysid.regions, sizeof sysid.regions, optarg)) { + fprintf(stderr, "%s: Too many regions specified (max 10)\n", argv[0]); + fail = 1; + } break; default: @@ -265,21 +224,17 @@ static int process_args(int argc, char **argv) } } - if (help) { - usage(argv[0]); - } else if (!fail) { - if (argv[optind]) - errors = show_arg_error(argv[0], errors, ERR_UNKNOWN_OPTION); - if (!outfile) - errors = show_arg_error(argv[0], errors, ERR_MISSING_OPTION); - fail = errors; + if (!(seen & FLAG_o)) { + fprintf(stderr, "%s: Missing required option -o\n", argv[0]); + fail = 1; } - - if (fail) { - fprintf(stderr, "\nUse -h option for help on correct usage.\n"); + if (argv[optind]) { + fprintf(stderr, "%s: Unknown option '%s'\n", argv[0], argv[optind]); + fail = 1; } + if (fail) fprintf(stderr, "\nUse -h option for help on correct usage.\n"); - return fail | help; + return fail; } int main(int argc, char **argv) @@ -292,9 +247,6 @@ int main(int argc, char **argv) return 1; } - if (sysid.regions[0] == ' ') strcpy(sysid.regions, "JTUBKAEL"); - if (sysid.peripherals[0] == ' ') sysid.peripherals[0] = 'J'; - for (int i = 0; i < 8; i++) { serialize_region_code(ipout, find_symbol(regiondefs, sysid.regions[i])); ipout += 32; -- cgit v1.2.3