aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libsimple-arg.c212
-rw-r--r--libsimple-arg.h10
2 files changed, 217 insertions, 5 deletions
diff --git a/libsimple-arg.c b/libsimple-arg.c
index a802c55..95581bf 100644
--- a/libsimple-arg.c
+++ b/libsimple-arg.c
@@ -88,6 +88,50 @@
} while (0)
+#define LONG_WITHOUT_ARG(LONG_FLAG)\
+ do {\
+ assert(nparsed < sizeof(parsed) / sizeof(*parsed));\
+ assert(FLAG() == LONG_FLAG[1]);\
+ assert(!strcmp(LFLAG(), LONG_FLAG));\
+ parsed[nparsed].short_used = 0;\
+ parsed[nparsed].long_used = 1;\
+ parsed[nparsed].have_arg = 0;\
+ parsed[nparsed].short_flag[0] = '\0';\
+ parsed[nparsed].short_flag[1] = '\0';\
+ parsed[nparsed].short_flag[2] = '\0';\
+ stpcpy(parsed[nparsed].long_flag, LONG_FLAG);\
+ parsed[nparsed].argument[0] = '\0';\
+ nparsed += 1;\
+ } while (0)
+
+
+#define LONG_WITH_ARG(LONG_FLAG)\
+ do {\
+ char *arg__;\
+ assert(nparsed < sizeof(parsed) / sizeof(*parsed));\
+ assert(FLAG() == LONG_FLAG[1]);\
+ assert(!strcmp(LFLAG(), LONG_FLAG) || !strncmp(LFLAG(), LONG_FLAG"=", sizeof(LONG_FLAG"=")));\
+ parsed[nparsed].short_used = 0;\
+ parsed[nparsed].long_used = 1;\
+ parsed[nparsed].have_arg = 1;\
+ parsed[nparsed].short_flag[0] = '\0';\
+ parsed[nparsed].short_flag[1] = '\0';\
+ parsed[nparsed].short_flag[2] = '\0';\
+ stpcpy(parsed[nparsed].long_flag, LONG_FLAG);\
+ assert(strlen(ARG()) < sizeof(parsed[nparsed].argument));\
+ assert((arg__ = ARG()));\
+ assert(arg__ == ARGNULL());\
+ stpcpy(parsed[nparsed].argument, ARG());\
+ nparsed += 1;\
+ } while (0)
+
+
+#define LONG_WITH_MISSING_ARG(LONG_FLAG)\
+ do {\
+ assert_unreached();\
+ } while (0)
+
+
#define ASSERT_ENTRY(SHORT_FLAG, LONG_FLAG, ARGUMENT)\
do {\
const char *volatile short_flag__ = (SHORT_FLAG);\
@@ -363,6 +407,102 @@ stop:
}
+static int
+parser7(int argc, char *argv[])
+{
+ PARSER_BEGIN;
+ ARGBEGIN {
+ case '-':
+ if (TESTLONG("--alpha", 0))
+ LONG_WITHOUT_ARG("--alpha");
+ else if (TESTLONG("--alpha=", 0))
+ LONG_WITHOUT_ARG("--alpha=");
+ else if (TESTLONG("--beta", 1))
+ LONG_WITH_ARG("--beta");
+ else if (TESTLONG("--gamma=", 1))
+ LONG_WITH_ARG("--gamma");
+ else if (TESTLONG("--gamma", 0))
+ LONG_WITHOUT_ARG("--gamma");
+ else if (TESTLONG("--missing", 1))
+ LONG_WITH_MISSING_ARG("--missing");
+ else
+ usage();
+ break;
+ default:
+ usage();
+ } ARGALT('+') {
+ case '+':
+ if (TESTLONG("++alpha", 0))
+ LONG_WITHOUT_ARG("++alpha");
+ else if (TESTLONG("++alpha=", 0))
+ LONG_WITHOUT_ARG("++alpha=");
+ else if (TESTLONG("++beta", 1))
+ LONG_WITH_ARG("++beta");
+ else if (TESTLONG("++gamma=", 1))
+ LONG_WITH_ARG("++gamma");
+ else if (TESTLONG("++gamma", 0))
+ LONG_WITHOUT_ARG("++gamma");
+ else if (TESTLONG("++missing", 1))
+ LONG_WITH_MISSING_ARG("++missing");
+ else
+ usage();
+ break;
+ default:
+ usage();
+ } ARGEND;
+ PARSER_END;
+}
+
+
+static int
+parser8(int argc, char *argv[])
+{
+ PARSER_BEGIN;
+ ARGBEGIN {
+ case 'a': SHORT_WITHOUT_ARG("-a"); break;
+ case 'A': SHORT_WITHOUT_ARG("-A"); break;
+ case 'b': SHORT_WITH_ARG("-b"); break;
+ case 'g': SHORT_WITH_ARG("-g"); break;
+ case 'G': SHORT_WITHOUT_ARG("-G"); break;
+ case 'm': SHORT_WITH_MISSING_ARG("-m"); break;
+ case '-':
+ ARGMAPLONG(((struct longopt []){
+ {"--alpha", 'a', 0},
+ {"--alpha=", 'A', 0},
+ {"--beta", 'b', 1},
+ {"--gamma=", 'g', 1},
+ {"--gamma", 'G', 0},
+ {"--missing", 'm', 1},
+ {NULL, '\0', 0},
+ }));
+ /* fall through */
+ default:
+ usage();
+ } ARGALT('+') {
+ case 'a': SHORT_WITHOUT_ARG("+a"); break;
+ case 'A': SHORT_WITHOUT_ARG("+A"); break;
+ case 'b': SHORT_WITH_ARG("+b"); break;
+ case 'g': SHORT_WITH_ARG("+g"); break;
+ case 'G': SHORT_WITHOUT_ARG("+G"); break;
+ case 'm': SHORT_WITH_MISSING_ARG("+m"); break;
+ case '+':
+ ARGMAPLONG(((struct longopt []){
+ {"++alpha", 'a', 0},
+ {"++alpha=", 'A', 0},
+ {"++beta", 'b', 1},
+ {"++gamma=", 'g', 1},
+ {"++gamma", 'G', 0},
+ {"++missing", 'm', 1},
+ {NULL, '\0', 0},
+ }));
+ /* fall through */
+ default:
+ usage();
+ } ARGEND;
+ PARSER_END;
+}
+
+
int
main(void)
{
@@ -484,6 +624,78 @@ main(void)
ASSERT_END();
}
+ assert(apply(parser7, "", "--alpha", "++alpha", "--alpha=", "++alpha=", "--missing") == -1);
+ ASSERT_ENTRY(NULL, "--alpha", NULL);
+ ASSERT_ENTRY(NULL, "++alpha", NULL);
+ ASSERT_ENTRY(NULL, "--alpha=", NULL);
+ ASSERT_ENTRY(NULL, "++alpha=", NULL);
+ ASSERT_END();
+
+ assert(apply(parser7, "", "++alpha", "--alpha", "++alpha=", "--alpha=", "++missing") == -1);
+ ASSERT_ENTRY(NULL, "++alpha", NULL);
+ ASSERT_ENTRY(NULL, "--alpha", NULL);
+ ASSERT_ENTRY(NULL, "++alpha=", NULL);
+ ASSERT_ENTRY(NULL, "--alpha=", NULL);
+ ASSERT_END();
+
+ assert(apply(parser7, "", "--beta", "abc", "--beta=xyz", "--betax") == -1);
+ ASSERT_ENTRY(NULL, "--beta", "abc");
+ ASSERT_ENTRY(NULL, "--beta", "xyz");
+ ASSERT_END();
+
+ assert(apply(parser7, "", "++beta", "abc", "++beta=xyz", "++betax") == -1);
+ ASSERT_ENTRY(NULL, "++beta", "abc");
+ ASSERT_ENTRY(NULL, "++beta", "xyz");
+ ASSERT_END();
+
+ assert(apply(parser7, "", "--gamma=123", "--gamma=", "--gamma", "789") == 1);
+ ASSERT_ENTRY(NULL, "--gamma", "123");
+ ASSERT_ENTRY(NULL, "--gamma", "");
+ ASSERT_ENTRY(NULL, "--gamma", NULL);
+ ASSERT_END();
+
+ assert(apply(parser7, "", "++gamma=123", "++gamma=", "++gamma", "789") == 1);
+ ASSERT_ENTRY(NULL, "++gamma", "123");
+ ASSERT_ENTRY(NULL, "++gamma", "");
+ ASSERT_ENTRY(NULL, "++gamma", NULL);
+ ASSERT_END();
+
+ assert(apply(parser8, "", "--alpha", "++alpha", "--alpha=", "++alpha=", "--missing") == -1);
+ ASSERT_ENTRY("-a", NULL, NULL);
+ ASSERT_ENTRY("+a", NULL, NULL);
+ ASSERT_ENTRY("-A", NULL, NULL);
+ ASSERT_ENTRY("+A", NULL, NULL);
+ ASSERT_END();
+
+ assert(apply(parser8, "", "++alpha", "--alpha", "++alpha=", "--alpha=", "++missing") == -1);
+ ASSERT_ENTRY("+a", NULL, NULL);
+ ASSERT_ENTRY("-a", NULL, NULL);
+ ASSERT_ENTRY("+A", NULL, NULL);
+ ASSERT_ENTRY("-A", NULL, NULL);
+ ASSERT_END();
+
+ assert(apply(parser8, "", "--beta", "abc", "--beta=xyz", "--betax") == -1);
+ ASSERT_ENTRY("-b", NULL, "abc");
+ ASSERT_ENTRY("-b", NULL, "xyz");
+ ASSERT_END();
+
+ assert(apply(parser8, "", "++beta", "abc", "++beta=xyz", "++betax") == -1);
+ ASSERT_ENTRY("+b", NULL, "abc");
+ ASSERT_ENTRY("+b", NULL, "xyz");
+ ASSERT_END();
+
+ assert(apply(parser8, "", "--gamma=123", "--gamma=", "--gamma", "789") == 1);
+ ASSERT_ENTRY("-g", NULL, "123");
+ ASSERT_ENTRY("-g", NULL, "");
+ ASSERT_ENTRY("-G", NULL, NULL);
+ ASSERT_END();
+
+ assert(apply(parser8, "", "++gamma=123", "++gamma=", "++gamma", "789") == 1);
+ ASSERT_ENTRY("+g", NULL, "123");
+ ASSERT_ENTRY("+g", NULL, "");
+ ASSERT_ENTRY("+G", NULL, NULL);
+ ASSERT_END();
+
argv0_1 = "[1]";
assert_exit(usage1());
assert(exit_status == 1);
diff --git a/libsimple-arg.h b/libsimple-arg.h
index 0ba316a..1f4291c 100644
--- a/libsimple-arg.h
+++ b/libsimple-arg.h
@@ -147,7 +147,7 @@ struct longopt {
* @param LONGOPTS:struct longopt * The options, list shall end
* with `NULL` as `.long_flag`
*/
-#define ARGMAPLONG(LONGOPTS)/* TODO test */\
+#define ARGMAPLONG(LONGOPTS)\
for (i_ = 0; (LONGOPTS)[i_].long_flag; i_++) {\
if (TESTLONG((LONGOPTS)[i_].long_flag, (LONGOPTS)[i_].with_arg)) {\
flag_ = (LONGOPTS)[i_].short_flag;\
@@ -338,7 +338,7 @@ struct longopt {
* @param WARG:int Whether the option takes an argument,
* should not have side-effects
*/
-#define TESTLONG(FLG, WARG)/* TODO test */\
+#define TESTLONG(FLG, WARG)\
((WARG)\
? ((!strncmp(lflag_, (FLG), (n_ = strlen(FLG), n_ -= ((FLG)[n_ - !!n_] == '='))) && lflag_[n_] == '=')\
? (lflag_[n_] = '\0',\
@@ -393,7 +393,7 @@ struct longopt {
*
* This macro also defines `char *argv0`
*
- * @param SYNOPSIS Description of the command line argument syntax
+ * @param SYNOPSIS:const char * Description of the command line argument syntax
*/
#define USAGE(SYNOPSIS)\
NUSAGE(1, SYNOPSIS)
@@ -409,8 +409,8 @@ struct longopt {
*
* This macro also defines `char *argv0`
*
- * @param SYNOPSIS Description of the command line argument syntax
- * @parma STATUS The exit value for the process
+ * @param SYNOPSIS:const char * Description of the command line argument syntax
+ * @parma STATUS:int The exit value for the process
*/
#if defined(__GNUC__) || defined(__clang__)
# define NUSAGE(STATUS, SYNOPSIS)\