summary refs log tree commit diff
path: root/bin
diff options
context:
space:
mode:
Diffstat (limited to 'bin')
-rw-r--r--bin/.gitignore1
-rw-r--r--bin/Makefile1
-rw-r--r--bin/README3
-rw-r--r--bin/bin.75
-rw-r--r--bin/hi.c45
5 files changed, 39 insertions, 16 deletions
diff --git a/bin/.gitignore b/bin/.gitignore
index d68c33f8..e2d2b44e 100644
--- a/bin/.gitignore
+++ b/bin/.gitignore
@@ -9,6 +9,7 @@ fbatt
 fbclock
 gfxx
 glitch
+hi
 hnel
 modem
 open
diff --git a/bin/Makefile b/bin/Makefile
index 619b3f50..d041d3a9 100644
--- a/bin/Makefile
+++ b/bin/Makefile
@@ -12,6 +12,7 @@ BINS += aes
 BINS += atch
 BINS += dtch
 BINS += glitch
+BINS += hi
 BINS += hnel
 BINS += modem
 BINS += open
diff --git a/bin/README b/bin/README
index 478373ae..53992a5d 100644
--- a/bin/README
+++ b/bin/README
@@ -16,6 +16,7 @@ DESCRIPTION
      fbclock(1)  framebuffer clock
      gfxx(1)     graphics data explorer
      glitch(1)   PNG glitcher
+     hi(1)       syntax highlighter
      hnel(1)     PTY input remapper
      modem(1)    fixed baud rate wrapper
      pbd(1)      macOS pasteboard daemon
@@ -33,4 +34,4 @@ DESCRIPTION
            GFX=fb
            GFX=x11
 
-Causal Agency                  January 26, 2019                  Causal Agency
+Causal Agency                  Feburary 6, 2019                  Causal Agency
diff --git a/bin/bin.7 b/bin/bin.7
index e350ff49..201ac3b0 100644
--- a/bin/bin.7
+++ b/bin/bin.7
@@ -1,4 +1,4 @@
-.Dd January 26, 2019
+.Dd Feburary 6, 2019
 .Dt BIN 7
 .Os "Causal Agency"
 .
@@ -43,6 +43,9 @@ graphics data explorer
 .It Xr glitch 1
 PNG glitcher
 .
+.It Xr hi 1
+syntax highlighter
+.
 .It Xr hnel 1
 PTY input remapper
 .
diff --git a/bin/hi.c b/bin/hi.c
index 965de239..90daf4d3 100644
--- a/bin/hi.c
+++ b/bin/hi.c
@@ -37,23 +37,23 @@ enum Class {
 
 struct Syntax {
 	enum Class class;
-	int flags;
 	const char *pattern;
+	const char *pattend;
 };
 
 // FIXME: Looks like [[:<:]] [[:>:]] are not supported on GNU.
 static const struct Syntax CSyntax[] = {
-	{ Keyword, 0,            "[[:<:]](enum|struct|typedef|union)[[:>:]]" },
-	{ Keyword, 0,            "[[:<:]](const|inline|static)[[:>:]]" },
-	{ Keyword, 0,            "[[:<:]](do|else|for|if|switch|while)[[:>:]]" },
-	{ Keyword, 0,            "[[:<:]](break|continue|goto|return)[[:>:]]" },
-	{ Keyword, 0,            "[[:<:]](case|default)[[:>:]]" },
-	{ Macro,   REG_NEWLINE,  "^#.*" },
-	{ String,  REG_NEWLINE,  "<[^[:blank:]=]*>" },
-	{ Comment, REG_NEWLINE,  "//.*" },
-	{ Comment, REG_ENHANCED, "/\\*.*?\\*/" }, // FIXME: Darwin-only.
-	{ String,  REG_NEWLINE,  "[LUu]?'([^']|\\\\')*'" },
-	{ String,  REG_NEWLINE,  "([LUu]|u8)?\"([^\"]|\\\\\")*\"" },
+	{ Keyword, "[[:<:]](enum|struct|typedef|union)[[:>:]]", NULL },
+	{ Keyword, "[[:<:]](const|inline|static)[[:>:]]", NULL },
+	{ Keyword, "[[:<:]](do|else|for|if|switch|while)[[:>:]]", NULL },
+	{ Keyword, "[[:<:]](break|continue|goto|return)[[:>:]]", NULL },
+	{ Keyword, "[[:<:]](case|default)[[:>:]]", NULL },
+	{ Macro,   "^#.*", NULL },
+	{ String,  "<[^[:blank:]=]*>", NULL },
+	{ Comment, "//.*", NULL },
+	{ Comment, "/\\*", "\\*/" },
+	{ String,  "[LUu]?'([^']|\\\\')*'", NULL },
+	{ String,  "([LUu]|u8)?\"([^\"]|\\\\\")*\"", NULL },
 };
 
 static const struct Language {
@@ -67,7 +67,7 @@ static const struct Language {
 
 static regex_t compile(const char *pattern, int flags) {
 	regex_t regex;
-	int error = regcomp(&regex, pattern, REG_EXTENDED | flags);
+	int error = regcomp(&regex, pattern, REG_EXTENDED | REG_NEWLINE | flags);
 	if (!error) return regex;
 	char buf[256];
 	regerror(error, &regex, buf, sizeof(buf));
@@ -76,7 +76,12 @@ static regex_t compile(const char *pattern, int flags) {
 
 static void highlight(struct Language lang, enum Class *hi, const char *str) {
 	for (size_t i = 0; i < lang.len; ++i) {
-		regex_t regex = compile(lang.syntax[i].pattern, lang.syntax[i].flags);
+		regex_t regex = compile(lang.syntax[i].pattern, 0);
+		regex_t regend = {0};
+		if (lang.syntax[i].pattend) {
+			regend = compile(lang.syntax[i].pattend, 0);
+		}
+
 		regmatch_t match = {0};
 		for (size_t offset = 0; str[offset]; offset += match.rm_eo) {
 			int error = regexec(
@@ -84,11 +89,23 @@ static void highlight(struct Language lang, enum Class *hi, const char *str) {
 			);
 			if (error == REG_NOMATCH) break;
 			if (error) errx(EX_SOFTWARE, "regexec: %d", error);
+
+			if (lang.syntax[i].pattend) {
+				regmatch_t end;
+				error = regexec(
+					&regend, &str[offset + match.rm_eo], 1, &end, REG_NOTBOL
+				);
+				if (error == REG_NOMATCH) break;
+				if (error) errx(EX_SOFTWARE, "regexec: %d", error);
+				match.rm_eo += end.rm_eo;
+			}
+
 			for (regoff_t j = match.rm_so; j < match.rm_eo; ++j) {
 				hi[offset + j] = lang.syntax[i].class;
 			}
 		}
 		regfree(&regex);
+		if (lang.syntax[i].pattend) regfree(&regend);
 	}
 }