1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
|
#!/usr/bin/env python
import argparse
import io
import os
import re
re_token = re.compile(r'^CT_(\w+),')
re_version = re.compile(r'.*UNCRUSTIFY_VERSION\s*"Uncrustify-([^"]+)"')
re_option = re.compile(r'extern (Bounded)?Option<[^>]+>')
re_enum_decl = re.compile(r'enum class (\w+)( *// *<(\w+)>)?')
re_enum_value = re.compile(r'(\w+)(?= *([,=]|//|$))')
re_aliases = re.compile(r'UNC_OPTVAL_ALIAS\(([^)]+)\)')
version = '0.0'
options = set()
values = set()
tokens = set()
root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
script = os.path.relpath(__file__, root)
# -----------------------------------------------------------------------------
def read_enum(f):
global values
for line in iter(f.readline, ''):
line = line.strip()
if line.startswith('{'):
for line in iter(f.readline, ''):
line = line.strip()
if line.startswith('};'):
return
if 'UNC_INTERNAL' in line:
return
if 'UNC_CONVERT_INTERNAL' in line:
return
mv = re_enum_value.match(line)
if mv is not None:
values.add(mv.group(1).lower())
# -----------------------------------------------------------------------------
def write_items(out, items):
for i in sorted(items):
out.write(u' <item>{}</item>\n'.format(i))
# -----------------------------------------------------------------------------
def write_options(out, args):
write_items(out, options)
# -----------------------------------------------------------------------------
def write_values(out, args):
write_items(out, values)
# -----------------------------------------------------------------------------
def write_tokens(out, args):
write_items(out, tokens)
# -----------------------------------------------------------------------------
def main():
parser = argparse.ArgumentParser(description='Generate uncrustify.xml')
parser.add_argument('output', type=str,
help='location of uncrustify.xml to write')
parser.add_argument('template', type=str,
help='location of uncrustify.xml.in ' +
'to use as template')
parser.add_argument('version', type=str,
help='location of uncrustify_version.h to read')
parser.add_argument('options', type=str,
help='location of options.h to read')
parser.add_argument('optvals', type=str,
help='location of option.h to read')
parser.add_argument('tokens', type=str,
help='location of token_enum.h to read')
args = parser.parse_args()
# Read version
with io.open(args.version, 'rt', encoding='utf-8') as f:
global version
for line in iter(f.readline, ''):
line = line.strip()
mv = re_version.match(line)
if mv:
version = mv.group(1)
# Read options
with io.open(args.options, 'rt', encoding='utf-8') as f:
global options
for line in iter(f.readline, ''):
line = line.strip()
if re_option.match(line):
n, d = f.readline().split(';')
options.add(n)
# Read option values
with io.open(args.optvals, 'rt', encoding='utf-8') as f:
global values
for line in iter(f.readline, ''):
line = line.strip()
if re_enum_decl.match(line):
read_enum(f)
continue
ma = re_aliases.match(line)
if ma:
for v in ma.group(1).split(',')[2:]:
v = v.strip()[1:-1]
values.add(v)
# Read tokens
with io.open(args.tokens, 'rt', encoding='utf-8') as f:
global tokens
for line in iter(f.readline, ''):
line = line.strip()
m = re_token.match(line)
if m and not m.group(1).endswith(u'_'):
tokens.add(m.group(1).lower())
# Declare replacements
replacements = {
u'##OPTION_KEYWORDS##': write_options,
u'##VALUE_KEYWORDS##': write_values,
u'##TOKEN_TYPE_KEYWORDS##': write_tokens,
}
# Write output file
with io.open(args.output, 'wt', encoding='utf-8') as out:
with io.open(args.template, 'rt', encoding='utf-8') as t:
for line in t:
directive = line.strip()
if directive in replacements:
replacements[directive](out, args)
else:
if '##VERSION##' in line:
line = line.replace('##VERSION##', version)
out.write(line)
# %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if __name__ == '__main__':
main()
|