Exemple #1
0
 def test_case_insensitive_windows_style(self):
     parser = ArgumentParserEx(prefix_chars="/")
     parser.add_argument("/nologo", action="store_true", ignore_case=True)
     ns = parser.parse_args(["/NOLOGO"])
     self.assertTrue(ns.nologo)
     ns = parser.parse_args(["/nologo"])
     self.assertTrue(ns.nologo)
Exemple #2
0
    def test_msvc_flag_with_value(self):
        parser = ArgumentParserEx(prefix_chars="/-")
        parser.set(ignore_case=True)
        parser.add_argument("/flag", action="msvc_flag_with_value")
        parser.add_argument("/ENABLE",
                            action="msvc_flag_with_value",
                            append=True,
                            dest="list")

        ns, remaining = parser.parse_known_args(["/FLAG"])
        self.assertListEqual(["/FLAG"], remaining)
        self.assertIsNone(vars(ns).get("flag"))

        ns, remaining = parser.parse_known_args(["/flag"])
        self.assertListEqual(["/flag"], remaining)
        self.assertIsNone(vars(ns).get("flag"))

        ns, remaining = parser.parse_known_args(["/flag:"])
        self.assertListEqual(["/flag:"], remaining)
        self.assertIsNone(vars(ns).get("flag"))

        ns = parser.parse_args(["/flag:value"])
        self.assertEqual("value", ns.flag)

        ns = parser.parse_args(["-FLAG:1,2,3"])
        self.assertEqual("1,2,3", ns.flag)

        ns = parser.parse_args(["/ENABLE:1", "-FlAg:2", "-enable:3"])
        self.assertEqual("2", ns.flag)
        self.assertEqual(["1", "3"], ns.list)
Exemple #3
0
    def test_raw_dest(self):
        parser = ArgumentParserEx()
        parser.add_argument("-arg1", action="store_true", raw_dest="args")
        parser.add_argument("--arg2", "-f", dest=None, raw_dest="args")
        parser.add_argument("file", raw_dest="args")
        parser.add_argument("files", nargs="*", dest=None, raw_dest="args")
        parser.add_argument("-D",
                            dest=None,
                            raw_dest="args",
                            raw_format="".join)

        ns = parser.parse_args(["--arg2", "1", "2"])
        self.assertListEqual([["--arg2", "1"], "2"], ns.args)

        ns = parser.parse_args(["--arg2=1", "1", "-arg1", "2", "3"])
        self.assertListEqual(["--arg2=1", "1", "-arg1", "2", "3"], ns.args)

        ns, remaining = parser.parse_known_args(
            ["1", "-fvalue", "2", "-unknown"])
        self.assertListEqual(["-unknown"], remaining)
        self.assertListEqual(["1", "-fvalue", "2"], ns.args)

        ns, remaining = parser.parse_known_args(
            ["1", "-unknown", "-fvalue", "2"])
        self.assertListEqual(["-unknown"], remaining)
        self.assertListEqual(["1", "-fvalue", "2"], ns.args)

        ns = parser.parse_args(["1", "-D", "2", "3", "-D4"])
        self.assertListEqual(["1", "-D2", "3", "-D4"], ns.args)
Exemple #4
0
    def test_values_starting_with_prefix(self):
        # standard ArgumentParser does not accept values starting with prefix_chars

        parser = ArgumentParserEx()
        parser.add_argument("-Xclang")
        ns = parser.parse_args(["-Xclang", "-no-color-output"])
        self.assertEqual("-no-color-output", ns.Xclang)

        parser = ArgumentParserEx()
        parser.add_argument("-f", nargs="2")
        ns = parser.parse_args(["-f", "-1", "-2"])
        self.assertListEqual(["-1", "-2"], ns.f)

        parser = ArgumentParserEx()
        parser.add_argument("-f", nargs="2", action="append")
        parser.add_argument("--enable", action="store_true")
        ns = parser.parse_args(["-f", "-1", "-2"])
        self.assertListEqual([["-1", "-2"]], ns.f)
        parser.add_argument("-f", nargs="2", action="append")
        ns = parser.parse_args(["-f", "-1", "-2", "-f", "-3", "-4"])
        self.assertListEqual([["-1", "-2"], ["-3", "-4"]], ns.f)
        ns, remaining = parser.parse_known_args(["-f", "-1", "-2", "-f", "-3"])
        self.assertListEqual(["-f", "-3"], remaining)
        self.assertListEqual([["-1", "-2"]], ns.f)
        ns, remaining = parser.parse_known_args(
            ["-f", "-1", "-2", "-f", "-3", "--enable", "-4"])
        self.assertListEqual(["-4"], remaining)
        self.assertListEqual([["-1", "-2"], ["-3", "--enable"]], ns.f)
        self.assertFalse(ns.enable)
        self.assertRaisesRegexp(
            ValueError,
            "Unparsed tokens",
            parser.parse_args,
            ["-f", "-1", "-2", "-f", "-3"],
        )

        parser = ArgumentParserEx()
        parser.add_argument("f", nargs="*")
        ns, remaining = parser.parse_known_args(["-1"])
        self.assertListEqual(["-1"], remaining)
        ns, remaining = parser.parse_known_args(["1", "2", "-3"])
        self.assertListEqual(["-3"], remaining)
        self.assertListEqual(["1", "2"], ns.f)
        ns, remaining = parser.parse_known_args(["1", "-2", "3"])
        self.assertListEqual(["-2"], remaining)
        self.assertListEqual(["1", "3"], ns.f)

        parser = ArgumentParserEx()
        parser.add_argument("f", nargs="+")
        ns, remaining = parser.parse_known_args(["-1", "-2"])
        self.assertListEqual(["-1", "-2"], remaining)

        parser = ArgumentParserEx()
        parser.add_argument("-f", nargs="+")
        ns, remaining = parser.parse_known_args(["-f", "-1", "-2"])
        self.assertListEqual(["-2"], remaining)
        self.assertListEqual(["-1"], ns.f)
