changeset 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
files en/examples/run-example
diffstat 1 files changed, 62 insertions(+), 44 deletions(-) [+]
line wrap: on
line diff
--- a/en/examples/run-example	Tue Aug 08 14:13:28 2006 -0700
+++ b/en/examples/run-example	Tue Aug 29 22:25:18 2006 -0700
@@ -27,7 +27,7 @@
 class example:
     shell = '/usr/bin/env bash'
     prompt = '__run_example_prompt__\n'
-    pi_re = re.compile('#\$\s*(name):\s*(.*)$')
+    pi_re = re.compile(r'#\$\s*(name):\s*(.*)$')
     
     def __init__(self, name):
         self.name = name
@@ -99,55 +99,71 @@
                 os._exit(0)
         self.cfp = os.fdopen(fd, 'w+')
         try:
-            # setup env and prompt
-            self.sendreceive('source %s\n\n' % rcfile)
-            for hunk in self.parse():
-                # is this line a processing instruction?
-                m = self.pi_re.match(hunk)
-                if m:
-                    pi, rest = m.groups()
-                    if pi == 'name':
-                        self.status('.')
-                        out = rest
-                        assert os.sep not in out
-                        if out:
-                            ofp = open('%s.%s.out' % (self.name, out), 'w')
-                        else:
-                            ofp = None
-                elif hunk.strip():
-                    # it's something we should execute
-                    output = self.sendreceive(hunk)
-                    if not ofp:
-                        continue
-                    # first, print the command we ran
-                    if not hunk.startswith('#'):
-                        nl = hunk.endswith('\n')
-                        hunk = ('$ \\textbf{%s}' %
-                                tex_escape(hunk.rstrip('\n')))
-                        if nl: hunk += '\n'
-                    ofp.write(hunk)
-                    # then its output
-                    ofp.write(tex_escape(output))
-            self.status('\n')
-            open(self.name + '.run', 'w')
+            clean_exit = True
+            try:
+                # setup env and prompt
+                self.sendreceive('source %s\n\n' % rcfile)
+                for hunk in self.parse():
+                    # is this line a processing instruction?
+                    m = self.pi_re.match(hunk)
+                    if m:
+                        pi, rest = m.groups()
+                        if pi == 'name':
+                            self.status('.')
+                            out = rest
+                            assert os.sep not in out
+                            if out:
+                                ofp = open('%s.%s.out' % (self.name, out), 'w')
+                            else:
+                                ofp = None
+                    elif hunk.strip():
+                        # it's something we should execute
+                        output = self.sendreceive(hunk)
+                        if not ofp:
+                            continue
+                        # first, print the command we ran
+                        if not hunk.startswith('#'):
+                            nl = hunk.endswith('\n')
+                            hunk = ('$ \\textbf{%s}' %
+                                    tex_escape(hunk.rstrip('\n')))
+                            if nl: hunk += '\n'
+                        ofp.write(hunk)
+                        # then its output
+                        ofp.write(tex_escape(output))
+                self.status('\n')
+                open(self.name + '.run', 'w')
+            except:
+                clean_exit = False
+                raise
         finally:
-            try:
-                output = self.sendreceive('exit\n')
-                if ofp:
-                    ofp.write(output)
-                self.cfp.close()
-            except IOError:
-                pass
+            if clean_exit:
+                try:
+                    output = self.sendreceive('exit\n')
+                    if ofp:
+                        ofp.write(output)
+                    self.cfp.close()
+                except IOError:
+                    pass
             os.kill(pid, signal.SIGTERM)
-            os.wait()
+            time.sleep(0.1)
+            os.kill(pid, signal.SIGKILL)
+            pid, rc = os.wait()
+            if rc:
+                if os.WIFEXITED(rc):
+                    print >> sys.stderr, '(exit %s)' % os.WEXITSTATUS(rc)
+                elif os.WIFSIGNALED(rc):
+                    print >> sys.stderr, '(signal %s)' % os.WTERMSIG(rc)
             shutil.rmtree(tmpdir)
+            return rc
 
 def main(path='.'):
     args = sys.argv[1:]
+    errs = 0
     if args:
         for a in args:
-            example(a).run()
-        return
+            if example(a).run():
+                errs += 1
+        return errs
     for name in os.listdir(path):
         if name == 'run-example' or name.startswith('.'): continue
         if name.endswith('.out') or name.endswith('~'): continue
@@ -155,8 +171,10 @@
         pathname = os.path.join(path, name)
         st = os.lstat(pathname)
         if stat.S_ISREG(st.st_mode) and st.st_mode & 0111:
-            example(pathname).run()
+            if example(pathname).run():
+                errs += 1
     print >> open(os.path.join(path, '.run'), 'w'), time.asctime()
+    return errs
 
 if __name__ == '__main__':
-    main()
+    sys.exit(main())