import globals # our source import re import sys import os, os.path class Comparison: def __init__(self, l1, l2): self.list2_file = '' # (last if there are many) file name with goal results (if they are stored in a file) self.list1 = self.prepare_fill_in_files(l1) self.list2 = self.prepare_fill_in_files(l2) self.p1 = 0 # updated position within list1 self.p2 = 0 # updated position within list2 self.equal = True # the final comparison result self.result = "" # details of comparing individual lines while not self.finished(): if not self.compare_element(): self.equal = False @staticmethod def load_platform_specific(file_name): name = file_name + "-" + globals.PLATFORM + ".goal" try: fin = open(os.path.join(globals.THISDIR, name)) # first we look for the file with the specialized name (platform-dependent)... except IOError as e1: try: fin = open(os.path.join(globals.THISDIR, file_name + ".goal")) # ...if there is no such file, we try to find the default file except IOError as e2: print() print(e1) print(e2) print('Proceeding as if the missing file were empty.') return [] list_of_lines = [] for line in fin: line = globals.stripEOL(line) list_of_lines.append(line) return list_of_lines def prepare_fill_in_files(self, list_of_lines): # when finds a line with SPEC_USEPLATFORMDEPENDENTFILE, replaces it with the contents of the appropriate file new_list = [] for l in list_of_lines: if l.startswith(globals.SPEC_INSERTPLATFORMDEPENDENTFILE): file_name = l[len(globals.SPEC_INSERTPLATFORMDEPENDENTFILE):] new_list += self.load_platform_specific(file_name) self.list2_file = file_name else: new_list.append(l) return new_list def finished(self): return self.p1 >= len(self.list1) and self.p2 >= len(self.list2) @staticmethod def compare_strings(s1, s2): if s1 == s2: return True if not globals.WIN_SLASH_SENSITIVE and os.path.sep == '\\': # give a chance for approximate comparison - does not distinguish /\ but only on the windows platform return s1.replace('\\', '/') == s2 # and matches only the local output, assuming that the goal uses linux-standard / else: return False def compare_element(self): e1 = "(missing)" if self.p1 >= len(self.list1) else self.list1[self.p1] e2 = "(missing)" if self.p2 >= len(self.list2) else self.list2[self.p2] e2disp = e2 if e2.startswith(globals.SPEC_SKIPTO): e2 = e2[len(globals.SPEC_SKIPTO):] waiting = True if self.p1 >= len(self.list1): # exception: skipto becomes a standard comparison when the input stream ends (because then we know we will not read anything more than we have now) waiting = False else: waiting = False if e2.startswith(globals.SPEC_REGEXP): equal = re.match(e2[len(globals.SPEC_REGEXP):], e1) else: equal = self.compare_strings(e1, e2) # ignoring the discrimination of /\ will work only when regexp's are not used self.result += repr(e1) + " " if equal: self.p2 += 1 else: if waiting: # handling skipto: if self.p1 >= len(self.list1): self.p2 += 1 else: equal = True else: self.p2 += 1 if equal: self.result += globals.ANSI_SETGREEN + "ok" + globals.ANSI_RESET + "\n" # if both are identical, we display only the left one else: self.result += globals.ANSI_SETRED + "" + globals.ANSI_RESET + " " self.result += repr(e2disp) + "\n" self.p1 += 1 return equal