From a464d3ec2c93e65da4ae752ac126c30e9897d63b Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Tue, 8 Feb 2005 16:15:58 +0000 Subject: option parsing --- opts.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 opts.c (limited to 'opts.c') diff --git a/opts.c b/opts.c new file mode 100644 index 0000000..3976d3a --- /dev/null +++ b/opts.c @@ -0,0 +1,99 @@ +/* + Mount option parsing + Copyright (C) 2004 Miklos Szeredi + + This program can be distributed under the terms of the GNU GPL. + See the file COPYING. +*/ + +#include "opts.h" +#include +#include + +static int process_option(char *arg, struct opt opts[], int case_sensitive) +{ + int i; + char *eq = strchr(arg, '='); + if (eq) + *eq = '\0'; + + for (i = 0; opts[i].optname != NULL; i++) { + if (case_sensitive) { + if (strcmp(opts[i].optname, arg) == 0) + break; + } else if (strcasecmp(opts[i].optname, arg) == 0) + break; + } + if (opts[i].optname == NULL) { + if (eq) + *eq = '='; + return 0; + } + opts[i].present = 1; + if (eq) { + if (opts[i].value) + free(opts[i].value); + opts[i].value = strdup(eq+1); + } + return 1; +} + +static int process_option_group(char *arg, struct opt opts[], + int case_sensitive) +{ + int remove = 1; + char *prevcomma = NULL; + while (1) { + int remove_one; + char *comma = strchr(arg, ','); + if (comma) + *comma = '\0'; + remove_one = process_option(arg, opts, case_sensitive); + if (remove_one) { + if (comma) + memmove(arg, comma + 1, strlen(comma + 1)); + } else { + remove = 0; + if (comma) + arg = comma + 1; + } + if (!remove_one && prevcomma) + *prevcomma = ','; + if (!comma) + break; + prevcomma = comma; + } + return remove; +} + +void process_options(int *argcp, char *argv[], struct opt opts[], + int case_sensitive) +{ + int argctr; + int newargctr; + + for (argctr = 1, newargctr = 1; argctr < *argcp; argctr++) { + char *arg = argv[argctr]; + int removed = 0; + if (arg[0] == '-' && arg[1] == 'o') { + if (arg[2]) + removed = process_option_group(arg+2, opts, case_sensitive); + else { + if (argctr + 1 < *argcp) { + argctr++; + arg = argv[argctr]; + removed = process_option_group(arg, opts, case_sensitive); + if (!removed && argctr != newargctr) + argv[newargctr++] = argv[argctr-1]; + } + } + } + if (!removed) { + if(argctr != newargctr) + argv[newargctr] = arg; + newargctr++; + } + } + *argcp = newargctr; +} + -- cgit v1.2.3