예제 #1
0
def parse_source_group(ctx, tokens, breakstack):
    """
  ::

    source_group(<name> [FILES <src>...] [REGULAR_EXPRESSION <regex>])
    source_group(TREE <root> [PREFIX <prefix>] [FILES <src>...])
    source_group(<name> <regex>)

  :see: https://cmake.org/cmake/help/latest/command/source_group.html
  """
    descriminator = get_nth_semantic_token(tokens, 0)
    if descriminator is not None and descriminator.spelling.upper() == "TREE":
        kwargs = {
            "PREFIX": PositionalParser(1),
            "FILES": PositionalParser("+")
        }
        return StandardArgTree.parse(ctx, tokens, 2, kwargs, [], breakstack)

    kwargs = {
        "FILES": PositionalParser("+"),
        "REGULAR_EXPRESSION": PositionalParser(1)
    }

    descriminator = get_nth_semantic_token(tokens, 1)
    if descriminator is not None and descriminator.spelling.upper(
    ) not in kwargs:
        return StandardArgTree.parse(ctx, tokens, 2, {}, [], breakstack)

    return StandardArgTree.parse(ctx, tokens, 1, kwargs, [], breakstack)
예제 #2
0
def parse_build_command(ctx, tokens, breakstack):
    """
  ::

    build_command(<variable>
                  [CONFIGURATION <config>]
                  [TARGET <target>]
                  [PROJECT_NAME <projname>] # legacy, causes warning
                 )

  :see: https://cmake.org/cmake/help/latest/command/build_command.html
  """
    kwargs = {
        "CONFIGURATION": PositionalParser(1),
        "TARGET": PositionalParser(1),
        "PROJECT_NAME": PositionalParser(1)
    }

    second_token = get_nth_semantic_token(tokens, 1)
    if second_token is not None and second_token.spelling.upper not in kwargs:
        ctx.lint_ctx.record_lint(
            "W0106",
            "build_command(<cachevariable> <makecommand>)",
            location=tokens[0].get_location())
        return StandardArgTree.parse(ctx, tokens, "2", {}, [], breakstack)

    return StandardArgTree.parse(ctx, tokens, "1", kwargs, [], breakstack)
예제 #3
0
def parse_file_lock(ctx, tokens, breakstack):
    """
  ::

    file(LOCK <path> [DIRECTORY] [RELEASE]
         [GUARD <FUNCTION|FILE|PROCESS>]
         [RESULT_VARIABLE <variable>]
         [TIMEOUT <seconds>])

  :see: https://cmake.org/cmake/help/v3.14/command/file.html#locking
  """

    return StandardArgTree.parse(ctx,
                                 tokens,
                                 npargs='+',
                                 kwargs={
                                     "GUARD":
                                     PositionalParser(
                                         1,
                                         flags=["FUNCTION", "FILE",
                                                "PROCESS"]),
                                     "RESULT_VARIABLE":
                                     PositionalParser(1),
                                     "TIMEOUT":
                                     PositionalParser(1)
                                 },
                                 flags=[
                                     "LOCK",
                                     "DIRECTORY",
                                     "RELEASE",
                                 ],
                                 breakstack=breakstack)
예제 #4
0
def parse_ctest_build(ctx, tokens, breakstack):
    """
  ::

    ctest_build([BUILD <build-dir>] [APPEND]
                [CONFIGURATION <config>]
                [FLAGS <flags>]
                [PROJECT_NAME <project-name>]
                [TARGET <target-name>]
                [NUMBER_ERRORS <num-err-var>]
                [NUMBER_WARNINGS <num-warn-var>]
                [RETURN_VALUE <result-var>]
                [CAPTURE_CMAKE_ERROR <result-var>]
                )

  :see: https://cmake.org/cmake/help/latest/command/ctest_build.html
  """
    kwargs = {
        "BUILD": PositionalParser(1),
        "CONFIGURATION": PositionalParser(1),
        "FLAGS": PositionalParser(1),
        "PROJECT_NAME": PositionalParser(1),
        "TARGET": PositionalParser(1),
        "NUMBER_ERRORS": PositionalParser(1),
        "NUMBER_WARNINGS": PositionalParser(1),
        "RETURN_VALUE": PositionalParser(1),
        "CAPTURE_CMAKE_ERROR": PositionalParser(1)
    }
    return StandardArgTree.parse(ctx, tokens, "+", kwargs, ["APPEND"],
                                 breakstack)