Exemple #5
0
    def test_single_hyphen_multichar_flag(self):
        parser = ArgumentParserEx()
        parser.add_argument("-flag")

        ns = parser.parse_args(["-flag", "value"])
        self.assertEqual("value", ns.flag)

        ns = parser.parse_args(["-flag=value"])
        self.assertEqual("value", ns.flag)
Exemple #6
0
    def test_force_suffix_value(self):
        parser = ArgumentParserEx()
        parser.add_argument(prefixes=["-Xclang"])
        ns = parser.parse_args(["-Xclangvalue"])
        self.assertEqual("value", ns.Xclang)

        parser = ArgumentParserEx()
        parser.add_argument("-Xclang", prefix=True)
        ns = parser.parse_args(["-Xclangvalue"])
        self.assertEqual("value", ns.Xclang)
Exemple #7
0
    def test_optional_positional_argument(self):
        parser = ArgumentParserEx()
        parser.add_argument("infile")
        parser.add_argument("outfile", nargs="?")

        ns = parser.parse_args(["inout.txt"])
        self.assertEqual("inout.txt", ns.infile)

        ns = parser.parse_args(["in.txt", "out.txt"])
        self.assertEqual("in.txt", ns.infile)
        self.assertEqual(["out.txt"], ns.outfile)
Exemple #8
0
    def test_conditional_arguments(self):
        self.skipTest("not implemented yet")
        parser = ArgumentParserEx()
        arg = parser.add_argument("-a")
        parser.add_argument("-b", after=[arg])

        ns = parser.parse_args(["-a", "1", "-b", "2"])
        self.assertEqual("1", ns.a)
        self.assertEqual("2", ns.b)

        ns = parser.parse_args(["-a", "1"])
        self.assertEqual("1", ns.a)

        ns, remaining = parser.parse_known_args(["-b", "1"])
        self.assertListEqual(["-b", "1"], remaining)
        self.assertIsNone(vars(ns).get("b"))
Exemple #9
0
    def test_strict_parsing(self):
        parser = ArgumentParserEx()
        parser.add_argument("arg1")

        self.assertRaisesRegexp(ValueError, "Required attribute not found",
                                parser.parse_args, [])
        self.assertRaisesRegexp(ValueError, "Unparsed tokens",
                                parser.parse_args, ["--option"])
        ns = parser.parse_args(["val"])
        self.assertEqual("val", ns.arg1)

        parser = ArgumentParserEx()
        parser.add_argument("--arg1", "-a", required=True)

        self.assertRaisesRegexp(ValueError, "Required attribute not found",
                                parser.parse_args, [])
        self.assertRaisesRegexp(ValueError, "Unparsed tokens",
                                parser.parse_args, ["--arg1="])
        self.assertRaisesRegexp(ValueError, "Unparsed tokens",
                                parser.parse_args, ["-a"])
        ns = parser.parse_args(["-aval"])
        self.assertEqual("val", ns.arg1)

        parser = ArgumentParserEx()
        parser.add_argument("arg1", nargs=2)

        self.assertRaisesRegexp(ValueError, "Required attribute not found",
                                parser.parse_args, [])
        self.assertRaisesRegexp(ValueError, "Not enough values",
                                parser.parse_args, ["a"])
        self.assertRaisesRegexp(ValueError, "Unparsed tokens",
                                parser.parse_args, ["a", "b", "c"])
        ns = parser.parse_args(["a", "b"])
        self.assertEqual(["a", "b"], ns.arg1)

        parser = ArgumentParserEx()
        parser.add_argument("--arg1", "-a", required=True, nargs=2)

        self.assertRaisesRegexp(ValueError, "Required attribute not found",
                                parser.parse_args, [])
        self.assertRaisesRegexp(ValueError, "Unparsed tokens",
                                parser.parse_args, ["--arg1", "val"])
        self.assertRaisesRegexp(ValueError, "Unparsed tokens",
                                parser.parse_args, ["-a", "val"])
        ns = parser.parse_args(["--arg1", "a", "b"])
        self.assertEqual(["a", "b"], ns.arg1)
Exemple #10
0
 def test_intermixed_args(self):
     parser = ArgumentParserEx()
     parser.add_argument("files", action="append")
     parser.add_argument("-D", action="append", dest="definitions")
     ns = parser.parse_args(["-DA=1", "a.cpp", "-DB=2", "b.cpp"])
     # standard ArgumentParser won't append 'b.cpp' here
     self.assertListEqual(["a.cpp", "b.cpp"], ns.files)
     self.assertListEqual(["A=1", "B=2"], ns.definitions)
Exemple #11
0
 def test_concatenate_flags(self):
     self.skipTest("not implemented yet")
     parser = ArgumentParserEx()
     parser.add_argument("-a", action="store_true")
     parser.add_argument("-b", action="store_true")
     ns = parser.parse_args(["-ab"])
     self.assertTrue(ns.a)
     self.assertTrue(ns.b)
Exemple #12
0
 def test_disable_concatenation(self):
     self.skipTest("not implemented yet")
     parser = ArgumentParserEx()
     parser.enable_flag_concatenation(False)
     parser.add_argument("-a", action="store_true")
     parser.add_argument("-b", action="store_true")
     ns, remaining = parser.parse_args(["-ab"])
     self.assertListEqual(["-ab"], remaining)
