616 if os.name == 'nt': |
616 if os.name == 'nt': |
617 replacements.append((r'\r\n', '\n')) |
617 replacements.append((r'\r\n', '\n')) |
618 return run(cmd, testtmp, self._options, replacements, env, |
618 return run(cmd, testtmp, self._options, replacements, env, |
619 self._runner.abort) |
619 self._runner.abort) |
620 |
620 |
621 |
|
622 needescape = re.compile(r'[\x00-\x08\x0b-\x1f\x7f-\xff]').search |
|
623 escapesub = re.compile(r'[\x00-\x08\x0b-\x1f\\\x7f-\xff]').sub |
|
624 escapemap = dict((chr(i), r'\x%02x' % i) for i in range(256)) |
|
625 escapemap.update({'\\': '\\\\', '\r': r'\r'}) |
|
626 def escapef(m): |
|
627 return escapemap[m.group(0)] |
|
628 def stringescape(s): |
|
629 return escapesub(escapef, s) |
|
630 |
|
631 class TTest(Test): |
621 class TTest(Test): |
632 """A "t test" is a test backed by a .t file.""" |
622 """A "t test" is a test backed by a .t file.""" |
633 |
623 |
634 SKIPPED_PREFIX = 'skipped: ' |
624 SKIPPED_PREFIX = 'skipped: ' |
635 FAILED_PREFIX = 'hghave check failed: ' |
625 FAILED_PREFIX = 'hghave check failed: ' |
|
626 NEEDESCAPE = re.compile(r'[\x00-\x08\x0b-\x1f\x7f-\xff]').search |
|
627 |
|
628 ESCAPESUB = re.compile(r'[\x00-\x08\x0b-\x1f\\\x7f-\xff]').sub |
|
629 ESCAPEMAP = dict((chr(i), r'\x%02x' % i) for i in range(256)).update( |
|
630 {'\\': '\\\\', '\r': r'\r'}) |
636 |
631 |
637 def _run(self, testtmp, replacements, env): |
632 def _run(self, testtmp, replacements, env): |
638 f = open(self._path) |
633 f = open(self._path) |
639 lines = f.readlines() |
634 lines = f.readlines() |
640 f.close() |
635 f.close() |
816 log('\ninfo, unknown linematch result: %r\n' % r) |
811 log('\ninfo, unknown linematch result: %r\n' % r) |
817 r = False |
812 r = False |
818 if r: |
813 if r: |
819 postout.append(' ' + el) |
814 postout.append(' ' + el) |
820 else: |
815 else: |
821 if needescape(lout): |
816 if self.NEEDESCAPE(lout): |
822 lout = stringescape(lout.rstrip('\n')) + ' (esc)\n' |
817 lout = TTest.stringescape('%s (esc)\n' % |
|
818 lout.rstrip('\n')) |
823 postout.append(' ' + lout) # Let diff deal with it. |
819 postout.append(' ' + lout) # Let diff deal with it. |
824 if r != '': # If line failed. |
820 if r != '': # If line failed. |
825 warnonly = 3 # for sure not |
821 warnonly = 3 # for sure not |
826 elif warnonly == 1: # Is "not yet" and line is warn only. |
822 elif warnonly == 1: # Is "not yet" and line is warn only. |
827 warnonly = 2 # Yes do warn. |
823 warnonly = 2 # Yes do warn. |
915 elif line.startswith(TTest.FAILED_PREFIX): |
911 elif line.startswith(TTest.FAILED_PREFIX): |
916 line = line.splitlines()[0] |
912 line = line.splitlines()[0] |
917 failed.append(line[len(TTest.FAILED_PREFIX):]) |
913 failed.append(line[len(TTest.FAILED_PREFIX):]) |
918 |
914 |
919 return missing, failed |
915 return missing, failed |
|
916 |
|
917 @staticmethod |
|
918 def _escapef(m): |
|
919 return TTest.ESCAPEMAP[m.group(0)] |
|
920 |
|
921 @staticmethod |
|
922 def _stringescape(s): |
|
923 return TTest.ESCAPESUB(TTest._escapef, s) |
|
924 |
920 |
925 |
921 wifexited = getattr(os, "WIFEXITED", lambda x: False) |
926 wifexited = getattr(os, "WIFEXITED", lambda x: False) |
922 def run(cmd, wd, options, replacements, env, abort): |
927 def run(cmd, wd, options, replacements, env, abort): |
923 """Run command in a sub-process, capturing the output (stdout and stderr). |
928 """Run command in a sub-process, capturing the output (stdout and stderr). |
924 Return a tuple (exitcode, output). output is None in debug mode.""" |
929 Return a tuple (exitcode, output). output is None in debug mode.""" |