#!/usr/bin/python
import re
import sys
def comment_remover(text):
def replacer(match):
s = match.group(0)
if s.startswith('/') or s.startswith('#'):
return " " # note: a space and not an empty string
else:
return s
pattern = re.compile(r'//.*?$|#.*?$|/\*.*?\*/|\'(?:\\.|[^\\\'])*\'|"(?:\\.|[^\\"])*"', re.DOTALL | re.MULTILINE)
return re.sub(pattern, replacer, text)
if len(sys.argv) < 3:
print('Usage: ' + sys.argv[0] + ' INFILE OUTFILE\n')
sys.exit(-1)
input = open(sys.argv[1], "r")
with input:
uncommented = comment_remover(input.read())
for char in '><\':|][!~*./()+-"{};,=':
tmp_str = ' ' + char + ' '
uncommented = tmp_str.join(uncommented.split(char))
uncommented_lines = uncommented.split('\n')
lines = list()
for line in uncommented_lines:
lines += re.split(' ', line.strip())
while "" in lines:
lines.remove("")
# lines now contains the preprocessed input - comments and preprocessor tokens stipped, and then tokenized
# lines is a list of tokens, we now scan for enums
output = open(sys.argv[2], "w")
with output:
def write_header():
output.write('// This code is generated, DO NOT EDIT.\n')
output.write('// Instead, edit ' + sys.argv[1] + ' and rerun ' + sys.argv[0] + '\n')
output.write('\n')
output.write('#pragma once\n')
output.write('\n')
output.write('#include "EnumMapping.hpp"\n')
def write_prolog(enum):
output.write('\n')
output.write('// ' + enum + '\n')
# output.write('template <>\n')
# output.write('const enum_map<' + enum + '>& enum_mapping()\n')
# output.write('const enum_map& enum_mapping(' + enum + ' e = static_cast<' + enum + '>(0))\n')
output.write('const enum_map& enum_mapping(' + enum + ')\n')
output.write('{\n')
# output.write(' static enum_map<' + enum + '> mapping("' + enum + '");\n')
output.write(' static enum_map mapping("' + enum + '");\n')
output.write(' if (!mapping.inited)\n')
output.write(' {\n')
def write_entry(enum, line):
output.write(' mapping.addMapping(' + enum + '::' + line + ', "' + line + '");\n')
def write_epilog():
output.write(' mapping.inited = true;\n')
output.write(' }\n')
output.write(' return mapping;\n')
output.write('}\n')
output.write('RegisterEnum register_' + enum + '("' + enum + '", enum_mapping(static_cast<' + enum + '>(0)));\n')
def write_footer():
output.write('\n')
enum = '???'
state = 0 # not inside an enum
write_header()
for line in lines:
# output.write('-' + line + '-\n')
if state == 0:
if line.startswith('"'):
state = 6
elif line == 'enum':
state = 1
elif state == 1:
if line == '{':
enum = 'anonymous'
state = 3
elif line != 'class':
enum = line
state = 2
else:
continue
write_prolog(enum)
elif state == 2:
if line == '{':
state = 3
elif state == 3:
if line == '}':
write_epilog()
state = 0
else:
write_entry(enum, line)
state = 4
elif state == 4:
if line.startswith('"'):
state = 5
elif line == '}':
write_epilog()
state = 0
elif line == ',':
state = 3
elif state == 5:
if line.endswith('"'):
state = 4
elif state == 6:
if line.endswith('"'):
state = 0
write_footer()