summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorlepelog <25211966+lepelog@users.noreply.github.com>2023-08-09 16:59:04 +0200
committerlepelog <25211966+lepelog@users.noreply.github.com>2023-08-09 16:59:04 +0200
commit42880ec9aed16f89c4685cc09369d583b4c1300e (patch)
treeb511b2836a7ee9327d4e1e9bfa165a21521bc82e /tools
init
Diffstat (limited to 'tools')
-rw-r--r--tools/download_dtk.py41
-rwxr-xr-xtools/dtkbin0 -> 5691696 bytes
-rw-r--r--tools/dtk_version1
-rw-r--r--tools/ninja_syntax.py199
-rw-r--r--tools/progress.csv3
-rw-r--r--tools/sjis.py12
-rw-r--r--tools/transform-dep.py77
7 files changed, 333 insertions, 0 deletions
diff --git a/tools/download_dtk.py b/tools/download_dtk.py
new file mode 100644
index 00000000..53273cdd
--- /dev/null
+++ b/tools/download_dtk.py
@@ -0,0 +1,41 @@
+import argparse
+import urllib.request
+import os
+import stat
+import platform
+from pathlib import Path
+
+REPO = "https://github.com/encounter/decomp-toolkit"
+
+
+def main():
+ parser = argparse.ArgumentParser()
+ parser.add_argument("tag_file", help="file containing GitHub tag")
+ parser.add_argument("output", type=Path, help="output file path")
+ args = parser.parse_args()
+
+ with open(args.tag_file, "r") as f:
+ tag = f.readline().rstrip()
+
+ uname = platform.uname()
+ suffix = ""
+ system = uname.system.lower()
+ if system == "darwin":
+ system = "macos"
+ elif system == "windows":
+ suffix = ".exe"
+ arch = uname.machine.lower()
+ if arch == "amd64":
+ arch = "x86_64"
+
+ url = f"{REPO}/releases/download/{tag}/dtk-{system}-{arch}{suffix}"
+ output = args.output
+ # print(f"Downloading {url} to {output}")
+ urllib.request.urlretrieve(url, output)
+
+ st = os.stat(output)
+ os.chmod(output, st.st_mode | stat.S_IEXEC)
+
+
+if __name__ == "__main__":
+ main() \ No newline at end of file
diff --git a/tools/dtk b/tools/dtk
new file mode 100755
index 00000000..f230bf05
--- /dev/null
+++ b/tools/dtk
Binary files differ
diff --git a/tools/dtk_version b/tools/dtk_version
new file mode 100644
index 00000000..6da69f36
--- /dev/null
+++ b/tools/dtk_version
@@ -0,0 +1 @@
+v0.3.4 \ No newline at end of file
diff --git a/tools/ninja_syntax.py b/tools/ninja_syntax.py
new file mode 100644
index 00000000..e73b21a4
--- /dev/null
+++ b/tools/ninja_syntax.py
@@ -0,0 +1,199 @@
+#!/usr/bin/python
+
+# Copyright 2011 Google Inc. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Python module for generating .ninja files.
+
+Note that this is emphatically not a required piece of Ninja; it's
+just a helpful utility for build-file-generation systems that already
+use Python.
+"""
+
+import re
+import textwrap
+
+def escape_path(word):
+ return word.replace('$ ', '$$ ').replace(' ', '$ ').replace(':', '$:')
+
+class Writer(object):
+ def __init__(self, output, width=78):
+ self.output = output
+ self.width = width
+
+ def newline(self):
+ self.output.write('\n')
+
+ def comment(self, text):
+ for line in textwrap.wrap(text, self.width - 2, break_long_words=False,
+ break_on_hyphens=False):
+ self.output.write('# ' + line + '\n')
+
+ def variable(self, key, value, indent=0):
+ if value is None:
+ return
+ if isinstance(value, list):
+ value = ' '.join(filter(None, value)) # Filter out empty strings.
+ self._line('%s = %s' % (key, value), indent)
+
+ def pool(self, name, depth):
+ self._line('pool %s' % name)
+ self.variable('depth', depth, indent=1)
+
+ def rule(self, name, command, description=None, depfile=None,
+ generator=False, pool=None, restat=False, rspfile=None,
+ rspfile_content=None, deps=None):
+ self._line('rule %s' % name)
+ self.variable('command', command, indent=1)
+ if description:
+ self.variable('description', description, indent=1)
+ if depfile:
+ self.variable('depfile', depfile, indent=1)
+ if generator:
+ self.variable('generator', '1', indent=1)
+ if pool:
+ self.variable('pool', pool, indent=1)
+ if restat:
+ self.variable('restat', '1', indent=1)
+ if rspfile:
+ self.variable('rspfile', rspfile, indent=1)
+ if rspfile_content:
+ self.variable('rspfile_content', rspfile_content, indent=1)
+ if deps:
+ self.variable('deps', deps, indent=1)
+
+ def build(self, outputs, rule, inputs=None, implicit=None, order_only=None,
+ variables=None, implicit_outputs=None, pool=None, dyndep=None):
+ outputs = as_list(outputs)
+ out_outputs = [escape_path(x) for x in outputs]
+ all_inputs = [escape_path(x) for x in as_list(inputs)]
+
+ if implicit:
+ implicit = [escape_path(x) for x in as_list(implicit)]
+ all_inputs.append('|')
+ all_inputs.extend(implicit)
+ if order_only:
+ order_only = [escape_path(x) for x in as_list(order_only)]
+ all_inputs.append('||')
+ all_inputs.extend(order_only)
+ if implicit_outputs:
+ implicit_outputs = [escape_path(x)
+ for x in as_list(implicit_outputs)]
+ out_outputs.append('|')
+ out_outputs.extend(implicit_outputs)
+
+ self._line('build %s: %s' % (' '.join(out_outputs),
+ ' '.join([rule] + all_inputs)))
+ if pool is not None:
+ self._line(' pool = %s' % pool)
+ if dyndep is not None:
+ self._line(' dyndep = %s' % dyndep)
+
+ if variables:
+ if isinstance(variables, dict):
+ iterator = iter(variables.items())
+ else:
+ iterator = iter(variables)
+
+ for key, val in iterator:
+ self.variable(key, val, indent=1)
+
+ return outputs
+
+ def include(self, path):
+ self._line('include %s' % path)
+
+ def subninja(self, path):
+ self._line('subninja %s' % path)
+
+ def default(self, paths):
+ self._line('default %s' % ' '.join(as_list(paths)))
+
+ def _count_dollars_before_index(self, s, i):
+ """Returns the number of '$' characters right in front of s[i]."""
+ dollar_count = 0
+ dollar_index = i - 1
+ while dollar_index > 0 and s[dollar_index] == '$':
+ dollar_count += 1
+ dollar_index -= 1
+ return dollar_count
+
+ def _line(self, text, indent=0):
+ """Write 'text' word-wrapped at self.width characters."""
+ leading_space = ' ' * indent
+ while len(leading_space) + len(text) > self.width:
+ # The text is too wide; wrap if possible.
+
+ # Find the rightmost space that would obey our width constraint and
+ # that's not an escaped space.
+ available_space = self.width - len(leading_space) - len(' $')
+ space = available_space
+ while True:
+ space = text.rfind(' ', 0, space)
+ if (space < 0 or
+ self._count_dollars_before_index(text, space) % 2 == 0):
+ break
+
+ if space < 0:
+ # No such space; just use the first unescaped space we can find.
+ space = available_space - 1
+ while True:
+ space = text.find(' ', space + 1)
+ if (space < 0 or
+ self._count_dollars_before_index(text, space) % 2 == 0):
+ break
+ if space < 0:
+ # Give up on breaking.
+ break
+
+ self.output.write(leading_space + text[0:space] + ' $\n')
+ text = text[space+1:]
+
+ # Subsequent lines are continuations, so indent them.
+ leading_space = ' ' * (indent+2)
+
+ self.output.write(leading_space + text + '\n')
+
+ def close(self):
+ self.output.close()
+
+
+def as_list(input):
+ if input is None:
+ return []
+ if isinstance(input, list):
+ return input
+ return [input]
+
+
+def escape(string):
+ """Escape a string such that it can be embedded into a Ninja file without
+ further interpretation."""
+ assert '\n' not in string, 'Ninja syntax does not allow newlines'
+ # We only have one special metacharacter: '$'.
+ return string.replace('$', '$$')
+
+
+def expand(string, vars, local_vars={}):
+ """Expand a string containing $vars as Ninja would.
+
+ Note: doesn't handle the full Ninja variable syntax, but it's enough
+ to make configure.py's use of it work.
+ """
+ def exp(m):
+ var = m.group(1)
+ if var == '$':
+ return '$'
+ return local_vars.get(var, vars.get(var, ''))
+ return re.sub(r'\$(\$|\w*)', exp, string) \ No newline at end of file
diff --git a/tools/progress.csv b/tools/progress.csv
new file mode 100644
index 00000000..97e3ab79
--- /dev/null
+++ b/tools/progress.csv
@@ -0,0 +1,3 @@
+code_count_in_rupees,code_completion_in_bytes,code_completion_in_percentage,data_count_in_gratitude crystals,data_completion_in_bytes,data_completion_in_percentage,sentence,created_at
+0,0,0.0,0,0,0.0,"
+You have 0 out of 9999 Rupees and 0 out of 80 gratitude crystals.",2023-07-12 16:27:48.804596
diff --git a/tools/sjis.py b/tools/sjis.py
new file mode 100644
index 00000000..a77ae917
--- /dev/null
+++ b/tools/sjis.py
@@ -0,0 +1,12 @@
+from argparse import ArgumentParser
+
+parser = ArgumentParser()
+parser.add_argument("input")
+parser.add_argument("output")
+args = parser.parse_args()
+
+with open(args.input, encoding="utf-8") as f:
+ txt = f.read()
+
+with open(args.output, 'w', encoding="shift-jis") as f:
+ f.write(txt) \ No newline at end of file
diff --git a/tools/transform-dep.py b/tools/transform-dep.py
new file mode 100644
index 00000000..5807ab1f
--- /dev/null
+++ b/tools/transform-dep.py
@@ -0,0 +1,77 @@
+#!/usr/bin/env python3
+# borrowed from prime-decomp
+import argparse
+import os
+from platform import uname
+from typing import List
+
+if os.name != 'nt':
+ wineprefix = os.environ.get('WINEPREFIX', os.path.join(os.environ['HOME'], '.wine'))
+ winedevices = os.path.join(wineprefix, 'dosdevices')
+
+
+def in_wsl() -> bool:
+ # wsl1 has Microsoft, wsl2 has microsoft-standard
+ release = uname().release
+ return 'microsoft-standard' in release or 'Microsoft' in release
+
+
+def convert_path(path: str) -> str:
+ # lowercase drive letter
+ path = path[0].lower() + path[1:]
+ if os.name == 'nt':
+ return path.replace('\\', '/')
+ elif path[0] == 'z':
+ # shortcut for z:
+ return path[2:].replace('\\', '/')
+ elif in_wsl():
+ if path.startswith(r'\\wsl'):
+ # first part could be wsl$ or wsl.localhost
+ pos = path.find('\\', 2)
+ pos = path.find('\\', pos + 1)
+ path = path[pos:]
+ return path.replace('\\', '/')
+ else:
+ path = path[0:1] + path[2:]
+ return os.path.join('/mnt', path.replace('\\', '/'))
+ else:
+ # use $WINEPREFIX/dosdevices to resolve path
+ return os.path.realpath(os.path.join(winedevices, path.replace('\\', '/')))
+
+
+def import_d_file(in_file: str) -> str:
+ out_lines: List[str] = []
+
+ with open(in_file, 'r') as file:
+ it = iter(file)
+ line = next(it)
+ if line.endswith(' \\\n'):
+ out_lines.append(line[:-3].replace('\\', '/') + " \\\n")
+ else:
+ out_lines.append(line.replace('\\', '/'))
+
+ return ''.join(out_lines)
+
+
+def main():
+ parser = argparse.ArgumentParser(
+ description="""Transform a .d file from Wine paths to normal paths"""
+ )
+ parser.add_argument(
+ "d_file",
+ help="""Dependency file in""",
+ )
+ parser.add_argument(
+ "d_file_out",
+ help="""Dependency file out""",
+ )
+ args = parser.parse_args()
+
+ output = import_d_file(args.d_file)
+
+ with open(args.d_file_out, "w", encoding="UTF-8") as f:
+ f.write(output)
+
+
+if __name__ == "__main__":
+ main()