From b0c9427c821b4ff0e4da0ed2651de1b83d01aeaf Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Thu, 10 Sep 2026 17:51:41 -0700 Subject: [PATCH] pvxs::GetOpt POSIXLY_CORRECT ordering --- tools/cliutil.cpp | 2 ++ tools/testcliutil.cpp | 30 ++++++++++++++++++++++++++---- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/tools/cliutil.cpp b/tools/cliutil.cpp index d5a1563..58d662f 100644 --- a/tools/cliutil.cpp +++ b/tools/cliutil.cpp @@ -75,6 +75,8 @@ nextarg: } else { positional.push_back(arg); + // replicate POSIXLY_CORRECT= behavior. Require options before positional. + allpos = true; } success = true; } diff --git a/tools/testcliutil.cpp b/tools/testcliutil.cpp index aff24c3..d4b0ada 100644 --- a/tools/testcliutil.cpp +++ b/tools/testcliutil.cpp @@ -49,7 +49,7 @@ struct test_print> { }} // namespace::detail MAIN(testcliutil) { - testPlan(24); + testPlan(30); { testDiag("case @%d", __LINE__); @@ -75,7 +75,7 @@ MAIN(testcliutil) { { testDiag("case @%d", __LINE__); - const char* argv[] = {"exe", "-v", "hello", "-aAa"}; + const char* argv[] = {"exe", "-v", "-aAa", "hello"}; pvxs::GetOpt opts(NELEMENTS(argv), const_cast(argv), "va:"); testOk(strcmp(opts.argv0, "exe")==0, "%s", opts.argv0); decltype (opts.arguments) arguments({{'v', nullptr}, {'a',"Aa"}}); @@ -86,12 +86,12 @@ MAIN(testcliutil) { { testDiag("case @%d", __LINE__); - const char* argv[] = {"exe", "-v", "hello", "-a"}; // missing value + const char* argv[] = {"exe", "-v", "-a"}; // missing value pvxs::GetOpt opts(NELEMENTS(argv), const_cast(argv), "va:"); testOk(strcmp(opts.argv0, "exe")==0, "%s", opts.argv0); decltype (opts.arguments) arguments({{'v', nullptr}, {'?',nullptr}}); testArrEq(opts.arguments, arguments); - decltype (opts.positional) positional({"hello"}); + decltype (opts.positional) positional; testArrEq(opts.positional, positional); } @@ -139,5 +139,27 @@ MAIN(testcliutil) { testArrEq(opts.positional, positional); } + { + testDiag("case @%d", __LINE__); + const char* argv[] = {"exe", "-v", "-1", "hello"}; + pvxs::GetOpt opts(NELEMENTS(argv), const_cast(argv), "va:"); + testOk(strcmp(opts.argv0, "exe")==0, "%s", opts.argv0); + decltype (opts.arguments) arguments({{'v', nullptr}, {-1, nullptr}}); + testArrEq(opts.arguments, arguments); + decltype (opts.positional) positional({"hello"}); + testArrEq(opts.positional, positional); + } + + { + testDiag("case @%d", __LINE__); + const char* argv[] = {"exe", "-v", "hello", "-1"}; + pvxs::GetOpt opts(NELEMENTS(argv), const_cast(argv), "va:"); + testOk(strcmp(opts.argv0, "exe")==0, "%s", opts.argv0); + decltype (opts.arguments) arguments({{'v', nullptr}}); + testArrEq(opts.arguments, arguments); + decltype (opts.positional) positional({"hello", "-1"}); + testArrEq(opts.positional, positional); + } + return testDone(); }