mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-26 12:53:13 +00:00
125 lines
3.3 KiB
Python
Executable file
125 lines
3.3 KiB
Python
Executable file
#!/usr/bin/env 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 {0} = \n\t".format(self.cfunc_name())
|
|
result += '\n\t'.join(self.lines)
|
|
result += ';\n'
|
|
return result
|
|
|
|
def cfunc_name(self):
|
|
# Translate - and . to underscore
|
|
try: #Python 2
|
|
translator = string.maketrans('-.', '__')
|
|
munged_name = string.translate(self.name, translator)
|
|
except AttributeError: #Python 3
|
|
translator = "".maketrans('-.', '__')
|
|
munged_name = self.name.translate(translator)
|
|
return "{0}_{1}".format(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 {0}".format(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.values():
|
|
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_{0}_scripts[{1}];'.format(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 = ["{0}L{1}, {2}{3}".format("{", stringize(func.name), func.cfunc_name(), "}") for func in funcs]
|
|
fd.write('const struct builtin_script_t internal_{0}_scripts[{1}] =\n'.format(type, len(funcs)))
|
|
fd.write('{\n\t')
|
|
fd.write(',\n\t'.join(func_refs))
|
|
fd.write('\n};\n')
|
|
fd.close()
|