omlish 0.0.0.dev188__py3-none-any.whl → 0.0.0.dev189__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- omlish/__about__.py +2 -2
- omlish/io/buffers.py +11 -0
- omlish/io/generators/stepped.py +11 -10
- omlish/subprocesses.py +1 -0
- omlish/term/vt100/__init__.py +0 -0
- omlish/term/vt100/c.py +106 -0
- omlish/term/vt100/states.py +271 -0
- {omlish-0.0.0.dev188.dist-info → omlish-0.0.0.dev189.dist-info}/METADATA +1 -1
- {omlish-0.0.0.dev188.dist-info → omlish-0.0.0.dev189.dist-info}/RECORD +14 -11
- /omlish/term/{vt100.py → vt100/terminal.py} +0 -0
- {omlish-0.0.0.dev188.dist-info → omlish-0.0.0.dev189.dist-info}/LICENSE +0 -0
- {omlish-0.0.0.dev188.dist-info → omlish-0.0.0.dev189.dist-info}/WHEEL +0 -0
- {omlish-0.0.0.dev188.dist-info → omlish-0.0.0.dev189.dist-info}/entry_points.txt +0 -0
- {omlish-0.0.0.dev188.dist-info → omlish-0.0.0.dev189.dist-info}/top_level.txt +0 -0
    
        omlish/__about__.py
    CHANGED
    
    
    
        omlish/io/buffers.py
    CHANGED
    
    | @@ -129,10 +129,15 @@ class DelimitingBuffer: | |
| 129 129 |  | 
| 130 130 |  | 
| 131 131 | 
             
            class ReadableListBuffer:
         | 
| 132 | 
            +
                # FIXME: merge with PrependableGeneratorReader
         | 
| 133 | 
            +
             | 
| 132 134 | 
             
                def __init__(self) -> None:
         | 
| 133 135 | 
             
                    super().__init__()
         | 
| 134 136 | 
             
                    self._lst: list[bytes] = []
         | 
| 135 137 |  | 
| 138 | 
            +
                def __len__(self) -> int:
         | 
| 139 | 
            +
                    return sum(map(len, self._lst))
         | 
| 140 | 
            +
             | 
| 136 141 | 
             
                def feed(self, d: bytes) -> None:
         | 
| 137 142 | 
             
                    if d:
         | 
| 138 143 | 
             
                        self._lst.append(d)
         | 
| @@ -171,6 +176,12 @@ class ReadableListBuffer: | |
| 171 176 |  | 
| 172 177 | 
             
                    return None
         | 
| 173 178 |  | 
| 179 | 
            +
                def read_exact(self, sz: int) -> bytes:
         | 
| 180 | 
            +
                    d = self.read(sz)
         | 
| 181 | 
            +
                    if d is None or len(d) != sz:
         | 
| 182 | 
            +
                        raise EOFError(f'ReadableListBuffer got {"no" if d is None else len(d)}, expected {sz}')
         | 
| 183 | 
            +
                    return d
         | 
| 184 | 
            +
             | 
| 174 185 | 
             
                def read_until(self, delim: bytes = b'\n') -> ta.Optional[bytes]:
         | 
| 175 186 | 
             
                    if not (lst := self._lst):
         | 
| 176 187 | 
             
                        return None
         | 
    
        omlish/io/generators/stepped.py
    CHANGED
    
    | @@ -2,6 +2,7 @@ import typing as ta | |
| 2 2 |  | 
| 3 3 | 
             
            from ... import check
         | 
| 4 4 | 
             
            from ... import lang
         | 
| 5 | 
            +
            from ..buffers import ReadableListBuffer
         | 
| 5 6 | 
             
            from .consts import DEFAULT_BUFFER_SIZE
         | 
| 6 7 | 
             
            from .direct import BytesDirectGenerator
         | 
| 7 8 | 
             
            from .direct import StrDirectGenerator
         | 
