1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
.. _additional-cmd:
===========================
Implementing Custom Parsers
===========================
------------------------------
Using the simple specification
------------------------------
You can tell the parser how to interpret your custom commands by specifying the
format of their call signature using the ``addtitional_commands`` configuration
variable. The format of the variable is a dictionary (a mapping in JSON/YAML)
where the keys should be the name of the command and the values satisfy the
following (recursive) schema:
.. code::
POSITIONAL_SPEC = {
# Number of positional arguments. Can be an integer indicating an exact
# number of arguments, or a string satisfying the regex:
# "(\d*)\+?|\*|\?". The semantics of the string:
#
# * "?": zero or one
# * "*": zero or more
# * "+": one or more
# * (\d+): exactly `n` positional arguments (e.g. "3")
# * (\d+)\+ : as many positional arguments as available, but at least
# `n` (e.g. "3+")
#
"nargs": <string,int>,
# Stores a list of keywords that are treated as positional arguments and
# included in the positional group, but annotated as keywords for special
# processing (e.g. case canonicalization).
"flags": [<string>, ...],
# Stores a list of tags to apply to this positional argument group. See
# below for more information on tags.
"tags": [<string>]
# If true, then this specification will be repeated indefinitately
"legacy": <bool>,
}
KEYWORD_SPEC = {
"pargs": [POSITIONAL_SPEC, ...],
"kwargs": {<string>: KEYWORD_SPEC}
}
As a shorthand:
* If a keyword specification contains no nested `kwargs` and only one
positional argument group, you may omit the `KEYWORD_SPEC` overhead and
write the `POSITIONAL_SPEC` directly (including shorthands below)
* There is only one positional group, you may omit the list
* The a positional contains now flags, and is not tagged, you may omit the
outer dictionary and write only the `nargs` value.
Tags
====
Positional argument groups support the following tags:
* `cmdline`: The positional arguments of this group are command line arguments
in a shell command. In particular this means that they will not be wrapped
vertically
* `file-list`: The positional arguments of this group are names/paths of files.
In the future this tag will enable certain filters for formatting or linting,
such as automatic sorting.
--------------------------------
Generating simple specifications
--------------------------------
There is an experimental utility called ``cmake-genparsers`` which can generate
simple specifications for cmake functions and macros that use
``cmake_parse_arguments``. The tool has very limited ability to process cmake
arguments. There is a frontend included in the python distribution. Usage
is
.. code::
usage:
cmake-genparsers [-h] [-o OUTFILE_PATH] infilepath [infilepath ...]
Parse cmake listfiles, find function and macro declarations, and generate
parsers for them.
positional arguments:
infilepaths
optional arguments:
-h, --help show this help message and exit
-v, --version show program's version number and exit
-l {error,warning,info,debug}, --log-level {error,warning,info,debug}
-o OUTFILE_PATH, --outfile-path OUTFILE_PATH
Write results to this file. Default is stdout.
-f {json,yaml,python}, --output-format {json,yaml,python}
For example:
.. code::
:~$ cmake-genparsers /usr/share/cmake-3.10/Modules/*.cmake
{ 'add_command': {'pargs': {'nargs': 1}},
'add_compiler_export_flags': {'pargs': {'nargs': 0}},
'add_feature_info': {'pargs': {'nargs': 3}},
'add_file_dependencies': {'pargs': {'nargs': 1}},
'add_flex_bison_dependency': {'pargs': {'nargs': 2}},
'add_jar': { 'kwargs': { 'ENTRY_POINT': 1,
'INCLUDE_JARS': '+',
'MANIFEST': 1,
'OUTPUT_DIR': 1,
'OUTPUT_NAME': 1,
...
or
.. code::
:~$ cmake-genparsers -f yaml /usr/share/cmake-3.10/Modules/*.cmake
add_file_dependencies:
pargs:
nargs: 1
android_add_test_data:
pargs:
nargs: 1+
flags: []
kwargs: {}
get_bundle_main_executable:
pargs:
...
This tool is still in the early stages of development so don't be surprised if
it chokes on some of your input files, or if it does not propery generate
specifications for your commands.
|