예제 #5
0
def parse_ctest_submit(ctx, tokens, breakstack):
    """
  ::

    ctest_submit([PARTS <part>...] [FILES <file>...]
                 [SUBMIT_URL <url>]
                 [BUILD_ID <result-var>]
                 [HTTPHEADER <header>]
                 [RETRY_COUNT <count>]
                 [RETRY_DELAY <delay>]
                 [RETURN_VALUE <result-var>]
                 [CAPTURE_CMAKE_ERROR <result-var>]
                 [QUIET]
                 )

  :see: https://cmake.org/cmake/help/latest/command/ctest_submit.html
  """
    kwargs = {
        "PARTS": PositionalParser("+"),
        "FILES": PositionalParser("+"),
        "SUBMIT_URL": PositionalParser(1),
        "BUILD_ID": PositionalParser(1),
        "HTTPHEADER": PositionalParser(1),
        "RETRY_COUNT": PositionalParser(1),
        "RETRY_DELAY": PositionalParser(1),
        "RETURN_VALUE": PositionalParser(1),
        "CAPTURE_CMAKE_ERROR": PositionalParser(1),
    }
    flags = ["QUIET"]
    return StandardArgTree.parse(ctx, tokens, "+", kwargs, flags, breakstack)
예제 #6
0
def parse_target_compile_features(ctx, tokens, breakstack):
    """
  ::

    target_compile_features(<target> <PRIVATE|PUBLIC|INTERFACE> <feature> [...])

  :see: https://cmake.org/cmake/help/latest/command/target_compile_features.html
  """
    kwargs = {
        "INTERFACE": PositionalParser("+"),
        "PUBLIC": PositionalParser("+"),
        "PRIVATE": PositionalParser("+"),
    }
    return StandardArgTree.parse(ctx, tokens, 1, kwargs, [], breakstack)
예제 #7
0
def parse_ctest_upload(ctx, tokens, breakstack):
    """
  ::

    ctest_upload(FILES <file>... [QUIET] [CAPTURE_CMAKE_ERROR <result-var>])

  :see: https://cmake.org/cmake/help/latest/command/ctest_upload.html
  """
    kwargs = {
        "FILES": PositionalParser("+"),
        "CAPTURE_CMAKE_ERROR": PositionalParser(1)
    }
    flags = ["QUIET"]
    return StandardArgTree.parse(ctx, tokens, "+", kwargs, flags, breakstack)
예제 #8
0
def parse_install_files(ctx, tokens, breakstack):
  """
  ::
    install(<FILES|PROGRAMS> files...
            TYPE <type> | DESTINATION <dir>
            [PERMISSIONS permissions...]
            [CONFIGURATIONS [Debug|Release|...]]
            [COMPONENT <component>]
            [RENAME <name>] [OPTIONAL] [EXCLUDE_FROM_ALL])

  :see: https://cmake.org/cmake/help/v3.14/command/install.html#files
  """
  return StandardArgTree.parse(
      ctx, tokens,
      npargs='*',
      kwargs={
          "FILES": PositionalParser('+'),
          "PROGRAMS": PositionalParser('+'),
          "TYPE": PositionalParser(1),
          "DESTINATION": PositionalParser(1),
          "PERMISSIONS": PositionalParser('+'),
          "CONFIGURATIONS": PositionalParser('+'),
          "COMPONENT": PositionalParser(1),
          "RENAME": PositionalParser(1),
      },
      flags=[
          "OPTIONAL",
          "EXCLUDE_FROM_ALL",
      ],
      breakstack=breakstack)
예제 #9
0
def parse_load_cache(ctx, tokens, breakstack):
    """
  ::

    load_cache(pathToBuildDirectory READ_WITH_PREFIX prefix entry1...)
    load_cache(pathToBuildDirectory [EXCLUDE entry1...]
               [INCLUDE_INTERNALS entry1...])

  :see: https://cmake.org/cmake/help/latest/command/load_cache.html
  """
    kwargs = {
        "READ_WITH_PREFIX": PositionalParser("2+"),
        "EXCLUDE": PositionalParser("+"),
        "INCLUDE_INTERNALS": PositionalParser("+")
    }
    return StandardArgTree.parse(ctx, tokens, 1, kwargs, [], breakstack)
