summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBobby Bingham <koorogi@koorogi.info>2015-08-01 12:03:41 -0500
committerBobby Bingham <koorogi@koorogi.info>2015-09-15 22:43:32 -0500
commit37ddf81b563a8e57a03be38ee07876b5be844ac9 (patch)
tree19ecbd868687dab28306fff91ab0d8576b76a11d
parenta8ffc5d80c10743dafa0e31981e1caa7e832c1b9 (diff)
simplify parameter handling
-rw-r--r--src/satmkboot.c150
1 files changed, 51 insertions, 99 deletions
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;