Name |
Date |
Size |
#Lines |
LOC |
||
---|---|---|---|---|---|---|
.. | - | - | ||||
NeuralNetworksTypes.t | D | 03-May-2024 | 29.7 KiB | 729 | 670 | |
OperandTypes.t | D | 03-May-2024 | 1.7 KiB | 59 | 49 | |
OperationTypes.t | D | 03-May-2024 | 1.3 KiB | 47 | 37 | |
README.md | D | 03-May-2024 | 8.3 KiB | 226 | 153 | |
Types.t | D | 03-May-2024 | 7.2 KiB | 258 | 197 | |
generate_api.py | D | 03-May-2024 | 14 KiB | 368 | 273 | |
generate_api.sh | D | 03-May-2024 | 2.3 KiB | 80 | 71 | |
types.spec | D | 03-May-2024 | 318.7 KiB | 7,826 | 7,536 |
README.md
1# API File Generation 2 3There are certain pieces of `NeuralNetworksTypes.h`, `Types.h`, 4`OperandTypes.h`, `OperationTypes.h`, and of our various `*.hal` files that 5ought to be kept in sync -- most notably the operand type and operation type 6definitions and descriptions. To avoid having to do this manually, a tool 7`generate_api.py` is employed to combine a single *specification file* with one 8*template file* per API file (`NeuralNetworksTypes.h`, `Types.h`, 9`OperandTypes.h`, `OperationTypes.h`, or `types.hal`) to produce that API file. 10The script `generate_api.sh` invokes `generate_api.py` once per API file, 11passing appropriate arguments. 12 13## `generate_api.sh` 14 15The environment variable `ANDROID_BUILD_TOP` must be set. 16 17Invoked with no arguments or with the `--mode=update` argument, this script 18regenerates each API file in place, by invoking `generate_api.py` once per 19generated file. 20 21Invoked with the `--mode=hook` argument, this script checks whether 22`NeuralNetworksTypes.h`, `Types.h`, `OperandTypes.h`, or `OperationTypes.h` 23needs to be regenerated. 24 25When the `--dryrun` argument is present, this script shows how it would invoke 26`generate_api.py` but does not actually regenerate files or check whether they 27need to be regenerated. 28 29## `generate_api.py` 30 31This tool generates a single output file from an input specification file and an 32input template file. It takes the following mandatory arguments: 33 34* `--output OUTPUT` path to generated output file (such as `Types.h`) 35* `--specification SPECIFICATION` path to input specification file 36* `--template TEMPLATE` path to input template file 37* `--kind KIND` token identifying kind of file to generate 38 39The "kind" is an arbitrary token that the specification file can reference with 40the `%kind` directive to help generate different text in different situations. 41It has no meaning to the tool itself. Today, the following kinds are used: 42`ndk` (when generating `NeuralNetworksTypes.h`), `canonical` (when generating 43`Types.h`, `OperandTypes.h`, and `OperationTypes.h`), `hal_1.0` (when generating 44`1.0/types.hal`), `hal_1.1`, `hal_1.2`, and `hal_1.3`. 45 46## Template File Syntax 47 48Every line of the template file is copied verbatim to the output file *unless* 49that line begins with `%`. 50 51A line that begins with `%%` is a comment, and is ignored. 52 53A line that begins with `%` and is not a comment is a *directive*. 54 55### Directives 56 57#### `%insert *name*` 58 59Copy the *section* with the specified *name* from the specification file to the 60output file. The section is defined by a `%section` directive in the 61specification file. 62 63#### `%insert-indented *count* *name*` 64 65Similar to `%insert *name*`, but each non-empty copied line is prefixed with 66*count* space characters. *count* must be a non-negative integer. 67 68## Specification File Syntax 69 70The specification file consists of comments, *directives*, and other text. 71 72A line that begins with `%%` is a comment, and is ignored. 73 74A line that begins with `%` and is not a comment is a *directive*. 75 76The meaning of a line that is neither a comment nor a directive depends on the 77context -- the *region* in which that line appears. 78 79### Regions 80 81The specification file is divided into *regions*, which are sequences of lines 82delimited by certain directives. 83 84Certain regions can enclose certain other regions, but this is very limited: 85 86* A conditional region can enclose a section region. 87* A section region can enclose a conditional region. 88 89Equivalently: 90 91* A conditional region can be enclosed by a section region. 92* A section region can be enclosed by a conditional region. 93 94#### null region 95 96A *null region* is a sequence of lines that is not part of any other region. 97For example, a specification file that contains no directives other than 98`%define` and `%define-kinds` consists of a single null region. 99 100Within a null region, all lines other than directives are treated as comments 101and are ignored. 102 103#### conditional region 104 105A *conditional region* is a sequence of lines immediately preceded by the `%kind 106*list*` directive and immediately followed by the `%/kind` directive. The 107`%kind` directive establishes a condition state **on** or **off** (see the 108description of the directive for details). When the condition is **on**, the 109lines in the region are processed normally (i.e., directives have their usual 110effect, and non-directive lines are added to the enclosing section region, if 111any). When the condition is **off**, lines in the region other than the `%else` 112directive are ignored *except* that even ignored directives undergo some level 113of syntactic and semantic checking. 114 115#### section region 116 117A *section region* is a sequence of lines immediately preceded by the `%section 118*name*` directive and immediately followed by the `%/section` directive. Every 119line in the sequence that doesn't begin with `%` undergoes macro substitution, 120and the resulting lines are associated with the section name. They can be 121inserted into the generated output file as directed by the template file's 122`%insert` and `%insert-indented` directives. They can be added to another 123section region with the with the specification file's `%insert` and 124`%insert-indented` directives. 125 126This is the mechanism by which a specification file contributes text to the 127generated output file. 128 129### Directives 130 131#### `%define *name* *body*` 132 133Defines a macro identified by the token *name*. The *body* is separated from 134the *name* by exactly one whitespace character, and extends to the end of the 135line -- it may contain whitespace itself. For example, 136 137 %define test this body begins and ends with a space character 138 139Macro substitution occurs within a section region: a substring `%{*name*}` is 140replaced with the corresponding *body*. Macro substitution is *not* recursive: 141A substring `%{*name2*}` in *body* will not undergo macro substitution, except 142as discussed for *macro arguments* below. 143 144Permitted in regions: null, conditional, section 145 146##### macro arguments 147 148The more general form of a macro invocation is `%{*name* *arglist*}`, where 149*arglist* is a list of whitespace-separated arguments. Within the *body*, a 150substring of the form `%{argnum}` will be replaced by the corresponding argument 151from *arglist*. For example, if the definition is 152 153``` 154%define test second is %{2}, first is %{1} 155``` 156 157then the macro invocation 158 159``` 160%{test alpha beta} 161``` 162 163is expanded to 164 165``` 166second is beta, first is alpha 167``` 168 169The only check on the number of arguments supplied at macro invocation time is 170that there must be at least as many arguments as the highest `%{argnum}` 171reference in the macro body. In the example above, `%{test alpha}` would be an 172error, but `%{test alpha beta gamma}` would not. 173 174#### `%insert *name*` 175 176Adds all lines from the named section region to the current section region. 177 178Permitted in regions: section 179 180#### `%insert-indented *count* *name*` 181 182Similar to `%insert *name*`, but each non-empty added line is prefixed 183with *count* space characters. *count* must be a non-negative integer. 184 185Permitted in regions: section 186 187#### `%kind *list*`, `%else`, `%/kind` 188 189`%kind *list*` creates a *conditional region* terminated by `%/kind`. 190 191The *list* consists of a space-delimited list of tokens, any of which may end in 192`*` to indicate a *wildcard pattern* or `+` to indicate a *lowest version 193pattern*. Any other pattern is a *simple pattern*. The condition is **on** in 194three cases: 195* One of the simple pattern tokens equals the "kind" 196* One of the wildcard pattern tokens less the `*` is a prefix of the "kind" 197* One of the lowest version pattern tokens less the `+` matches the "kind" or 198 the "kind" matches any token to the right from the lowest version pattern in 199 the list passed to %define-kinds 200 201In all other cases, the condition is **off**. 202 203Within the region, the condition is inverted every time the `%else` directive 204appears. 205 206Permitted in regions: null, section 207 208#### `%define-kinds *list*` 209 210This directive has two purposes: 211 212* Validity-checking. If the "kind" is not on the space-delimited *list* of tokens, 213 `generate_api.py` terminates with an error. 214* Ordering the possible kinds for the *lowest version pattern* (see the section 215 above for the explanation of the pattern). 216 217Only one such directive is allowed per specification file. 218 219Permitted in regions: null, section 220 221#### `%section *name*`, `%/section` 222 223`%section *name*` creates a *section region* terminated by `%/section`. 224 225Permitted in regions: null, conditional 226