-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathweave.py
125 lines (111 loc) · 3.11 KB
/
weave.py
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
#! /usr/bin/python3
# Converts templates into files
import sys
from io import StringIO
class Process:
def __init__(self):
self.current_output = None
self.current_file = None
self.current_storage = None
self.storages = {}
def finish_storing(self):
if self.current_storage is not None:
self.storages[self.current_storage] = self.current_file.getvalue()
self.current_file = self.current_output
self.current_storage = None
def handle_command(self, command):
ix = command.find(' ')
if ix != -1:
arguments = command[ix + 1:]
command = command[:ix]
else:
arguments = ''
if command == 'comment':
return
if command in {'store', 'return'}:
self.finish_storing()
if command == 'return':
pass
elif command == 'store':
self.current_file = StringIO()
self.current_storage = arguments
elif command == 'load':
print(self.storages[arguments], file = self.current_file)
else:
# fallback
print(self.storages[command], file = self.current_file)
#self.include_generated_text(command)
def prefix_line(self):
print("/* This file is automatically generated */", file = self.current_file)
def process_file(self, infile, outfile):
self.current_file = self.current_output = outfile
self.prefix_line()
for line in infile:
if line.endswith('\n'):
line = line[:-1]
if line.startswith('@@'):
print(line[1:], file = self.current_file)
elif line.startswith('@'):
self.handle_command(line[1:].strip())
else:
print(line, file = self.current_file)
self.finish_storing()
def main():
filenames = []
latest = None
i = 1
while i < len(sys.argv):
arg = sys.argv[i]
if arg.startswith('-'):
if arg.startswith('-d'):
if len(arg) == 2:
i += 1
if i >= len(sys.argv):
print("Error: expected command after -t flag", file = sys.stderr)
exit(1)
cmd = sys.argv[i]
else:
cmd = arg[2:]
latest = [cmd, 'declare']
filenames.append(latest)
elif arg == '-h':
print(f"{sys.argv[0]} {{-d <DECLARATION FILENAME>|<INPUT FILENAME> (-o <OUTPUT FILENAME>)}}")
exit(0)
elif arg == '-o':
if len(arg) == 2:
i += 1
if i >= len(sys.argv):
print("Error: expected file name after -o flag", file = sys.stderr)
exit(1)
fn = sys.argv[i]
arg = '-o ' + fn
else:
fn = arg[2:]
if latest is None or latest[1] is not None:
print(f"Error: expected input file before {arg}", file = sys.stderr)
exit(1)
else:
latest[1] = ('-o', fn)
else:
print(f"Error: unknown flag {arg}", file = sys.stderr)
exit(1)
else:
latest = [arg, None]
filenames.append(latest)
i += 1
process = Process()
for infilename, modifier in filenames:
if type(modifier) is tuple and modifier[0] == '-o':
outfilename = modifier[1]
elif infilename.endswith('.t'):
outfilename = infilename[:-2]
else:
outfilename = infilename + '.out'
with open(infilename, 'r') as infile:
if modifier == 'declare':
process.process_file(infile, StringIO()) # ignores output
else:
with open(outfilename, 'w') as outfile:
process.process_file(infile, outfile)
if __name__ == '__main__':
main()