Skip to content

Commit

Permalink
Change data driven "str" type to represent a quoted string literal (q…
Browse files Browse the repository at this point in the history
…mk#16516)

* Change data driven "str" type to represent a quoted string literal

* Update docs
  • Loading branch information
fauxpark authored and waffle87 committed Mar 23, 2022
1 parent 5ac1dd4 commit 1d2b336
Show file tree
Hide file tree
Showing 6 changed files with 37 additions and 13 deletions.
2 changes: 1 addition & 1 deletion data/mappings/info_config.json
Expand Up @@ -3,7 +3,7 @@
{
# Format:
# <config.h key>: {"info_key": <info.json key>, ["value_type": <value_type>], ["to_json": <true/false>], ["to_c": <true/false>]}
# value_type: one of "array", "array.int", "bool", "int", "hex", "list", "mapping"
# value_type: one of "array", "array.int", "bool", "int", "hex", "list", "mapping", "str", "raw"
# to_json: Default `true`. Set to `false` to exclude this mapping from info.json
# to_c: Default `true`. Set to `false` to exclude this mapping from config.h
# warn_duplicate: Default `true`. Set to `false` to turn off warning when a value exists in both places
Expand Down
4 changes: 2 additions & 2 deletions data/mappings/info_rules.json
Expand Up @@ -3,7 +3,7 @@
{
# Format:
# <rules.mk key>: {"info_key": <info.json key>, ["value_type": <value_type>], ["to_json": <true/false>], ["to_c": <true/false>]}
# value_type: one of "array", "array.int", "bool", "int", "list", "hex", "mapping"
# value_type: one of "array", "array.int", "bool", "int", "list", "hex", "mapping", "str", "raw"
# to_json: Default `true`. Set to `false` to exclude this mapping from info.json
# to_c: Default `true`. Set to `false` to exclude this mapping from rules.mk
# warn_duplicate: Default `true`. Set to `false` to turn off warning when a value exists in both places
Expand All @@ -20,6 +20,6 @@
"MOUSEKEY_ENABLE": {"info_key": "mouse_key.enabled", "value_type": "bool"},
"NO_USB_STARTUP_CHECK": {"info_key": "usb.no_startup_check", "value_type": "bool"},
"SPLIT_KEYBOARD": {"info_key": "split.enabled", "value_type": "bool"},
"SPLIT_TRANSPORT": {"info_key": "split.transport.protocol", "value_type": "str", "to_c": false},
"SPLIT_TRANSPORT": {"info_key": "split.transport.protocol", "to_c": false},
"WAIT_FOR_USB": {"info_key": "usb.wait_for", "value_type": "bool"}
}
5 changes: 3 additions & 2 deletions docs/data_driven_config.md
Expand Up @@ -44,7 +44,7 @@ In other cases you should group like options together in an `object`. This is pa
In most cases you can add a simple mapping. These are maintained as JSON files in `data/mappings/info_config.json` and `data/mappings/info_rules.json`, and control mapping for `config.h` and `rules.mk`, respectively. Each mapping is keyed by the `config.h` or `rules.mk` variable, and the value is a hash with the following keys:

* `info_key`: (required) The location within `info.json` for this value. See below.
* `value_type`: (optional) Default `str`. The format for this variable's value. See below.
* `value_type`: (optional) Default `raw`. The format for this variable's value. See below.
* `to_json`: (optional) Default `true`. Set to `false` to exclude this mapping from info.json
* `to_c`: (optional) Default `true`. Set to `false` to exclude this mapping from config.h
* `warn_duplicate`: (optional) Default `true`. Set to `false` to turn off warning when a value exists in both places
Expand All @@ -57,14 +57,15 @@ Under the hood we use [Dotty Dict](https://dotty-dict.readthedocs.io/en/latest/)

#### Value Types

By default we treat all values as simple strings. If your value is more complex you can use one of these types to intelligently parse the data:
By default we treat all values as unquoted "raw" data. If your value is more complex you can use one of these types to intelligently parse the data:

* `array`: A comma separated array of strings
* `array.int`: A comma separated array of integers
* `int`: An integer
* `hex`: A number formatted as hex
* `list`: A space separate array of strings
* `mapping`: A hash of key/value pairs
* `str`: A quoted string literal

### Add code to extract it

Expand Down
25 changes: 20 additions & 5 deletions lib/python/qmk/cli/generate/config_h.py
Expand Up @@ -9,9 +9,7 @@
from qmk.json_schema import json_load, validate
from qmk.keyboard import keyboard_completer, keyboard_folder
from qmk.keymap import locate_keymap
from qmk.commands import dump_lines
from qmk.path import normpath
from qmk.constants import GPL2_HEADER_C_LIKE, GENERATED_HEADER_C_LIKE


def direct_pins(direct_pins, postfix):
Expand Down Expand Up @@ -84,7 +82,7 @@ def generate_config_items(kb_info_json, config_h_lines):

for config_key, info_dict in info_config_map.items():
info_key = info_dict['info_key']
key_type = info_dict.get('value_type', 'str')
key_type = info_dict.get('value_type', 'raw')
to_config = info_dict.get('to_config', True)

if not to_config:
Expand Down Expand Up @@ -112,6 +110,11 @@ def generate_config_items(kb_info_json, config_h_lines):
config_h_lines.append(f'#ifndef {key}')
config_h_lines.append(f'# define {key} {value}')
config_h_lines.append(f'#endif // {key}')
elif key_type == 'str':
config_h_lines.append('')
config_h_lines.append(f'#ifndef {config_key}')
config_h_lines.append(f'# define {config_key} "{config_value}"')
config_h_lines.append(f'#endif // {config_key}')
elif key_type == 'bcd_version':
(major, minor, revision) = config_value.split('.')
config_h_lines.append('')
Expand Down Expand Up @@ -183,7 +186,7 @@ def generate_config_h(cli):
kb_info_json = dotty(info_json(cli.args.keyboard))

# Build the info_config.h file.
config_h_lines = [GPL2_HEADER_C_LIKE, GENERATED_HEADER_C_LIKE, '#pragma once']
config_h_lines = ['/* This file was generated by `qmk generate-config-h`. Do not edit or copy.', ' */', '', '#pragma once']

generate_config_items(kb_info_json, config_h_lines)

Expand All @@ -196,4 +199,16 @@ def generate_config_h(cli):
generate_split_config(kb_info_json, config_h_lines)

# Show the results
dump_lines(cli.args.output, config_h_lines, cli.args.quiet)
config_h = '\n'.join(config_h_lines)

if cli.args.output:
cli.args.output.parent.mkdir(parents=True, exist_ok=True)
if cli.args.output.exists():
cli.args.output.replace(cli.args.output.parent / (cli.args.output.name + '.bak'))
cli.args.output.write_text(config_h, encoding='utf-8')

if not cli.args.quiet:
cli.log.info('Wrote info_config.h to %s.', cli.args.output)

else:
print(config_h)
4 changes: 3 additions & 1 deletion lib/python/qmk/cli/generate/rules_mk.py
Expand Up @@ -21,7 +21,7 @@ def process_mapping_rule(kb_info_json, rules_key, info_dict):
return None

info_key = info_dict['info_key']
key_type = info_dict.get('value_type', 'str')
key_type = info_dict.get('value_type', 'raw')

try:
rules_value = kb_info_json[info_key]
Expand All @@ -34,6 +34,8 @@ def process_mapping_rule(kb_info_json, rules_key, info_dict):
return f'{rules_key} ?= {"yes" if rules_value else "no"}'
elif key_type == 'mapping':
return '\n'.join([f'{key} ?= {value}' for key, value in rules_value.items()])
elif key_type == 'str':
return f'{rules_key} ?= "{rules_value}"'

return f'{rules_key} ?= {rules_value}'

Expand Down
10 changes: 8 additions & 2 deletions lib/python/qmk/info.py
Expand Up @@ -411,7 +411,7 @@ def _extract_config_h(info_data):

for config_key, info_dict in info_config_map.items():
info_key = info_dict['info_key']
key_type = info_dict.get('value_type', 'str')
key_type = info_dict.get('value_type', 'raw')

try:
if config_key in config_c and info_dict.get('to_json', True):
Expand Down Expand Up @@ -443,6 +443,9 @@ def _extract_config_h(info_data):
elif key_type == 'int':
dotty_info[info_key] = int(config_c[config_key])

elif key_type == 'str':
dotty_info[info_key] = config_c[config_key].strip('"')

elif key_type == 'bcd_version':
major = int(config_c[config_key][2:4])
minor = int(config_c[config_key][4])
Expand Down Expand Up @@ -491,7 +494,7 @@ def _extract_rules_mk(info_data):

for rules_key, info_dict in info_rules_map.items():
info_key = info_dict['info_key']
key_type = info_dict.get('value_type', 'str')
key_type = info_dict.get('value_type', 'raw')

try:
if rules_key in rules and info_dict.get('to_json', True):
Expand Down Expand Up @@ -523,6 +526,9 @@ def _extract_rules_mk(info_data):
elif key_type == 'int':
dotty_info[info_key] = int(rules[rules_key])

elif key_type == 'str':
dotty_info[info_key] = rules[rules_key].strip('"')

else:
dotty_info[info_key] = rules[rules_key]

Expand Down

0 comments on commit 1d2b336

Please sign in to comment.