Exemple #13
0
    def test_deepcopy_1(self):
        parser = ArgumentParserEx()
        parser.add_argument("-a")

        parser = deepcopy(parser)

        ns = parser.parse_args(["-a", "1"])
        self.assertEqual("1", ns.a)
Exemple #14
0
class MsvcMc(ParserBase):
    priority = 7

    @staticmethod
    def add_arguments(arg_parser):
        pass

    def __init__(self, context, platform=None):
        ParserBase.__init__(self, context)

        self.platform = get_platform(platform)
        self.program_re = self.platform.get_program_path_re("mc")

        # https://docs.microsoft.com/en-us/windows/windows/wes/message-compiler--mc-exe-
        # Currently, only small subset of flags is supported
        self.parser = ArgumentParserEx()
        self.parser.set(raw_dest="args")
        self.parser.add_argument("-h",
                                 raw_handler=self.input_dir,
                                 dest="header_dir")
        self.parser.add_argument("-r",
                                 raw_handler=self.input_dir,
                                 dest="resource_dir")
        self.parser.add_argument("manifest_file",
                                 raw_handler=self.input_file,
                                 dest="manifest_file")

    def parse(self, target):
        tokens = target.get("tokens") or []
        if not tokens:
            return target

        if not self.program_re.match(tokens[0]):
            return target

        tokens.pop(0)
        namespace = self.parser.parse_args(tokens)

        if namespace.header_dir is None:
            namespace.header_dir = target["working_dir"]
        header_dir = self.context.get_dir_arg(
            self.context.normalize_path(namespace.header_dir))

        if namespace.resource_dir is None:
            namespace.resource_dir = target["working_dir"]
        resource_dir = self.context.get_dir_arg(
            self.context.normalize_path(namespace.resource_dir))

        filename_no_ext = os.path.basename(namespace.manifest_file)
        filename_no_ext = os.path.splitext(filename_no_ext)[0]

        output = [
            header_dir + "/" + filename_no_ext + ".h",
            resource_dir + "/" + filename_no_ext + ".rc",
        ]

        return get_command_target(None, "mc", namespace.args, output,
                                  namespace.dependencies)
Exemple #15
0
    def test_msvc_flag_with_value_with_append(self):
        parser = ArgumentParserEx(prefix_chars="/-")
        parser.set(ignore_case=True)
        parser.add_argument("/flag",
                            action="msvc_flag_with_value",
                            dest="flags",
                            append=True)

        ns = parser.parse_args(["/flag:a", "/flag:b"])
        self.assertListEqual(["a", "b"], ns.flags)
Exemple #16
0
 def test_correct_list_order(self):
     parser = ArgumentParserEx(prefix_chars="-/")
     parser.set_defaults(definitions=[])
     parser.add_argument("/c", action="store_true", dest="compile_only")
     parser.add_argument("-D", action="append", dest="definitions")
     parser.add_argument("-I", action="append", dest="include_dirs")
     parser.add_argument("-U", action="append", dest="definitions")
     parser.add_argument("files", nargs="*")
     ns = parser.parse_args(
         ["/c", "-D1", "/U", "2", "/D3", "-I.", "-U4", "a.cpp"])
     self.assertListEqual(["1", "2", "3", "4"], ns.definitions)
Exemple #17
0
class CMake(Parser):
    priority = 7

    @staticmethod
    def add_arguments(arg_parser):
        pass

    @staticmethod
    def is_applicable(project=None, log_type=None):
        return True

    def __init__(self, context, platform=None):
        self.context = context
        self.platform = get_platform(platform)
        self.program_re = self.platform.get_program_path_re("cmake")

        self.parser = ArgumentParserEx(prog="cmake")
        self.parser.add_argument("-E", dest="command", nargs="+")

    def parse(self, target):
        tokens = target.get("tokens")
        if not tokens:
            return target

        if not self.program_re.match(tokens[0]):
            return target

        namespace = self.parser.parse_args(tokens[1:])

        if not namespace.command:
            return target

        command = namespace.command[0]
        args = namespace.command[1:]

        dependencies = []
        targets = []
        if command == "cmake_symlink_library":
            # on Mac
            source = self.context.get_file_arg(
                self.context.platform.normalize_path(args[0]), dependencies)
            destinations = args[1:]
            for dest in destinations:
                target_dependencies = copy(dependencies)
                output = self.context.get_output(dest, target_dependencies)
                targets.append(
                    get_copy_target(None, source, output, target_dependencies))
        else:
            logger.warning("Unsupported CMake command: {}".format(command))

        return targets
Exemple #18
0
    def test_default_values(self):
        parser = ArgumentParserEx()
        parser.add_argument("arg1", default="default")

        ns = parser.parse_args([])
        self.assertEqual("default", ns.arg1)

        ns = parser.parse_args(["value"])
        self.assertEqual("value", ns.arg1)

        parser = ArgumentParserEx()
        parser.add_argument("-a", default=[], action="append")

        ns = parser.parse_args([])
        self.assertEqual([], ns.a)

        ns.a.append("value")

        ns = parser.parse_args([])
        self.assertEqual([], ns.a)

        ns = parser.parse_args(["-aval"])
        self.assertEqual(["val"], ns.a)
Exemple #19
0
 def test_no_prefix_chars(self):
     parser = ArgumentParserEx()
     parser.add_argument("-D", action="append", dest="definitions")
     parser.add_argument(
         flags=["cmd"],
         action="append",
         nargs="+",
         dest="commands",
         args_regexp=re.compile(r"^(?!cmd)"),
     )
     ns = parser.parse_args(
         ["-DA=1", "cmd", "cl.exe", "cmd", "gcc", "/c", "a.cpp"])
     self.assertListEqual(["A=1"], ns.definitions)
     self.assertListEqual([["cl.exe"], ["gcc", "/c", "a.cpp"]], ns.commands)
