aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias Andrée <maandree@operamail.com>2013-08-27 22:44:01 +0200
committerMattias Andrée <maandree@operamail.com>2013-08-27 22:44:01 +0200
commitd1ef8c1c0236cefec9a8cad12a816998bd670819 (patch)
tree17fb298d26680f02f4c3a4b96df097302beafac7
parentissue 7, bash version (diff)
downloadargparser-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.c74
-rw-r--r--src/argparser.h19
-rw-r--r--src/test.c2
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
diff --git a/src/test.c b/src/test.c
index 4e52f1e..9d65b2e 100644
--- a/src/test.c
+++ b/src/test.c
@@ -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");