// Copyright 2021 Benjamin Barenblat // // Licensed under the Apache License, Version 2.0 (the "License"); you may not // use this file except in compliance with the License. You may obtain a copy of // the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the // License for the specific language governing permissions and limitations under // the License. // Parses and interprets terminfo string capabilities. These are written in a // simple stack-based programming language whose semantics are documented in // terminfo(5). #ifndef EC_GOLDFISHTERM_INTERNAL_STRING_CAPABILITY_H_ #define EC_GOLDFISHTERM_INTERNAL_STRING_CAPABILITY_H_ #include #include #include #include #include "goldfishterm/internal/emit.h" #include "goldfishterm/terminfo.h" #include "third_party/abseil/absl/types/optional.h" #include "third_party/abseil/absl/types/variant.h" namespace goldfishterm_internal { using StringCapabilityParameter = absl::variant; struct InterpretStringCapabilityInput { std::string capability; std::vector parameters; // The number of lines affected by this operation. int lines_affected; // The minimum baud rate at which padding should be expanded. int padding_baud_rate; // The padding character, or absl::nullopt if the terminal doesn't support // padding. absl::optional pad_char; // True iff the terminal supports XON/XOFF handshaking. bool has_xon_xoff; // The baud rate of the terminal. int baud; // The number of extra bits sent per character. For a terminal emulator, this // is generally 0; for an RS-232 line, it's generally 2 or 3 (one start bit, // one stop bit, and possibly one parity bit). int extra_bits_per_character; // Constructs an InterpretStringCapabilityInput with fail-safe defaults. explicit InterpretStringCapabilityInput() noexcept : lines_affected(1), padding_baud_rate(0), pad_char('\0'), has_xon_xoff(false), baud(9600), extra_bits_per_character(0) {} // Constructs an InterpretStringCapabilityInput from a terminfo entry. explicit InterpretStringCapabilityInput( const goldfishterm::TerminfoEntry& terminfo, std::string capability_, std::vector parameters_, int baud_, int lines_affected_) noexcept : capability(std::move(capability_)), parameters(std::move(parameters_)), lines_affected(lines_affected_), padding_baud_rate( terminfo.get(goldfishterm::NumericCapability::kPaddingBaudRate) .value_or(0)), pad_char(terminfo.get(goldfishterm::StringCapability::kCharPadding) .value_or(std::string(1, '\0'))[0]), has_xon_xoff(terminfo.get(goldfishterm::BooleanCapability::kXonXoff)), baud(baud_), extra_bits_per_character(0) {} }; struct InterpretStringCapabilityResult { // Terms in the emitter EDSL (see emit.h). std::vector> terms; // The expected cost of emitting these terms. This is a unitless, arbitrarily // scaled real number; it will be at least 0, but you should not rely on any // absolute semantics. float cost; }; // Interprets a terminfo string capability, expanding parameters and inserting // padding and delays as appropriate. Throws std::runtime_error if parsing or // interpretation fails. InterpretStringCapabilityResult InterpretStringCapability( const InterpretStringCapabilityInput&); } // namespace goldfishterm_internal #endif // EC_GOLDFISHTERM_INTERNAL_STRING_CAPABILITY_H_