예제 #10
0
def parse_target_sources(ctx, tokens, breakstack):
    """
  ::

    target_sources(<target>
      <INTERFACE|PUBLIC|PRIVATE> [items1...]
      [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])

  :see: https://cmake.org/cmake/help/latest/command/target_sources.html
  """
    kwargs = {
        "INTERFACE": PositionalParser("+"),
        "PUBLIC": PositionalParser("+"),
        "PRIVATE": PositionalParser("+"),
    }
    return StandardArgTree.parse(ctx, tokens, 1, kwargs, [], breakstack)
예제 #11
0
def parse_file_copy(ctx, tokens, breakstack):
    """
  ::

    file(<COPY|INSTALL> <files>... DESTINATION <dir>
         [FILE_PERMISSIONS <permissions>...]
         [DIRECTORY_PERMISSIONS <permissions>...]
         [NO_SOURCE_PERMISSIONS] [USE_SOURCE_PERMISSIONS]
         [FILES_MATCHING]
         [[PATTERN <pattern> | REGEX <regex>]
          [EXCLUDE] [PERMISSIONS <permissions>...]] [...])

  :see: https://cmake.org/cmake/help/v3.14/command/file.html#filesystem
  """

    return StandardArgTree.parse(
        ctx,
        tokens,
        npargs='*',
        kwargs={
            "COPY":
            PositionalParser('*'),
            "DESTINATION":
            PositionalParser(1),
            "FILE_PERMISSIONS":
            PositionalParser('+',
                             flags=[
                                 "OWNER_READ", "OWNER_WRITE", "OWNER_EXECUTE",
                                 "GROUP_READ", "GROUP_WRITE", "GROUP_EXECUTE",
                                 "WORLD_READ", "WORLD_WRITE", "WORLD_EXECUTE",
                                 "SETUID", "SETGID"
                             ]),
            "DIRECTORY_PERMISSIONS":
            PositionalParser('+'),
            "PATTERN":
            PatternNode.parse,
            "REGEX":
            PatternNode.parse,
        },
        flags=[
            "INSTALL",
            "NO_SOURCE_PERMISSIONS",
            "USE_SOURCE_PERMISSIONS",
            "FILES_MATCHING",
        ],
        breakstack=breakstack)
예제 #12
0
def parse_create_test_sourcelist(ctx, tokens, breakstack):
    """
  ::

    create_test_sourcelist(sourceListName driverName
                           test1 test2 test3
                           EXTRA_INCLUDE include.h
                           FUNCTION function)

  :see: https://cmake.org/cmake/help/latest/command/create_test_sourcelist.html
  """

    kwargs = {
        "EXTRA_INCLUDE": PositionalParser(1),
        "FUNCTION": PositionalParser(1)
    }
    return StandardArgTree.parse(ctx, tokens, "3+", kwargs, [], breakstack)
예제 #13
0
def parse_install_export(ctx, tokens, breakstack):
  """
  ::

    install(EXPORT <export-name> DESTINATION <dir>
            [NAMESPACE <namespace>] [[FILE <name>.cmake]|
            [PERMISSIONS permissions...]
            [CONFIGURATIONS [Debug|Release|...]]
            [EXPORT_LINK_INTERFACE_LIBRARIES]
            [COMPONENT <component>]
            [EXCLUDE_FROM_ALL])

  :see: https://cmake.org/cmake/help/v3.14/command/install.html#installing-exports
  """
  return StandardArgTree.parse(
      ctx, tokens,
      npargs='*',
      kwargs={
          "EXPORT": PositionalParser(1),
          "DESTINATION": PositionalParser(1),
          "NAMESPACE": PositionalParser(1),
          "FILE": PositionalParser(1),
          "PERMISSIONS": PositionalParser('+'),
          "CONFIGURATIONS": PositionalParser('+'),
          "COMPONENT": PositionalParser(1),
      },
      flags=[
          "EXCLUDE_FROM_ALL"
      ],
      breakstack=breakstack)
예제 #14
0
def parse_ctest_update(ctx, tokens, breakstack):
    """
  ::

    ctest_update([SOURCE <source-dir>]
                 [RETURN_VALUE <result-var>]
                 [CAPTURE_CMAKE_ERROR <result-var>]
                 [QUIET])

  :see: https://cmake.org/cmake/help/latest/command/ctest_update.html
  """
    kwargs = {
        "SOURCE": PositionalParser(1),
        "RETURN_VALUE": PositionalParser(1),
        "CAPTURE_CMAKE_ERROR": PositionalParser(1)
    }
    flags = ["QUIET"]
    return StandardArgTree.parse(ctx, tokens, "+", kwargs, flags, breakstack)
