about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLeah Neukirchen <leah@vuxu.org>2017-11-19 16:35:58 +0100
committerLeah Neukirchen <leah@vuxu.org>2017-11-19 16:35:58 +0100
commit21d745532f3a4ae93cc6a0479cadaf3660189933 (patch)
treeac7a65aa8f49503c650b9e9d6c892e8c62d3e69d
parent603c12cdf15afcbc9131369583dcdf5e8beadbe9 (diff)
downloadlr-21d745532f3a4ae93cc6a0479cadaf3660189933.tar.gz
lr-21d745532f3a4ae93cc6a0479cadaf3660189933.tar.xz
lr-21d745532f3a4ae93cc6a0479cadaf3660189933.zip
print_format: add escapes for octal and hex bytes
-rw-r--r--lr.16
-rw-r--r--lr.c29
2 files changed, 32 insertions, 3 deletions
diff --git a/lr.1 b/lr.1
index fac5493..a79fb39 100644
--- a/lr.1
+++ b/lr.1
@@ -157,8 +157,12 @@ Implies
 format strings support the following escape sequences:
 .Pp
 .Bl -tag -compact -width Ds
-.It Ic \ea , \eb , \ef , \en , \er , \ev , \e0
+.It Ic \ea , \eb , \ef , \en , \er , \ev
 Special characters as in C.
+.It Ic \e Ns Ar ddd
+Byte with one, two or three-digit octal value.
+.It Ic \ex Ns Ar dd
+Byte with one or two-digit hexadecimal value.
 .It Ic \&%%
 A plain
 .Sq % .
diff --git a/lr.c b/lr.c
index 7d75f3f..9328f55 100644
--- a/lr.c
+++ b/lr.c
@@ -1831,6 +1831,7 @@ hyperlink_off()
 void
 print_format(struct fileinfo *fi)
 {
+	int c, v;
 	char *s;
 	for (s = format; *s; s++) {
 		if (*s == '\\') {
@@ -1842,8 +1843,32 @@ print_format(struct fileinfo *fi)
 			case 'r': putchar('\r'); break;
 			case 't': putchar('\t'); break;
 			case 'v': putchar('\v'); break;
-			case '0': putchar('\0'); break;
-			// TODO: \NNN
+			case '0': case '1': case '2': case '3':
+			case '4': case '5': case '6': case '7':
+				for (c = 3, v = 0;
+				     c > 0 && *s >= '0' && *s <= '7';
+				     s++, c--) {
+					v = (v << 3) + ((*s) - '0');
+				}
+				s--;
+				putchar(v & 0xff);
+				break;
+			case 'x':
+				s++;
+				for (c = 2, v = 0;
+				     c > 0 && isxdigit((unsigned char)*s);
+				     s++, c--) {
+					v <<= 4;
+					if (*s >= 'A' && *s <= 'F')
+						v += *s - 'A' + 10;
+					else if (*s >= 'a' && *s <= 'f')
+						v += *s - 'a' + 10;
+					else
+						v += *s - '0';
+				}
+				s--;
+				putchar(v);
+				break;
 			default: putchar(*s);
 			}
 			continue;