/_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) |
/_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 |
/_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() |
/_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() |