예제 #15
0
def parse_exec_program(ctx, tokens, breakstack):
  """
  ::

    exec_program(Executable [directory in which to run]
                 [ARGS <arguments to executable>]
                 [OUTPUT_VARIABLE <var>]
                 [RETURN_VALUE <var>])

  :see: https://cmake.org/cmake/help/latest/command/exec_program.html
  """
  kwargs = {
      "ARGS": PositionalParser("+"),
      "OUTPUT_VARIABLE": PositionalParser(1),
      "RETURN_VALUE": PositionalParser(1)
  }

  return StandardArgTree.parse(ctx, tokens, 2, kwargs, [], breakstack)
예제 #16
0
def parse_include_external_msproject(ctx, tokens, breakstack):
    """
  ::

    include_external_msproject(projectname location
                           [TYPE projectTypeGUID]
                           [GUID projectGUID]
                           [PLATFORM platformName]
                           dep1 dep2 ...)

  :see: https://cmake.org/cmake/help/latest/command/include_external_msproject.html
  """
    kwargs = {
        "TYPE": PositionalParser(1),
        "GUID": PositionalParser(1),
        "PLATFORM": PositionalParser(1)
    }
    return StandardArgTree.parse(ctx, tokens, "2+", kwargs, [], breakstack)
예제 #17
0
def parse_file_read(ctx, tokens, breakstack):
    """
  ::

    file(READ <filename> <variable>
         [OFFSET <offset>] [LIMIT <max-in>] [HEX])

  :see: https://cmake.org/cmake/help/v3.14/command/file.html#read
  """

    return StandardArgTree.parse(ctx,
                                 tokens,
                                 npargs='*',
                                 kwargs={
                                     "OFFSET": PositionalParser(1),
                                     "LIMIT": PositionalParser(1),
                                 },
                                 flags=["READ", "HEX"],
                                 breakstack=breakstack)
예제 #18
0
def parse_math(ctx, tokens, breakstack):
    """
  ::

    math(EXPR <variable> "<expression>" [OUTPUT_FORMAT <format>])

  :see: https://cmake.org/cmake/help/latest/command/math.html
  """
    kwargs = {"OUTPUT_FORMAT": PositionalParser(1)}
    return StandardArgTree.parse(ctx, tokens, "3", kwargs, [], breakstack)
예제 #19
0
def parse_ctest_configure(ctx, tokens, breakstack):
    """
  ::

    ctest_configure([BUILD <build-dir>] [SOURCE <source-dir>] [APPEND]
                    [OPTIONS <options>] [RETURN_VALUE <result-var>] [QUIET]
                    [CAPTURE_CMAKE_ERROR <result-var>])

  :see: https://cmake.org/cmake/help/latest/command/ctest_configure.html
  """
    kwargs = {
        "BUILD": PositionalParser(1),
        "SOURCE": PositionalParser(1),
        "OPTIONS": PositionalParser(1),
        "RETURN_VALUE": PositionalParser(1),
        "CAPTURE_CMAKE_ERROR": PositionalParser(1)
    }
    return StandardArgTree.parse(ctx, tokens, "+", kwargs, ["APPEND", "QUIET"],
                                 breakstack)
예제 #20
0
def parse_fetchcontent_getproperties(ctx, tokens, breakstack):
    """
  ::

    FetchContent_GetProperties( <name>
      [SOURCE_DIR <srcDirVar>]
      [BINARY_DIR <binDirVar>]
      [POPULATED <doneVar>]
    )
  """
    return StandardArgTree.parse(ctx,
                                 tokens,
                                 npargs=1,
                                 kwargs={
                                     "SOURCE_DIR": PositionalParser(1),
                                     "BINARY_DIR": PositionalParser(1),
                                     "POPULATED": PositionalParser(1),
                                 },
                                 flags=[],
                                 breakstack=breakstack)
