diff --git a/CHANGES.txt b/CHANGES.txt index 677d73964f..9c18fe5d0d 100755 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -43,6 +43,11 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER - Suppress missing SConscript deprecation warning if `must_exist=False` is used. + From Dillan Mills: + - Fix support for short options (`-x`). + - Add support for long and short options with nargs != '?' to contain spaces: + - `--extra A B C` and `-x A B C` will both work as expected + RELEASE 4.0.1 - Mon, 16 Jul 2020 16:06:40 -0700 diff --git a/SCons/Script/SConsOptions.py b/SCons/Script/SConsOptions.py index aa31635323..ac43d36e6c 100644 --- a/SCons/Script/SConsOptions.py +++ b/SCons/Script/SConsOptions.py @@ -261,6 +261,76 @@ def error(self, msg): sys.stderr.write("SCons Error: %s\n" % msg) sys.exit(2) + def _process_short_opts(self, rargs, values): + """ + SCons-specific processing of short options. + + This is copied directly from the normal + optparse._process_short_opts() method, except that, if configured + to do so, we catch the exception thrown when an unknown option + is encountered and just stick it back on the "leftover" arguments + for later (re-)processing. + """ + arg = rargs.pop(0) + stop = False + i = 1 + for ch in arg[1:]: + opt = "-" + ch + option = self._short_opt.get(opt) + i += 1 # we have consumed a character + + try: + if not option: + raise optparse.BadOptionError(opt) + except optparse.BadOptionError: + if self.preserve_unknown_options: + # SCons-specific: if requested, add unknown options to + # the "leftover arguments" list for later processing. + self.largs.append(arg) + return + raise + + if option.takes_value(): + had_explicit_value = False + + # Any characters left in arg? Pretend they're the + # next arg, and stop consuming characters of arg. + if i < len(arg): + rargs.insert(0, arg[i:]) + stop = True + had_explicit_value = True + + nargs = option.nargs + if len(rargs) < nargs: + if nargs == 1: + self.error(_("%s option requires an argument") % opt) + else: + self.error(_("%s option requires %d arguments") + % (opt, nargs)) + elif nargs == 1: + value = rargs.pop(0) + if not had_explicit_value: + SCons.Script._Remove_Target(value) + if '=' in value: + SCons.Script._Remove_Argument(value) + else: + value = tuple(rargs[0:nargs]) + del rargs[0:nargs] + for i in range(len(value)): + if not had_explicit_value or i > 0: + SCons.Script._Remove_Target(value[i]) + if '=' in value[i]: + SCons.Script._Remove_Argument(value[i]) + + + else: # option doesn't take a value + value = None + + option.process(opt, value, values, self) + + if stop: + break + def _process_long_opt(self, rargs, values): """ SCons-specific processing of long options. @@ -322,9 +392,18 @@ def _process_long_opt(self, rargs, values): % (opt, nargs)) elif nargs == 1: value = rargs.pop(0) + if not had_explicit_value: + SCons.Script._Remove_Target(value) + if '=' in value: + SCons.Script._Remove_Argument(value) else: value = tuple(rargs[0:nargs]) del rargs[0:nargs] + for i in range(len(value)): + if not had_explicit_value or i > 0: + SCons.Script._Remove_Target(value[i]) + if '=' in value[i]: + SCons.Script._Remove_Argument(value[i]) elif had_explicit_value: self.error(_("%s option does not take a value") % opt) @@ -334,69 +413,6 @@ def _process_long_opt(self, rargs, values): option.process(opt, value, values, self) - def reparse_local_options(self): - """ Re-parse the leftover command-line options. - - Parse options stored in `self.largs`, so that any value - overridden on the command line is immediately available - if the user turns around and does a :func:`GetOption` right away. - - We mimic the processing of the single args - in the original OptionParser :func:`_process_args`, but here we - allow exact matches for long-opts only (no partial argument names!). - Otherwise there could be problems in :func:`add_local_option` - below. When called from there, we try to reparse the - command-line arguments that - - 1. haven't been processed so far (`self.largs`), but - 2. are possibly not added to the list of options yet. - - So, when we only have a value for "--myargument" so far, - a command-line argument of "--myarg=test" would set it, - per the behaviour of :func:`_match_long_opt`, - which allows for partial matches of the option name, - as long as the common prefix appears to be unique. - This would lead to further confusion, because we might want - to add another option "--myarg" later on (see issue #2929). - - """ - rargs = [] - largs_restore = [] - # Loop over all remaining arguments - skip = False - for l in self.largs: - if skip: - # Accept all remaining arguments as they are - largs_restore.append(l) - else: - if len(l) > 2 and l[0:2] == "--": - # Check long option - lopt = (l,) - if "=" in l: - # Split into option and value - lopt = l.split("=", 1) - - if lopt[0] in self._long_opt: - # Argument is already known - rargs.append('='.join(lopt)) - else: - # Not known yet, so reject for now - largs_restore.append('='.join(lopt)) - else: - if l == "--" or l == "-": - # Stop normal processing and don't - # process the rest of the command-line opts - largs_restore.append(l) - skip = True - else: - rargs.append(l) - - # Parse the filtered list - self.parse_args(rargs, self.values) - # Restore the list of remaining arguments for the - # next call of AddOption/add_local_option... - self.largs = self.largs + largs_restore - def add_local_option(self, *args, **kw): """ Adds a local option to the parser. @@ -413,7 +429,7 @@ def add_local_option(self, *args, **kw): self.local_option_group = group result = group.add_option(*args, **kw) - + if result: # The option was added successfully. We now have to add the # default value to our object that holds the default values @@ -424,8 +440,8 @@ def add_local_option(self, *args, **kw): # available if the user turns around and does a GetOption() # right away. setattr(self.values.__defaults__, result.dest, result.default) - self.reparse_local_options() - + self.parse_args(self.largs, self.values) + return result class SConsIndentedHelpFormatter(optparse.IndentedHelpFormatter): @@ -508,7 +524,7 @@ def Parser(version): """ formatter = SConsIndentedHelpFormatter(max_help_position=30) - + op = SConsOptionParser(option_class=SConsOption, add_help_option=False, formatter=formatter, diff --git a/SCons/Script/__init__.py b/SCons/Script/__init__.py index ee9b3828b7..02c34e0419 100644 --- a/SCons/Script/__init__.py +++ b/SCons/Script/__init__.py @@ -215,6 +215,21 @@ def _Add_Arguments(alist): ARGUMENTS[a] = b ARGLIST.append((a, b)) +def _Remove_Argument(aarg): + if aarg: + a, b = aarg.split('=', 1) + + # remove from ARGLIST first which would contain duplicates if -x A=B A=B was specified on the CL + if (a, b) in ARGLIST: + ARGLIST.remove((a, b)) + + # Remove first in case no matching values left in ARGLIST + ARGUMENTS.pop(a, None) + # Set ARGUMENTS[A] back to latest value in ARGLIST (assuming order matches CL order) + for item in ARGLIST: + if item[0] == a: + ARGUMENTS[a] = item[1] + def _Add_Targets(tlist): if tlist: COMMAND_LINE_TARGETS.extend(tlist) @@ -225,6 +240,15 @@ def _Add_Targets(tlist): _build_plus_default._add_Default = _build_plus_default._do_nothing _build_plus_default._clear = _build_plus_default._do_nothing +def _Remove_Target(targ): + if targ: + if targ in COMMAND_LINE_TARGETS: + COMMAND_LINE_TARGETS.remove(targ) + if targ in BUILD_TARGETS: + BUILD_TARGETS.remove(targ) + if targ in _build_plus_default: + _build_plus_default.remove(targ) + def _Set_Default_Targets_Has_Been_Called(d, fs): return DEFAULT_TARGETS diff --git a/test/AddOption/args-and-targets.py b/test/AddOption/args-and-targets.py new file mode 100644 index 0000000000..1187934fb9 --- /dev/null +++ b/test/AddOption/args-and-targets.py @@ -0,0 +1,263 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Verify that when an option is specified which takes args, +those do not end up treated as targets. +""" + +import TestSCons + +test = TestSCons.TestSCons(match = TestSCons.match_re_dotall) + +# test.write('SConstruct', """\ +# env = Environment() +# AddOption('-x', '--extra', +# nargs=1, +# dest='extra', +# action='store', +# type='string', +# metavar='ARG1', +# default=(), +# help='An argument to the option') +# print(str(GetOption('extra'))) +# print(COMMAND_LINE_TARGETS) +# """) + +# # arg using = +# test.run('-Q -q --extra=A TARG', status=1, stdout="A\n\\['TARG'\\]\n") +# # arg not using = +# test.run('-Q -q --extra A TARG', status=1, stdout="A\n\\['TARG'\\]\n") +# # short arg with space +# test.run('-Q -q -x A TARG', status=1, stdout="A\n\\['TARG'\\]\n") +# # short arg with no space +# test.run('-Q -q -xA TARG', status=1, stdout="A\n\\['TARG'\\]\n") + +# test.write('SConstruct', """\ +# env = Environment() +# AddOption('-x', '--extra', +# nargs=2, +# dest='extra', +# action='append', +# type='string', +# metavar='ARG1', +# default=[], +# help='An argument to the option') +# print(str(GetOption('extra'))) +# print(COMMAND_LINE_TARGETS) +# """) + +# # many args and opts +# test.run('-Q -q --extra=A B TARG1 -x C D TARG2 -xE F TARG3 --extra G H TARG4', +# status=1, stdout="\\[\\('A', 'B'\\), \\('C', 'D'\\), \\('E', 'F'\\), \\('G', 'H'\\)\\]\n\\['TARG1', 'TARG2', 'TARG3', 'TARG4'\\]\n") + +# test.write('SConstruct', """\ +# env = Environment() +# AddOption('-x', '--extra', +# nargs=1, +# dest='extra', +# action='store', +# type='string', +# metavar='ARG1', +# default=(), +# help='An argument to the option') +# print(str(GetOption('extra'))) +# print(COMMAND_LINE_TARGETS) +# print(ARGUMENTS.get('A', None)) +# """) + +# # opt value and target are same name +# test.run('-Q -q --extra=TARG1 TARG1', status=1, stdout="TARG1\n\\['TARG1'\\]\nNone\n") +# test.run('-Q -q --extra TARG1 TARG1', status=1, stdout="TARG1\n\\['TARG1'\\]\nNone\n") +# test.run('-Q -q -xTARG1 TARG1', status=1, stdout="TARG1\n\\['TARG1'\\]\nNone\n") +# test.run('-Q -q -x TARG1 TARG1', status=1, stdout="TARG1\n\\['TARG1'\\]\nNone\n") + +# # target first +# test.run('-Q -q TARG1 --extra=TARG1', status=1, stdout="TARG1\n\\['TARG1'\\]\nNone\n") +# test.run('-Q -q TARG1 --extra TARG1', status=1, stdout="TARG1\n\\['TARG1'\\]\nNone\n") +# test.run('-Q -q TARG1 -xTARG1', status=1, stdout="TARG1\n\\['TARG1'\\]\nNone\n") +# test.run('-Q -q TARG1 -x TARG1', status=1, stdout="TARG1\n\\['TARG1'\\]\nNone\n") + +# # equals in opt value +# test.run('-Q -q --extra=A=B TARG1', status=1, stdout="A=B\n\\['TARG1'\\]\nNone\n") +# test.run('-Q -q --extra A=B TARG1', status=1, stdout="A=B\n\\['TARG1'\\]\nNone\n") +# test.run('-Q -q -xA=B TARG1', status=1, stdout="A=B\n\\['TARG1'\\]\nNone\n") +# test.run('-Q -q -x A=B TARG1', status=1, stdout="A=B\n\\['TARG1'\\]\nNone\n") + +# # equals in opt value and a different argument +# test.run('-Q -q --extra=A=B A=C TARG1', status=1, stdout="A=B\n\\['TARG1'\\]\nC\n") +# test.run('-Q -q --extra A=B A=C TARG1', status=1, stdout="A=B\n\\['TARG1'\\]\nC\n") +# test.run('-Q -q -xA=B A=C TARG1', status=1, stdout="A=B\n\\['TARG1'\\]\nC\n") +# test.run('-Q -q -x A=B A=C TARG1', status=1, stdout="A=B\n\\['TARG1'\\]\nC\n") + +# # different argument first +# test.run('-Q -q A=C --extra=A=B TARG1', status=1, stdout="A=B\n\\['TARG1'\\]\nC\n") +# test.run('-Q -q A=C --extra A=B TARG1', status=1, stdout="A=B\n\\['TARG1'\\]\nC\n") +# test.run('-Q -q A=C -xA=B TARG1', status=1, stdout="A=B\n\\['TARG1'\\]\nC\n") +# test.run('-Q -q A=C -x A=B TARG1', status=1, stdout="A=B\n\\['TARG1'\\]\nC\n") + +# # equals in opt value and the same as an argument +# test.run('-Q -q --extra=A=B A=B TARG1', status=1, stdout="A=B\n\\['TARG1'\\]\nB\n") +# test.run('-Q -q --extra A=B A=B TARG1', status=1, stdout="A=B\n\\['TARG1'\\]\nB\n") +# test.run('-Q -q -xA=B A=B TARG1', status=1, stdout="A=B\n\\['TARG1'\\]\nB\n") +# test.run('-Q -q -x A=B A=B TARG1', status=1, stdout="A=B\n\\['TARG1'\\]\nB\n") + +# # same argument first +# test.run('-Q -q A=B --extra=A=B TARG1', status=1, stdout="A=B\n\\['TARG1'\\]\nB\n") +# test.run('-Q -q A=B --extra A=B TARG1', status=1, stdout="A=B\n\\['TARG1'\\]\nB\n") +# test.run('-Q -q A=B -xA=B TARG1', status=1, stdout="A=B\n\\['TARG1'\\]\nB\n") +# test.run('-Q -q A=B -x A=B TARG1', status=1, stdout="A=B\n\\['TARG1'\\]\nB\n") + +# test.write('SConstruct', """\ +# env = Environment() +# AddOption('-x', '--extra', +# nargs=1, +# dest='extra', +# action='store', +# type='string', +# metavar='ARG1', +# default=(), +# help='An argument to the option') +# if 'A' in BUILD_TARGETS: +# BUILD_TARGETS.append('B') +# print(str(GetOption('extra'))) +# print(BUILD_TARGETS) +# """) + +# # Nested target +# test.run('-Q -q -x A TARG1', status=1, stdout="A\n\\['TARG1'\\]\n") +# test.run('-Q -q -x A A TARG1', status=1, stdout="A\n\\['A', 'TARG1', 'B'\\]\n") +# test.run('-Q -q A -x A TARG1', status=1, stdout="A\n\\['A', 'TARG1', 'B'\\]\n") + +# test.write('SConstruct', """\ +# env = Environment() +# AddOption('-x', '--extra', +# nargs=1, +# dest='extra', +# action='store', +# type='string', +# metavar='ARG1', +# default=(), +# help='An argument to the option') +# if 'A' in BUILD_TARGETS: +# AddOption('--foo', +# nargs=1, +# dest='foo', +# action='store', +# type='string', +# metavar='FOO1', +# default=(), +# help='An argument to the option') +# print(str(GetOption('extra'))) +# print(str(GetOption('foo'))) +# print(COMMAND_LINE_TARGETS) +# """) + +# # nested option +# test.run('-Q -q -x A --foo=C TARG1', status=2, stdout="A\n", stderr="""\ +# AttributeError: 'Values' object has no attribute 'foo': +# File ".+SConstruct", line \\d+: +# print\\(str\\(GetOption\\('foo'\\)\\)\\) +# File ".+SCons/Script/Main.py", line \\d+: +# return getattr\\(OptionsParser.values, name\\) +# File ".+SCons/Script/SConsOptions.py", line \\d+: +# return getattr\\(self.__dict__\\['__defaults__'\\], attr\\) +# """) +# test.run('-Q -q -x A A --foo=C TARG1', status=1, stdout="A\nC\n\\['A', 'TARG1'\\]\n") +# test.run('-Q -q A -x A --foo=C TARG1', status=1, stdout="A\nC\n\\['A', 'TARG1'\\]\n") + + +############################################ +################ Fail Case ################# +############################################ + +test.write('SConstruct', """\ +env = Environment() +if 'A' in BUILD_TARGETS: + BUILD_TARGETS.append('B') +AddOption('-x', '--extra', + nargs=1, + dest='extra', + action='store', + type='string', + metavar='ARG1', + default=(), + help='An argument to the option') +print(str(GetOption('extra'))) +print(BUILD_TARGETS) +""") + +# Nested target +test.run('-Q -q -x A TARG1', status=1, stdout="A\n\\['TARG1'\\]\n") +test.run('-Q -q -x A A TARG1', status=1, stdout="A\n\\['A', 'TARG1', 'B'\\]\n") +test.run('-Q -q A -x A TARG1', status=1, stdout="A\n\\['A', 'TARG1', 'B'\\]\n") + +test.write('SConstruct', """\ +env = Environment() +if 'A' in BUILD_TARGETS: + AddOption('--foo', + nargs=1, + dest='foo', + action='store', + type='string', + metavar='FOO1', + default=(), + help='An argument to the option') +AddOption('-x', '--extra', + nargs=1, + dest='extra', + action='store', + type='string', + metavar='ARG1', + default=(), + help='An argument to the option') +print(str(GetOption('extra'))) +print(str(GetOption('foo'))) +print(COMMAND_LINE_TARGETS) +""") + +# nested option +test.run('-Q -q -x A --foo=C TARG1', status=2, stdout="A\n", stderr="""\ +AttributeError: 'Values' object has no attribute 'foo': + File ".+SConstruct", line \\d+: + print\\(str\\(GetOption\\('foo'\\)\\)\\) + File ".+SCons/Script/Main.py", line \\d+: + return getattr\\(OptionsParser.values, name\\) + File ".+SCons/Script/SConsOptions.py", line \\d+: + return getattr\\(self.__dict__\\['__defaults__'\\], attr\\) +""") +test.run('-Q -q -x A A --foo=C TARG1', status=1, stdout="A\nC\n\\['A', 'TARG1'\\]\n") +test.run('-Q -q A -x A --foo=C TARG1', status=1, stdout="A\nC\n\\['A', 'TARG1'\\]\n") + + + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/AddOption/basic.py b/test/AddOption/basic.py index b1b8f2e1de..bd4b13912a 100644 --- a/test/AddOption/basic.py +++ b/test/AddOption/basic.py @@ -35,7 +35,7 @@ test.write('SConstruct', """\ env = Environment() -AddOption('--force', +AddOption('-F', '--force', action="store_true", help='force installation (overwrite any existing files)') AddOption('--prefix', @@ -65,6 +65,9 @@ status=1, stdout="None\nNone\n") +test.run('-Q -q . -F', + stdout="True\nNone\n") + test.pass_test() # Local Variables: diff --git a/test/AddOption/multi-arg.py b/test/AddOption/multi-arg.py new file mode 100644 index 0000000000..1324fd57b4 --- /dev/null +++ b/test/AddOption/multi-arg.py @@ -0,0 +1,128 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Verify that when an option is specified with nargs > 1, +SCons consumes those correctly into the args. +""" + +import TestSCons + +test = TestSCons.TestSCons() + +# First, test an option with nargs=2 and no others: +test.write('SConstruct', """\ +env = Environment() +AddOption('-x', '--extras', + nargs=2, + dest='extras', + action='store', + type='string', + metavar='FILE1 FILE2', + default=(), + help='two extra files to install') +print(str(GetOption('extras'))) +print(COMMAND_LINE_TARGETS) +""") + +# no args +test.run('-Q -q .', stdout="()\n['.']\n") + +# one arg, should fail +test.run('-Q -q . --extras A', status=2, stderr="""\ +usage: scons [OPTION] [TARGET] ... + +SCons Error: --extras option requires 2 arguments +""") +#one arg, short option +test.run('-Q -q . -x A', status=2, stderr="""\ +usage: scons [OPTION] [TARGET] ... + +SCons Error: -x option requires 2 arguments +""") +# two args +test.run('-Q -q . --extras A B', stdout="('A', 'B')\n['.']\n") +# two args, short option +test.run('-Q -q . -x A B', stdout="('A', 'B')\n['.']\n") +# -- means the rest are not processed as args +test.run('-Q -q . -- --extras A B', status=1, stdout="()\n['.', '--extras', 'A', 'B']\n") + +# Now test what has been a bug: another option is +# also defined, this impacts the collection of args for the nargs>1 opt +test.write('SConstruct', """\ +env = Environment() +AddOption('-P', '--prefix', + nargs=1, + dest='prefix', + action='store', + type='string', + metavar='DIR', + help='installation prefix') +AddOption('-x', '--extras', + nargs=2, + dest='extras', + action='store', + type='string', + metavar='FILE1 FILE2', + default=(), + help='two extra files to install') +print(str(GetOption('prefix'))) +print(str(GetOption('extras'))) +print(COMMAND_LINE_TARGETS) +""") +# no opts +test.run('-Q -q .', stdout="None\n()\n['.']\n") +# first opt long, one arg +test.run('-Q -q . --prefix=/home/foo', stdout="/home/foo\n()\n['.']\n") +test.run('-Q -q . --prefix /home/foo', stdout="/home/foo\n()\n['.']\n") +# first opt short, one arg +test.run('-Q -q . -P/home/foo', stdout="/home/foo\n()\n['.']\n") +test.run('-Q -q . -P /home/foo', stdout="/home/foo\n()\n['.']\n") +# second opt long, two args +test.run('-Q -q . --extras=A B', stdout="None\n('A', 'B')\n['.']\n") +test.run('-Q -q . --extras A B', stdout="None\n('A', 'B')\n['.']\n") +# second opt short, two args +test.run('-Q -q . -xA B', stdout="None\n('A', 'B')\n['.']\n") +test.run('-Q -q . -x A B', stdout="None\n('A', 'B')\n['.']\n") +# both opts long +test.run('-Q -q . --prefix=/home/foo --extras=A B', stdout="/home/foo\n('A', 'B')\n['.']\n") +test.run('-Q -q . --prefix /home/foo --extras A B', stdout="/home/foo\n('A', 'B')\n['.']\n") +# both opts short +test.run('-Q -q . -P/home/foo -xA B', stdout="/home/foo\n('A', 'B')\n['.']\n") +test.run('-Q -q . -P /home/foo -x A B', stdout="/home/foo\n('A', 'B')\n['.']\n") +# don't process +test.run('-Q -q . -- --prefix=/home/foo --extras=A B',status=1, + stdout="None\n()\n['.', '--prefix=/home/foo', '--extras=A', 'B']\n") +test.run('-Q -q . -- --prefix /home/foo --extras A B',status=1, + stdout="None\n()\n['.', '--prefix', '/home/foo', '--extras', 'A', 'B']\n") + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: \ No newline at end of file diff --git a/test/SCONSFLAGS.py b/test/SCONSFLAGS.py index db866e8ac3..1d626a7352 100644 --- a/test/SCONSFLAGS.py +++ b/test/SCONSFLAGS.py @@ -63,16 +63,21 @@ test.must_not_contain_any_line(test.stdout(), ['Help text.']) test.must_contain_all_lines(test.stdout(), ['-H, --help-options']) -os.environ['SCONSFLAGS'] = '-Z' expect = r"""usage: scons [OPTION] [TARGET] ... SCons Error: no such option: -Z """ -test.run(arguments = "-H", status = 2, +test.run(arguments = "-Z", status = 2, stderr = expect, match=TestSCons.match_exact) +os.environ['SCONSFLAGS'] = '-Z' + +test.run(status = 2, + stderr = expect, + match=TestSCons.match_exact) + test.pass_test() # Local Variables: