comparison en/examples/run-example @ 71:ddf533d41c09

Propagate errors correctly.
author Bryan O'Sullivan <bos@serpentine.com>
date Tue, 29 Aug 2006 22:25:18 -0700
parents 365b41b6a15e
children 12df31afb4e1
comparison
equal deleted inserted replaced
70:365b41b6a15e 71:ddf533d41c09
25 return s 25 return s
26 26
27 class example: 27 class example:
28 shell = '/usr/bin/env bash' 28 shell = '/usr/bin/env bash'
29 prompt = '__run_example_prompt__\n' 29 prompt = '__run_example_prompt__\n'
30 pi_re = re.compile('#\$\s*(name):\s*(.*)$') 30 pi_re = re.compile(r'#\$\s*(name):\s*(.*)$')
31 31
32 def __init__(self, name): 32 def __init__(self, name):
33 self.name = name 33 self.name = name
34 34
35 def parse(self): 35 def parse(self):
97 print >> sys.stderr, '%s: %s' % (cmdline[0], err.strerror) 97 print >> sys.stderr, '%s: %s' % (cmdline[0], err.strerror)
98 sys.stderr.flush() 98 sys.stderr.flush()
99 os._exit(0) 99 os._exit(0)
100 self.cfp = os.fdopen(fd, 'w+') 100 self.cfp = os.fdopen(fd, 'w+')
101 try: 101 try:
102 # setup env and prompt 102 clean_exit = True
103 self.sendreceive('source %s\n\n' % rcfile) 103 try:
104 for hunk in self.parse(): 104 # setup env and prompt
105 # is this line a processing instruction? 105 self.sendreceive('source %s\n\n' % rcfile)
106 m = self.pi_re.match(hunk) 106 for hunk in self.parse():
107 if m: 107 # is this line a processing instruction?
108 pi, rest = m.groups() 108 m = self.pi_re.match(hunk)
109 if pi == 'name': 109 if m:
110 self.status('.') 110 pi, rest = m.groups()
111 out = rest 111 if pi == 'name':
112 assert os.sep not in out 112 self.status('.')
113 if out: 113 out = rest
114 ofp = open('%s.%s.out' % (self.name, out), 'w') 114 assert os.sep not in out
115 else: 115 if out:
116 ofp = None 116 ofp = open('%s.%s.out' % (self.name, out), 'w')
117 elif hunk.strip(): 117 else:
118 # it's something we should execute 118 ofp = None
119 output = self.sendreceive(hunk) 119 elif hunk.strip():
120 if not ofp: 120 # it's something we should execute
121 continue 121 output = self.sendreceive(hunk)
122 # first, print the command we ran 122 if not ofp:
123 if not hunk.startswith('#'): 123 continue
124 nl = hunk.endswith('\n') 124 # first, print the command we ran
125 hunk = ('$ \\textbf{%s}' % 125 if not hunk.startswith('#'):
126 tex_escape(hunk.rstrip('\n'))) 126 nl = hunk.endswith('\n')
127 if nl: hunk += '\n' 127 hunk = ('$ \\textbf{%s}' %
128 ofp.write(hunk) 128 tex_escape(hunk.rstrip('\n')))
129 # then its output 129 if nl: hunk += '\n'
130 ofp.write(tex_escape(output)) 130 ofp.write(hunk)
131 self.status('\n') 131 # then its output
132 open(self.name + '.run', 'w') 132 ofp.write(tex_escape(output))
133 self.status('\n')
134 open(self.name + '.run', 'w')
135 except:
136 clean_exit = False
137 raise
133 finally: 138 finally:
134 try: 139 if clean_exit:
135 output = self.sendreceive('exit\n') 140 try:
136 if ofp: 141 output = self.sendreceive('exit\n')
137 ofp.write(output) 142 if ofp:
138 self.cfp.close() 143 ofp.write(output)
139 except IOError: 144 self.cfp.close()
140 pass 145 except IOError:
146 pass
141 os.kill(pid, signal.SIGTERM) 147 os.kill(pid, signal.SIGTERM)
142 os.wait() 148 time.sleep(0.1)
149 os.kill(pid, signal.SIGKILL)
150 pid, rc = os.wait()
151 if rc:
152 if os.WIFEXITED(rc):
153 print >> sys.stderr, '(exit %s)' % os.WEXITSTATUS(rc)
154 elif os.WIFSIGNALED(rc):
155 print >> sys.stderr, '(signal %s)' % os.WTERMSIG(rc)
143 shutil.rmtree(tmpdir) 156 shutil.rmtree(tmpdir)
157 return rc
144 158
145 def main(path='.'): 159 def main(path='.'):
146 args = sys.argv[1:] 160 args = sys.argv[1:]
161 errs = 0
147 if args: 162 if args:
148 for a in args: 163 for a in args:
149 example(a).run() 164 if example(a).run():
150 return 165 errs += 1
166 return errs
151 for name in os.listdir(path): 167 for name in os.listdir(path):
152 if name == 'run-example' or name.startswith('.'): continue 168 if name == 'run-example' or name.startswith('.'): continue
153 if name.endswith('.out') or name.endswith('~'): continue 169 if name.endswith('.out') or name.endswith('~'): continue
154 if name.endswith('.run'): continue 170 if name.endswith('.run'): continue
155 pathname = os.path.join(path, name) 171 pathname = os.path.join(path, name)
156 st = os.lstat(pathname) 172 st = os.lstat(pathname)
157 if stat.S_ISREG(st.st_mode) and st.st_mode & 0111: 173 if stat.S_ISREG(st.st_mode) and st.st_mode & 0111:
158 example(pathname).run() 174 if example(pathname).run():
175 errs += 1
159 print >> open(os.path.join(path, '.run'), 'w'), time.asctime() 176 print >> open(os.path.join(path, '.run'), 'w'), time.asctime()
177 return errs
160 178
161 if __name__ == '__main__': 179 if __name__ == '__main__':
162 main() 180 sys.exit(main())