예제 #21
0
def parse_add_custom_command_events(ctx, tokens, breakstack):
    """
  ::
    add_custom_command(TARGET <target>
                    PRE_BUILD | PRE_LINK | POST_BUILD
                    COMMAND command1 [ARGS] [args1...]
                    [COMMAND command2 [ARGS] [args2...] ...]
                    [BYPRODUCTS [files...]]
                    [WORKING_DIRECTORY dir]
                    [COMMENT comment]
                    [VERBATIM] [USES_TERMINAL]
                    [COMMAND_EXPAND_LISTS])
  :see: https://cmake.org/cmake/help/latest/command/add_custom_command.html
  """
    subtree = StandardArgTree.parse(ctx,
                                    tokens,
                                    npargs='*',
                                    kwargs={
                                        "BYPRODUCTS": PositionalParser('*'),
                                        "COMMAND": ShellCommandNode.parse,
                                        "COMMENT": PositionalParser('*'),
                                        "TARGET": PositionalParser(1),
                                        "WORKING_DIRECTORY":
                                        PositionalParser(1)
                                    },
                                    flags=[
                                        "APPEND", "VERBATIM", "USES_TERMINAL",
                                        "COMMAND_EXPAND_LISTS", "PRE_BUILD",
                                        "PRE_LINK", "POST_BUILD"
                                    ],
                                    breakstack=breakstack)

    subtree.check_required_kwargs(
        ctx.lint_ctx,
        {
            # Truly required keyword arguments
            "COMMAND": "E1125",
            # Required by convention
            "COMMENT": "C0113"
        })
    return subtree
예제 #22
0
def parse_ctest_run_script(ctx, tokens, breakstack):
    """
  ::

    ctest_run_script([NEW_PROCESS] script_file_name script_file_name1
                     script_file_name2 ... [RETURN_VALUE var])

  :see: https://cmake.org/cmake/help/latest/command/ctest_run_script.html
  """
    kwargs = {"RETURN_VALUE": PositionalParser(1)}
    flags = ["NEW_PROCESS"]
    return StandardArgTree.parse(ctx, tokens, "+", kwargs, flags, breakstack)
예제 #23
0
def parse_ctest_start(ctx, tokens, breakstack):
    """
  ::

    ctest_start(<model> [<source> [<binary>]] [GROUP <group>] [QUIET])
    ctest_start([<model> [<source> [<binary>]]] [GROUP <group>] APPEND [QUIET])

  :see: https://cmake.org/cmake/help/latest/command/ctest_start.html
  """
    kwargs = {"GROUP": PositionalParser(1)}
    flags = ["QUIET", "APPEND"]
    return StandardArgTree.parse(ctx, tokens, "+", kwargs, flags, breakstack)
예제 #24
0
def parse_ctest_coverage(ctx, tokens, breakstack):
    """
  ::

    ctest_coverage([BUILD <build-dir>] [APPEND]
                   [LABELS <label>...]
                   [RETURN_VALUE <result-var>]
                   [CAPTURE_CMAKE_ERROR <result-var>]
                   [QUIET]
                   )

  :see: https://cmake.org/cmake/help/latest/command/ctest_coverage.html
  """
    kwargs = {
        "BUILD": PositionalParser(1),
        "LABELS": PositionalParser("+"),
        "RETURN_VALUE": PositionalParser(1),
        "CAPTURE_CMAKE_ERROR": PositionalParser(1),
    }
    return StandardArgTree.parse(ctx, tokens, "+", kwargs, ["APPEND", "QUIET"],
                                 breakstack)
예제 #25
0
def parse_install_targets(ctx, tokens, breakstack):
  """
  ::

    install_targets(<dir> [RUNTIME_DIRECTORY dir] target target)

  :see: https://cmake.org/cmake/help/latest/command/install_targets.html
  """
  kwargs = {
      "RUNTIME_DIRECTORY": PositionalParser(1)
  }
  return StandardArgTree.parse(ctx, tokens, "2+", kwargs, [], breakstack)
예제 #26
0
def parse_install_script(ctx, tokens, breakstack):
  """
  ::

    install([[SCRIPT <file>] [CODE <code>]]
            [COMPONENT <component>] [EXCLUDE_FROM_ALL] [...])

  :see: https://cmake.org/cmake/help/v3.14/command/install.html#custom-installation-logic
  """
  return StandardArgTree.parse(
      ctx, tokens,
      npargs='*',
      kwargs={
          "SCRIPT": PositionalParser(1),
          "CODE": PositionalParser(1),
          "COMPONENT": PositionalParser(1),
      },
      flags=[
          "EXCLUDE_FROM_ALL"
      ],
      breakstack=breakstack)
