diff options
Diffstat (limited to 'lib/python/qmk/cli/generate/config_h.py')
-rwxr-xr-x | lib/python/qmk/cli/generate/config_h.py | 152 |
1 files changed, 152 insertions, 0 deletions
diff --git a/lib/python/qmk/cli/generate/config_h.py b/lib/python/qmk/cli/generate/config_h.py new file mode 100755 index 0000000000..7ddad745d1 --- /dev/null +++ b/lib/python/qmk/cli/generate/config_h.py @@ -0,0 +1,152 @@ +"""Used by the make system to generate info_config.h from info.json. +""" +from pathlib import Path + +from dotty_dict import dotty +from milc import cli + +from qmk.decorators import automagic_keyboard, automagic_keymap +from qmk.info import _json_load, info_json +from qmk.path import is_keyboard, normpath + + +def direct_pins(direct_pins): + """Return the config.h lines that set the direct pins. + """ + rows = [] + + for row in direct_pins: + cols = ','.join(map(str, [col or 'NO_PIN' for col in row])) + rows.append('{' + cols + '}') + + col_count = len(direct_pins[0]) + row_count = len(direct_pins) + + return """ +#ifndef MATRIX_COLS +# define MATRIX_COLS %s +#endif // MATRIX_COLS + +#ifndef MATRIX_ROWS +# define MATRIX_ROWS %s +#endif // MATRIX_ROWS + +#ifndef DIRECT_PINS +# define DIRECT_PINS {%s} +#endif // DIRECT_PINS +""" % (col_count, row_count, ','.join(rows)) + + +def pin_array(define, pins): + """Return the config.h lines that set a pin array. + """ + pin_num = len(pins) + pin_array = ', '.join(map(str, [pin or 'NO_PIN' for pin in pins])) + + return f""" +#ifndef {define}S +# define {define}S {pin_num} +#endif // {define}S + +#ifndef {define}_PINS +# define {define}_PINS {{ {pin_array} }} +#endif // {define}_PINS +""" + + +def matrix_pins(matrix_pins): + """Add the matrix config to the config.h. + """ + pins = [] + + if 'direct' in matrix_pins: + pins.append(direct_pins(matrix_pins['direct'])) + + if 'cols' in matrix_pins: + pins.append(pin_array('MATRIX_COL', matrix_pins['cols'])) + + if 'rows' in matrix_pins: + pins.append(pin_array('MATRIX_ROW', matrix_pins['rows'])) + + return '\n'.join(pins) + + +@cli.argument('-o', '--output', arg_only=True, type=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('-kb', '--keyboard', help='Keyboard to generate config.h for.') +@cli.subcommand('Used by the make system to generate info_config.h from info.json', hidden=True) +@automagic_keyboard +@automagic_keymap +def generate_config_h(cli): + """Generates the info_config.h file. + """ + # Determine our keyboard(s) + if not cli.config.generate_config_h.keyboard: + cli.log.error('Missing paramater: --keyboard') + cli.subcommands['info'].print_help() + return False + + if not is_keyboard(cli.config.generate_config_h.keyboard): + cli.log.error('Invalid keyboard: "%s"', cli.config.generate_config_h.keyboard) + return False + + # Build the info_config.h file. + kb_info_json = dotty(info_json(cli.config.generate_config_h.keyboard)) + info_config_map = _json_load(Path('data/mappings/info_config.json')) + + config_h_lines = ['/* This file was generated by `qmk generate-config-h`. Do not edit or copy.' ' */', '', '#pragma once'] + + # Iterate through the info_config map to generate basic things + for config_key, info_dict in info_config_map.items(): + info_key = info_dict['info_key'] + key_type = info_dict.get('value_type', 'str') + to_config = info_dict.get('to_config', True) + + if not to_config: + continue + + try: + config_value = kb_info_json[info_key] + except KeyError: + continue + + if key_type.startswith('array'): + config_h_lines.append('') + config_h_lines.append(f'#ifndef {config_key}') + config_h_lines.append(f'# define {config_key} {{ {", ".join(map(str, config_value))} }}') + config_h_lines.append(f'#endif // {config_key}') + elif key_type == 'bool': + if config_value: + config_h_lines.append('') + config_h_lines.append(f'#ifndef {config_key}') + config_h_lines.append(f'# define {config_key}') + config_h_lines.append(f'#endif // {config_key}') + elif key_type == 'mapping': + for key, value in config_value.items(): + config_h_lines.append('') + config_h_lines.append(f'#ifndef {key}') + config_h_lines.append(f'# define {key} {value}') + config_h_lines.append(f'#endif // {key}') + else: + 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}') + + if 'matrix_pins' in kb_info_json: + config_h_lines.append(matrix_pins(kb_info_json['matrix_pins'])) + + # Show the results + 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.name + '.bak') + cli.args.output.write_text(config_h) + + if not cli.args.quiet: + cli.log.info('Wrote info_config.h to %s.', cli.args.output) + + else: + print(config_h) |