Exemple #20
0
class Icupkg(ParserBase):
    priority = 7

    def __init__(self, context, platform=platform.system().lower()):
        ParserBase.__init__(self, context)

        self.platform = get_platform(platform)
        self.program_re = self.platform.get_program_path_re("icupkg")

        # https://helpmanual.io/help/icupkg/
        self.parser = ArgumentParserEx()
        self.parser.set(dest=None, raw_dest="args")
        self.parser.add_argument("--type", "-t", choices=["l", "b", "e"])
        self.parser.add_argument("--copyright", "-c")
        self.parser.add_argument("--comment", "-C")
        self.parser.add_argument("--add", "-a")
        self.parser.add_argument("--remove", "-r")
        self.parser.add_argument("--extract", "-x")
        self.parser.add_argument("--writepkg", "-w", action="store_true")
        self.parser.add_argument("--matchmode", "-m")
        self.parser.add_argument("--auto_toc_prefix", action="store_true")
        self.parser.add_argument("--auto_toc_prefix_with_type", action="store_true")
        self.parser.add_argument("--sourcedir", "-s", raw_handler=self.input_dir)
        self.parser.add_argument("--destdir", "-d", raw_handler=self.input_dir)
        self.parser.add_argument("--list", "-l", action="store_true")
        self.parser.add_argument("--outlist", "-o", raw_handler=self.output_file)
        self.parser.add_argument("infilename", raw_handler=self.input_file)
        self.parser.add_argument("outfilename", nargs="?", raw_handler=self.output_file)

    def parse(self, target):
        tokens = target.get("tokens") or []
        if not tokens:
            return target

        if not self.program_re.match(tokens[0]):
            return target

        tokens.pop(0)
        namespace = self.parser.parse_args(tokens)
        return get_command_target(
            None,
            program="icupkg",
            args=namespace.args,
            output=namespace.output,
            dependencies=namespace.dependencies,
        )
Exemple #21
0
    def test_mutually_exclusive_group(self):
        self.skipTest("not implemented yet")
        parser = ArgumentParserEx()
        group = parser.add_mutually_exclusive_group()
        group.add_argument("-a", action="store_const", const="a", dest="mode")
        group.add_argument("-b", action="store_const", const="b", dest="mode")

        ns, remaining = parser.parse_known_args(["-ab"])
        self.assertListEqual(["-ab"], remaining)
        self.assertIsNone(vars(ns).get("mode"))

        ns, remaining = parser.parse_known_args(["-a", "-b"])
        self.assertListEqual(["-b"], remaining)
        self.assertEqual("a", ns.mode)

        ns = parser.parse_args(["-b"])
        self.assertEqual("b", ns.mode)
Exemple #22
0
 def test_compatiblity_arguments(self):
     # test ArgumentParser interface compatibility
     # these arguments are simply ignored
     parser = ArgumentParserEx(
         prog="test",
         usage="usage",
         description="description",
         epilog="epilog",
         parents=[],
         formatter_class=object,
         fromfile_prefix_chars="fromfile_prefix_chars",
         argument_default=None,
         conflict_handler="error",
         add_help=True,
     )
     parser.add_argument("-a", help="help", metavar="metavar")
     ns = parser.parse_args(["-a1"])
     self.assertEqual("1", ns.a)
Exemple #23
0
    def test_msvc_flag(self):
        parser = ArgumentParserEx(prefix_chars="/")
        parser.add_argument("/GR", action="msvc_flag", dest="rtti")
        parser.add_argument(
            "/INCREMENTAL",
            action="msvc_flag",
            msvc_false_suffix=":NO",
            dest="incremental",
        )
        parser.add_argument(
            "/flag",
            action="msvc_flag",
            msvc_true_suffix=":on",
            msvc_false_suffix=":off",
            ignore_case=True,
        )

        ns = parser.parse_args(["/GR-"])
        self.assertFalse(ns.rtti)
        ns = parser.parse_args(["/GR"])
        self.assertTrue(ns.rtti)
        ns = parser.parse_args(["/INCREMENTAL"])
        self.assertTrue(ns.incremental)
        ns = parser.parse_args(["/INCREMENTAL:NO"])
        self.assertFalse(ns.incremental)
        ns = parser.parse_args(["/FLAG:ON"])
        self.assertTrue(ns.flag)
        ns = parser.parse_args(["/flag:off"])
        self.assertFalse(ns.flag)

        ns = parser.parse_args([])
        self.assertIsNone(vars(ns).get("flag"))
        self.assertIsNone(vars(ns).get("rtti"))
        self.assertIsNone(vars(ns).get("incremental"))

        ns, remaining = parser.parse_known_args(["/flag:unknown"])
        self.assertListEqual(["/flag:unknown"], remaining)
        self.assertIsNone(vars(ns).get("flag"))

        parser.set_defaults(flag=False)
        ns = parser.parse_args([])
        self.assertFalse(ns.flag)
Exemple #24
0
    def test_dest_is_none(self):
        parser = ArgumentParserEx()
        parser.add_argument("-opt", dest=None, required=True)
        parser.add_argument("pos", dest=None)

        ns = parser.parse_args(["-opt", "1", "2"])
        self.assertIsNone(vars(ns).get("opt"))
        self.assertIsNone(vars(ns).get("pos"))

        ns, remaining = parser.parse_known_args(["-opt"])
        self.assertListEqual(["-opt"], remaining)

        ns, remaining = parser.parse_known_args(["1"])
        self.assertListEqual([], remaining)
        self.assertIsNone(vars(ns).get("opt"))
        self.assertIsNone(vars(ns).get("pos"))

        self.assertRaisesRegexp(ValueError, "Required attribute not found",
                                parser.parse_args, ["1"])
