aboutsummaryrefslogtreecommitdiff
path: root/goldfishterm/internal/string_capability.h
diff options
context:
space:
mode:
Diffstat (limited to 'goldfishterm/internal/string_capability.h')
-rw-r--r--goldfishterm/internal/string_capability.h106
1 files changed, 106 insertions, 0 deletions
diff --git a/goldfishterm/internal/string_capability.h b/goldfishterm/internal/string_capability.h
new file mode 100644
index 0000000..ddae964
--- /dev/null
+++ b/goldfishterm/internal/string_capability.h
@@ -0,0 +1,106 @@
+// 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 <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#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<int, std::string>;
+
+struct InterpretStringCapabilityInput {
+ std::string capability;
+ std::vector<StringCapabilityParameter> 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<char> 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<StringCapabilityParameter> 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<std::shared_ptr<const EmitTerm>> 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_