summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/pastify-test.cc29
-rw-r--r--src/pastify.cc81
-rw-r--r--src/pastify.hh3
3 files changed, 101 insertions, 12 deletions
diff --git a/src/pastify-test.cc b/src/pastify-test.cc
index 1a4c7f56..fd8ab6d9 100644
--- a/src/pastify-test.cc
+++ b/src/pastify-test.cc
@@ -63,16 +63,17 @@ test_pastify_brackets_c1(void)
}
static void
-test_pastify_control(std::string const& ctrl)
+test_pastify_control(std::string const& ctrl,
+ std::string const& pict)
{
- test_pastify(ctrl, ""sv);
- test_pastify(ctrl + ctrl, ""sv);
- test_pastify("abc"s + ctrl, "abc"sv);
- test_pastify("abc"s + ctrl + ctrl, "abc"sv);
- test_pastify(ctrl + "abc"s, "abc"sv);
- test_pastify(ctrl + ctrl + "abc"s, "abc"sv);
- test_pastify("abc"s + ctrl + "abc"s, "abcabc"sv);
- test_pastify("abc"s + ctrl + ctrl + "abc"s, "abcabc"sv);
+ test_pastify(ctrl, pict);
+ test_pastify(ctrl + ctrl, pict + pict);
+ test_pastify("abc"s + ctrl, "abc"s + pict);
+ test_pastify("abc"s + ctrl + ctrl, "abc"s + pict + pict);
+ test_pastify(ctrl + "abc"s, pict + "abc"s);
+ test_pastify(ctrl + ctrl + "abc"s, pict + pict + "abc"s);
+ test_pastify("abc"s + ctrl + "abc"s, "abc"s + pict + "abc"s);
+ test_pastify("abc"s + ctrl + ctrl + "abc"s, "abc"s + pict + pict + "abc"s);
}
static void
@@ -82,7 +83,10 @@ test_pastify_control_c0(void const* ptr)
auto ctrl = ""s;
ctrl.push_back(c);
- test_pastify_control(ctrl);
+ auto pict = std::string{};
+ vte::terminal::append_control_picture(pict, c);
+
+ test_pastify_control(ctrl, pict);
}
static void
@@ -94,7 +98,10 @@ test_pastify_control_c1(void const* ptr)
ctrl.push_back(0xc2);
ctrl.push_back(c);
- test_pastify_control(ctrl);
+ auto pict = std::string{};
+ vte::terminal::append_control_picture(pict, c);
+
+ test_pastify_control(ctrl, pict);
}
struct TestString {
diff --git a/src/pastify.cc b/src/pastify.cc
index a52e0e46..da9560db 100644
--- a/src/pastify.cc
+++ b/src/pastify.cc
@@ -70,6 +70,14 @@ pastify_string(std::string_view str,
break;
switch (str[run]) {
+ case 0x01 ... 0x09:
+ case 0x0b ... 0x0c:
+ case 0x0e ... 0x1f:
+ case 0x7f:
+ append_control_picture(rv, str[run]);
+ ++run;
+ break;
+
case '\x0a':
rv.push_back('\x0d');
++run;
@@ -77,6 +85,8 @@ pastify_string(std::string_view str,
case '\xc2': {
auto const c = next_char(run);
if (c >= 0x80 && c <= 0x9f) {
+ append_control_picture(rv, c);
+
/* Skip both bytes of a C1 */
run += 2;
} else {
@@ -87,11 +97,11 @@ pastify_string(std::string_view str,
break;
}
default:
- /* Swallow this byte */
++run;
break;
}
+ /* run is <= str.size() */
str = str.substr(run);
}
@@ -105,4 +115,73 @@ pastify_string(std::string_view str,
return rv;
}
+/*
+ * append_control_picture:
+ * @str:
+ * @c:
+ *
+ * Appends the control picture for @ctrl (or if @ctrl has no control
+ * picture in unicode, appends U+FFFD).
+ */
+void
+append_control_picture(std::string& str,
+ char32_t ctrl)
+{
+ switch (ctrl) {
+ case 0x00 ... 0x1f: /* C0 */
+ // U+2400 SYMBOL FOR NULL
+ // U+2401 SYMBOL FOR START OF HEADING
+ // U+2402 SYMBOL FOR START OF TEXT
+ // U+2403 SYMBOL FOR END OF TEXT
+ // U+2404 SYMBOL FOR END OF TRANSMISSION
+ // U+2405 SYMBOL FOR ENQUIRY
+ // U+2406 SYMBOL FOR ACKNOWLEDGE
+ // U+2407 SYMBOL FOR BELL
+ // U+2408 SYMBOL FOR BACKSPACE
+ // U+2409 SYMBOL FOR HORIZONTAL TABULATION
+ // U+240A SYMBOL FOR LINE FEED
+ // U+240B SYMBOL FOR VERTICAL TABULATION
+ // U+240C SYMBOL FOR FORM FEED
+ // U+240D SYMBOL FOR CARRIAGE RETURN
+ // U+240E SYMBOL FOR SHIFT OUT
+ // U+240F SYMBOL FOR SHIFT IN
+ // U+2410 SYMBOL FOR DATA LINK ESCAPE
+ // U+2411 SYMBOL FOR DEVICE CONTROL ONE
+ // U+2412 SYMBOL FOR DEVICE CONTROL TWO
+ // U+2413 SYMBOL FOR DEVICE CONTROL THREE
+ // U+2414 SYMBOL FOR DEVICE CONTROL FOUR
+ // U+2415 SYMBOL FOR NEGATIVE ACKNOWLEDGE
+ // U+2416 SYMBOL FOR SYNCHRONOUS IDLE
+ // U+2417 SYMBOL FOR END OF TRANSMISSION BLOCK
+ // U+2418 SYMBOL FOR CANCEL
+ // U+2419 SYMBOL FOR END OF MEDIUM
+ // U+241A SYMBOL FOR SUBSTITUTE
+ // U+241B SYMBOL FOR ESCAPE
+ // U+241C SYMBOL FOR FILE SEPARATOR
+ // U+241D SYMBOL FOR GROUP SEPARATOR
+ // U+241E SYMBOL FOR RECORD SEPARATOR
+ // U+241F SYMBOL FOR UNIT SEPARATOR
+ str.push_back('\xe2');
+ str.push_back('\x90');
+ str.push_back(ctrl + 0x80);
+ break;
+
+ case 0x7f: /* DEL */
+ str.append("\xe2\x90\xa1"); // U+2421 SYMBOL FOR DELETE
+ break;
+
+ case 0x80 ... 0x9f: /* C1 */
+ // Unfortunately, over 20 years after being first proposed, unicode
+ // **still** does not have control pictures for the C1 controls.
+ //
+ // Use U+FFFD instead.
+ str.append("\xef\xbf\xbd");
+ break;
+
+ default:
+ // This function may only be called for controls
+ __builtin_unreachable();
+ }
+}
+
} // namespace vte::terminal
diff --git a/src/pastify.hh b/src/pastify.hh
index a0abf3ba..807205c0 100644
--- a/src/pastify.hh
+++ b/src/pastify.hh
@@ -27,4 +27,7 @@ std::string pastify_string(std::string_view str,
bool insert_brackets,
bool c1 = false);
+void append_control_picture(std::string& str,
+ char32_t ctrl);
+
} // namespace vte::terminal