| @@ -149,33 +150,33 @@ def read_into_str_stepped_generator( | |
| 149 150 |  | 
| 150 151 | 
             
            @lang.autostart
         | 
| 151 152 | 
             
            def buffer_bytes_stepped_reader_generator(g: BytesSteppedReaderGenerator) -> BytesSteppedGenerator:
         | 
| 153 | 
            +
                i: bytes | None
         | 
| 152 154 | 
             
                o = g.send(None)
         | 
| 153 | 
            -
                 | 
| 155 | 
            +
                rlb = ReadableListBuffer()
         | 
| 154 156 | 
             
                eof = False
         | 
| 155 157 |  | 
| 156 158 | 
             
                while True:
         | 
| 157 159 | 
             
                    if eof:
         | 
| 158 160 | 
             
                        raise EOFError
         | 
| 159 161 |  | 
| 160 | 
            -
                    if not  | 
| 161 | 
            -
                         | 
| 162 | 
            -
             | 
| 162 | 
            +
                    if not len(rlb):
         | 
| 163 | 
            +
                        if (more := check.isinstance((yield None), bytes)):
         | 
| 164 | 
            +
                            rlb.feed(more)
         | 
| 165 | 
            +
                        else:
         | 
| 163 166 | 
             
                            eof = True
         | 
| 164 167 |  | 
| 165 168 | 
             
                    if o is None:
         | 
| 166 | 
            -
                        i =  | 
| 167 | 
            -
                        buf = None
         | 
| 169 | 
            +
                        i = check.not_none(rlb.read())
         | 
| 168 170 |  | 
| 169 171 | 
             
                    elif isinstance(o, int):
         | 
| 170 | 
            -
                        while len( | 
| 172 | 
            +
                        while len(rlb) < o:
         | 
| 171 173 | 
             
                            more = check.isinstance((yield None), bytes)
         | 
| 172 174 | 
             
                            if not more:
         | 
| 173 175 | 
             
                                raise EOFError
         | 
| 174 176 | 
             
                            # FIXME: lol - share guts with readers
         | 
| 175 | 
            -
                             | 
| 177 | 
            +
                            rlb.feed(more)
         | 
| 176 178 |  | 
| 177 | 
            -
                        i =  | 
| 178 | 
            -
                        buf = buf[o:]
         | 
| 179 | 
            +
                        i = check.not_none(rlb.read(o))
         | 
| 179 180 |  | 
| 180 181 | 
             
                    else:
         | 
| 181 182 | 
             
                        raise TypeError(o)
         | 
    
        omlish/subprocesses.py
    CHANGED
    
    
| 
            File without changes
         | 
    
        omlish/term/vt100/c.py
    ADDED
    
    | @@ -0,0 +1,106 @@ | |
| 1 | 
            +
            import io
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            from ... import check
         | 
| 4 | 
            +
            from .states import ACTIONS_IN_ORDER
         | 
| 5 | 
            +
            from .states import STATE_TABLES
         | 
| 6 | 
            +
            from .states import STATES
         | 
| 7 | 
            +
            from .states import STATES_IN_ORDER
         | 
| 8 | 
            +
            from .states import StateTransition
         | 
| 9 | 
            +
            from .states import check_state_tables
         | 
| 10 | 
            +
             | 
| 11 | 
            +
             | 
| 12 | 
            +
            def _pad(s: str, length: int) -> str:
         | 
| 13 | 
            +
                return s + ' ' * (length - len(s))
         | 
| 14 | 
            +
             | 
| 15 | 
            +
             | 
| 16 | 
            +
            def _generate_c() -> dict[str, str]:
         | 
| 17 | 
            +
                out = {}
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                #
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                f = io.StringIO()
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                f.write('typedef enum {\n')
         | 
| 24 | 
            +
                for i, state in enumerate(STATES_IN_ORDER):
         | 
| 25 | 
            +
                    f.write(f'   VTPARSE_STATE_{state.upper()} = {i + 1},\n')
         | 
| 26 | 
            +
                f.write('} vtparse_state_t;\n\n')
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                f.write('typedef enum {\n')
         | 
| 29 | 
            +
                for i, action_str in enumerate(ACTIONS_IN_ORDER):
         | 
| 30 | 
            +
                    f.write(f'   VTPARSE_ACTION_{action_str.upper()} = {i + 1},\n')
         | 
| 31 | 
            +
                f.write('} vtparse_action_t;\n\n')
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                f.write('typedef unsigned char state_change_t;\n')
         | 
| 34 | 
            +
                f.write(f'extern state_change_t STATE_TABLE[{len(STATES_IN_ORDER)}][256];\n')
         | 
| 35 | 
            +
                f.write(f'extern vtparse_action_t ENTRY_ACTIONS[{len(STATES_IN_ORDER)}];\n')
         | 
| 36 | 
            +
                f.write(f'extern vtparse_action_t EXIT_ACTIONS[{len(STATES_IN_ORDER)}];\n')
         | 
| 37 | 
            +
                f.write(f'extern char *ACTION_NAMES[{len(ACTIONS_IN_ORDER) + 1}];\n')
         | 
| 38 | 
            +
                f.write(f'extern char *STATE_NAMES[{len(STATES_IN_ORDER) + 1}];\n\n')
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                out['vtparse_table.h'] = f.getvalue()
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                #
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                f = io.StringIO()
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                f.write('#include "vtparse_table.h"\n\n')
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                f.write('char *ACTION_NAMES[] = {\n')
         | 
| 49 | 
            +
                f.write('   "<no action>",\n')
         | 
| 50 | 
            +
                for action_str in ACTIONS_IN_ORDER:
         | 
| 51 | 
            +
                    f.write(f'   "{action_str.upper()}",\n')
         | 
| 52 | 
            +
                f.write('};\n\n')
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                f.write('char *STATE_NAMES[] = {\n')
         | 
| 55 | 
            +
                f.write('   "<no state>",\n')
         | 
| 56 | 
            +
                for state in STATES_IN_ORDER:
         | 
| 57 | 
            +
                    f.write(f'   "{state}",\n')
         | 
| 58 | 
            +
                f.write('};\n\n')
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                f.write(f'state_change_t STATE_TABLE[{len(STATES_IN_ORDER)}][256] = {{\n')
         | 
| 61 | 
            +
                for i, state in enumerate(STATES_IN_ORDER):
         | 
| 62 | 
            +
                    f.write(f'  {{  /* VTPARSE_STATE_{state.upper()} = {i} */\n')
         | 
| 63 | 
            +
                    for j, state_change in enumerate(STATE_TABLES[state]):
         | 
| 64 | 
            +
                        if not state_change:
         | 
| 65 | 
            +
                            f.write('    0,\n')
         | 
| 66 | 
            +
                        else:
         | 
| 67 | 
            +
                            action = next((s for s in state_change if isinstance(s, str)), None)
         | 
| 68 | 
            +
                            state_trans = next((s for s in state_change if isinstance(s, StateTransition)), None)
         | 
| 69 | 
            +
                            action_str = f'VTPARSE_ACTION_{action.upper()}' if action else '0'
         | 
| 70 | 
            +
                            state_str = f'VTPARSE_STATE_{state_trans.to_state}' if state_trans else '0'
         | 
| 71 | 
            +
                            f.write(
         | 
| 72 | 
            +
                                f'/*{str(j).rjust(3)}*/  {_pad(action_str, 33)} | ({_pad(state_str, 33)} << 4),\n')
         | 
| 73 | 
            +
                    f.write('  },\n')
         | 
| 74 | 
            +
                f.write('};\n\n')
         | 
| 75 | 
            +
             | 
| 76 | 
            +
                f.write('vtparse_action_t ENTRY_ACTIONS[] = {\n')
         | 
| 77 | 
            +
                for state in STATES_IN_ORDER:
         | 
| 78 | 
            +
                    actions = STATES[state]
         | 
| 79 | 
            +
                    if 'on_entry' in actions:
         | 
| 80 | 
            +
                        f.write(f"   VTPARSE_ACTION_{check.isinstance(actions['on_entry'], str).upper()}, /* {state} */\n")
         | 
| 81 | 
            +
                    else:
         | 
| 82 | 
            +
                        f.write(f'   0  /* none for {state} */,\n')
         | 
| 83 | 
            +
                f.write('};\n\n')
         | 
| 84 | 
            +
             | 
| 85 | 
            +
                f.write('vtparse_action_t EXIT_ACTIONS[] = {\n')
         | 
| 86 | 
            +
                for state in STATES_IN_ORDER:
         | 
| 87 | 
            +
                    actions = STATES[state]
         | 
| 88 | 
            +
                    if 'on_exit' in actions:
         | 
| 89 | 
            +
                        f.write(f"   VTPARSE_ACTION_{check.isinstance(actions['on_exit'], str).upper()}, /* {state} */\n")
         | 
| 90 | 
            +
                    else:
         | 
| 91 | 
            +
                        f.write(f'   0  /* none for {state} */,\n')
         | 
| 92 | 
            +
                f.write('};\n\n')
         | 
| 93 | 
            +
             | 
| 94 | 
            +
                out['vtparse_table.c'] = f.getvalue()
         | 
| 95 | 
            +
             | 
| 96 | 
            +
                #
         | 
| 97 | 
            +
             | 
| 98 | 
            +
                return out
         | 
| 99 | 
            +
             | 
| 100 | 
            +
             | 
| 101 | 
            +
            if __name__ == '__main__':
         | 
| 102 | 
            +
                check_state_tables(STATE_TABLES)
         | 
| 103 | 
            +
                for f, c in _generate_c().items():
         | 
| 104 | 
            +
                    print(f)
         | 
| 105 | 
            +
                    print(c)
         | 
| 106 | 
            +
                    print()
         | 
| @@ -0,0 +1,271 @@ | |
| 1 | 
            +
            """
         | 
| 2 | 
            +
            Original author: Joshua Haberman
         | 
| 3 | 
            +
            https://github.com/haberman/vtparse/blob/198ea4382f824dbb3f0e5b5553a9eb3290764694/vtparse_tables.rb
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            ==
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            https://vt100.net/emu/dec_ansi_parser
         | 
| 8 | 
            +
            https://github.com/haberman/vtparse
         | 
| 9 | 
            +
            """
         | 
| 10 | 
            +
            import typing as ta
         | 
| 11 | 
            +
             | 
| 12 | 
            +
             | 
| 13 | 
            +
            ##
         | 
| 14 | 
            +
             | 
| 15 | 
            +
             | 
| 16 | 
            +
            class StateTransition(ta.NamedTuple):
         | 
| 17 | 
            +
                to_state: str
         | 
| 18 | 
            +
             | 
| 19 | 
            +
             | 
| 20 | 
            +
            TransitionMap: ta.TypeAlias = ta.Mapping[
         | 
| 21 | 
            +
                int | range | str,
         | 
| 22 | 
            +
                str | StateTransition | tuple[str | StateTransition, ...],
         | 
| 23 | 
            +
            ]
         | 
| 24 | 
            +
             | 
| 25 | 
            +
             | 
| 26 | 
            +
            ##
         | 
| 27 | 
            +
             | 
| 28 | 
            +
             | 
| 29 | 
            +
            # Define the anywhere transitions
         | 
| 30 | 
            +
            ANYWHERE_TRANSITIONS: TransitionMap = {
         | 
| 31 | 
            +
                0x18: ('execute', StateTransition('ground')),
         | 
| 32 | 
            +
                0x1a: ('execute', StateTransition('ground')),
         | 
| 33 | 
            +
                range(0x80, 0x90): ('execute', StateTransition('ground')),
         | 
| 34 | 
            +
                range(0x91, 0x98): ('execute', StateTransition('ground')),
         | 
| 35 | 
            +
                0x99: ('execute', StateTransition('ground')),
         | 
| 36 | 
            +
                0x9a: ('execute', StateTransition('ground')),
         | 
| 37 | 
            +
                0x9c: StateTransition('ground'),
         | 
| 38 | 
            +
                0x1b: StateTransition('escape'),
         | 
| 39 | 
            +
                0x98: StateTransition('sos_pm_apc_string'),
         | 
| 40 | 
            +
                0x9e: StateTransition('sos_pm_apc_string'),
         | 
| 41 | 
            +
                0x9f: StateTransition('sos_pm_apc_string'),
         | 
| 42 | 
            +
                0x90: StateTransition('dcs_entry'),
         | 
| 43 | 
            +
                0x9d: StateTransition('osc_string'),
         | 
| 44 | 
            +
                0x9b: StateTransition('csi_entry'),
         | 
| 45 | 
            +
            }
         | 
| 46 | 
            +
             | 
| 47 | 
            +
             | 
| 48 | 
            +
            # Global states dictionary
         | 
| 49 | 
            +
            STATES: ta.Mapping[str, TransitionMap] = {
         | 
| 50 | 
            +
                # Define state transitions
         | 
| 51 | 
            +
                'ground': {
         | 
| 52 | 
            +
                    range(0x18): 'execute',
         | 
| 53 | 
            +
                    0x19: 'execute',
         | 
| 54 | 
            +
                    range(0x1c, 0x20): 'execute',
         | 
| 55 | 
            +
                    range(0x20, 0x80): 'print',
         | 
| 56 | 
            +
                },
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                'escape': {
         | 
| 59 | 
            +
                    'on_entry': 'clear',
         | 
| 60 | 
            +
                    range(0x18): 'execute',
         | 
| 61 | 
            +
                    0x19: 'execute',
         | 
| 62 | 
            +
                    range(0x1c, 0x20): 'execute',
         | 
| 63 | 
            +
                    0x7f: 'ignore',
         | 
| 64 | 
            +
                    range(0x20, 0x30): ('collect', StateTransition('escape_intermediate')),
         | 
| 65 | 
            +
                    range(0x30, 0x50): ('esc_dispatch', StateTransition('ground')),
         | 
| 66 | 
            +
                    range(0x51, 0x58): ('esc_dispatch', StateTransition('ground')),
         | 
| 67 | 
            +
                    0x59: ('esc_dispatch', StateTransition('ground')),
         | 
| 68 | 
            +
                    0x5a: ('esc_dispatch', StateTransition('ground')),
         | 
| 69 | 
            +
                    0x5c: ('esc_dispatch', StateTransition('ground')),
         | 
| 70 | 
            +
                    range(0x60, 0x7f): ('esc_dispatch', StateTransition('ground')),
         | 
| 71 | 
            +
                    0x5b: StateTransition('csi_entry'),
         | 
| 72 | 
            +
                    0x5d: StateTransition('osc_string'),
         | 
| 73 | 
            +
                    0x50: StateTransition('dcs_entry'),
         | 
| 74 | 
            +
                    0x58: StateTransition('sos_pm_apc_string'),
         | 
| 75 | 
            +
                    0x5e: StateTransition('sos_pm_apc_string'),
         | 
| 76 | 
            +
                    0x5f: StateTransition('sos_pm_apc_string'),
         | 
| 77 | 
            +
                },
         | 
| 78 | 
            +
             | 
| 79 | 
            +
                'escape_intermediate': {
         | 
| 80 | 
            +
                    range(0x18): 'execute',
         | 
| 81 | 
            +
                    0x19: 'execute',
         | 
| 82 | 
            +
                    range(0x1c, 0x20): 'execute',
         | 
| 83 | 
            +
                    range(0x20, 0x30): 'collect',
         | 
| 84 | 
            +
                    0x7f: 'ignore',
         | 
| 85 | 
            +
                    range(0x30, 0x7f): ('esc_dispatch', StateTransition('ground')),
         | 
| 86 | 
            +
                },
         | 
| 87 | 
            +
             | 
| 88 | 
            +
                'csi_entry': {
         | 
| 89 | 
            +
                    'on_entry': 'clear',
         | 
| 90 | 
            +
                    range(0x18): 'execute',
         | 
| 91 | 
            +
                    0x19: 'execute',
         | 
| 92 | 
            +
                    range(0x1c, 0x20): 'execute',
         | 
| 93 | 
            +
                    0x7f: 'ignore',
         | 
| 94 | 
            +
                    range(0x20, 0x30): ('collect', StateTransition('csi_intermediate')),
         | 
| 95 | 
            +
                    0x3a: StateTransition('csi_ignore'),
         | 
| 96 | 
            +
                    range(0x30, 0x3a): ('param', StateTransition('csi_param')),
         | 
| 97 | 
            +
                    0x3b: ('param', StateTransition('csi_param')),
         | 
| 98 | 
            +
                    range(0x3c, 0x40): ('collect', StateTransition('csi_param')),
         | 
| 99 | 
            +
                    range(0x40, 0x7f): ('csi_dispatch', StateTransition('ground')),
         | 
| 100 | 
            +
                },
         | 
| 101 | 
            +
             | 
| 102 | 
            +
                'csi_ignore': {
         | 
| 103 | 
            +
                    range(0x18): 'execute',
         | 
| 104 | 
            +
                    0x19: 'execute',
         | 
| 105 | 
            +
                    range(0x1c, 0x20): 'execute',
         | 
| 106 | 
            +
                    range(0x20, 0x40): 'ignore',
         | 
| 107 | 
            +
                    0x7f: 'ignore',
         | 
| 108 | 
            +
                    range(0x40, 0x7f): StateTransition('ground'),
         | 
| 109 | 
            +
                },
         | 
| 110 | 
            +
             | 
| 111 | 
            +
                'csi_param': {
         | 
| 112 | 
            +
                    range(0x18): 'execute',
         | 
| 113 | 
            +
                    0x19: 'execute',
         | 
| 114 | 
            +
                    range(0x1c, 0x20): 'execute',
         | 
| 115 | 
            +
                    range(0x30, 0x3a): 'param',
         | 
| 116 | 
            +
                    0x3b: 'param',
         | 
| 117 | 
            +
                    0x7f: 'ignore',
         | 
| 118 | 
            +
                    0x3a: StateTransition('csi_ignore'),
         | 
| 119 | 
            +
                    range(0x3c, 0x40): StateTransition('csi_ignore'),
         | 
| 120 | 
            +
                    range(0x20, 0x30): ('collect', StateTransition('csi_intermediate')),
         | 
| 121 | 
            +
                    range(0x40, 0x7f): ('csi_dispatch', StateTransition('ground')),
         | 
| 122 | 
            +
                },
         | 
| 123 | 
            +
             | 
| 124 | 
            +
                'csi_intermediate': {
         | 
| 125 | 
            +
                    range(0x18): 'execute',
         | 
| 126 | 
            +
                    0x19: 'execute',
         | 
| 127 | 
            +
                    range(0x1c, 0x20): 'execute',
         | 
| 128 | 
            +
                    range(0x20, 0x30): 'collect',
         | 
| 129 | 
            +
                    0x7f: 'ignore',
         | 
| 130 | 
            +
                    range(0x30, 0x40): StateTransition('csi_ignore'),
         | 
| 131 | 
            +
                    range(0x40, 0x7f): ('csi_dispatch', StateTransition('ground')),
         | 
| 132 | 
            +
                },
         | 
| 133 | 
            +
             | 
| 134 | 
            +
                'dcs_entry': {
         | 
| 135 | 
            +
                    'on_entry': 'clear',
         | 
| 136 | 
            +
                    range(0x18): 'ignore',
         | 
| 137 | 
            +
                    0x19: 'ignore',
         | 
| 138 | 
            +
                    range(0x1c, 0x20): 'ignore',
         | 
| 139 | 
            +
                    0x7f: 'ignore',
         | 
| 140 | 
            +
                    0x3a: StateTransition('dcs_ignore'),
         | 
| 141 | 
            +
                    range(0x20, 0x30): ('collect', StateTransition('dcs_intermediate')),
         | 
| 142 | 
            +
                    range(0x30, 0x3a): ('param', StateTransition('dcs_param')),
         | 
| 143 | 
            +
                    0x3b: ('param', StateTransition('dcs_param')),
         | 
| 144 | 
            +
                    range(0x3c, 0x40): ('collect', StateTransition('dcs_param')),
         | 
| 145 | 
            +
                    range(0x40, 0x7f): (StateTransition('dcs_passthrough')),
         | 
| 146 | 
            +
                },
         | 
| 147 | 
            +
             | 
| 148 | 
            +
                'dcs_intermediate': {
         | 
| 149 | 
            +
                    range(0x18): 'ignore',
         | 
| 150 | 
            +
                    0x19: 'ignore',
         | 
| 151 | 
            +
                    range(0x1c, 0x20): 'ignore',
         | 
| 152 | 
            +
                    range(0x20, 0x30): 'collect',
         | 
| 153 | 
            +
                    0x7f: 'ignore',
         | 
| 154 | 
            +
                    range(0x30, 0x40): StateTransition('dcs_ignore'),
         | 
| 155 | 
            +
                    range(0x40, 0x7f): StateTransition('dcs_passthrough'),
         | 
| 156 | 
            +
                },
         | 
| 157 | 
            +
             | 
| 158 | 
            +
                'dcs_ignore': {
         | 
| 159 | 
            +
                    range(0x18): 'ignore',
         | 
| 160 | 
            +
                    0x19: 'ignore',
         | 
| 161 | 
            +
                    range(0x1c, 0x80): 'ignore',
         | 
| 162 | 
            +
                },
         | 
| 163 | 
            +
             | 
| 164 | 
            +
                'dcs_param': {
         | 
| 165 | 
            +
                    range(0x18): 'ignore',
         | 
| 166 | 
            +
                    0x19: 'ignore',
         | 
| 167 | 
            +
                    range(0x1c, 0x20): 'ignore',
         | 
| 168 | 
            +
                    range(0x30, 0x3a): 'param',
         | 
| 169 | 
            +
                    0x3b: 'param',
         | 
| 170 | 
            +
                    0x7f: 'ignore',
         | 
| 171 | 
            +
                    0x3a: StateTransition('dcs_ignore'),
         | 
| 172 | 
            +
                    range(0x3c, 0x40): StateTransition('dcs_ignore'),
         | 
| 173 | 
            +
                    range(0x20, 0x30): ('collect', StateTransition('dcs_intermediate')),
         | 
| 174 | 
            +
                    range(0x40, 0x7f): StateTransition('dcs_passthrough'),
         | 
| 175 | 
            +
                },
         | 
| 176 | 
            +
             | 
| 177 | 
            +
                'dcs_passthrough': {
         | 
| 178 | 
            +
                    'on_entry': 'hook',
         | 
| 179 | 
            +
                    range(0x18): 'put',
         | 
| 180 | 
            +
                    0x19: 'put',
         | 
| 181 | 
            +
                    range(0x1c, 0x20): 'put',
         | 
| 182 | 
            +
                    range(0x20, 0x7f): 'put',
         | 
| 183 | 
            +
                    0x7f: 'ignore',
         | 
| 184 | 
            +
                    'on_exit': 'unhook',
         | 
| 185 | 
            +
                },
         | 
| 186 | 
            +
             | 
| 187 | 
            +
                'sos_pm_apc_string': {
         | 
| 188 | 
            +
                    range(0x18): 'ignore',
         | 
| 189 | 
            +
                    0x19: 'ignore',
         | 
| 190 | 
            +
                    range(0x1c, 0x80): 'ignore',
         | 
| 191 | 
            +
                },
         | 
| 192 | 
            +
             | 
| 193 | 
            +
                'osc_string': {
         | 
| 194 | 
            +
                    'on_entry': 'osc_start',
         | 
| 195 | 
            +
                    range(0x18): 'ignore',
         | 
| 196 | 
            +
                    0x19: 'ignore',
         | 
| 197 | 
            +
                    range(0x1c, 0x20): 'ignore',
         | 
| 198 | 
            +
                    range(0x20, 0x80): 'osc_put',
         | 
| 199 | 
            +
                    'on_exit': 'osc_end',
         | 
| 200 | 
            +
                },
         | 
| 201 | 
            +
            }
         | 
| 202 | 
            +
             | 
| 203 | 
            +
             | 
| 204 | 
            +
            ##
         | 
| 205 | 
            +
             | 
| 206 | 
            +
             | 
| 207 | 
            +
            ACTIONS_IN_ORDER = sorted(
         | 
| 208 | 
            +
                action
         | 
| 209 | 
            +
                for state, transitions in STATES.items()
         | 
| 210 | 
            +
                for keys, actions in transitions.items()
         | 
| 211 | 
            +
                for action in ([actions] if not isinstance(actions, tuple) else actions)
         | 
| 212 | 
            +
                if isinstance(action, str)
         | 
| 213 | 
            +
            )
         | 
| 214 | 
            +
             | 
| 215 | 
            +
            STATES_IN_ORDER = sorted(STATES)
         | 
| 216 | 
            +
             | 
| 217 | 
            +
             | 
| 218 | 
            +
            ##
         | 
| 219 | 
            +
             | 
| 220 | 
            +
             | 
| 221 | 
            +
            TransitionTable: ta.TypeAlias = tuple[tuple[str | StateTransition, ...], ...]
         | 
| 222 | 
            +
             | 
| 223 | 
            +
             | 
| 224 | 
            +
            def _build_state_tables() -> ta.Mapping[str, TransitionTable]:
         | 
| 225 | 
            +
                # Expand the range-based data structures into fully expanded tables
         | 
| 226 | 
            +
                state_tables: dict[str, list] = {}
         | 
| 227 | 
            +
             | 
| 228 | 
            +
                def expand_ranges(dct):
         | 
| 229 | 
            +
                    array = [None] * 256
         | 
| 230 | 
            +
                    for k, v in dct.items():
         | 
| 231 | 
            +
                        if isinstance(k, range):
         | 
| 232 | 
            +
                            for i in k:
         | 
| 233 | 
            +
                                array[i] = v
         | 
| 234 | 
            +
                        elif isinstance(k, int):
         | 
| 235 | 
            +
                            array[k] = v
         | 
| 236 | 
            +
                    return array
         | 
| 237 | 
            +
             | 
| 238 | 
            +
                for s, t in STATES.items():
         | 
| 239 | 
            +
                    state_tables[s] = expand_ranges(t)
         | 
| 240 | 
            +
             | 
| 241 | 
            +
                # Seed all the states with the anywhere transitions
         | 
| 242 | 
            +
                anywhere_transitions_expanded = expand_ranges(ANYWHERE_TRANSITIONS)
         | 
| 243 | 
            +
             | 
| 244 | 
            +
                for state, transitions in state_tables.items():
         | 
| 245 | 
            +
                    for i, transition in enumerate(anywhere_transitions_expanded):
         | 
| 246 | 
            +
                        if transition is not None:
         | 
| 247 | 
            +
                            if transitions[i] is not None:
         | 
| 248 | 
            +
                                raise ValueError(
         | 
| 249 | 
            +
                                    f'State {state} already had a transition defined for 0x{i:02x}, but that transition is also an '
         | 
| 250 | 
            +
                                    f'anywhere transition!',
         | 
| 251 | 
            +
                                )
         | 
| 252 | 
            +
                            transitions[i] = transition
         | 
| 253 | 
            +
             | 
| 254 | 
            +
                # For consistency, make all transitions tuples of actions
         | 
| 255 | 
            +
                return {
         | 
| 256 | 
            +
                    state: tuple(tuple(t if isinstance(t, (list, tuple)) else [t]) for t in transitions)
         | 
| 257 | 
            +
                    for state, transitions in state_tables.items()
         | 
| 258 | 
            +
                }
         | 
| 259 | 
            +
             | 
| 260 | 
            +
             | 
| 261 | 
            +
            STATE_TABLES = _build_state_tables()
         | 
| 262 | 
            +
             | 
| 263 | 
            +
             | 
| 264 | 
            +
            ##
         | 
| 265 | 
            +
             | 
| 266 | 
            +
             | 
| 267 | 
            +
            def check_state_tables(state_tables: ta.Mapping[str, TransitionTable]) -> None:
         | 
| 268 | 
            +
                for state, transitions in state_tables.items():
         | 
| 269 | 
            +
                    for i, val in enumerate(transitions):
         | 
| 270 | 
            +
                        if not val:
         | 
| 271 | 
            +
                            raise ValueError(f'No transition defined from state {state}, char 0x{i:02x}!')
         | 
| @@ -1,5 +1,5 @@ | |
| 1 1 | 
             
            omlish/.manifests.json,sha256=lRkBDFxlAbf6lN5upo3WSf-owW8YG1T21dfpbQL-XHM,7598
         | 
| 2 | 
            -
            omlish/__about__.py,sha256= | 
| 2 | 
            +
            omlish/__about__.py,sha256=Gs9hXW7PiNiRdGtxDHSxJf4Q0yutVUp9BalCHX8po30,3409
         | 
| 3 3 | 
             
            omlish/__init__.py,sha256=SsyiITTuK0v74XpKV8dqNaCmjOlan1JZKrHQv5rWKPA,253
         | 
| 4 4 | 
             
            omlish/c3.py,sha256=ubu7lHwss5V4UznbejAI0qXhXahrU01MysuHOZI9C4U,8116
         | 
| 5 5 | 
             
            omlish/cached.py,sha256=UI-XTFBwA6YXWJJJeBn-WkwBkfzDjLBBaZf4nIJA9y0,510
         | 
| @@ -11,7 +11,7 @@ omlish/libc.py,sha256=8r7Ejyhttk9ruCfBkxNTrlzir5WPbDE2vmY7VPlceMA,15362 | |
| 11 11 | 
             
            omlish/multiprocessing.py,sha256=QZT4C7I-uThCAjaEY3xgUYb-5GagUlnE4etN01LDyU4,5186
         | 
| 12 12 | 
             
            omlish/runmodule.py,sha256=PWvuAaJ9wQQn6bx9ftEL3_d04DyotNn8dR_twm2pgw0,700
         | 
| 13 13 | 
             
            omlish/shlex.py,sha256=bsW2XUD8GiMTUTDefJejZ5AyqT1pTgWMPD0BMoF02jE,248
         | 
| 14 | 
            -
            omlish/subprocesses.py,sha256= | 
| 14 | 
            +
            omlish/subprocesses.py,sha256=KOvt5gvpq2uisjYKyU_XUPZyM6yq8ywgbfWjz-lx9CQ,8686
         | 
| 15 15 | 
             
            omlish/sync.py,sha256=QJ79kxmIqDP9SeHDoZAf--DpFIhDQe1jACy8H4N0yZI,2928
         | 
| 16 16 | 
             
            omlish/antlr/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
         | 
| 17 17 | 
             
            omlish/antlr/delimit.py,sha256=3Byvh9_Ip8ftM_SeSEmMbnNo1jrxk-xm8HnHDp_nDaI,3466
         | 
| @@ -310,7 +310,7 @@ omlish/inject/impl/proxy.py,sha256=1ko0VaKqzu9UG8bIldp9xtUrAVUOFTKWKTjOCqIGr4s,1 | |
| 310 310 | 
             
            omlish/inject/impl/scopes.py,sha256=hKnzNieB-fJSFEXDP_QG1mCfIKoVFIfFlf9LiIt5tk4,5920
         | 
| 311 311 | 
             
            omlish/io/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
         | 
| 312 312 | 
             
            omlish/io/abc.py,sha256=Cxs8KB1B_69rxpUYxI-MTsilAmNooJJn3w07DKqYKkE,1255
         | 
| 313 | 
            -
            omlish/io/buffers.py,sha256= | 
| 313 | 
            +
            omlish/io/buffers.py,sha256=qo1hCqTfKvlbSmddneporqCtW0rZJ_Mv2GrQTI1Hbk0,5636
         | 
| 314 314 | 
             
            omlish/io/pyio.py,sha256=q4RBFVpBE5PYjnGPGT-_4pcZb7dFJmLJ4LtI8OoDRQY,95433
         | 
| 315 315 | 
             
            omlish/io/trampoline.py,sha256=oUKTQg1F5xQS1431Kt7MbK-NZpX509ubcXU-s86xJr8,7171
         | 
| 316 316 | 
             
            omlish/io/compress/__init__.py,sha256=qV-aDfPWykTMYcoQmE8THZ4KFDRzqwN3QPPNEJVarXY,86
         | 
| @@ -335,7 +335,7 @@ omlish/io/generators/__init__.py,sha256=YsSLJY9uw72eX3iXd_A0pM69g7EvEqMFdCdR_BBD | |
| 335 335 | 
             
            omlish/io/generators/consts.py,sha256=4r6IMLBMic6MJHVn9UiORIkkPAuxsqtzFT3KV0fatC0,33
         | 
| 336 336 | 
             
            omlish/io/generators/direct.py,sha256=A9VJB1rNKU3l-NatpYIwyCLI3R_ybGglmdx6sAtoTo4,324
         | 
| 337 337 | 
             
            omlish/io/generators/readers.py,sha256=MolTFCzcnD5XoP0su0YUNHJ0xlHC3KTihvWAi75y8Bo,4336
         | 
| 338 | 
            -
            omlish/io/generators/stepped.py,sha256= | 
| 338 | 
            +
            omlish/io/generators/stepped.py,sha256=WZnLpCzv5pA6jLdb1lplXoKRPbREw9wO586Dew5EzV4,5129
         | 
| 339 339 | 
             
            omlish/iterators/__init__.py,sha256=yMavf5FofiS1EU4UFuWPXiFZ03W0H-y7MuMxW8FUaEE,358
         | 
| 340 340 | 
             
            omlish/iterators/iterators.py,sha256=ghI4dO6WPyyFOLTIIMaHQ_IOy2xXaFpGPqveZ5YGIBU,3158
         | 
| 341 341 | 
             
            omlish/iterators/recipes.py,sha256=53mkexitMhkwXQZbL6DrhpT0WePQ_56uXd5Jaw3DfzI,467
         | 
| @@ -547,7 +547,10 @@ omlish/sql/tabledefs/tabledefs.py,sha256=lIhvlt0pk6G7RZAtDFsFXm5j0l9BvRfnP7vNGey | |
| 547 547 | 
             
            omlish/term/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
         | 
| 548 548 | 
             
            omlish/term/codes.py,sha256=gqouA7KDyGzyCmmu8ejGhT_8XJGsejdTQh2pSCMbWAQ,6150
         | 
| 549 549 | 
             
            omlish/term/progressbar.py,sha256=TiwdmPSMa5jQj35i1NQURTWQGy4eWUNx_XiPM38JtvQ,3184
         | 
| 550 | 
            -
            omlish/term/vt100.py,sha256= | 
| 550 | 
            +
            omlish/term/vt100/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
         | 
| 551 | 
            +
            omlish/term/vt100/c.py,sha256=cAhDKXI81PZRtFmTotfad3HZGREP1QnOlWYoAw6v-Fw,3532
         | 
| 552 | 
            +
            omlish/term/vt100/states.py,sha256=OxPUxfFTcfz56MhtDgIigEApChOtN6XO1g6R2H08mu4,8303
         | 
| 553 | 
            +
            omlish/term/vt100/terminal.py,sha256=sYLddUSrubCJPnI6f2t5Pzp0tFGLLBKyYdDfKmkwREM,9363
         | 
| 551 554 | 
             
            omlish/testing/__init__.py,sha256=M_BQrcCHkoL-ZvE-UpQ8XxXNYRRawhjUz4rCJnAqM2A,152
         | 
| 552 555 | 
             
            omlish/testing/testing.py,sha256=TT2wwSzPZ_KhIvKxpM1qc1yHKD-LHDNgGrcr_h8vs7c,2895
         | 
| 553 556 | 
             
            omlish/testing/pytest/__init__.py,sha256=B2nyJrjIoNcEopbg0IZ5UUDs4OHmQ8qqElFJfGcDdas,257
         | 
| @@ -576,9 +579,9 @@ omlish/text/indent.py,sha256=6Jj6TFY9unaPa4xPzrnZemJ-fHsV53IamP93XGjSUHs,1274 | |
| 576 579 | 
             
            omlish/text/minja.py,sha256=KAmZ2POcLcxwF4DPKxdWa16uWxXmVz1UnJXLSwt4oZo,5761
         | 
| 577 580 | 
             
            omlish/text/parts.py,sha256=7vPF1aTZdvLVYJ4EwBZVzRSy8XB3YqPd7JwEnNGGAOo,6495
         | 
| 578 581 | 
             
            omlish/text/random.py,sha256=jNWpqiaKjKyTdMXC-pWAsSC10AAP-cmRRPVhm59ZWLk,194
         | 
| 579 | 
            -
            omlish-0.0.0. | 
| 580 | 
            -
            omlish-0.0.0. | 
| 581 | 
            -
            omlish-0.0.0. | 
| 582 | 
            -
            omlish-0.0.0. | 
| 583 | 
            -
            omlish-0.0.0. | 
| 584 | 
            -
            omlish-0.0.0. | 
| 582 | 
            +
            omlish-0.0.0.dev189.dist-info/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
         | 
| 583 | 
            +
            omlish-0.0.0.dev189.dist-info/METADATA,sha256=JRj7SgIl1vGF733weElFasb6_IEBNT8cTHUdlW4Aq98,4264
         | 
| 584 | 
            +
            omlish-0.0.0.dev189.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
         | 
| 585 | 
            +
            omlish-0.0.0.dev189.dist-info/entry_points.txt,sha256=Lt84WvRZJskWCAS7xnQGZIeVWksprtUHj0llrvVmod8,35
         | 
| 586 | 
            +
            omlish-0.0.0.dev189.dist-info/top_level.txt,sha256=pePsKdLu7DvtUiecdYXJ78iO80uDNmBlqe-8hOzOmfs,7
         | 
| 587 | 
            +
            omlish-0.0.0.dev189.dist-info/RECORD,,
         | 
| 
            File without changes
         | 
| 
            File without changes
         | 
| 
            File without changes
         | 
| 
            File without changes
         | 
| 
            File without changes
         |