diff --git a/docs/changelog.txt b/docs/changelog.txt index 973cbfc85..f98d1b197 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -44,7 +44,9 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: ## Lua - ``gui.Painter``: fixed error when calling ``viewport()`` method - `xlsxreader`: Added Lua class wrappers for the xlsxreader plugin API -- ``utils.processArgsGetopt()``: now returns negative numbers (e.g. ``-10``) in the list of positional parameters instead of treating it as an option string equivalent to ``-1 -0``. +- ``utils.processArgsGetopt()``: now returns negative numbers (e.g. ``-10``) in the list of positional parameters instead of treating it as an option string equivalent to ``-1 -0`` +- ``utils.processArgsGetopt()``: now properly handles ``--`` as a marker to treat all further parameters as non-options +- ``utils.processArgsGetopt()``: now detects when a required arguments to long-form options are missing ## Documentation - Added more client library implementations to the `remote interface docs ` diff --git a/library/lua/3rdparty/alt_getopt.lua b/library/lua/3rdparty/alt_getopt.lua index 7d1dbd056..df4f51402 100644 --- a/library/lua/3rdparty/alt_getopt.lua +++ b/library/lua/3rdparty/alt_getopt.lua @@ -100,6 +100,7 @@ function get_ordered_opts(args, sh_opts, long_opts) local a = args[optind] if a == '--' then optind = optind + 1 + break elseif a:sub(1, 2) == '--' then local pos = a:find('=', 1, true) if pos then @@ -113,7 +114,7 @@ function get_ordered_opts(args, sh_opts, long_opts) local opt = a:sub(3) opts[count] = opt if has_arg(options, opt) then - if i == #args then + if optind == #args then qerror(string.format( 'Missing value for option "%s"', a)) end diff --git a/test/library/utils.lua b/test/library/utils.lua index d1f3f696b..b2c63dafd 100644 --- a/test/library/utils.lua +++ b/test/library/utils.lua @@ -91,9 +91,13 @@ function test.processArgsGetopt_happy_path() args = {'nonopt1', '-nfoo', 'nonopt2', '-1', '-10', '-0v'} expect.table_eq({'nonopt1', 'nonopt2', '-1', '-10', '-0v'}, process(args, false, false, 'foo')) + + args = {'nonopt1', '--', '-nfoo', '--nonopt2', 'nonopt3'} + expect.table_eq({'nonopt1', '-nfoo', '--nonopt2', 'nonopt3'}, + process(args, false, false, nil)) end -function test.processArgsGetopt_errors() +function test.processArgsGetopt_action_errors() expect.error_match('missing option letter', function() utils.processArgsGetopt({}, {{handler=function() end}}) end) @@ -106,3 +110,37 @@ function test.processArgsGetopt_errors() expect.error_match('handler missing', function() utils.processArgsGetopt({}, {{'r'}}) end) end + +function test.processArgsGetopt_parsing_errors() + expect.error_match('Unknown option', + function() utils.processArgsGetopt({'-abc'}, + {{'a', handler=function() end}}) + end, + 'use undefined short option') + + expect.error_match('Unknown option', + function() utils.processArgsGetopt({'--abc'}, + {{'a', handler=function() end}}) + end, + 'use undefined long option') + + expect.error_match('Bad usage', + function() utils.processArgsGetopt({'--ab=c'}, + {{'a', 'ab', handler=function() end}}) + end, + 'pass value to param that does not take one') + + expect.error_match('Missing value', + function() utils.processArgsGetopt({'-a'}, + {{'a', 'ab', hasArg=true, + handler=function() end}}) + end, + 'fail to pass value to short param that requires one') + + expect.error_match('Missing value', + function() utils.processArgsGetopt({'--ab'}, + {{'a', 'ab', hasArg=true, + handler=function() end}}) + end, + 'fail to pass value to long param that requires one') +end