aboutsummaryrefslogtreecommitdiffstats
path: root/src/libs/3rdparty/syntax-highlighting/data/generators/generate-cmake-syntax.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/3rdparty/syntax-highlighting/data/generators/generate-cmake-syntax.py')
-rw-r--r--src/libs/3rdparty/syntax-highlighting/data/generators/generate-cmake-syntax.py151
1 files changed, 151 insertions, 0 deletions
diff --git a/src/libs/3rdparty/syntax-highlighting/data/generators/generate-cmake-syntax.py b/src/libs/3rdparty/syntax-highlighting/data/generators/generate-cmake-syntax.py
new file mode 100644
index 0000000000..61f60a682d
--- /dev/null
+++ b/src/libs/3rdparty/syntax-highlighting/data/generators/generate-cmake-syntax.py
@@ -0,0 +1,151 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+#
+# Generate Kate syntax file for CMake
+#
+# Copyright (c) 2017, Alex Turbov <i.zaufi@gmail.com>
+#
+# To install prerequisites:
+#
+# $ pip install --user click jinja2 yaml
+#
+# To use:
+#
+# $ ./generate-cmake-syntax.py cmake.yaml > ../syntax/cmake.xml
+#
+import click
+import jinja2
+import pathlib
+import re
+import yaml
+
+import pprint
+
+
+_TEMPLATED_NAME = re.compile('<[^>]+>')
+_PROPERTY_KEYS = [
+ 'global-properties'
+ , 'directory-properties'
+ , 'target-properties'
+ , 'source-properties'
+ , 'test-properties'
+ , 'cache-properties'
+ , 'install-properties'
+ ]
+_KW_RE_LIST = ['kw', 're']
+
+
+def try_transform_placeholder_string_to_regex(name):
+ '''
+ NOTE Some placeholders are not IDs, but numbers...
+ `CMAKE_MATCH_<N>` 4 example
+ '''
+ m = _TEMPLATED_NAME.split(name)
+ if 'CMAKE_MATCH_' in m:
+ return '\\bCMAKE_MATCH_[0-9]+\\b'
+
+ return '\\b{}\\b'.format('&id_re;'.join(list(m))) if 1 < len(m) else name
+
+
+def partition_iterable(fn, iterable):
+ true, false = [], []
+ for i in iterable:
+ (false, true)[int(fn(i))].append(i)
+ return true, false
+
+
+def _transform_command_set(cmd, list_name):
+ args, args_re = partition_iterable(lambda x: _TEMPLATED_NAME.search(x) is None, cmd[list_name])
+ del cmd[list_name]
+ list_name = list_name.replace('-', '_')
+
+ cmd[list_name] = {k: sorted(set(v)) for k, v in zip(_KW_RE_LIST, [args, args_re])}
+ cmd[list_name]['re'] = [*map(lambda x: try_transform_placeholder_string_to_regex(x), args_re)]
+
+ return cmd
+
+
+def transform_command(cmd):
+ can_be_nulary = True
+
+ if 'name' not in cmd:
+ raise RuntimeError('Command have no name')
+
+ if 'named-args' in cmd:
+ new_cmd = _transform_command_set(cmd, 'named-args')
+ assert new_cmd == cmd
+ can_be_nulary = False
+
+ if 'special-args' in cmd:
+ new_cmd = _transform_command_set(cmd, 'special-args')
+ assert new_cmd == cmd
+ can_be_nulary = False
+
+ if 'property-args' in cmd:
+ new_cmd = _transform_command_set(cmd, 'property-args')
+ assert new_cmd == cmd
+ can_be_nulary = False
+
+ cmd['nested_parentheses'] = cmd['nested-parentheses?'] if 'nested-parentheses?' in cmd else False
+
+ if 'nulary?' in cmd and cmd['nulary?'] and not can_be_nulary:
+ raise RuntimeError('Command `{}` w/ args declared nulary!?'.format(cmd['name']))
+
+ return cmd
+
+
+#BEGIN Jinja filters
+
+def cmd_is_nulary(cmd):
+ assert not ('named-args' in cmd or 'special-args' in cmd or 'property-args' in cmd)
+ return 'nulary?' in cmd and cmd['nulary?']
+
+#END Jinja filters
+
+
+@click.command()
+@click.argument('input_yaml', type=click.File('r'))
+@click.argument('template', type=click.File('r'), default='./cmake.xml.tpl')
+def cli(input_yaml, template):
+ data = yaml.load(input_yaml)
+
+ # Partition `variables` list into "pure" words and regexes to match
+ data['variables'] = {
+ k: sorted(set(v)) for k, v in zip(_KW_RE_LIST, [*partition_iterable(lambda x: _TEMPLATED_NAME.search(x) is None, data['variables'])])
+ }
+ data['variables']['re'] = [*map(lambda x: try_transform_placeholder_string_to_regex(x), data['variables']['re'])]
+
+ # Transform properties and make all-properties list
+ data['properties'] = {}
+ for prop in _PROPERTY_KEYS:
+ python_prop_list_name = prop.replace('-', '_')
+ props, props_re = partition_iterable(lambda x: _TEMPLATED_NAME.search(x) is None, data[prop])
+ del data[prop]
+
+ data['properties'][python_prop_list_name] = {k: sorted(set(v)) for k, v in zip(_KW_RE_LIST, [props, props_re])}
+ data['properties'][python_prop_list_name]['re'] = [*map(lambda x: try_transform_placeholder_string_to_regex(x), props_re)]
+
+
+ data['properties']['kinds'] = [*map(lambda name: name.replace('-', '_'), _PROPERTY_KEYS)]
+
+ # Make all commands list
+ data['commands'] = [*map(lambda cmd: transform_command(cmd), data['scripting-commands'] + data['project-commands'] + data['ctest-commands'])]
+
+ data['generator_expressions'] = data['generator-expressions']
+
+
+ env = jinja2.Environment(
+ keep_trailing_newline=True
+ )
+
+ # Register convenience filters
+ env.tests['nulary'] = cmd_is_nulary
+
+ tpl = env.from_string(template.read())
+ result = tpl.render(data)
+ print(result)
+
+
+if __name__ == '__main__':
+ cli()
+ # TODO Handle execptions and show errors