Exemple #25
0
 def test_dest_naming(self):
     parser = ArgumentParserEx(prefix_chars="/-")
     parser.add_argument("-a-b", action="store_true")
     parser.add_argument("-++", action="store_true")
     parser.add_argument("/b:c", dest="_f", action="store_true")
     parser.add_argument("--c~d", action="store_true")
     parser.add_argument("-UPPER", action="store_true")
     self.assertRaisesRegexp(
         ValueError,
         "Invalid dest: '@flag'",
         parser.add_argument,
         "-flag",
         dest="@flag",
         action="store_true",
     )
     ns = parser.parse_args(["-a-b", "-++", "/b:c", "--c~d", "-UPPER"])
     self.assertTrue(ns.a_b)
     self.assertTrue(ns.__)
     self.assertTrue(ns._f)
     self.assertTrue(ns.c_d)
     self.assertTrue(ns.UPPER)
Exemple #26
0
    def test_gnu_ar_parser(self):
        self.skipTest("not implemented yet")
        # GNU ar has a surprisingly complex syntax,
        # it's a good test-case for ArgumentParserEx
        parser = ArgumentParserEx()
        operation = parser.add_mutually_exclusive_group()
        arg_r = operation.add_argument(flags=["-r", "r"], action="store_true")
        arg_q = operation.add_argument(flags=["-q", "q"], action="store_true")
        arg_a = parser.add_argument("-a",
                                    after=[arg_r, arg_q],
                                    action="store_true")
        arg_b = parser.add_argument("-b",
                                    after=[arg_r, arg_q],
                                    action="store_true")
        arg_N = parser.add_argument("-N",
                                    after=[arg_r, arg_q],
                                    action="store_true")
        parser.add_argument("relpos", after=[arg_a, arg_b])
        parser.add_argument("count", after=[arg_N], type=int)
        parser.add_argument("archive")
        parser.add_argument("member", nargs="*", dest="members")

        ns = parser.parse_args(["-q", "lib.a", "a.o", "b.o"])
        self.assertTrue(ns.q)
        self.assertEqual("lib.a", ns.archive)
        self.assertListEqual(["a.o", "b.o"], ns.members)

        ns = parser.parse_args(["-qa", "a.o", "lib.a", "b.o", "c.o"])
        self.assertTrue(ns.q)
        self.assertTrue(ns.a)
        self.assertEqual("a.o", ns.relpos)
        self.assertEqual("lib.a", ns.archive)
        self.assertListEqual(["a.o", "b.o"], ns.members)

        ns = parser.parse_args(["-qN", "1", "lib.a", "a.o", "b.o"])
        self.assertTrue(ns.q)
        self.assertTrue(ns.N)
        self.assertEqual(1, ns.count)
        self.assertEqual("lib.a", ns.archive)
        self.assertListEqual(["a.o", "b.o"], ns.members)

        ns = parser.parse_args(["-raN", "a.o", "1", "lib.a", "b.o", "c.o"])
        self.assertTrue(ns.r)
        self.assertTrue(ns.a)
        self.assertTrue(ns.N)
        self.assertEqual("a.o", ns.relpos)
        self.assertEqual(1, ns.count)
        self.assertEqual("lib.a", ns.archive)
        self.assertListEqual(["b.o", "c.o"], ns.members)

        ns = parser.parse_args(["raN", "a.o", "1", "lib.a", "b.o", "c.o"])
        self.assertTrue(ns.r)
        self.assertTrue(ns.a)
        self.assertTrue(ns.N)
        self.assertEqual("a.o", ns.relpos)
        self.assertEqual(1, ns.count)
        self.assertEqual("lib.a", ns.archive)
        self.assertListEqual(["b.o", "c.o"], ns.members)

        self.assertRaisesRegexp(ValueError, "doot", parser.parse_args,
                                ["rq", "lib.a", "a.o"])

        self.assertRaisesRegexp(ValueError, "doot", parser.parse_args,
                                ["-ar", "lib.a", "a.o"])
