diff options
author | Mattias Andrée <maandree@operamail.com> | 2013-08-27 22:44:01 +0200 |
---|---|---|
committer | Mattias Andrée <maandree@operamail.com> | 2013-08-27 22:44:01 +0200 |
commit | d1ef8c1c0236cefec9a8cad12a816998bd670819 (patch) | |
tree | 17fb298d26680f02f4c3a4b96df097302beafac7 | |
parent | issue 7, bash version (diff) | |
download | argparser-d1ef8c1c0236cefec9a8cad12a816998bd670819.tar.gz argparser-d1ef8c1c0236cefec9a8cad12a816998bd670819.tar.bz2 argparser-d1ef8c1c0236cefec9a8cad12a816998bd670819.tar.xz |
issue 7, c version
Signed-off-by: Mattias Andrée <maandree@operamail.com>
-rw-r--r-- | src/argparser.c | 74 | ||||
-rw-r--r-- | src/argparser.h | 19 | ||||
-rw-r--r-- | src/test.c | 2 |
3 files changed, 82 insertions, 13 deletions
diff --git a/src/argparser.c b/src/argparser.c index 644f6fd..7c80759 100644 --- a/src/argparser.c +++ b/src/argparser.c @@ -31,6 +31,7 @@ #define VARIADIC 3 /* Prototype for static functions */ +static char* args__abbreviations(char* argument); static void _sort(char** list, long count, char** temp); static void sort(char** list, long count); static void _sort_ptr(void** list, long count, void** temp); @@ -123,8 +124,9 @@ static long args_map_values_size; * @param program The name of the program, `null` for automatic * @param usestderr Whether to use stderr instead of stdout * @param alternative Whether to use single dash/plus long options + * @param abbreviations Abbreviated option expander, `null` for disabled */ -void args_init(char* description, char* usage, char* longdescription, char* program, long usestderr, long alternative) +void args_init(char* description, char* usage, char* longdescription, char* program, long usestderr, long alternative, char* (*abbreviations)(char*, char**, long)) { char* term = getenv("TERM"); args_linuxvt = 0; @@ -159,6 +161,7 @@ void args_init(char* description, char* usage, char* longdescription, char* prog args_options = (args_Option*)malloc(args_options_size * sizeof(args_Option)); map_init(&args_optmap); map_init(&args_opts); + args_abbreviations = abbreviations; } @@ -225,6 +228,49 @@ void args_dispose() /** + * The standard abbrevation expander + * + * @param argument The option that not recognised + * @param options All recognised options + * @param count The number of elements in `options` + * @return The only possible expansion, otherwise `null` + */ +char* args_standard_abbreviations(char* argument, char** options, long count) +{ + char* rc = null; + long i; + for (i = 0; i < count; i++) + { + long match = 0; + char* opt = *options; + while (*(argument + match) && (*(opt + match) == *(argument + match))) + match++; + if (*(argument + match) == 0) + { + if (rc) + return null; + rc = opt; + } + } + return rc; +} + + +/** + * Abbreviated option expansion function + * + * @param argument The option that is not recognised + * @return The only alternative, or `null` + */ +char* args__abbreviations(char* argument) +{ + if (args_abbreviations == null) + return null; + return args_abbreviations(argument, args_get_optmap(), args_get_optmap_count()); +} + + +/** * Creates, but does not add, a option that takes no arguments * * @param trigger Function to invoke when the option is used, with the used option and the standard option @@ -1309,6 +1355,7 @@ long args_parse(int argc, char** argv) char** argend = argv + argc; long dashed = false, tmpdashed = false, get = 0, dontget = 0, rc = true; long argptr = 0, optptr = 0, queuesize = argc - 1; + char* injection = null; char** argqueue; char** optqueue; @@ -1337,9 +1384,10 @@ long args_parse(int argc, char** argv) optqueue = (char**)malloc(queuesize * sizeof(char*)); args_freequeue = (void**)malloc(queuesize * sizeof(void*)); - while (argv != argend) + while ((argv != argend) || injection) { - char* arg = *argv++; + char* arg = injection ? injection : *argv++; + injection = null; if ((get > 0) && (dontget == 0)) { char* arg_opt = *(optqueue + optptr - get--); @@ -1413,9 +1461,12 @@ long args_parse(int argc, char** argv) } else { - if (++args_unrecognised_count <= 5) - fprintf(args_out, "%s: warning: unrecognised option %s\n", args_program, arg); - rc = false; + if ((injection = args__abbreviations(arg)) == null) + { + if (++args_unrecognised_count <= 5) + fprintf(args_out, "%s: warning: unrecognised option %s\n", args_program, arg_opt); + rc = false; + } free(arg_opt); } } @@ -1432,11 +1483,12 @@ long args_parse(int argc, char** argv) args_optmap_trigger(arg, null); } else - { - if (++args_unrecognised_count <= 5) - fprintf(args_out, "%s: warning: unrecognised option %s\n", args_program, arg); - rc = false; - } + if ((injection = args__abbreviations(arg)) == null) + { + if (++args_unrecognised_count <= 5) + fprintf(args_out, "%s: warning: unrecognised option %s\n", args_program, arg); + rc = false; + } } else { diff --git a/src/argparser.h b/src/argparser.h index 3c06584..eb073cd 100644 --- a/src/argparser.h +++ b/src/argparser.h @@ -192,6 +192,11 @@ char** args_files; */ long args_files_count; +/** + * Abbreviated option expander, `null` for disabled + */ +char* (*args_abbreviations)(char*, char**, long); + /** @@ -204,8 +209,9 @@ long args_files_count; * @param program The name of the program, `null` for automatic * @param usestderr Whether to use stderr instead of stdout * @param alternative Whether to use single dash/plus long options + * @param abbreviations Abbreviated option expander, `null` for disabled */ -extern void args_init(char* description, char* usage, char* longdescription, char* program, long usestderr, long alternative); +extern void args_init(char* description, char* usage, char* longdescription, char* program, long usestderr, long alternative, char* (*abbreviations)(char*, char**, long)); /** @@ -215,6 +221,17 @@ extern void args_dispose(void); /** + * The standard abbrevation expander + * + * @param argument The option that not recognised + * @param options All recognised options + * @param count The number of elements in `options` + * @return The only possible expansion, otherwise `null` + */ +extern char* args_standard_abbreviations(char* argument, char** options, long count); + + +/** * Creates, but does not add, a option that takes no arguments * * @param trigger Function to invoked when the option is used, with the used option and the standard option @@ -41,7 +41,7 @@ int main(int argc, char** argv) "GNU Affero General Public License for more details.\n" "\n" "You should have received a copy of the GNU Affero General Public License\n" - "along with this library. If not, see <http://www.gnu.org/licenses/>.", 0, 1, 0); + "along with this library. If not, see <http://www.gnu.org/licenses/>.", 0, 1, 0, args_standard_abbreviations); args_add_option(args_new_argumentless(NULL, 1, "-h", "-?", "--help", NULL), "Prints this help message\n(and exits)"); args_add_option(args_new_argumentless(NULL, 0, "--hello", NULL), "Prints the text: hello world"); |