summaryrefslogtreecommitdiffstats
path: root/src/bfstd.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/bfstd.c')
-rw-r--r--src/bfstd.c40
1 files changed, 35 insertions, 5 deletions
diff --git a/src/bfstd.c b/src/bfstd.c
index e338831..e125be6 100644
--- a/src/bfstd.c
+++ b/src/bfstd.c
@@ -619,6 +619,31 @@ static size_t unprintable_len(const char *str, size_t len) {
return cur - str;
}
+/** Convert a special char into a well-known escape sequence like "\n". */
+static const char *c_esc(char c) {
+ // https://www.gnu.org/software/bash/manual/html_node/ANSI_002dC-Quoting.html
+ switch (c) {
+ case '\a':
+ return "\\a";
+ case '\b':
+ return "\\b";
+ case '\033':
+ return "\\e";
+ case '\f':
+ return "\\f";
+ case '\n':
+ return "\\n";
+ case '\r':
+ return "\\r";
+ case '\t':
+ return "\\t";
+ case '\v':
+ return "\\v";
+ default:
+ return NULL;
+ }
+}
+
char *wordesc(const char *str) {
size_t len = strlen(str);
@@ -666,11 +691,16 @@ char *wordesc(const char *str) {
cur = xstpecpy(cur, end, "$'");
size_t uplen = unprintable_len(str, len);
for (size_t i = 0; i < uplen; ++i) {
- static const char *hex[] = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"};
- unsigned char byte = str[i];
- cur = xstpecpy(cur, end, "\\x");
- cur = xstpecpy(cur, end, hex[byte / 0x10]);
- cur = xstpecpy(cur, end, hex[byte % 0x10]);
+ const char *esc = c_esc(str[i]);
+ if (esc) {
+ cur = xstpecpy(cur, end, esc);
+ } else {
+ static const char *hex[] = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"};
+ unsigned char byte = str[i];
+ cur = xstpecpy(cur, end, "\\x");
+ cur = xstpecpy(cur, end, hex[byte / 0x10]);
+ cur = xstpecpy(cur, end, hex[byte % 0x10]);
+ }
}
cur = xstpecpy(cur, end, "'");