Exemple #27
0
class MsvcMl(CompilerParser):
    filename_re = os_ext.Windows.get_program_path_re("ml", "ml64")

    priority = 7

    def __init__(self, context, ignore_compile_flags=None):
        CompilerParser.__init__(self,
                                context,
                                ignore_compile_flags=ignore_compile_flags)

        # Visual Studio ml.exe arguments
        # https://docs.microsoft.com/en-us/cpp/assembler/masm/ml-and-ml64-command-line-reference?view=vs-2017
        self.parser = ArgumentParserEx(prefix_chars="-/")
        self.parser.set_defaults(compile_flags=[],
                                 link_flags=[],
                                 include_dirs=[],
                                 infiles=[])
        # TODO: publish all meaningful flags
        self.parser.set(dest=None, raw_dest="compile_flags")
        self.parser.add_argument("/c",
                                 action="store_true",
                                 raw_dest=None,
                                 dest="compile_only")
        # Generates common object file format (COFF) type of object module
        self.parser.add_argument("/coff", action="store_true")
        # Preserves case of all user identifiers
        self.parser.add_argument("/Cp", action="store_true")
        # Maps all identifiers to upper case
        self.parser.add_argument("/Cu", action="store_true")
        # Preserves case in public and extern symbols
        self.parser.add_argument("/Cx", action="store_true")
        self.parser.add_argument("/D", raw_format=format_flag_gnu)
        self.parser.add_argument("/errorreport",
                                 prefix=True,
                                 nargs="?",
                                 ignore_case=True)
        self.parser.add_argument("/Fo",
                                 prefix=True,
                                 raw_dest=None,
                                 dest="output")
        # stack size
        self.parser.add_argument("/F", prefix=True)
        # Generates emulator fix-ups for floating-point arithmetic
        self.parser.add_argument("/FPi", action="store_true")
        # Specifies use of C-style function calling and naming conventions
        self.parser.add_argument("/Gd", action="store_true")
        # Specifies use of __stdcall function calling and naming conventions
        self.parser.add_argument("/GZ", action="store_true")
        self.parser.add_argument("/I",
                                 action="append",
                                 raw_dest=None,
                                 dest="include_dirs")
        self.parser.add_argument("/nologo",
                                 action="store_true",
                                 ignore_case=True)
        # Generates object module file format (OMF) type of object module
        self.parser.add_argument("/omf", action="store_true")
        self.parser.add_argument("/Ta",
                                 prefix=True,
                                 action="append",
                                 raw_dest=None,
                                 dest="infiles")
        self.parser.add_argument("/safeseh",
                                 action="store_true",
                                 ignore_case=True)
        # Warning flags
        self.parser.add_argument(flags=["/W", "/WX"], action="store_true")
        self.parser.add_argument("/W", choices="0123")
        # line-number information in object file
        self.parser.add_argument("/Zd", action="store_true")
        # Generate CodeView information in object file
        self.parser.add_argument("/Zi", action="store_true")
        # Makes all symbols public
        self.parser.add_argument("/Zf", action="store_true")
        # Packs structures on the specified byte boundary
        self.parser.add_argument("/Zp", prefix=True, type=int)
        self.parser.add_argument("infiles",
                                 nargs="*",
                                 dest="infiles",
                                 raw_dest=None)

    include_re = re.compile(r"(?:\b|%)include\s+(?P<path>[^\s\n][^\n]*)",
                            re.IGNORECASE)

    def parse(self, target):
        tokens = target.get("tokens") or []
        if not tokens:
            return target

        if not self.filename_re.match(tokens[0]):
            return target

        if len(tokens) < 2 or tokens[1] == ":":
            # skip warning message
            return target

        tokens.pop(0)

        namespace = self.parser.parse_args(tokens)
        assert namespace.compile_only

        dependencies = []

        self.process_namespace(namespace)

        # ml.exe doesn't support /showIncludes or anything similar
        add_included_dependencies(
            self.context,
            self.include_re,
            dependencies,
            namespace.include_dirs,
            namespace.infiles,
            self.context.working_dir,
        )

        include_dirs = []
        for dir in namespace.include_dirs:
            dir = self.context.normalize_path(dir)
            arg = self.context.get_dir_arg(dir, dependencies)
            if arg:
                include_dirs.append(arg)

        sources = []
        for infile in namespace.infiles:
            sources.append(
                get_source_file_reference(
                    self.context.get_file_arg(
                        self.context.normalize_path(infile), dependencies),
                    "MASM",
                ))

        output = self.context.get_output(
            self.context.normalize_path(namespace.output))

        return get_module_target(
            ModuleTypes.object_lib,
            None,
            output,
            compile_flags=namespace.compile_flags,
            include_dirs=include_dirs,
            dependencies=dependencies,
            sources=sources,
        )
Exemple #28
0
class MsvcLib(Parser):
    filename_re = os_ext.Windows.get_program_path_re("lib")
    link_re = os_ext.Windows.get_program_path_re("link")
    lld_link_re = os_ext.Windows.get_program_path_re("lld-link")

    priority = 7

    @staticmethod
    def add_arguments(arg_parser):
        pass

    @staticmethod
    def is_applicable(project=None, log_type=None):
        return True

    def __init__(self, context, project_version=None):
        self.context = context
        self.project_version = project_version

        # Visual Studio lib.exe arguments
        # https://docs.microsoft.com/en-us/cpp/build/reference/running-lib?view=vs-2019
        self.parser = ArgumentParserEx(prefix_chars="-/")
        self.parser.set_defaults(compile_flags=[],
                                 link_flags=[],
                                 include_dirs=[],
                                 infiles=[])
        # TODO: publish all meaningful flags
        self.parser.set(ignore_case=True, dest=None, raw_dest="link_flags")
        self.parser.add_argument("/ignore", action="msvc_flag_with_value")
        self.parser.add_argument("/libpath",
                                 action="msvc_flag_with_value",
                                 append=True,
                                 raw_dest=None)
        self.parser.add_argument("/ltcg", action="store_true")
        self.parser.add_argument("/machine", action="msvc_flag_with_value")
        self.parser.add_argument("/out",
                                 action="msvc_flag_with_value",
                                 dest="output",
                                 raw_dest=None)
        self.parser.add_argument("/nologo", action="store_true")
        self.parser.add_argument("/wx",
                                 action="msvc_flag",
                                 msvc_false_suffix=":no")
        self.parser.add_argument("infiles",
                                 dest="infiles",
                                 nargs="*",
                                 raw_dest=None)

        # lld-link.exe arguments (/lib mode)
        # Cannot find documentation online
        self.lld_link_parser = deepcopy(self.parser)
        self.lld_link_parser.add_argument("/llvmlibthin", action="store_true")
        self.lld_link_parser.set(prefix_chars="-")
        self.lld_link_parser.add_argument("--color-diagnostics",
                                          action="store_true")

    def parse(self, target):
        tokens = target.get("tokens") or []
        if not tokens:
            return target

        is_lld_link = False
        if self.link_re.match(tokens[0]) and is_lib_shim(tokens):
            is_lld_link = bool(self.lld_link_re.match(tokens[0]))
            tokens = tokens[2:]
        elif not self.filename_re.match(tokens[0]):
            return target
        else:
            tokens.pop(0)

        if len(tokens) > 0:
            if tokens[0] == ":":
                # skipping parsing output of utilities, like: `lib : warning ...`
                return target

        if is_lld_link:
            namespace = self.lld_link_parser.parse_args(tokens)
        else:
            namespace = self.parser.parse_args(tokens)

        dependencies = []

        libs = []
        objects = []
        for infile in namespace.infiles:
            if os_ext.is_static_lib(infile):
                libs.append(self.context.get_lib_arg(infile, dependencies, []))
            else:
                path = next(
                    os_ext.Windows.get_obj_file_locations(
                        infile, [], self.context.working_dir))
                if self.context.find_target(self.context.get_file_arg(
                        path)) or os.path.exists(path):
                    objects.append(
                        self.context.get_file_arg(path, dependencies))
                else:
                    # System object file, treat it as a linker flag
                    # https://docs.microsoft.com/en-us/cpp/c-runtime-library/link-options
                    objects.append(infile)

        output = self.context.normalize_path(namespace.output)
        descr = os_ext.parse_static_lib(output)
        module_name = descr["module_name"]
        name = descr["target_name"]
        version = descr["version"] or self.project_version
        output = self.context.get_output(output, dependencies)

        return get_module_target(
            ModuleTypes.static_lib,
            name,
            output,
            dependencies=dependencies,
            module_name=module_name,
            libs=libs,
            objects=objects,
            version=version,
            link_flags=namespace.link_flags,
        )
