From 8ce63106b946e68b1adfb72c2de0b8e312dd1c06 Mon Sep 17 00:00:00 2001 From: Walther Chen Date: Fri, 25 Oct 2024 11:44:32 -0400 Subject: [PATCH] Update .editorconfig to reflect current style (#1571) * Update .editorconfig to reflect current style * .editorconfig use tabs for python * update msvc_build_libraries.py from two-space to tab indent * update test/src/tester.py from 4-space to tab indent --- .editorconfig | 9 +- msvc_build_libraries.py | 216 +++++++------- test/src/tester.py | 614 ++++++++++++++++++++-------------------- 3 files changed, 418 insertions(+), 421 deletions(-) diff --git a/.editorconfig b/.editorconfig index c082bb5e5..3344697bb 100644 --- a/.editorconfig +++ b/.editorconfig @@ -11,18 +11,15 @@ indent_style = space indent_size = 4 [*.{c,cc,h}] -indent_style = space -indent_size = 4 +indent_style = tab [*.{c3}] -indent_style = space -indent_size = 4 +indent_style = tab [*.{json,toml,yml,gyp}] indent_style = space indent_size = 2 [*.{py,pyi}] -indent_style = space -indent_size = 2 +indent_style = tab diff --git a/msvc_build_libraries.py b/msvc_build_libraries.py index 458ad79d8..ad6c8bded 100755 --- a/msvc_build_libraries.py +++ b/msvc_build_libraries.py @@ -19,55 +19,55 @@ import tempfile from pathlib import Path if (platform.system() == "Windows"): - print("Creating msvc_sdk for compilation without VS.") + print("Creating msvc_sdk for compilation without VS.") else: - print("Creating msvc_sdk for cross platform compilation to Windows.") + print("Creating msvc_sdk for cross platform compilation to Windows.") OUTPUT = Path(tempfile.mkdtemp()) # output folder SDK_OUTPUT = Path("msvc_sdk") if (not os.environ.get('PYTHONHTTPSVERIFY', '') and - getattr(ssl, '_create_unverified_context', None)): - ssl._create_default_https_context = ssl._create_unverified_context + getattr(ssl, '_create_unverified_context', None)): + ssl._create_default_https_context = ssl._create_unverified_context MANIFEST_URL = "https://aka.ms/vs/17/release/channel" def download(url): - with urllib.request.urlopen(url) as res: - return res.read() + with urllib.request.urlopen(url) as res: + return res.read() def download_progress(url, check, name, f): - data = io.BytesIO() - with urllib.request.urlopen(url) as res: - total = int(res.headers["Content-Length"]) - size = 0 - while True: - block = res.read(1<<20) - if not block: - break - f.write(block) - data.write(block) - size += len(block) - perc = size * 100 // total - print(f"\r{name} ... {perc}%", end="") - print() - data = data.getvalue() - digest = hashlib.sha256(data).hexdigest() - if check.lower() != digest: - exit(f"Hash mismatch for f{pkg}") - return data + data = io.BytesIO() + with urllib.request.urlopen(url) as res: + total = int(res.headers["Content-Length"]) + size = 0 + while True: + block = res.read(1<<20) + if not block: + break + f.write(block) + data.write(block) + size += len(block) + perc = size * 100 // total + print(f"\r{name} ... {perc}%", end="") + print() + data = data.getvalue() + digest = hashlib.sha256(data).hexdigest() + if check.lower() != digest: + exit(f"Hash mismatch for f{pkg}") + return data # super crappy msi format parser just to find required .cab files def get_msi_cabs(msi): - index = 0 - while True: - index = msi.find(b".cab", index+4) - if index < 0: - return - yield msi[index-32:index+4].decode("ascii") + index = 0 + while True: + index = msi.find(b".cab", index+4) + if index < 0: + return + yield msi[index-32:index+4].decode("ascii") def first(items, cond): - return next(item for item in items if cond(item)) + return next(item for item in items if cond(item)) ### parse command-line arguments @@ -96,40 +96,40 @@ vsmanifest = json.loads(download(payload)) packages = {} for p in vsmanifest["packages"]: - packages.setdefault(p["id"].lower(), []).append(p) + packages.setdefault(p["id"].lower(), []).append(p) msvc = {} sdk_path = {} for pid,p in packages.items(): - if pid.startswith("Microsoft.VisualStudio.Component.VC.".lower()) and pid.endswith(".x86.x64".lower()): - pver = ".".join(pid.split(".")[4:6]) - if pver[0].isnumeric(): - msvc[pver] = pid - elif pid.startswith("Microsoft.VisualStudio.Component.Windows10SDK.".lower()) or \ - pid.startswith("Microsoft.VisualStudio.Component.Windows11SDK.".lower()): - pver = pid.split(".")[-1] - if pver.isnumeric(): - sdk_path[pver] = pid + if pid.startswith("Microsoft.VisualStudio.Component.VC.".lower()) and pid.endswith(".x86.x64".lower()): + pver = ".".join(pid.split(".")[4:6]) + if pver[0].isnumeric(): + msvc[pver] = pid + elif pid.startswith("Microsoft.VisualStudio.Component.Windows10SDK.".lower()) or \ + pid.startswith("Microsoft.VisualStudio.Component.Windows11SDK.".lower()): + pver = pid.split(".")[-1] + if pver.isnumeric(): + sdk_path[pver] = pid if args.show_versions: - print("MSVC versions:", " ".join(sorted(msvc.keys()))) - print("Windows SDK versions:", " ".join(sorted(sdk_path.keys()))) - exit(0) + print("MSVC versions:", " ".join(sorted(msvc.keys()))) + print("Windows SDK versions:", " ".join(sorted(sdk_path.keys()))) + exit(0) msvc_ver = args.msvc_version or max(sorted(msvc.keys())) sdk_ver = args.sdk_version or max(sorted(sdk_path.keys())) if msvc_ver in msvc: - msvc_pid = msvc[msvc_ver] - msvc_ver = ".".join(msvc_pid.split(".")[4:-2]) + msvc_pid = msvc[msvc_ver] + msvc_ver = ".".join(msvc_pid.split(".")[4:-2]) else: - exit(f"Unknown MSVC version: f{args.msvc_version}") + exit(f"Unknown MSVC version: f{args.msvc_version}") if sdk_ver in sdk_path: - sdk_pid = sdk_path[sdk_ver] + sdk_pid = sdk_path[sdk_ver] else: - exit(f"Unknown Windows SDK version: f{args.sdk_version}") + exit(f"Unknown Windows SDK version: f{args.sdk_version}") print(f"Downloading MSVC v{msvc_ver} and Windows SDK v{sdk_ver}") @@ -141,9 +141,9 @@ resource = first(tools["localizedResources"], lambda x: x["language"] == "en-us" license = resource["license"] if not args.accept_license: - accept = input(f"Do you accept Visual Studio license at {license}, and also confirm that you have a valid license Visual Studio license allowing you to download the VS Build Tools [Y/N] ?") - if not accept or accept[0].lower() != "y": - exit(0) + accept = input(f"Do you accept Visual Studio license at {license}, and also confirm that you have a valid license Visual Studio license allowing you to download the VS Build Tools [Y/N] ?") + if not accept or accept[0].lower() != "y": + exit(0) shutil.rmtree(SDK_OUTPUT, ignore_errors = True) total_download = 0 @@ -151,82 +151,82 @@ total_download = 0 ### download Windows SDK archs = [ - #"arm", - #"arm64", - "x64", - #"x86" + #"arm", + #"arm64", + "x64", + #"x86" ] msvc_packages = [ - f"microsoft.vc.{msvc_ver}.asan.headers.base", + f"microsoft.vc.{msvc_ver}.asan.headers.base", ] for arch in archs: - msvc_packages.append(f"microsoft.vc.{msvc_ver}.crt.{arch}.desktop.base") - msvc_packages.append(f"microsoft.vc.{msvc_ver}.crt.{arch}.store.base") - msvc_packages.append(f"microsoft.vc.{msvc_ver}.asan.{arch}.base") + msvc_packages.append(f"microsoft.vc.{msvc_ver}.crt.{arch}.desktop.base") + msvc_packages.append(f"microsoft.vc.{msvc_ver}.crt.{arch}.store.base") + msvc_packages.append(f"microsoft.vc.{msvc_ver}.asan.{arch}.base") for pkg in msvc_packages: - p = first(packages[pkg], lambda p: p.get("language") in (None, "en-US")) - for payload in p["payloads"]: - with tempfile.TemporaryFile() as f: - data = download_progress(payload["url"], payload["sha256"], pkg, f) - total_download += len(data) - with zipfile.ZipFile(f) as z: - for name in z.namelist(): - if name.startswith("Contents/"): - out = OUTPUT / Path(name).relative_to("Contents") - out.parent.mkdir(parents=True, exist_ok=True) - out.write_bytes(z.read(name)) + p = first(packages[pkg], lambda p: p.get("language") in (None, "en-US")) + for payload in p["payloads"]: + with tempfile.TemporaryFile() as f: + data = download_progress(payload["url"], payload["sha256"], pkg, f) + total_download += len(data) + with zipfile.ZipFile(f) as z: + for name in z.namelist(): + if name.startswith("Contents/"): + out = OUTPUT / Path(name).relative_to("Contents") + out.parent.mkdir(parents=True, exist_ok=True) + out.write_bytes(z.read(name)) sdk_packages = [ - # Windows SDK libs - "Windows SDK for Windows Store Apps Libs-x86_en-us.msi", - "Windows SDK Desktop Libs x64-x86_en-us.msi", - # CRT headers & libs - "Universal CRT Headers Libraries and Sources-x86_en-us.msi", + # Windows SDK libs + "Windows SDK for Windows Store Apps Libs-x86_en-us.msi", + "Windows SDK Desktop Libs x64-x86_en-us.msi", + # CRT headers & libs + "Universal CRT Headers Libraries and Sources-x86_en-us.msi", ] with tempfile.TemporaryDirectory() as d: - dst = Path(d) + dst = Path(d) - sdk_pkg = packages[sdk_pid][0] - sdk_pkg = packages[first(sdk_pkg["dependencies"], lambda x: True).lower()][0] + sdk_pkg = packages[sdk_pid][0] + sdk_pkg = packages[first(sdk_pkg["dependencies"], lambda x: True).lower()][0] - msi = [] - cabs = [] + msi = [] + cabs = [] - # download msi files - for pkg in sdk_packages: - payload = first(sdk_pkg["payloads"], lambda p: p["fileName"] == f"Installers\\{pkg}") - msi.append(dst / pkg) - with open(dst / pkg, "wb") as f: - data = download_progress(payload["url"], payload["sha256"], pkg, f) - total_download += len(data) - cabs += list(get_msi_cabs(data)) + # download msi files + for pkg in sdk_packages: + payload = first(sdk_pkg["payloads"], lambda p: p["fileName"] == f"Installers\\{pkg}") + msi.append(dst / pkg) + with open(dst / pkg, "wb") as f: + data = download_progress(payload["url"], payload["sha256"], pkg, f) + total_download += len(data) + cabs += list(get_msi_cabs(data)) - # download .cab files - for pkg in cabs: - payload = first(sdk_pkg["payloads"], lambda p: p["fileName"] == f"Installers\\{pkg}") - with open(dst / pkg, "wb") as f: - download_progress(payload["url"], payload["sha256"], pkg, f) + # download .cab files + for pkg in cabs: + payload = first(sdk_pkg["payloads"], lambda p: p["fileName"] == f"Installers\\{pkg}") + with open(dst / pkg, "wb") as f: + download_progress(payload["url"], payload["sha256"], pkg, f) - print("Unpacking msi files...") + print("Unpacking msi files...") - # run msi installers - for m in msi: - if (platform.system() == "Windows"): - subprocess.check_call(["msiexec.exe", "/a", m, "/quiet", "/qn", f"TARGETDIR={OUTPUT.resolve()}"]) - else: - subprocess.check_call(["msiextract", m, '-C', OUTPUT.resolve()]) + # run msi installers + for m in msi: + if (platform.system() == "Windows"): + subprocess.check_call(["msiexec.exe", "/a", m, "/quiet", "/qn", f"TARGETDIR={OUTPUT.resolve()}"]) + else: + subprocess.check_call(["msiextract", m, '-C', OUTPUT.resolve()]) ### versions if (platform.system() == "Windows"): - window_kit = OUTPUT / "Windows Kits/" + window_kit = OUTPUT / "Windows Kits/" else: - window_kit = OUTPUT / "Program Files/Windows Kits/" + window_kit = OUTPUT / "Program Files/Windows Kits/" ucrt = list(window_kit.glob("*/Lib/*/ucrt"))[0] um = list(window_kit.glob("*/Lib/*/um"))[0] @@ -235,9 +235,9 @@ lib = list((OUTPUT / "VC/Tools/MSVC/").glob("*/lib"))[0] SDK_OUTPUT.mkdir(exist_ok=True) for arch in archs: - out_dir = SDK_OUTPUT / arch - shutil.copytree(ucrt / arch, out_dir, dirs_exist_ok=True) - shutil.copytree(um / arch, out_dir, dirs_exist_ok=True) - shutil.copytree(lib / arch, out_dir, dirs_exist_ok=True) + out_dir = SDK_OUTPUT / arch + shutil.copytree(ucrt / arch, out_dir, dirs_exist_ok=True) + shutil.copytree(um / arch, out_dir, dirs_exist_ok=True) + shutil.copytree(lib / arch, out_dir, dirs_exist_ok=True) print("Congratulations! The 'msvc_sdk' directory was successfully generated.") diff --git a/test/src/tester.py b/test/src/tester.py index 66a4fdbdc..d60e508ba 100644 --- a/test/src/tester.py +++ b/test/src/tester.py @@ -9,355 +9,355 @@ TEST_DIR = tempfile.mkdtemp().replace('\\', '/') + '/c3test/' class Config: - run_skipped = False - cwd = "." - numtests = 0 - numsuccess = 0 - numskipped = 0 + run_skipped = False + cwd = "." + numtests = 0 + numsuccess = 0 + numskipped = 0 class File: - def __init__(self, filepath): - with open(filepath, encoding='utf8') as reader: - self.content = reader.read().splitlines() - self.filepath = filepath - self.filename = os.path.basename(filepath) + def __init__(self, filepath): + with open(filepath, encoding='utf8') as reader: + self.content = reader.read().splitlines() + self.filepath = filepath + self.filename = os.path.basename(filepath) class TargetFile: - def __init__(self, filepath, is_target, line_offset): - self.is_target = is_target - self.line_offset = line_offset - if is_target: - self.file = open(filepath, mode="wb") - else: - self.expected_lines = [] - self.file = None - self.filepath = filepath - self.filename = os.path.basename(filepath) + def __init__(self, filepath, is_target, line_offset): + self.is_target = is_target + self.line_offset = line_offset + if is_target: + self.file = open(filepath, mode="wb") + else: + self.expected_lines = [] + self.file = None + self.filepath = filepath + self.filename = os.path.basename(filepath) - def close(self): - if self.file: - self.file.close() - self.file = None + def close(self): + if self.file: + self.file.close() + self.file = None - def write(self, line): - if self.file: - self.file.write(bytearray(line, "utf-8")) - self.file.write(b"\n") - else: - self.expected_lines.append(line) + def write(self, line): + if self.file: + self.file.write(bytearray(line, "utf-8")) + self.file.write(b"\n") + else: + self.expected_lines.append(line) class Issues: - def __init__(self, conf, file, single): - self.conf = conf - self.sourcefile = file - self.single = single - self.line = 0 - self.file_start = 0 - self.line_offset = 0 - self.has_errors = False - self.error_message = "unknown" - self.skip = False - self.cur = 0 - self.debuginfo = False - self.safe = False - self.arch = None - self.current_file = None - self.files = [] - self.errors = {} - self.warnings = {} - self.opts = [] + def __init__(self, conf, file, single): + self.conf = conf + self.sourcefile = file + self.single = single + self.line = 0 + self.file_start = 0 + self.line_offset = 0 + self.has_errors = False + self.error_message = "unknown" + self.skip = False + self.cur = 0 + self.debuginfo = False + self.safe = False + self.arch = None + self.current_file = None + self.files = [] + self.errors = {} + self.warnings = {} + self.opts = [] - def exit_error(self, message): - print('Error in file ' + self.sourcefile.filepath + ': ' + message) - exit(-1) + def exit_error(self, message): + print('Error in file ' + self.sourcefile.filepath + ': ' + message) + exit(-1) - def set_failed(self): - if not self.has_errors: - print(" Failed.") - self.has_errors = True + def set_failed(self): + if not self.has_errors: + print(" Failed.") + self.has_errors = True - def check_line(self, typ, file, line, col, message): - map_ = {} - if typ == 'Error': - map_ = self.errors - elif typ == 'Warning': - map_ = self.warnings - else: - self.exit_error("Unknown type: " + typ) - file = os.path.basename(file) - key = file + ":" + line - value = map_.get(key) - if value is None: - return False - if value in message: - del map_[key] - return True - else: - return False + def check_line(self, typ, file, line, col, message): + map_ = {} + if typ == 'Error': + map_ = self.errors + elif typ == 'Warning': + map_ = self.warnings + else: + self.exit_error("Unknown type: " + typ) + file = os.path.basename(file) + key = file + ":" + line + value = map_.get(key) + if value is None: + return False + if value in message: + del map_[key] + return True + else: + return False - def parse_result(self, lines): - for line in lines: - parts = line.split('|', maxsplit=5) - if len(parts) != 5: - self.exit_error("Illegal error result: " + line) - if not self.check_line(parts[0], parts[1], parts[2], parts[3], parts[4]): - self.set_failed() - print("Unexpected " + parts[0].lower() + " in " + os.path.basename(parts[1]) + " line " + parts[2] + ":", end="") - print('"' + parts[4] + '"') - if len(self.errors) > 0: - self.set_failed() - print("Expected errors that never occurred:") - num = 1 - for key, value in self.errors.items(): - pos = key.split(":", 2) - print(str(num) + ". " + pos[0] + " line: " + pos[1] + " expected: \"" + value + "\"") - num += 1 + def parse_result(self, lines): + for line in lines: + parts = line.split('|', maxsplit=5) + if len(parts) != 5: + self.exit_error("Illegal error result: " + line) + if not self.check_line(parts[0], parts[1], parts[2], parts[3], parts[4]): + self.set_failed() + print("Unexpected " + parts[0].lower() + " in " + os.path.basename(parts[1]) + " line " + parts[2] + ":", end="") + print('"' + parts[4] + '"') + if len(self.errors) > 0: + self.set_failed() + print("Expected errors that never occurred:") + num = 1 + for key, value in self.errors.items(): + pos = key.split(":", 2) + print(str(num) + ". " + pos[0] + " line: " + pos[1] + " expected: \"" + value + "\"") + num += 1 - def compile(self, args): - os.chdir(TEST_DIR) - target = "" - debug = "-g0 " - if self.arch: - target = " --target " + self.arch - if self.debuginfo: - debug = "-g " - opts = "" - for opt in self.opts: - opts += ' ' + opt - if self.safe: - opts += " --safe=yes" - else: - opts += " --safe=no" - code = subprocess.run(self.conf.compiler + target + ' -O0 ' + opts + ' ' + debug + args, - universal_newlines=True, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - os.chdir(self.conf.cwd) - if code.returncode != 0 and code.returncode != 1: - self.set_failed() - print("Error (" + str(code.returncode) + "): " + code.stderr) - self.has_errors = True - return - self.parse_result(code.stderr.splitlines(keepends=False)) + def compile(self, args): + os.chdir(TEST_DIR) + target = "" + debug = "-g0 " + if self.arch: + target = " --target " + self.arch + if self.debuginfo: + debug = "-g " + opts = "" + for opt in self.opts: + opts += ' ' + opt + if self.safe: + opts += " --safe=yes" + else: + opts += " --safe=no" + code = subprocess.run(self.conf.compiler + target + ' -O0 ' + opts + ' ' + debug + args, + universal_newlines=True, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + os.chdir(self.conf.cwd) + if code.returncode != 0 and code.returncode != 1: + self.set_failed() + print("Error (" + str(code.returncode) + "): " + code.stderr) + self.has_errors = True + return + self.parse_result(code.stderr.splitlines(keepends=False)) - def parse_single(self): - self.current_file = TargetFile(TEST_DIR + self.sourcefile.filename, True, 1) - lines = len(self.sourcefile.content) - while self.line < lines: - line = self.sourcefile.content[self.line].strip() - if "// #" in line: - self.parse_trailing_directive(line) - self.current_file.write(self.sourcefile.content[self.line]) - self.line += 1 + def parse_single(self): + self.current_file = TargetFile(TEST_DIR + self.sourcefile.filename, True, 1) + lines = len(self.sourcefile.content) + while self.line < lines: + line = self.sourcefile.content[self.line].strip() + if "// #" in line: + self.parse_trailing_directive(line) + self.current_file.write(self.sourcefile.content[self.line]) + self.line += 1 - self.current_file.close() - print("- " + str(self.conf.numtests) + "/" + str( - self.conf.numtests - self.conf.numsuccess - 1) + " " + self.sourcefile.filepath + ":", end="") - self.compile("--test compile-only " + self.current_file.filepath) - if not self.has_errors: - self.conf.numsuccess += 1 - print(" Passed.") + self.current_file.close() + print("- " + str(self.conf.numtests) + "/" + str( + self.conf.numtests - self.conf.numsuccess - 1) + " " + self.sourcefile.filepath + ":", end="") + self.compile("--test compile-only " + self.current_file.filepath) + if not self.has_errors: + self.conf.numsuccess += 1 + print(" Passed.") - def parse_header_directive(self, line): - line = line[4:].strip() - if line.startswith("safe:"): - self.safe = line[5:].strip() == "yes" - return - if line.startswith("debuginfo:"): - self.debuginfo = line[10:].strip() == "yes" - return - if line.startswith("opt:"): - self.opts.append(line[4:].strip()) - return - if line.startswith("target:"): - self.arch = line[7:].strip() - return - if line.startswith("file:"): - if self.current_file: - self.current_file.close() - line = line[5:].strip() - self.current_file = TargetFile(TEST_DIR + line, True, -self.line) - self.files.append(self.current_file) - return - elif line.startswith("expect:"): - line = line[7:].strip() - if self.current_file: - self.current_file.close() - self.current_file = TargetFile(TEST_DIR + line, False, 0) - self.files.append(self.current_file) - return - else: - self.exit_error("unknown header directive " + line) + def parse_header_directive(self, line): + line = line[4:].strip() + if line.startswith("safe:"): + self.safe = line[5:].strip() == "yes" + return + if line.startswith("debuginfo:"): + self.debuginfo = line[10:].strip() == "yes" + return + if line.startswith("opt:"): + self.opts.append(line[4:].strip()) + return + if line.startswith("target:"): + self.arch = line[7:].strip() + return + if line.startswith("file:"): + if self.current_file: + self.current_file.close() + line = line[5:].strip() + self.current_file = TargetFile(TEST_DIR + line, True, -self.line) + self.files.append(self.current_file) + return + elif line.startswith("expect:"): + line = line[7:].strip() + if self.current_file: + self.current_file.close() + self.current_file = TargetFile(TEST_DIR + line, False, 0) + self.files.append(self.current_file) + return + else: + self.exit_error("unknown header directive " + line) - def parse_trailing_directive(self, line): - line = line.split('// #', 2)[1].strip() - if line.startswith("warning:"): - print("TODO" + line) - exit(-1) - elif line.startswith("target:"): - self.arch = line[7:].strip() - elif line.startswith("error:"): - line = line[6:].strip() - self.errors[self.current_file.filename + ":%d" % (self.line + self.current_file.line_offset)] = line - else: - self.exit_error("unknown trailing directive " + line) + def parse_trailing_directive(self, line): + line = line.split('// #', 2)[1].strip() + if line.startswith("warning:"): + print("TODO" + line) + exit(-1) + elif line.startswith("target:"): + self.arch = line[7:].strip() + elif line.startswith("error:"): + line = line[6:].strip() + self.errors[self.current_file.filename + ":%d" % (self.line + self.current_file.line_offset)] = line + else: + self.exit_error("unknown trailing directive " + line) - def parse_template(self): - lines = len(self.sourcefile.content) - while self.line < lines: - line = self.sourcefile.content[self.line].strip() - if line.startswith("// #") or line.startswith("/* #"): - self.parse_header_directive(line) - self.line += 1 - continue - elif "// #" in line: - self.parse_trailing_directive(line) - if not self.current_file: - self.current_file = TargetFile(TEST_DIR + self.sourcefile.filename[:-4] + ".c3", True, 1) - self.files.append(self.current_file) - self.current_file.write(self.sourcefile.content[self.line]) - self.line += 1 + def parse_template(self): + lines = len(self.sourcefile.content) + while self.line < lines: + line = self.sourcefile.content[self.line].strip() + if line.startswith("// #") or line.startswith("/* #"): + self.parse_header_directive(line) + self.line += 1 + continue + elif "// #" in line: + self.parse_trailing_directive(line) + if not self.current_file: + self.current_file = TargetFile(TEST_DIR + self.sourcefile.filename[:-4] + ".c3", True, 1) + self.files.append(self.current_file) + self.current_file.write(self.sourcefile.content[self.line]) + self.line += 1 - if self.current_file: - self.current_file.close() - self.current_file = None + if self.current_file: + self.current_file.close() + self.current_file = None - print("- " + str(self.conf.numtests) + "/" + str( - self.conf.numtests - self.conf.numsuccess - 1) + " " + self.sourcefile.filepath + ":", end="") - files_to_compile = "" - for file in self.files: - if file.is_target: - files_to_compile += " " + file.filepath + print("- " + str(self.conf.numtests) + "/" + str( + self.conf.numtests - self.conf.numsuccess - 1) + " " + self.sourcefile.filepath + ":", end="") + files_to_compile = "" + for file in self.files: + if file.is_target: + files_to_compile += " " + file.filepath - self.compile("--test compile-only " + files_to_compile) - if self.has_errors: - return + self.compile("--test compile-only " + files_to_compile) + if self.has_errors: + return - for file in self.files: - if not file.is_target: - if not os.path.exists(file.filepath): - self.set_failed() - print("Did not compile file " + file.filename) - return - with open(file.filepath) as reader: - lines = reader.read().splitlines() - searched_line = 0 - current_line = 0 - total_lines = len(file.expected_lines) - while searched_line < total_lines: - line = file.expected_lines[searched_line].strip() - next_line = None - if searched_line + 1 < total_lines: - alt_line = file.expected_lines[searched_line + 1].strip() - if alt_line.startswith("??"): - next_line = alt_line[2:].strip() - if line == "": - searched_line += 1 - continue - if current_line >= len(lines): - self.set_failed() - print(file.filename + " did not contain: \"" + line + "\"") - print("\n\n\n---------------------------------------------------> " + file.filename + "\n\n") - print("\n".join(lines) + "\n") - print("<---------------------------------------------------- " + self.sourcefile.filename) - print("") - return - if line in lines[current_line]: - current_line += 1 - searched_line += 1 - continue - if next_line is not None and next_line in lines[current_line]: - current_line += 1 - searched_line += 2 - continue - current_line += 1 - if not self.has_errors: - self.conf.numsuccess += 1 - print(" Passed.") + for file in self.files: + if not file.is_target: + if not os.path.exists(file.filepath): + self.set_failed() + print("Did not compile file " + file.filename) + return + with open(file.filepath) as reader: + lines = reader.read().splitlines() + searched_line = 0 + current_line = 0 + total_lines = len(file.expected_lines) + while searched_line < total_lines: + line = file.expected_lines[searched_line].strip() + next_line = None + if searched_line + 1 < total_lines: + alt_line = file.expected_lines[searched_line + 1].strip() + if alt_line.startswith("??"): + next_line = alt_line[2:].strip() + if line == "": + searched_line += 1 + continue + if current_line >= len(lines): + self.set_failed() + print(file.filename + " did not contain: \"" + line + "\"") + print("\n\n\n---------------------------------------------------> " + file.filename + "\n\n") + print("\n".join(lines) + "\n") + print("<---------------------------------------------------- " + self.sourcefile.filename) + print("") + return + if line in lines[current_line]: + current_line += 1 + searched_line += 1 + continue + if next_line is not None and next_line in lines[current_line]: + current_line += 1 + searched_line += 2 + continue + current_line += 1 + if not self.has_errors: + self.conf.numsuccess += 1 + print(" Passed.") - def parse(self): - if len(self.sourcefile.content) == 0: - self.exit_error("File was empty") - is_skip = self.sourcefile.content[0].startswith("// #skip") - if is_skip != self.skip: - print("- " + str(self.conf.numtests) + "/" + str( - self.conf.numtests - self.conf.numsuccess - 1) + " " + self.sourcefile.filepath + ": *SKIPPED*") - self.conf.numskipped += 1 - return - if is_skip: - self.line += 1 - if self.single: - self.parse_single() - else: - self.parse_template() + def parse(self): + if len(self.sourcefile.content) == 0: + self.exit_error("File was empty") + is_skip = self.sourcefile.content[0].startswith("// #skip") + if is_skip != self.skip: + print("- " + str(self.conf.numtests) + "/" + str( + self.conf.numtests - self.conf.numsuccess - 1) + " " + self.sourcefile.filepath + ": *SKIPPED*") + self.conf.numskipped += 1 + return + if is_skip: + self.line += 1 + if self.single: + self.parse_single() + else: + self.parse_template() def usage(): - print("Usage: " + sys.argv[0] + " [-s]") - print('') - print('Options:') - print(" -s, --skipped only run skipped tests") - exit(-1) + print("Usage: " + sys.argv[0] + " [-s]") + print('') + print('Options:') + print(" -s, --skipped only run skipped tests") + exit(-1) def handle_file(filepath, conf): - if filepath.endswith('.c3'): - single = True - elif filepath.endswith('.c3t'): - single = False - else: - return + if filepath.endswith('.c3'): + single = True + elif filepath.endswith('.c3t'): + single = False + else: + return - shutil.rmtree(TEST_DIR, ignore_errors=True) - os.mkdir(TEST_DIR, mode=0o777) + shutil.rmtree(TEST_DIR, ignore_errors=True) + os.mkdir(TEST_DIR, mode=0o777) - conf.numtests += 1 + conf.numtests += 1 - issues = Issues(conf, File(filepath), single) - issues.parse() + issues = Issues(conf, File(filepath), single) + issues.parse() def handle_dir(filepath, conf): - for file in os.listdir(filepath): - file = filepath + "/" + file - if os.path.isdir(file): - handle_dir(file, conf) - elif os.path.isfile(file): - handle_file(file, conf) + for file in os.listdir(filepath): + file = filepath + "/" + file + if os.path.isdir(file): + handle_dir(file, conf) + elif os.path.isfile(file): + handle_file(file, conf) def main(): - args = len(sys.argv) - conf = Config() - if args < 3 or args > 4: - usage() - conf.compiler = os.getcwd() + "/" + sys.argv[1] - if not os.path.isfile(conf.compiler): - print("Error: Invalid path to compiler: " + conf.compiler) - usage() - if args == 4: - if sys.argv[3] != '-s' and sys.argv[3] != '--skipped': - usage() - conf.run_skipped = True - filepath = sys.argv[2] - if filepath.endswith('/'): - filepath = filepath[:-1] - conf.cwd = os.getcwd() - if os.path.isfile(filepath): - handle_file(filepath, conf) - elif os.path.isdir(filepath): - handle_dir(filepath, conf) - else: - print("Error: Invalid path to tests: " + filepath) - usage() + args = len(sys.argv) + conf = Config() + if args < 3 or args > 4: + usage() + conf.compiler = os.getcwd() + "/" + sys.argv[1] + if not os.path.isfile(conf.compiler): + print("Error: Invalid path to compiler: " + conf.compiler) + usage() + if args == 4: + if sys.argv[3] != '-s' and sys.argv[3] != '--skipped': + usage() + conf.run_skipped = True + filepath = sys.argv[2] + if filepath.endswith('/'): + filepath = filepath[:-1] + conf.cwd = os.getcwd() + if os.path.isfile(filepath): + handle_file(filepath, conf) + elif os.path.isdir(filepath): + handle_dir(filepath, conf) + else: + print("Error: Invalid path to tests: " + filepath) + usage() - print("Found %d tests: %.1f%% (%d / %d) passed (%d skipped)." % ( - conf.numtests, 100 * conf.numsuccess / max(1, conf.numtests - conf.numskipped), conf.numsuccess, - conf.numtests - conf.numskipped, conf.numskipped)) - if conf.numsuccess != conf.numtests - conf.numskipped: - exit(-1) - exit(0) + print("Found %d tests: %.1f%% (%d / %d) passed (%d skipped)." % ( + conf.numtests, 100 * conf.numsuccess / max(1, conf.numtests - conf.numskipped), conf.numsuccess, + conf.numtests - conf.numskipped, conf.numskipped)) + if conf.numsuccess != conf.numtests - conf.numskipped: + exit(-1) + exit(0) main()