diff --git a/_tools/get_started.py b/_tools/get_started.py index e1edbceeb5..3e2a505648 100644 --- a/_tools/get_started.py +++ b/_tools/get_started.py @@ -1,34 +1,34 @@ -#!/usr/bin/python3 -# Copyright Magomed Kostoev -# Published under MIT license - -import os - -def log(s, end = "\n"): - print(s, end = end, flush = True) - -def install_python_script(src, dst, tools_lib): - log(f"Copying {src}... ", end = "") - - with open(src) as src_file: - script = src_file.read() - tools_lib_escaped = tools_lib.replace("\\", "\\\\") - repl_from = "path_to_lib = '../lib'" - repl_to = f"path_to_lib ='{tools_lib_escaped}'" - script = script.replace(repl_from, repl_to, 1) - with open(dst, "w") as dst_file: - dst_file.write(script) - - log(f"Done") - -if __name__ == "__main__": - tools_get_started_py = os.path.abspath(__file__) - tools = os.sep.join(tools_get_started_py.split(os.sep)[:-1]) - tools_lib = os.sep.join([tools, "lib"]) - tools_workspace = os.sep.join([tools, "workspace"]) - # Copy scripts from _tools/workspace to current folder, but let them know - # where the _tools/lib is (change their value of tools_lib variable) - tools_workspace_run_py = os.sep.join([tools_workspace, "run.py"]) - tools_workspace_build_py = os.sep.join([tools_workspace, "build.py"]) - install_python_script(tools_workspace_run_py, "run.py", tools_lib) - install_python_script(tools_workspace_build_py, "build.py", tools_lib) +#!/bin/python3 +# Copyright Magomed Kostoev +# Published under MIT license + +import os + +def log(s, end = "\n"): + print(s, end = end, flush = True) + +def install_python_script(src, dst, tools_lib): + log(f"Copying {src}... ", end = "") + + with open(src) as src_file: + script = src_file.read() + tools_lib_escaped = tools_lib.replace("\\", "\\\\") + repl_from = "path_to_lib = '../lib'" + repl_to = f"path_to_lib ='{tools_lib_escaped}'" + script = script.replace(repl_from, repl_to, 1) + with open(dst, "w") as dst_file: + dst_file.write(script) + + log(f"Done") + +if __name__ == "__main__": + tools_get_started_py = os.path.abspath(__file__) + tools = os.sep.join(tools_get_started_py.split(os.sep)[:-1]) + tools_lib = os.sep.join([tools, "lib"]) + tools_workspace = os.sep.join([tools, "workspace"]) + # Copy scripts from _tools/workspace to current folder, but let them know + # where the _tools/lib is (change their value of tools_lib variable) + tools_workspace_run_py = os.sep.join([tools_workspace, "run.py"]) + tools_workspace_build_py = os.sep.join([tools_workspace, "build.py"]) + install_python_script(tools_workspace_run_py, "run.py", tools_lib) + install_python_script(tools_workspace_build_py, "build.py", tools_lib) diff --git a/_tools/lib/tupfile_parser.py b/_tools/lib/tupfile_parser.py index 2fbf812bc3..010c07e95e 100644 --- a/_tools/lib/tupfile_parser.py +++ b/_tools/lib/tupfile_parser.py @@ -1,153 +1,153 @@ -# Copyright Magomed Kostoev -# Published under MIT license - -class Rule: - pass - -def get_config(config_name): - if config_name == "KPACK_CMD": - # Just never pack the file for now - return "" - else: - print(f"Unknown config name: {config_name}") - exit(-1) - -def skip_whitespaces(src, ptr): - while len(src) > ptr and src[ptr] == " ": - ptr += 1 - return ptr - -# Returns True if @src has @string starting from @ptr index -def match_string(src, ptr, string): - if len(src) <= ptr + len(string): - return False - for i in range(len(string)): - if src[ptr + i] != string[i]: - return False - return True - -def parse_tup_getconfig(src, ptr): - # Skip get straight to the argument - ptr += len("tup.getconfig(") - ptr = skip_whitespaces(src, ptr) - if src[ptr] != "\"": - print("Expected \"config name\" as tup.getconfig parameter") - exit() - (config_name, ptr) = parse_string(src, ptr) - ptr = skip_whitespaces(src, ptr) - # Skip closing parenthese of the tup.getconfig call - assert(src[ptr] == ")") - ptr += 1 - return (get_config(config_name), ptr) - -def parse_string(src, ptr): - ptr += 1 - string = "" - while src[ptr] != "\"": - string += src[ptr] - ptr += 1 - # Skip the closing "\"" - ptr += 1 - ptr = skip_whitespaces(src, ptr) - # Check if we have concatination here - if match_string(src, ptr, ".."): - # Skip the ".." - ptr += 2 - # The expression parsing should result in a string - (string_to_add, ptr) = parse_expression(src, ptr) - # Concat our string to the resulting string - string += string_to_add - return (string, ptr) - -def parse_expression(src, ptr): - ptr = skip_whitespaces(src, ptr) - result = "WAT?!" - if src[ptr] == "\"": - (result, ptr) = parse_string(src, ptr) - elif match_string(src, ptr, "tup.getconfig("): - (result, ptr) = parse_tup_getconfig(src, ptr) - else: - print(f"Can't handle anything starting with '{src[ptr]}'") - exit(-1) - ptr = skip_whitespaces(src, ptr) - return (result, ptr) - -def expect_comma(src, ptr): - comma_skept = False - ptr = skip_whitespaces(src, ptr) - if src[ptr] == ",": - ptr += 1 - return (True, ptr) - else: - return (False, ptr) - -def parse_arguments(src, ptr): - result = [] - # Parse first argument - (argument, ptr) = parse_expression(src, ptr) - result.append(argument) - (comma_encoutered, ptr) = expect_comma(src, ptr) - # Parse the second argument if it's there - if comma_encoutered: - (argument, ptr) = parse_expression(src, ptr) - result.append(argument) - (comma_encoutered, ptr) = expect_comma(src, ptr) - # Parse third argument if it's there - if comma_encoutered: - (argument, ptr) = parse_expression(src, ptr) - result.append(argument) - return result - -def parse_rule(src, ptr): - # Get straight to the first argument - ptr += len("tup.rule(") - # Parse the arguments - args = parse_arguments(src, ptr) - # Build the rule object - result = Rule() - if len(args) == 3: - result.input = args[0] - result.command = args[1] - result.output = args[2] - # Replace %f with input file in rule's command - if type(result.input == str): - result.command = result.command.replace("%f", result.input) - else: - print("Command building with non-string tup.rule's first argument" - + " isn't implemented") - exit() - # Replace %o with output file in rule's command - if type(result.output == str): - result.command = result.command.replace("%o", result.output) - else: - print("Command building with non-string tup.rule's first argument" - + " isn't implemented") - exit() - elif len(args) == 2: - result.input = [] - result.command = args[0] - result.output = args[1] - else: - print(f"tup.rule can only take 2 or 3 arguments, not {len(args)}") - exit(-1) - # Unify the API - return arrays as input and output - if type(result.input) == str: - result.input = [ result.input ] - else: - assert(type(result.input) == list) - if type(result.output) == str: - result.output = [ result.output ] - else: - assert(type(result.output) == list) - return result - -def parse(file_name): - rules = [] - with open(file_name) as f: - tupfile = f.read() - rule_begin_index = tupfile.find("tup.rule(") - while (rule_begin_index != -1): - rules.append(parse_rule(tupfile, rule_begin_index)) - # Find the next tup.rule call - rule_begin_index = tupfile.find("tup.rule(", rule_begin_index + len("tup.rule(")) - return rules +# Copyright Magomed Kostoev +# Published under MIT license + +class Rule: + pass + +def get_config(config_name): + if config_name == "KPACK_CMD": + # Just never pack the file for now + return "" + else: + print(f"Unknown config name: {config_name}") + exit(-1) + +def skip_whitespaces(src, ptr): + while len(src) > ptr and src[ptr] == " ": + ptr += 1 + return ptr + +# Returns True if @src has @string starting from @ptr index +def match_string(src, ptr, string): + if len(src) <= ptr + len(string): + return False + for i in range(len(string)): + if src[ptr + i] != string[i]: + return False + return True + +def parse_tup_getconfig(src, ptr): + # Skip get straight to the argument + ptr += len("tup.getconfig(") + ptr = skip_whitespaces(src, ptr) + if src[ptr] != "\"": + print("Expected \"config name\" as tup.getconfig parameter") + exit() + (config_name, ptr) = parse_string(src, ptr) + ptr = skip_whitespaces(src, ptr) + # Skip closing parenthese of the tup.getconfig call + assert(src[ptr] == ")") + ptr += 1 + return (get_config(config_name), ptr) + +def parse_string(src, ptr): + ptr += 1 + string = "" + while src[ptr] != "\"": + string += src[ptr] + ptr += 1 + # Skip the closing "\"" + ptr += 1 + ptr = skip_whitespaces(src, ptr) + # Check if we have concatination here + if match_string(src, ptr, ".."): + # Skip the ".." + ptr += 2 + # The expression parsing should result in a string + (string_to_add, ptr) = parse_expression(src, ptr) + # Concat our string to the resulting string + string += string_to_add + return (string, ptr) + +def parse_expression(src, ptr): + ptr = skip_whitespaces(src, ptr) + result = "WAT?!" + if src[ptr] == "\"": + (result, ptr) = parse_string(src, ptr) + elif match_string(src, ptr, "tup.getconfig("): + (result, ptr) = parse_tup_getconfig(src, ptr) + else: + print(f"Can't handle anything starting with '{src[ptr]}'") + exit(-1) + ptr = skip_whitespaces(src, ptr) + return (result, ptr) + +def expect_comma(src, ptr): + comma_skept = False + ptr = skip_whitespaces(src, ptr) + if src[ptr] == ",": + ptr += 1 + return (True, ptr) + else: + return (False, ptr) + +def parse_arguments(src, ptr): + result = [] + # Parse first argument + (argument, ptr) = parse_expression(src, ptr) + result.append(argument) + (comma_encoutered, ptr) = expect_comma(src, ptr) + # Parse the second argument if it's there + if comma_encoutered: + (argument, ptr) = parse_expression(src, ptr) + result.append(argument) + (comma_encoutered, ptr) = expect_comma(src, ptr) + # Parse third argument if it's there + if comma_encoutered: + (argument, ptr) = parse_expression(src, ptr) + result.append(argument) + return result + +def parse_rule(src, ptr): + # Get straight to the first argument + ptr += len("tup.rule(") + # Parse the arguments + args = parse_arguments(src, ptr) + # Build the rule object + result = Rule() + if len(args) == 3: + result.input = args[0] + result.command = args[1] + result.output = args[2] + # Replace %f with input file in rule's command + if type(result.input == str): + result.command = result.command.replace("%f", result.input) + else: + print("Command building with non-string tup.rule's first argument" + + " isn't implemented") + exit() + # Replace %o with output file in rule's command + if type(result.output == str): + result.command = result.command.replace("%o", result.output) + else: + print("Command building with non-string tup.rule's first argument" + + " isn't implemented") + exit() + elif len(args) == 2: + result.input = [] + result.command = args[0] + result.output = args[1] + else: + print(f"tup.rule can only take 2 or 3 arguments, not {len(args)}") + exit(-1) + # Unify the API - return arrays as input and output + if type(result.input) == str: + result.input = [ result.input ] + else: + assert(type(result.input) == list) + if type(result.output) == str: + result.output = [ result.output ] + else: + assert(type(result.output) == list) + return result + +def parse(file_name): + rules = [] + with open(file_name) as f: + tupfile = f.read() + rule_begin_index = tupfile.find("tup.rule(") + while (rule_begin_index != -1): + rules.append(parse_rule(tupfile, rule_begin_index)) + # Find the next tup.rule call + rule_begin_index = tupfile.find("tup.rule(", rule_begin_index + len("tup.rule(")) + return rules diff --git a/_tools/workspace/build.py b/_tools/workspace/build.py index 06fc7dfbc4..06cfbdca53 100644 --- a/_tools/workspace/build.py +++ b/_tools/workspace/build.py @@ -1,24 +1,24 @@ -import sys -import os - -path_to_lib = '../lib' -sys.path.append(path_to_lib) - -import tupfile_parser - -def build(): - if not os.path.exists("Tupfile.lua"): - print("No Tupfile.lua, can't build anything") - exit() - - tup_rules = tupfile_parser.parse("Tupfile.lua") - program_files = [] - for rule in tup_rules: - # TODO: Manage source dependencies - # TODO: Inform about tools required for the build - os.system(rule.command) - program_files += rule.output - return program_files - -if __name__ == "__main__": +import sys +import os + +path_to_lib = '../lib' +sys.path.append(path_to_lib) + +import tupfile_parser + +def build(): + if not os.path.exists("Tupfile.lua"): + print("No Tupfile.lua, can't build anything") + exit() + + tup_rules = tupfile_parser.parse("Tupfile.lua") + program_files = [] + for rule in tup_rules: + # TODO: Manage source dependencies + # TODO: Inform about tools required for the build + os.system(rule.command) + program_files += rule.output + return program_files + +if __name__ == "__main__": build() \ No newline at end of file diff --git a/_tools/workspace/run.py b/_tools/workspace/run.py index 3c6a3b7f12..82c3ac587e 100644 --- a/_tools/workspace/run.py +++ b/_tools/workspace/run.py @@ -1,103 +1,103 @@ -import os -import sys -import shutil -import urllib.request -import subprocess - -import build - -path_to_lib = '../lib' -sys.path.append(path_to_lib) - -from makeflop import Floppy - -# TODO: Move into _tools/lib -def get_file_directory(path): - path = path.replace("\\", "/") - if "/" in path: - folder = "/".join(path.split("/")[:-1]) - if folder == "": - return "/" # It was a file in the root folder - return folder - else: - return "." # Just a filename, let's return current folder - -# TODO: Move into _tools/lib -def is_win32(): - return True if sys.platform == "win32" else False - -# TODO: Move into _tools/lib -def is_linux(): - return True if sys.platform == "linux" or sys.platform == "linux2" else False - -# TODO: Move into _tools/lib -def is_osx(): - return True if sys.platform == "darwin" else False - -# TODO: Move into _tools/lib -def log(s, end = "\n"): - print(s, end = end, flush = True) - -# TODO: Move into _tools/lib -def download(link, path): - log(f"Downloading {path}... ", end = "") - urllib.request.urlretrieve(link, path) - log("Done.") - -# TODO: Move into _tools/lib -def path(*args): - return os.sep.join(args) - -# TODO: Move into _tools/lib -def run_qemu(start_dir = "workspace"): - qemu_command = f"qemu-system-i386" - flags = "" - flags += "-L . " # IDK why it does not work without this - flags += "-m 128 " - flags += f"-drive format=raw,file={start_dir}/kolibri.img,index=0,if=floppy -boot a " - flags += "-vga vmware " - flags += "-net nic,model=rtl8139 -net user " - flags += "-soundhw ac97 " - if is_win32(): - qemu_full_path = shutil.which(qemu_command) - qemu_directory = get_file_directory(qemu_full_path) - flags += f"-L {qemu_directory} " - s = f"{qemu_command} {flags}" - qemu_stdout = open(f"{start_dir}/qemu_stdout.log", "w") - qemu_stderr = open(f"{start_dir}/qemu_stderr.log", "w") - if is_win32(): - return subprocess.Popen(s, bufsize = 0, stdout = qemu_stdout, stderr = qemu_stderr, stdin = subprocess.DEVNULL, shell = True, start_new_session = True) - else: - a = shlex.split(s) - return subprocess.Popen(a, bufsize = 0, stdout = qemu_stdout, stderr = qemu_stderr, stdin = subprocess.DEVNULL, start_new_session = True) - -if __name__ == "__main__": - program_files = build.build() - - os.makedirs("workspace", exist_ok = True) - - if not os.path.exists("workspace/kolibri.img"): - img_url = "http://builds.kolibrios.org/eng/data/data/kolibri.img" - download(img_url, "workspace/kolibri.img") - - # Open the IMG - with open("workspace/kolibri.img", "rb") as img: - img_data = img.read() - img = Floppy(img_data) - - # Remove unuseful folders - img.delete_path("GAMES") - img.delete_path("DEMOS") - img.delete_path("3D") - - log("Moving program files into kolibri image... ", end = "") - for file_name in program_files: - with open(file_name, "rb") as file: - file_data = file.read() - if not img.add_file_path(file_name, file_data): - print(f"Coudn't move {file_name} into IMG") - img.save("workspace/kolibri.img") - log("Done") - - # TODO: Autorun - run_qemu() +import os +import sys +import shutil +import urllib.request +import subprocess + +import build + +path_to_lib = '../lib' +sys.path.append(path_to_lib) + +from makeflop import Floppy + +# TODO: Move into _tools/lib +def get_file_directory(path): + path = path.replace("\\", "/") + if "/" in path: + folder = "/".join(path.split("/")[:-1]) + if folder == "": + return "/" # It was a file in the root folder + return folder + else: + return "." # Just a filename, let's return current folder + +# TODO: Move into _tools/lib +def is_win32(): + return True if sys.platform == "win32" else False + +# TODO: Move into _tools/lib +def is_linux(): + return True if sys.platform == "linux" or sys.platform == "linux2" else False + +# TODO: Move into _tools/lib +def is_osx(): + return True if sys.platform == "darwin" else False + +# TODO: Move into _tools/lib +def log(s, end = "\n"): + print(s, end = end, flush = True) + +# TODO: Move into _tools/lib +def download(link, path): + log(f"Downloading {path}... ", end = "") + urllib.request.urlretrieve(link, path) + log("Done.") + +# TODO: Move into _tools/lib +def path(*args): + return os.sep.join(args) + +# TODO: Move into _tools/lib +def run_qemu(start_dir = "workspace"): + qemu_command = f"qemu-system-i386" + flags = "" + flags += "-L . " # IDK why it does not work without this + flags += "-m 128 " + flags += f"-drive format=raw,file={start_dir}/kolibri.img,index=0,if=floppy -boot a " + flags += "-vga vmware " + flags += "-net nic,model=rtl8139 -net user " + flags += "-soundhw ac97 " + if is_win32(): + qemu_full_path = shutil.which(qemu_command) + qemu_directory = get_file_directory(qemu_full_path) + flags += f"-L {qemu_directory} " + s = f"{qemu_command} {flags}" + qemu_stdout = open(f"{start_dir}/qemu_stdout.log", "w") + qemu_stderr = open(f"{start_dir}/qemu_stderr.log", "w") + if is_win32(): + return subprocess.Popen(s, bufsize = 0, stdout = qemu_stdout, stderr = qemu_stderr, stdin = subprocess.DEVNULL, shell = True, start_new_session = True) + else: + a = shlex.split(s) + return subprocess.Popen(a, bufsize = 0, stdout = qemu_stdout, stderr = qemu_stderr, stdin = subprocess.DEVNULL, start_new_session = True) + +if __name__ == "__main__": + program_files = build.build() + + os.makedirs("workspace", exist_ok = True) + + if not os.path.exists("workspace/kolibri.img"): + img_url = "http://builds.kolibrios.org/eng/data/data/kolibri.img" + download(img_url, "workspace/kolibri.img") + + # Open the IMG + with open("workspace/kolibri.img", "rb") as img: + img_data = img.read() + img = Floppy(img_data) + + # Remove unuseful folders + img.delete_path("GAMES") + img.delete_path("DEMOS") + img.delete_path("3D") + + log("Moving program files into kolibri image... ", end = "") + for file_name in program_files: + with open(file_name, "rb") as file: + file_data = file.read() + if not img.add_file_path(file_name, file_data): + print(f"Coudn't move {file_name} into IMG") + img.save("workspace/kolibri.img") + log("Done") + + # TODO: Autorun + run_qemu()