Exemple #29
0
    def test_nargs(self):
        parser = ArgumentParserEx()
        parser.add_argument("--attr2", action="store", nargs="1")
        parser.add_argument("attr1", action="store", nargs="1")

        ns, remaining = parser.parse_known_args(
            ["--attr2", "val1", "val2", "--attr2", "val3"])
        self.assertListEqual([], remaining)
        self.assertEqual(["val2"], ns.attr1)
        self.assertEqual(["val3"], ns.attr2)

        parser = ArgumentParserEx()
        parser.add_argument("--attr2", action="store", nargs="2")
        parser.add_argument("attr1", action="store", nargs="2")

        ns, remaining = parser.parse_known_args(
            ["--attr2", "val1", "val2", "val3", "val4"])
        self.assertListEqual([], remaining)
        self.assertEqual(["val3", "val4"], ns.attr1)
        self.assertEqual(["val1", "val2"], ns.attr2)

        ns, remaining = parser.parse_known_args(
            ["val1", "val2", "--attr2", "val3", "val4", "val5"])
        self.assertListEqual(["val5"], remaining)
        self.assertEqual(["val1", "val2"], ns.attr1)
        self.assertEqual(["val3", "val4"], ns.attr2)

        ns, remaining = parser.parse_known_args(["val1", "--attr2", "val2"])
        self.assertListEqual(["--attr2"], remaining)
        self.assertEqual(["val1", "val2"], ns.attr1)
        self.assertIsNone(vars(ns).get("attr2"))

        ns, remaining = parser.parse_known_args(
            ["val1", "--attr2", "val2", "val3", "val4"])
        self.assertListEqual([], remaining)
        self.assertEqual(["val1", "val4"], ns.attr1)
        self.assertEqual(["val2", "val3"], ns.attr2)

        ns, remaining = parser.parse_known_args(
            ["val1", "--attr2", "val2", "val3"])
        self.assertListEqual([], remaining)
        self.assertEqual(["val1"], ns.attr1)
        self.assertEqual(["val2", "val3"], ns.attr2)

        parser = ArgumentParserEx()
        parser.add_argument("attr1", action="store", nargs="?")
        parser.add_argument("--attr2", action="store", nargs="?")

        ns, remaining = parser.parse_known_args(["val1", "--attr2"])
        self.assertListEqual([], remaining)
        self.assertEqual(["val1"], ns.attr1)
        self.assertEqual([], ns.attr2)

        ns, remaining = parser.parse_known_args(["--attr2", "val1"])
        self.assertListEqual([], remaining)
        self.assertEqual(None, ns.attr1)
        self.assertEqual(["val1"], ns.attr2)

        parser = ArgumentParserEx()
        parser.add_argument("--attr2", action="store", nargs="+")
        parser.add_argument("attr1", action="store", nargs="+")

        ns, remaining = parser.parse_known_args(["val1", "val2", "--attr2"])
        self.assertListEqual(["--attr2"], remaining)
        self.assertEqual(["val1", "val2"], ns.attr1)
        self.assertIsNone(vars(ns).get("attr2"))

        ns, remaining = parser.parse_known_args(["--attr2", "val1", "val2"])
        self.assertListEqual([], remaining)
        self.assertIsNone(vars(ns).get("attr1"))
        self.assertEqual(["val1", "val2"], ns.attr2)

        ns, remaining = parser.parse_known_args(
            ["val1", "val2", "--attr2", "val3"])
        self.assertListEqual([], remaining)
        self.assertEqual(["val1", "val2"], ns.attr1)
        self.assertEqual(["val3"], ns.attr2)

        parser = ArgumentParserEx()
        parser.add_argument("attr1", action="store", nargs="*")
        parser.add_argument("--attr2", action="store", nargs="*")

        ns, remaining = parser.parse_known_args(["val1", "val2", "--attr2"])
        self.assertListEqual([], remaining)
        self.assertEqual(["val1", "val2"], ns.attr1)
        self.assertEqual([], ns.attr2)

        ns, remaining = parser.parse_known_args(["--attr2", "val1", "val2"])
        self.assertListEqual([], remaining)
        self.assertEqual([], ns.attr1)
        self.assertEqual(["val1", "val2"], ns.attr2)

        ns, remaining = parser.parse_known_args(["val1", "--attr2", "val2"])
        self.assertListEqual([], remaining)
        self.assertEqual(["val1"], ns.attr1)
        self.assertEqual(["val2"], ns.attr2)

        parser = ArgumentParserEx()
        parser.add_argument("-C", action="append", nargs="?")
        ns = parser.parse_args(["-C", "a1", "-C"])
        self.assertListEqual([["a1"], []], ns.C)

        parser = ArgumentParserEx()
        parser.add_argument("-C", action="append", nargs="*")
        ns = parser.parse_args(["-C", "a1", "-C", "b1", "b2", "-C"])
        self.assertListEqual([["a1"], ["b1", "b2"], []], ns.C)

        parser = ArgumentParserEx()
        parser.add_argument("-C", action="append", nargs="+")
        ns = parser.parse_args(["-C", "a1", "-C", "b1", "b2"])
        self.assertListEqual([["a1"], ["b1", "b2"]], ns.C)

        parser = ArgumentParserEx()
        parser.add_argument("C", action="append", nargs="?")
        ns = parser.parse_args(["1"])
        self.assertListEqual([["1"]], ns.C)
        ns, remaining = parser.parse_known_args(["1", "2"])
        self.assertListEqual(["2"], remaining)
        self.assertListEqual([["1"]], ns.C)
        ns = parser.parse_args([])
        self.assertIsNone(ns.C)

        parser = ArgumentParserEx()
        parser.add_argument("C", action="append", nargs="*")
        ns = parser.parse_args(["1"])
        self.assertListEqual([["1"]], ns.C)
        ns = parser.parse_args(["1", "2"])
        self.assertListEqual([["1", "2"]], ns.C)
        ns, _remaining = parser.parse_known_args(["1", "2", "-a", "3"])
        self.assertListEqual([["1", "2"], ["3"]], ns.C)
        ns, _remaining = parser.parse_known_args(["1", "2", "-a"])
        self.assertListEqual([["1", "2"]], ns.C)
        # Check that empty list does not raise an Exception
        parser.parse_args([])

        parser = ArgumentParserEx()
        parser.add_argument("C", action="append", nargs="+")
        ns = parser.parse_args(["1"])
        self.assertListEqual([["1"]], ns.C)
        ns = parser.parse_args(["1", "2"])
        self.assertListEqual([["1", "2"]], ns.C)
        ns, _remaining = parser.parse_known_args(["1", "2", "-a", "3"])
        self.assertListEqual([["1", "2"], ["3"]], ns.C)
        ns, _remaining = parser.parse_known_args(["1", "2", "-a"])
        self.assertListEqual([["1", "2"]], ns.C)
        self.assertRaisesRegexp(ValueError, "Required attribute not found",
                                parser.parse_args, [])
