#!/usr/bin/python import string, sys, os.path escapes = {} escapes['\a'] = r'\a' escapes['\b'] = r'\b' escapes['\f'] = r'\f' escapes['\n'] = r'\n' escapes['\r'] = r'\r' #escapes['\t'] = r'\t' # Let's replace tabs with four spaces # so the text looks nicely indented in the C source escapes['\t'] = r' ' escapes['\v'] = r'\v' # escapes['\''] = r'\'' escapes['\"'] = r'\"' escapes['\\'] = r'\\' def escape(c): if c in escapes: return (escapes[c], False) elif c not in string.printable: return ("\\x%x" % ord(c), True) else: return (c, False) def stringize(line): newline = '"' was_escape = False for c in line: # Avoid an issue where characters after a hexadecimal escape are treated as part of that escape # by adding two quotes if was_escape and c in string.hexdigits: newline += '""' chars, was_escape = escape(c) newline += chars newline += '"' return newline class cfunc: def __init__(self, type, name, lines): self.type = type self.name = name self.lines = lines def cdef(self): result = "" result += "static const char * const %s = \n\t" % self.cfunc_name() result += '\n\t'.join(self.lines) result += ';\n' return result def cfunc_name(self): # Translate - and . to underscore translator = string.maketrans('-.', '__') munged_name = string.translate(self.name, translator) return "%s_%s" % (self.type, munged_name) TYPES = ['function', 'completion'] type_to_funcs = dict((t, []) for t in TYPES) for file in sys.argv[1:]: fd = open(file, 'r') newlines = [] for line in fd: newlines.append(stringize(line)) fd.close() dirname = os.path.dirname(file) # Try to figure out the file type (completion or function) matches = [dir in dirname for dir in TYPES] if matches.count(True) is not 1: print "Cannot determine the type of the file at path %s" % file sys.exit(-1) type = TYPES[matches.index(True)] name = os.path.basename(file) name, ext = os.path.splitext(name) newfunc = cfunc(type, name, newlines) type_to_funcs[type].append(newfunc) # Sort our functions by name for funcs in type_to_funcs.itervalues(): funcs.sort(key=cfunc.cfunc_name) # Output our header fd = open('builtin_scripts.h', 'w') fd.write('/* This file is generated by internalize_scripts.py */\n\n') fd.write("""struct builtin_script_t { const wchar_t *name; const char *def; };""") fd.write('\n') for type in TYPES: funcs = type_to_funcs[type] fd.write('\n') fd.write('extern const struct builtin_script_t internal_%s_scripts[%d];' % (type, len(funcs))) fd.write('\n') fd.close() # Output the function definitions fd = open('builtin_scripts.cpp', 'w') fd.write('/* This file is generated by internalize_scripts.py */\n\n') fd.write('#include "builtin_scripts.h"\n\n') for type in TYPES: for func in type_to_funcs[type]: fd.write(func.cdef()) fd.write('\n') # Output the refs for type in TYPES: funcs = type_to_funcs[type] func_refs = ["{L%s, %s}" % (stringize(func.name), func.cfunc_name()) for func in funcs] fd.write('const struct builtin_script_t internal_%s_scripts[%d] =\n' % (type, len(funcs))) fd.write('{\n\t') fd.write(',\n\t'.join(func_refs)) fd.write('\n};\n') fd.close()