From e04073f5432faab70f6f749627ee86123d104434 Mon Sep 17 00:00:00 2001 From: Orbyfied Date: Mon, 13 Feb 2023 22:53:15 +0100 Subject: [PATCH] remove unnecessary libpy --- libpy/args.py | 213 -------------------------------------------------- libpy/util.py | 132 ------------------------------- tool.py | 3 - 3 files changed, 348 deletions(-) delete mode 100644 libpy/args.py delete mode 100644 libpy/util.py diff --git a/libpy/args.py b/libpy/args.py deleted file mode 100644 index 309b4f9..0000000 --- a/libpy/args.py +++ /dev/null @@ -1,213 +0,0 @@ -from libpy.util import * - -################################ -# CLI -################################ - -def stitch_args(argv): - str = "" - l = len(argv) - for i in range(1, l): - arg = argv[i] - if " " in arg: - str += "\"" + argv[i] + "\" " - else: - str += argv[i] + " " - return str - -# the pos value to signal the argument -# should be appended to the end -POS_APPEND_BACK = 0xFFFFFFFF - -class ArgError(RuntimeError): - def __init__(self, *args: object) -> None: - super().__init__(*args) - -# simple arg repr -class Arg: - # create a simple named arg - def new(name: str, char: str, ty: type): - return Arg(name, char, ty, None, None) - # create a simple positional arg - def new_positional(name: str, ty: type): - return Arg(name, None, ty, None, POS_APPEND_BACK) - # create a positional arg at the specified idx/pos - def new_positional_at(name: str, ty: type, pos: int): - return Arg(name, None, ty, None, pos) - # create a switch arg - def new_switch(name: str, char: str, ty: type, switch_handler): - return Arg(name, char, ty, switch_handler, None) - # create a boolean switch arg - def new_bool_switch(name: str, char: str): - return Arg.new_switch(name, char, bool, lambda *_ : True) - - def __init__(self, name: str, char: str, ty: type, sw_handler, pos: int): - self.name = name - self.char = char - self.ty = ty - self.sw_handler = sw_handler - self.pos = pos - self.defv = None - - def default(self, val): - self.defv = val - return self - -# a parser for a type -class TypeParser: - def __init__(self, ty: type, pfunc): - self.ty = ty - self.pfunc = pfunc - - # abstract: parses the type - def parse(self, parser, arg: Arg, reader: Reader): - return self.pfunc(parser, arg, reader) - -## Default Types ## - -def _parse_str(_1, _2, reader: Reader): - sc = reader.current() - if sc == '\'' or sc == "\"": - str = "" - reader.next() - while reader.current() and reader.current() != sc: - c = reader.current() - if c == '\\': - str += reader.next() - reader.next() - continue - str += c - reader.next() - reader.next() - return str - else: - return reader.collect(lambda c : not c.isspace()) - -def _parse_bool(_1, _2, reader: Reader): - if reader.current() == '1': - return True - elif reader.current() == '0': - return False - str = reader.collect(lambda c : not c.isspace()) - if str == 'true': - return True - return False - -def define_default_types(parser): - parser.define_type(TypeParser(int, lambda _1, _2, reader : int(reader.collect(lambda c : c.isdigit() or c == '-')))) - parser.define_type(TypeParser(float, lambda _1, _2, reader : float(reader.collect(lambda c : c.isdigit() or c == '-' or c == '.')))) - parser.define_type(TypeParser(str, _parse_str)) - parser.define_type(TypeParser(bool, _parse_bool)) - -# arg parser -class ArgParser: - def __init__(self): - self.arg_map = { } # args by name - self.pos_args = [ ] # positioned list of args - self.by_char = { } # args by char - self.types = { } # type parsers - - define_default_types(self) - - def define_type(self, ty: TypeParser): - self.types[ty.ty] = ty - - def get_type(self, ty: type): - if not ty in self.types: - raise ArgError("no type parser defined for " + str(ty)) - return self.types[ty] - - def add(self, arg: Arg): - self.arg_map[arg.name] = arg - if arg.char != None: - self.by_char[arg.char] = arg - if arg.pos != None: - if arg.pos == POS_APPEND_BACK: - self.pos_args.append(arg) - else: - self.pos_args.insert(get_idx_by_pos(len(self.pos_args), arg.pos), arg) - - def parse_val(self, arg: Arg, reader: Reader): - try: - return self.get_type(arg.ty).parse(self, arg, reader) - except ArgError as e: - print("arg: error occured parsing " + arg.name + ": " + e) - raise ArgError("arg parse failed") - - def parse_errexit(self, arg_str: str, out: dict = None): - try: - return self.parse(arg_str, out=out) - except ArgError as e: - print(full_type_name(e.__class__) + ": " + flat_concat(e.args)) - os._exit(-1) - - def parse(self, arg_str: str, out: dict = None): - if not out: - out = { } - - pIdx = 0 # positional arg index - reader = Reader(arg_str) # string reader - c = None # char - - while reader.current() != None: - # collect whitespace - reader.pcollect(lambda c : c.isspace()) - - c = reader.current() - if not c: - break - - # check for flags - if c == '-': - # check for named - if reader.next() == '-': - # collect name - reader.next() - name = reader.collect(lambda c : c != ' ' and c != '=') - - if not name in self.arg_map: - raise ArgError("unknown arg by name " + name) - arg = self.arg_map[name] - - # check for explicit value - # or spaced value - # otherwise handle switch - val = None - if not arg.sw_handler or reader.current() == '=': - reader.next() - val = self.parse_val(arg, reader) - else: # switch - val = arg.sw_handler(self, arg) - - # put val - out[arg.name] = val - else: - while reader.current() != None and reader.current() != ' ': - if not reader.current() in self.by_char: - raise ArgError("unknown arg by char '" + reader.current() + "'") - arg = self.by_char[reader.current()] - - # check switch - if not arg.sw_handler: - reader.next() - val = self.parse_val(arg, reader) - out[arg.name] = val - break - else: - out[arg.name] = arg.sw_handler(self, arg) - reader.next() - else: - # handle positional arg - if pIdx >= len(self.pos_args): - raise ArgError("unexpected positional argument " + str(pIdx)) - arg = self.pos_args[pIdx] - pIdx += 1 - val = self.parse_val(arg, reader) - out[arg.name] = val - - # set default values for all unset args - for arg in self.arg_map.values(): - if not arg.name in out and arg.defv: - out[arg.name] = arg.defv - - return out \ No newline at end of file diff --git a/libpy/util.py b/libpy/util.py deleted file mode 100644 index 2597f31..0000000 --- a/libpy/util.py +++ /dev/null @@ -1,132 +0,0 @@ -import os - -################################ -# Utilities -################################ - -class Reader: - def __init__(self, str): - self.str = str - self.idx = 0 - - def current(self): - if self.idx < 0 or self.idx >= len(self.str): - return None - return self.str[self.idx] - - def next(self, amt = 1): - self.idx += amt - if self.idx < 0 or self.idx >= len(self.str): - return None - return self.str[self.idx] - - def prev(self, amt = 1): - self.idx -= amt - if self.idx < 0 or self.idx >= len(self.str): - return None - return self.str[self.idx] - - def peek(self, off): - idx = self.idx + off - if idx >= len(self.str) or idx < 0: - return None - return self.str[idx] - - def at(self, index): - if index > 0: - return self.str[index] - else: - idx = self.idx - abs(index) - if idx >= len(self.str) or idx < 0: - return None - return self.str[idx] - - def collect(self, pred): - str = "" - while self.current() != None and pred(self.current()): - str += self.current() - self.next() - return str - - def pcollect(self, pred): - while self.current() != None and pred(self.current()): - self.next() - return str - -# check if the given char is a path sep -def is_path_sep(char): - return char == '\\' or char == '/' - -# fixes the given path and replaces -# placeholders in it -def fix_path(pstr): - seg = "" - segments = [] - reader = Reader(pstr) - char = reader.current() - while char != None: - # check for separator - if is_path_sep(char): - if len(seg) > 2 and seg[0] == '%': - seg = os.getenv(seg[1:-1]) - segments.append(seg) - seg = "" - else: - seg += char - - char = reader.next() - - # stitch to string - result = "" - for segment in segments: - result += segment + "/" - return result - -# get index by position/offset -# into a list of length len -def get_idx_by_pos(len, pos): - if pos < 0: - return len + pos - else: - return pos - -def flat_concat(list): - rstr = "" - l = len(list) - for i in range(0, l): - rstr += str(list[i]) - if i < l - 1: - rstr += ", " - return rstr - -# -# from: https://stackoverflow.com/questions/2020014/get-fully-qualified-class-name-of-an-object-in-python -# -def full_type_name(klass): - module = klass.__module__ - if module == 'builtins': - return klass.__qualname__ # avoid outputs like 'builtins.str' - return module + '.' + klass.__qualname__ - -def replace_placeholders(istr: str, vals: dict): - reader = Reader(istr) - ostr = "" - while reader.current(): - # check for placeholder - if reader.current() == '$' and reader.peek(1) == '{': - reader.next(2) - - # collect name - name = reader.collect(lambda c : c != '}') - reader.next() # close brackets - - # replace name - val = None - if name in vals: - val = vals[name] - ostr += str(val) - else: - # append char - ostr += reader.current() - reader.next() - return ostr \ No newline at end of file diff --git a/tool.py b/tool.py index cb6660f..4b2b3bb 100644 --- a/tool.py +++ b/tool.py @@ -7,9 +7,6 @@ import os import sys -from libpy.util import * -from libpy.args import * - ## Find the root project directory ## which is the directory which contains settings.gradle def find_root_project_dir():