Exemple #30
0
    def test_implicit_default_values(self):
        parser = ArgumentParserEx()
        parser.add_argument("-a")
        parser.add_argument("-b", dest="dest_b")
        parser.add_argument("-c", nargs=2)
        parser.add_argument("-d", action="append")
        parser.add_argument("-e", action="store")
        parser.add_argument("-f", nargs="*")
        parser.add_argument("-g", nargs="+")
        parser.add_argument("-i", nargs="?")
        parser.add_argument("-j", nargs="*", action="append")
        parser.add_argument("-k", nargs="+", action="append")
        parser.add_argument("-l", nargs="?", action="append")
        ns = parser.parse_args([])
        self.assertIsNone(getattr(ns, "a", "default"))
        self.assertIsNone(getattr(ns, "dest_b", "default"))
        self.assertIsNone(getattr(ns, "c", "default"))
        self.assertIsNone(getattr(ns, "d", "default"))
        self.assertIsNone(getattr(ns, "e", "default"))
        self.assertIsNone(getattr(ns, "f", "default"))
        self.assertIsNone(getattr(ns, "g", "default"))
        self.assertIsNone(getattr(ns, "i", "default"))
        self.assertIsNone(getattr(ns, "j", "default"))
        self.assertIsNone(getattr(ns, "k", "default"))
        self.assertIsNone(getattr(ns, "l", "default"))

        parser = ArgumentParserEx()
        parser.add_argument("a")
        self.assertRaisesRegexp(ValueError, "Required attribute not found",
                                parser.parse_args, [])
        parser = ArgumentParserEx()
        parser.add_argument("b", nargs=2)
        self.assertRaisesRegexp(ValueError, "Required attribute not found",
                                parser.parse_args, [])
        parser = ArgumentParserEx()
        parser.add_argument("c", action="append")
        self.assertRaisesRegexp(ValueError, "Required attribute not found",
                                parser.parse_args, [])
        parser = ArgumentParserEx()
        parser.add_argument("d", action="store")
        self.assertRaisesRegexp(ValueError, "Required attribute not found",
                                parser.parse_args, [])

        parser = ArgumentParserEx()
        parser.add_argument("e", nargs="*")
        ns = parser.parse_args([])
        self.assertEqual([], getattr(ns, "e", "default"))

        parser = ArgumentParserEx()
        parser.add_argument("f", nargs="?")
        ns = parser.parse_args([])
        self.assertIsNone(getattr(ns, "f", "default"))

        parser = ArgumentParserEx()
        parser.add_argument("g", nargs="*", action="append")
        ns = parser.parse_args([])
        # ArgumentParser: [[]]
        self.assertEqual([], getattr(ns, "g", "default"))

        parser = ArgumentParserEx()
        parser.add_argument("h", nargs="?", action="append")
        ns = parser.parse_args([])
        # ArgumentParser: [None]
        self.assertIsNone(getattr(ns, "h", "default"))