예제 #27
0
def parse_add_custom_command_standard(ctx, tokens, breakstack):
    """
  ::

      add_custom_command(OUTPUT output1 [output2 ...]
                         COMMAND command1 [ARGS] [args1...]
                         [COMMAND command2 [ARGS] [args2...] ...]
                         [MAIN_DEPENDENCY depend]
                         [DEPENDS [depends...]]
                         [BYPRODUCTS [files...]]
                         [IMPLICIT_DEPENDS <lang1> depend1
                                          [<lang2> depend2] ...]
                         [WORKING_DIRECTORY dir]
                         [COMMENT comment]
                         [DEPFILE depfile]
                         [JOB_POOL job_pool]
                         [VERBATIM] [APPEND] [USES_TERMINAL]
                         [COMMAND_EXPAND_LISTS])

  :see: https://cmake.org/cmake/help/latest/command/add_custom_command.html
  """
    subtree = StandardArgTree.parse(
        ctx,
        tokens,
        npargs='*',
        kwargs={
            "BYPRODUCTS": PositionalParser('*'),
            "COMMAND": ShellCommandNode.parse,
            "COMMENT": PositionalParser('*'),
            "DEPENDS": PositionalParser('*'),
            "DEPFILE": PositionalParser(1),
            "JOB_POOL": PositionalParser(1),
            "IMPLICIT_DEPENDS": TupleParser(2, '+'),
            "MAIN_DEPENDENCY": PositionalParser(1),
            "OUTPUT": PositionalParser('+'),
            "WORKING_DIRECTORY": PositionalParser(1)
        },
        flags=["APPEND", "VERBATIM", "USES_TERMINAL", "COMMAND_EXPAND_LISTS"],
        breakstack=breakstack)

    subtree.check_required_kwargs(
        ctx.lint_ctx,
        {
            # Truly required keyword arguments
            "COMMAND": "E1125",
            # Required by convention
            "COMMENT": "C0113"
        })

    return subtree
예제 #28
0
def parse_file_generate_output(ctx, tokens, breakstack):
    """
  ::

    file(GENERATE OUTPUT output-file
        <INPUT input-file|CONTENT content>
        [CONDITION expression])

  :see: https://cmake.org/cmake/help/v3.14/command/file.html#writing
  """

    return StandardArgTree.parse(ctx,
                                 tokens,
                                 npargs=1,
                                 kwargs={
                                     "OUTPUT": PositionalParser(1),
                                     "INPUT": PositionalParser(1),
                                     "CONTENT": PositionalParser('+'),
                                     "CONDITION": ConditionalGroupNode.parse,
                                 },
                                 flags=["GENERATE"],
                                 breakstack=breakstack)
예제 #29
0
def parse_file_glob(ctx, tokens, breakstack):
    """
  ::

    file(GLOB <variable>
        [LIST_DIRECTORIES true|false] [RELATIVE <path>] [CONFIGURE_DEPENDS]
        [<globbing-expressions>...])
    file(GLOB_RECURSE <variable> [FOLLOW_SYMLINKS]
        [LIST_DIRECTORIES true|false] [RELATIVE <path>] [CONFIGURE_DEPENDS]
        [<globbing-expressions>...])
  :see: https://cmake.org/cmake/help/v3.14/command/file.html#filesystem
  """

    return StandardArgTree.parse(
        ctx,
        tokens,
        npargs='+',
        kwargs={
            "LIST_DIRECTORIES": PositionalParser(1),
            "RELATIVE": PositionalParser(1)
        },
        flags=["GLOB", "GLOB_RECURSE", "CONFIGURE_DEPENDS", "FOLLOW_SYMLINKS"],
        breakstack=breakstack)
예제 #30
0
def parse_subdirs(ctx, tokens, breakstack):
  """
  ::

    subdirs(dir1 dir2 ...[EXCLUDE_FROM_ALL exclude_dir1 exclude_dir2 ...]
            [PREORDER] )

  :see: https://cmake.org/cmake/help/latest/command/subdirs.html
  """
  kwargs = {
      "EXCLUDE_FROM_ALL": PositionalParser("+"),
  }
  flags = ["PREORDER"]
  return StandardArgTree.parse(ctx, tokens, "+", kwargs, flags, breakstack)