pythonterminalncursesterminfotermcap

Delay in terminfo parameterized strings


In the manpage of terminfo, it is mentioned that $<> in the encoding for specifying delay in ms, and within it's angular brackets is the a number with at most one decimal place of precision.

And with the following python script I confirmed that $< is only used for specifying delay i.e. there wasn't a parameterized string where $< had been used for not specifying delay.

#!/usr/bin/env python3
# './test/data/stressTestTerms.txt' contains contains terminal names
# and directory './test/data/mirror' contains terminal databases of 2718 terminals

import subprocess
import re


def check_dollar_angular(caps):
    string_caps = [cap for cap in caps.split(',') if '=' in cap]

    # search for $<..> type delays in string caps
    delay = r"\$<(\d+(\.(\d)+)?\*?/?|(\.(\d)+)?\*?/?)>"

    caps_with_dollar = 0
    delay_matches = 0

    for cap in string_caps:
        matches = list(re.finditer(delay, cap))
        dollar_idx = cap.find('$<')

        if dollar_idx != -1:
            caps_with_dollar += 1
            if any([True if match.start() == dollar_idx else False for match in matches]):
                delay_matches += 1

    if caps_with_dollar == delay_matches:
        return True
    else:
        return False


if __name__ == "__main__":

    with open('./test/data/stressTestTerms.txt') as terminal_names:
        res = []

        for each_terminal in terminal_names:
            output = subprocess.run(
                ['infocmp', '-0', '-A', './test/data/mirror', each_terminal.strip()], stdout=subprocess.PIPE)

            try:
                output.check_returncode()
                caps = output.stdout.decode('utf-8')

                res.append(check_dollar_angular(caps))

            except subprocess.CalledProcessError as e:
                print(e)

        if (not all(res)):
            print(
                "We have a terminal where in one of it's caps there is a dollar-angular but it doesn't signify delay")
        else:
            print(
                "Success! no terminal found where '$<' is used for anything else other than specifying delay")

So my question is, Whether $< be part of text/sequence and not represent a delay? Eg. can there be a case(now or in the future terminals) like: $<%p1%d or $<A, where there is no ending angular bracket and delay isn't meant to be specified using $< and still be valid terminfo sequence?


Solution

  • The manual page is pretty explicit about syntax:

       A  delay  in  milliseconds  may appear anywhere in a string capability,
       enclosed in $<..> brackets, as in el=\EK$<5>,  and  padding  characters
       are supplied by tputs(3x) to provide this delay.
    
       o   The delay must be a number with at most one decimal place of preci-
           sion; it may be followed by suffixes "*" or "/" or both.
    
       o   A "*" indicates that the padding required is  proportional  to  the
           number  of lines affected by the operation, and the amount given is
           the per-affected-unit padding required.  (In  the  case  of  insert
           character, the factor is still the number of lines affected.)
    
           Normally, padding is advisory if the device has the xon capability;
           it is used for cost computation but does not trigger delays.
    
       o   A "/" suffix indicates that the padding is mandatory and  forces  a
           delay of the given number of milliseconds even on devices for which
           xon is present to indicate flow control.
    

    If there's no ending <, and the enclosed text is not a valid number (with possible * and/or /), then tputs should not treat it as a delay.

    There's no example with $< not followed by a digit or "." in ncurses's terminal database, but that does not mean it would be invalid, since the terminal database should be able to describe most strings (aside from the special case where \200 (octal) is treated the same as \0 to accommodate the C language's NUL-terminated strings.