so much more shit man
This commit is contained in:
parent
9e065cd638
commit
e8ffddf93f
|
@ -1,39 +0,0 @@
|
|||
from lark import Lark
|
||||
from lark.lexer import Token
|
||||
from lark.tree import Branch
|
||||
|
||||
import re
|
||||
|
||||
def parse_string(token: Token):
|
||||
if token.type == 'STRING':
|
||||
string = token.value[1:-1]
|
||||
string = re.sub(r"\\n","\n", string)
|
||||
string = re.sub(r"\\t","\t", string)
|
||||
string = re.sub(r"\\r","\r", string)
|
||||
string = re.sub(r"\\(.)",r"\1", string)
|
||||
return string
|
||||
elif token.type == 'RAW_STRING':
|
||||
string = token.value[1:-1]
|
||||
return string
|
||||
elif token.type == 'LONG_STRING':
|
||||
string = re.match(re.compile(r"<<\s*(?P<terminator>[^\n]+)\n(.*)\n(?P=terminator)", re.MULTILINE + re.DOTALL),token.value)
|
||||
assert string is not None
|
||||
string = string.group(2)
|
||||
return string
|
||||
|
||||
def process_patch(branch: Branch[Token]):
|
||||
# First instruction is always file declaration
|
||||
target_file = parse_string(branch.children[0].children[0]) # pyright: ignore[reportUnknownMemberType, reportArgumentType]
|
||||
|
||||
for inst in branch.children[1:]:
|
||||
match inst.data:
|
||||
case "insert":
|
||||
print(f"Inserting {parse_string(inst.children[1])} at {inst.children[0]} in {target_file}")
|
||||
|
||||
if __name__ == '__main__':
|
||||
lark = Lark.open('grammar.lark', rel_to=__file__)
|
||||
|
||||
with open('test.txt', 'r') as f:
|
||||
result = lark.parse(f.read())
|
||||
for patch in result.children:
|
||||
process_patch(patch)
|
26
buildtool/patcher/filepatcher.py
Normal file
26
buildtool/patcher/filepatcher.py
Normal file
|
@ -0,0 +1,26 @@
|
|||
from polly import parse_patch_file
|
||||
from polly import parse_location
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
from ..task.util import *
|
||||
|
||||
def read_insertion(action, patch_file):
|
||||
with open(patch_file, 'r') as f:
|
||||
src = f.read()
|
||||
location = parse_location(action["at"], src)
|
||||
|
||||
|
||||
def process_patch_file(patch_file: str, check_date: bool = True):
|
||||
patches = parse_patch_file(patch_file)
|
||||
|
||||
for patch in patches:
|
||||
target_dest = (PATCHED_RSC_DIR / patch["target"])
|
||||
if check_date and target_dest.exists() and target_dest.stat().st_mtime > patch["timestamp"]:
|
||||
# Patch skipped
|
||||
continue
|
||||
|
||||
insertions = [read_insertion(action) for action in patch["actions"]]
|
||||
insertions = [x for x in insertions if x is not None]
|
||||
|
||||
|
|
@ -38,4 +38,7 @@ LINE_COLUMN: /ln\d+c\d+/
|
|||
IDENTIFIER: /[a-zA-Z_][a-zA-Z0-9_]*/
|
||||
PATTERN: /\/([^\/\\]|\\.)*\//
|
||||
|
||||
COMMENT: /#[^\r\n]+/
|
||||
|
||||
%ignore /[\t \f\n]+/
|
||||
%ignore COMMENT
|
77
buildtool/patcher/polly.py
Normal file
77
buildtool/patcher/polly.py
Normal file
|
@ -0,0 +1,77 @@
|
|||
from lark import Lark
|
||||
from lark.lexer import Token
|
||||
from lark.tree import Branch
|
||||
|
||||
import os
|
||||
|
||||
import re
|
||||
|
||||
from math import floor
|
||||
|
||||
def parse_string(token: Token):
|
||||
if token.type == 'STRING':
|
||||
string = token.value[1:-1]
|
||||
string = re.sub(r"\\n","\n", string)
|
||||
string = re.sub(r"\\t","\t", string)
|
||||
string = re.sub(r"\\r","\r", string)
|
||||
string = re.sub(r"\\(.)",r"\1", string)
|
||||
return string
|
||||
elif token.type == 'RAW_STRING':
|
||||
string = token.value[1:-1]
|
||||
return string
|
||||
elif token.type == 'LONG_STRING':
|
||||
string = re.match(re.compile(r"<<\s*(?P<terminator>[^\n]+)\n(.*)\n(?P=terminator)", re.MULTILINE + re.DOTALL),token.value)
|
||||
assert string is not None
|
||||
string = string.group(2)
|
||||
return string
|
||||
|
||||
def parse_location(location: Token):
|
||||
assert isinstance(location.value, str)
|
||||
m = re.match(r"ln([0-9]+)(?:c([0-9]+))?", location.value)
|
||||
if m:
|
||||
ln, col = m.groups()
|
||||
return {"type": "lncol", "line": ln, "column": col}
|
||||
|
||||
m = re.match(r"ch([0-9]+)", location.value)
|
||||
if m:
|
||||
ch = m.groups()[0]
|
||||
return {"type": "char", "index": ch}
|
||||
|
||||
raise RuntimeError("Cannot parse location")
|
||||
|
||||
def absolute_location(location, src: str):
|
||||
if location["type"] == "char":
|
||||
return location["index"]
|
||||
elif location["type"] == "lncol":
|
||||
j = 0
|
||||
for i, x in enumerate(src.split('\n')):
|
||||
if i ==
|
||||
j += len(x) + 1
|
||||
|
||||
print(f"Cannot insert at line {location['line']}. The file is not long enough.")
|
||||
exit(-1)
|
||||
|
||||
def parse_patch(branch: Branch[Token], mtime: float):
|
||||
# First instruction is always file declaration
|
||||
target_file = parse_string(branch.children[0].children[0]) # pyright: ignore[reportUnknownMemberType, reportArgumentType]
|
||||
|
||||
actions = []
|
||||
|
||||
for inst in branch.children[1:]:
|
||||
match inst.data:
|
||||
case "insert":
|
||||
actions.append({"type": "insert", "at": parse_location(inst.children[0]), "content": parse_string(inst.children[1])})
|
||||
# print(f"Inserting {parse_string(inst.children[1])} at {inst.children[0]} in {target_file}")
|
||||
|
||||
return {"target": target_file, "actions": actions, "timestamp": mtime}
|
||||
|
||||
def parse_patch_file(file: str):
|
||||
lark = Lark.open('grammar.lark', rel_to=__file__)
|
||||
|
||||
mtime = os.path.getmtime(file)
|
||||
|
||||
with open(file, 'r') as f:
|
||||
result = lark.parse(f.read())
|
||||
patches = [parse_patch(patch, mtime) for patch in result.children]
|
||||
|
||||
return patches
|
|
@ -1,7 +1,7 @@
|
|||
from pathlib import Path
|
||||
import shutil
|
||||
|
||||
def merge_into(src: Path | str, dest: Path | str):
|
||||
def merge_into(src: Path | str, dest: Path | str, check_date: bool = True):
|
||||
src = Path(src)
|
||||
dest = Path(dest)
|
||||
|
||||
|
@ -13,7 +13,7 @@ def merge_into(src: Path | str, dest: Path | str):
|
|||
dest_file = dest / src_file.relative_to(src)
|
||||
|
||||
# Don't update if dest is newer than source
|
||||
if dest_file.exists() and src_file.stat().st_mtime < dest_file.stat().st_mtime:
|
||||
if check_date and dest_file.exists() and src_file.stat().st_mtime < dest_file.stat().st_mtime:
|
||||
continue
|
||||
|
||||
dest_file.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
@ -21,4 +21,3 @@ def merge_into(src: Path | str, dest: Path | str):
|
|||
changed = True
|
||||
|
||||
return changed
|
||||
|
|
@ -9,33 +9,18 @@ from .extract import extract
|
|||
def patch_resources():
|
||||
_ = extract()
|
||||
|
||||
# The way we merge resources is as follows:
|
||||
# First, we copy our raw-resources from src/resources
|
||||
# Second, we apply our patches, which are handled by polly
|
||||
# Finally, we populate all missing entries from build/extracted
|
||||
# The reason we do this is that build/extracted will always have a date greater than src/resources
|
||||
# until the files are modified after first build, which makes simply merging-by-date impossible.
|
||||
first_time = False
|
||||
|
||||
s = fileutil.merge_into(SRC_RESOURCES_DIR, PATCHED_RSC_DIR)
|
||||
# Copy original resources only the first time
|
||||
if not PATCHED_RSC_DIR.exists():
|
||||
print("Copying original resources...")
|
||||
shutil.copytree(EXTRACTED_DIR, PATCHED_RSC_DIR, ignore=shutil.ignore_patterns("smali*"))
|
||||
first_time = True
|
||||
|
||||
s = fileutil.merge_into(SRC_RESOURCES_DIR, PATCHED_RSC_DIR, check_date=not first_time)
|
||||
if s:
|
||||
print("Copied custom resources from src/resources")
|
||||
else:
|
||||
print("Skipped copying resources from src/resources")
|
||||
|
||||
print("Copying original resources...")
|
||||
for (cd, _, files) in EXTRACTED_DIR.walk():
|
||||
for file in files:
|
||||
# Don't copy smali code
|
||||
if file.startswith("smali"):
|
||||
continue
|
||||
|
||||
src_file = cd / file
|
||||
dest_file = PATCHED_RSC_DIR / src_file.relative_to(EXTRACTED_DIR)
|
||||
|
||||
# Don't update if dest is newer than source
|
||||
if dest_file.exists() and src_file.stat().st_mtime < dest_file.stat().st_mtime:
|
||||
continue
|
||||
|
||||
dest_file.parent.mkdir(parents=True, exist_ok=True)
|
||||
_ = shutil.copyfile(src_file, dest_file)
|
||||
|
12
src/patches/public.patch
Normal file
12
src/patches/public.patch
Normal file
|
@ -0,0 +1,12 @@
|
|||
file 'res/values/public.xml'
|
||||
|
||||
insert ln17595 << @end
|
||||
<public type="drawable" name="oval_yellow" id="0x7f08f001" /> <!-- YKit-BringBackPhoebe -->
|
||||
<public type="id" name="ykit_settings" id="0x7f0bf001" /> <!-- YKit-Settings -->
|
||||
<public type="id" name="ykit_version" id="0x7f0bf003" /> <!-- YKit-Settings -->
|
||||
<public type="id" name="text_color_yellow" id="0x7f0bf002" /> <!-- YKit-BringBackPhoebe -->
|
||||
<public type="layout" name="activity_ykit_settings" id="0x7f0ef001" /> <!-- YKit-Settings -->
|
||||
<public type="raw" name="ykit_meow" id="0x7f12f001" /> <!-- YKit-Settings -->
|
||||
@end
|
||||
|
||||
#17595
|
17601
src/patches/public.xml
Normal file
17601
src/patches/public.xml
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue