_SCREENLINE_IGNORE_CHAR = '§'
_SCREENLINE_PADDING_SUFFIX = 2 * _SCREENLINE_IGNORE_CHAR
-_N_ARGS_FOR_CMD = {
- _MARK_ANCHOR: 1,
- _MARK_COMMENT: 2,
- _MARK_LOG: 2,
- _MARK_LOGSRVRMSG: 3,
- _MARK_PROMPT: 1,
- _MARK_REPEAT: 2,
- _MARK_SCREENLINE: 3,
- _MARK_SERVERMSG: 2,
- _MARK_WAIT: 1
+_SIGNATURE_FOR_CMD = {
+ _MARK_LOG: (2, 0),
+ _MARK_LOGSRVRMSG: (3, 0),
+ _MARK_PROMPT: (1, None),
+ _MARK_REPEAT: (2, 1),
+ _MARK_SCREENLINE: (3, 0),
+ _MARK_SERVERMSG: (2, 0),
+ _MARK_WAIT: (1, 0),
}
self._lines_t = [(str(idx + 1), line.rstrip('\n'))
for idx, line in enumerate(f.readlines())]
- def expand_parsed(marker: str, parse_into: Callable, **kwargs) -> bool:
- inserts: list[tuple[str, str]] = []
- for idx, line_t in enumerate(self._lines_t):
- if not line_t[1]:
- continue
+ def expand_parsed(marker: str, parse_into: Callable, **kwargs) -> None:
+ new_lines_t: list[tuple[str, str]] = []
+ for line_t in reversed(self._lines_t):
cmd_name, remains = line_t[1].split(_SEP_0, maxsplit=1)
- if not cmd_name == marker:
- continue
- inserts = parse_into(line_t[0],
- self._args_for_cmd(cmd_name, remains),
- **kwargs)
- self._lines_t = (self._lines_t[:idx]
- + inserts
- + self._lines_t[idx + 1:])
- break
- return bool(inserts)
+ inserts = [line_t]
+ if cmd_name == marker:
+ inserts = parse_into(
+ line_t[0],
+ self._args_for_cmd(cmd_name, remains),
+ **kwargs)
+ new_lines_t[0:0] = inserts
+ self._lines_t = new_lines_t
def split_server_put_and_log(index_str: str,
args: tuple[str, ...],
**__
) -> list[tuple[str, str]]:
inserts: list[tuple[str, str]] = []
- for inserted_t in self._lines_t[
- int(anchors[args[0]+'-in'] + 1):
- int(anchors[args[0]+'-out'])]:
+ for inserted_t in self._lines_t[int(anchors[args[0]+'-in']):
+ int(anchors[args[0]+'-out'])]:
insert = inserted_t[1]
- if len(args) == 2 and insert:
- cmd_name, remains = insert.split(_SEP_0, maxsplit=1)
- if cmd_name == _MARK_ANCHOR:
- continue
- args_ = list(self._args_for_cmd(cmd_name, remains))
- if args[1][0] in '+-':
- args_[0] = _SEP_1.join(
- str(int(n) + int(args[1]))
- for n in args_[0].split(_SEP_1) if n
- ) or ','
- else:
- args_[0] = args[1]
+ cmd_name, remains = insert.split(_SEP_0, maxsplit=1)
+ if cmd_name == _MARK_ANCHOR: # anchors should be unique,
+ continue # so avoid their repittion
+ args_idx = _SIGNATURE_FOR_CMD[cmd_name][1]
+ args_ = list(self._args_for_cmd(cmd_name, remains))
+ if len(args) == 2\
+ and args_idx is not None\
+ and len(args_) > args_idx:
+ args_[args_idx] = _SEP_1.join(
+ str(int(n) + int(args[1]))
+ for n in args_[args_idx].split(_SEP_1) if n
+ ) or ','
insert = _SEP_0.join([cmd_name] + args_)
inserts += [(index_str + ':r:' + inserted_t[0], insert)]
return inserts
- while expand_parsed(_MARK_LOGSRVRMSG, split_server_put_and_log):
- pass
+ self._lines_t = [line_t for line_t in self._lines_t
+ if line_t[1]
+ and not line_t[1].startswith(_MARK_COMMENT)]
+ expand_parsed(_MARK_LOGSRVRMSG, split_server_put_and_log)
while True:
anchors: dict[str, int] = {}
for idx, line_t in enumerate(self._lines_t):
if line_t[1].startswith(_MARK_ANCHOR):
anchors[line_t[1].split(_SEP_0, maxsplit=1)[1]] = idx
- if not expand_parsed(_MARK_REPEAT, repeat, anchors=anchors):
+ snapshot_before = self._lines_t[:]
+ expand_parsed(_MARK_REPEAT, repeat, anchors=anchors)
+ if self._lines_t == snapshot_before:
break
- self._lines_t = [
- line_t for line_t in self._lines_t
- if line_t[1] and not (line_t[1].startswith(_MARK_ANCHOR)
- or line_t[1].startswith(_MARK_COMMENT))]
+ self._lines_t = [line_t for line_t in self._lines_t
+ if not line_t[1].startswith(_MARK_ANCHOR)]
+
if self._verbose:
title_idx = 'line number(s)'
title_cmdname = 'command'
@staticmethod
def _args_for_cmd(cmd_name: str, remains: str) -> tuple[str, ...]:
- n_args = _N_ARGS_FOR_CMD[cmd_name]
+ n_args = _SIGNATURE_FOR_CMD[cmd_name][0]
return ((remains,) if n_args == 1
else tuple(remains.split(_SEP_0, maxsplit=n_args - 1)))