aboutsummaryrefslogtreecommitdiffhomepage
path: root/internalize_scripts.py
blob: 68a2f64804cc457c2460605f8e49059d6b7420b2 (plain)
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
#!/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()