First stab at codegen.
This commit is contained in:
parent
acb2f34c5c
commit
e3fe9fac60
8 changed files with 123 additions and 27 deletions
|
|
@ -49,6 +49,7 @@ subcommands = [
|
|||
'qmk.cli.generate.api',
|
||||
'qmk.cli.generate.autocorrect_data',
|
||||
'qmk.cli.generate.compilation_database',
|
||||
'qmk.cli.generate.community_modules',
|
||||
'qmk.cli.generate.config_h',
|
||||
'qmk.cli.generate.develop_pr_list',
|
||||
'qmk.cli.generate.dfu_header',
|
||||
|
|
|
|||
75
lib/python/qmk/cli/generate/community_modules.py
Normal file
75
lib/python/qmk/cli/generate/community_modules.py
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
from argcomplete.completers import FilesCompleter
|
||||
|
||||
from milc import cli
|
||||
from milc.attrdict import AttrDict
|
||||
|
||||
import qmk.path
|
||||
from qmk.commands import dump_lines, parse_configurator_json
|
||||
from qmk.constants import GPL2_HEADER_C_LIKE, GENERATED_HEADER_C_LIKE
|
||||
|
||||
class ModuleAPI(AttrDict):
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__()
|
||||
for key, value in kwargs.items():
|
||||
self[key] = value
|
||||
|
||||
MODULE_API_LIST = [
|
||||
ModuleAPI(ret_type='void', name='keyboard_pre_init', args='void', call_params='', ret_val=None),
|
||||
ModuleAPI(ret_type='void', name='keyboard_post_init', args='void', call_params='', ret_val=None),
|
||||
ModuleAPI(ret_type='void', name='housekeeping_task', args='void', call_params='', ret_val=None),
|
||||
ModuleAPI(ret_type='bool', name='process_record', args='uint16_t keycode, keyrecord_t *record', call_params='keycode, record', ret_val='true'),
|
||||
]
|
||||
|
||||
@cli.argument('-o', '--output', arg_only=True, type=qmk.path.normpath, help='File to write to')
|
||||
@cli.argument('-q', '--quiet', arg_only=True, action='store_true', help="Quiet mode, only output error messages")
|
||||
@cli.argument('filename', type=qmk.path.FileType('r'), arg_only=True, completer=FilesCompleter('.json'), help='Configurator JSON file')
|
||||
@cli.subcommand('Creates a community_modules.h from a keymap.json file.')
|
||||
def generate_community_modules_h(cli):
|
||||
"""Creates a community_modules.h from a keymap.json file
|
||||
"""
|
||||
if cli.args.output and cli.args.output.name == '-':
|
||||
cli.args.output = None
|
||||
|
||||
lines = [GPL2_HEADER_C_LIKE, GENERATED_HEADER_C_LIKE, '#pragma once', '']
|
||||
keymap_json = parse_configurator_json(cli.args.filename)
|
||||
if keymap_json and 'modules' in keymap_json:
|
||||
for module in keymap_json['modules']:
|
||||
for api in MODULE_API_LIST:
|
||||
lines.append(f'{api.ret_type} {api.name}_{module}({api.args});')
|
||||
dump_lines(cli.args.output, lines, cli.args.quiet)
|
||||
|
||||
@cli.argument('-o', '--output', arg_only=True, type=qmk.path.normpath, help='File to write to')
|
||||
@cli.argument('-q', '--quiet', arg_only=True, action='store_true', help="Quiet mode, only output error messages")
|
||||
@cli.argument('filename', type=qmk.path.FileType('r'), arg_only=True, completer=FilesCompleter('.json'), help='Configurator JSON file')
|
||||
@cli.subcommand('Creates a community_modules.c from a keymap.json file.')
|
||||
def generate_community_modules_c(cli):
|
||||
"""Creates a community_modules.c from a keymap.json file
|
||||
"""
|
||||
if cli.args.output and cli.args.output.name == '-':
|
||||
cli.args.output = None
|
||||
|
||||
lines = [GPL2_HEADER_C_LIKE, GENERATED_HEADER_C_LIKE, '#include QMK_KEYBOARD_H', '#include "community_modules.h"']
|
||||
keymap_json = parse_configurator_json(cli.args.filename)
|
||||
if keymap_json and 'modules' in keymap_json:
|
||||
for module in keymap_json['modules']:
|
||||
for api in MODULE_API_LIST:
|
||||
lines.append('')
|
||||
lines.append(f'__attribute__((weak)) {api.ret_type} {api.name}_{module}({api.args}) {{ ')
|
||||
if api.ret_val:
|
||||
lines.append(f' return {api.ret_val};')
|
||||
lines.append('}')
|
||||
|
||||
for api in MODULE_API_LIST:
|
||||
lines.append('')
|
||||
lines.append(f'{api.ret_type} {api.name}_modules({api.args}) {{')
|
||||
if api.ret_type == 'bool':
|
||||
lines.append(' return true')
|
||||
for module in keymap_json['modules']:
|
||||
if api.ret_type == 'bool':
|
||||
lines.append(f' && {api.name}_{module}({api.call_params})')
|
||||
else:
|
||||
lines.append(f' {api.name}_{module}({api.call_params});')
|
||||
if api.ret_type == 'bool':
|
||||
lines.append(' ;')
|
||||
lines.append('}')
|
||||
dump_lines(cli.args.output, lines, cli.args.quiet)
|
||||
|
|
@ -55,6 +55,7 @@ def process_mapping_rule(kb_info_json, rules_key, info_dict):
|
|||
def generate_rules_mk(cli):
|
||||
"""Generates a rules.mk file from info.json.
|
||||
"""
|
||||
user_keymap = None
|
||||
converter = None
|
||||
# Determine our keyboard/keymap
|
||||
if cli.args.filename:
|
||||
|
|
@ -99,6 +100,14 @@ def generate_rules_mk(cli):
|
|||
if converter:
|
||||
rules_mk_lines.append(generate_rule('CONVERT_TO', converter))
|
||||
|
||||
if user_keymap and 'modules' in user_keymap:
|
||||
for module in user_keymap['modules']:
|
||||
rules_mk_lines.append('')
|
||||
rules_mk_lines.append(f'COMMUNITY_MODULES += {module}')
|
||||
rules_mk_lines.append(f'OPT_DEFS += -DMODULE_{module.upper()}=TRUE')
|
||||
rules_mk_lines.append(f'VPATH += modules/{module}')
|
||||
rules_mk_lines.append(f'include modules/{module}/rules.mk')
|
||||
|
||||
# Show the results
|
||||
dump_lines(cli.args.output, rules_mk_lines)
|
||||
|
||||
|
|
|
|||
|
|
@ -334,33 +334,6 @@ def write_json(keyboard, keymap, layout, layers, macros=None):
|
|||
return write_file(keymap_file, keymap_content)
|
||||
|
||||
|
||||
def write(keymap_json):
|
||||
"""Generate the `keymap.c` and write it to disk.
|
||||
|
||||
Returns the filename written to.
|
||||
|
||||
`keymap_json` should be a dict with the following keys:
|
||||
keyboard
|
||||
The name of the keyboard
|
||||
|
||||
keymap
|
||||
The name of the keymap
|
||||
|
||||
layout
|
||||
The LAYOUT macro this keymap uses.
|
||||
|
||||
layers
|
||||
An array of arrays describing the keymap. Each item in the inner array should be a string that is a valid QMK keycode.
|
||||
|
||||
macros
|
||||
A list of macros for this keymap.
|
||||
"""
|
||||
keymap_content = generate_c(keymap_json)
|
||||
keymap_file = qmk.path.keymaps(keymap_json['keyboard'])[0] / keymap_json['keymap'] / 'keymap.c'
|
||||
|
||||
return write_file(keymap_file, keymap_content)
|
||||
|
||||
|
||||
def locate_keymap(keyboard, keymap, force_layout=None):
|
||||
"""Returns the path to a keymap for a specific keyboard.
|
||||
"""
|
||||
|
|
|
|||
Loading…
Reference in a new issue