Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/third_party/python/jinxed/jinxed/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 8 kB image not shown  

Quelle  _tparm.py   Sprache: Python

 
# -*- coding: utf-8 -*-
# Copyright 2019 - 2022 Avram Lubkin, All Rights Reserved

# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

"""
An pure Python implementation of tparm
Based on documentation in man(5) terminfo and comparing behavior of curses.tparm
"""

from collections import deque
import operator
import re


OPERATORS = {b'+': operator.add,
             b'-': operator.sub,
             b'*': operator.mul,
             b'/': operator.floordiv,
             b'm': operator.mod,
             b'&': operator.and_,
             b'|': operator.or_,
             b'^': operator.xor,
             b'=': operator.eq,
             b'>': operator.gt,
             b'<': operator.lt,
             b'~': operator.inv,
             b'!': operator.not_,
             b'A'lambda x, y: bool(x and y),
             b'O'lambda x, y: bool(x or y)}

FILTERS = (('_literal_percent', br'%%'),
           ('_pop_c', br'%c'),
           ('_increment_one_two', br'%i'),
           ('_binary_op', br'%([\+\-\*/m\&\|\^=>),
           ('_unary_op', br'%([\~!])'),
           ('_push_param', br'%p([1-9]\d*)'),
           ('_set_dynamic', br'%P([a-z])'),
           ('_get_dynamic', br'%g([a-z])'),
           ('_set_static', br'%P([A-Z])'),
           ('_get_static', br'%g([A-Z])'),
           ('_char_constant', br"%'(.)'"),
           ('_int_constant', br'%{(\d+)}'),
           ('_push_len', br'%l'),
           ('_cond_if', br'%\?(.+?)(?=%t)'),
           ('_cond_then_else', br'%t(.+?)(?=%e)'),
           ('_cond_then_fi', br'%t(.+?)(?=%;)'),
           ('_cond_else', br'%e(.+?)(?=%;|$)'),
           ('_cond_fi', br'%;'),
           ('_printf', br'%:?[^%]*?[doxXs]'),
           ('_unmatched', br'%.'),
           ('_literal', br'[^%]+'))

PATTERNS = tuple((re.compile(pattern), filter_) for filter_, pattern in FILTERS)
NULL = type('Null', (int,), {})(0)


class TParm(object):  # pylint: disable=useless-object-inheritance
    """
    Class to hold tparm methods and persist variables between calls
    """

    def __init__(self, *params, **kwargs):

        self.rtn = b''
        self.stack = deque()

        # The spec for tparm allows c string parameters, but most implementations don't
        # The reference code makes a best effort to determine which parameters require strings
        # We'll allow them without trying to predict
        for param in params:
            if not isinstance(param, (int, bytes)):
                raise TypeError('Parameters must be integers or bytes, not %s' %
                                type(param).__name__)
        self.params = list(params)

        static = kwargs.get('static')
        self.static = {} if static is None else static
        self.dynamic = {}

    def __call__(self, string, *params):
        self.dynamic = {}  # As of ncurses 6.3, dynamic variables do not persist between calls
        return self.child(*params).parse(string)

    def _literal_percent(self, group):  # pylint: disable=unused-argument
        """
        Literal percent sign
        """
        self.rtn += b'%'

    def _pop_c(self, group):  # pylint: disable=unused-argument
        """
        Return pop() like %c in printf
        """

        try:
            value = self.stack.pop()
        except IndexError:
            value = NULL

        # Treat null as 0x80
        if value is NULL:
            value = 0x80

        self.rtn += b'%c' % value

    def _increment_one_two(self, group):  # pylint: disable=unused-argument
        """
        Add 1 to first two parameters
        Missing parameters are treated as 0's
        """
        for index in (0, 1):
            try:
                self.params[index] += 1
            except IndexError:
                self.params.append(1)

    def _binary_op(self, group):
        """
        Perform a binary operation on the last two items on the stack
        The order of evaluation is the order the items were placed on the stack
        """
        second_val = self.stack.pop()
        self.stack.append(OPERATORS[group](self.stack.pop(), second_val))

    def _unary_op(self, group):
        """
        Perform a unary operation on the last item on the stack
        """
        self.stack.append(OPERATORS[group](self.stack.pop()))

    def _push_param(self, group):
        """
        Push a parameter onto the stack
        If the parameter is missing, push Null
        """
        try:
            self.stack.append(self.params[int(group) - 1])
        except IndexError:
            self.stack.append(NULL)

    def _set_dynamic(self, group):
        """
        Set the a dynamic variable to pop()
        """
        self.dynamic[group] = self.stack.pop()

    def _get_dynamic(self, group):
        """
        Push the value of a dynamic variable onto the stack
        """
        self.stack.append(self.dynamic.get(group, NULL))

    def _set_static(self, group):
        """
        Set the a static variable to pop()
        """
        self.static[group] = self.stack.pop()

    def _get_static(self, group):
        """
        Push the value of a static variable onto the stack
        """
        self.stack.append(self.static.get(group, NULL))

    def _char_constant(self, group):
        """
        Push an character constant onto the stack
        """
        self.stack.append(ord(group))

    def _int_constant(self, group):
        """
        Push an integer constant onto the stack
        """
        self.stack.append(int(group))

    def _push_len(self, group):  # pylint: disable=unused-argument
        """
        Replace the last item on the stack with its length
        """
        self.stack.append(len(self.stack.pop()))

    def _cond_if(self, group):
        """
        Recursively evaluate the body of the if statement
        """
        self.parse(group)

    def _cond_then_else(self, group):
        """
        If the last item on the stack is True,
        recursively evaluate then statement

        Do not consume last item on stack
        """
        if self.stack[-1]:
            self.parse(group)

    def _cond_then_fi(self, group):
        """
        If the last item on the stack is True,
        recursively evaluate then statement

        Always consume last item on stack
        """
        if self.stack.pop():
            self.parse(group)

    def _cond_else(self, group):
        """
        If the last item on the stack is False,
        recursively evaluate the both of the else statement

        Always consume last item on stack
        """
        if not self.stack.pop():
            self.parse(group)

    def _cond_fi(self, group):  # pylint: disable=unused-argument
        """
        End if statement
        """

    def _printf(self, group):
        """
        Subset of printf-like formatting
        """

        # : is an escape to prevent flags from being treated as % operators, ignore
        # Python 2 returns as ':', Python 3 returns as 58
        if group[1] in (b':', 58):
            group = b'%' + group[2:]

        try:
            value = self.stack.pop()
        except IndexError:
            value = NULL

        # Treat null as empty string when string formatting
        # Python 2 returns as 's', Python 3 returns as 115
        if value is NULL and group[-1] in (b's', 115):
            value = b''

        self.rtn += group % value

    def _unmatched(self, group):  # pylint: disable=unused-argument
        """
        Escape pattern with no spec is skipped
        """

    def _literal(self, group):
        """
        Anything not prefaced with a known pattern spec is treated literally
        """
        self.rtn += group

    def parse(self, string):
        """
        Parsing loop
        Evaluate regex patterns in order until a pattern is matched
        """

        if not isinstance(string, bytes):
            raise TypeError("A bytes-like object is required, not '%s'" % type(string).__name__)

        index = 0
        length = len(string)

        while index < length:
            for filt, meth in PATTERNS:  # pragma: no branch
                match = re.match(filt, string[index:])
                if match:
                    group = match.groups()[-1] if match.groups() else match.group(0)
                    getattr(self, meth)(group)
                    index += match.end()
                    break

        return self.rtn

    def child(self, *params):
        """
        Return a new instance with the same variables, but different parameters
        """
        return self.__class__(*params, static=self.static, dynamic=self.dynamic)


tparm = TParm()  # pylint: disable=invalid-name
"""Reimplementation of :py:func:`curses.tparm`"""

Messung V0.5
C=98 H=100 G=98

¤ Dauer der Verarbeitung: 0.1 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.