shithub: mc

Download patch

ref: 24020b49aee678a72f3d9883371af8c70e4af9a5
parent: e7ba66a1d2698910fcc0ba4aeadff491fb0ead94
author: Ori Bernstein <ori@markovcorp.com>
date: Tue Jan 3 10:46:38 EST 2017

Add regex escaping.

--- a/lib/escfmt/bld.sub
+++ b/lib/escfmt/bld.sub
@@ -4,6 +4,7 @@
 	escsh.myr
 	eschtml.myr
 	escurl.myr
+	escre.myr
 
 	lib ../std:std
         lib ../sys:sys
--- /dev/null
+++ b/lib/escfmt/escre.myr
@@ -1,0 +1,40 @@
+use std
+
+pkg escfmt =
+	type escre = byte[:]
+
+	const re	: (s : byte[:] -> escre) 
+;;
+
+const __init__ = {
+	var s = ("" : escre)
+	std.fmtinstall(std.typeof(s), refmt, [][:])
+}
+
+const re = {s
+	-> (s : escre)
+}
+
+const refmt = {sb, ap, args
+	var s : byte[:]
+
+	s = std.vanext(ap)
+	for c in std.bychar(s)
+		match c
+		| '|':	std.sbputs(sb, "\\|")
+		| '*':	std.sbputs(sb, "\\*")
+		| '+':	std.sbputs(sb, "\\+")
+		| '?':	std.sbputs(sb, "\\?")
+		| '[':	std.sbputs(sb, "\\[")
+		| ']':	std.sbputs(sb, "\\]")
+		| '^':	std.sbputs(sb, "\\^")
+		| '$':	std.sbputs(sb, "\\$")
+		| '.':	std.sbputs(sb, "\\.")
+		| '\\':	std.sbputs(sb, "\\.")
+		| '(':	std.sbputs(sb, "\\(")
+		| ')':	std.sbputs(sb, "\\)")
+		| _:	std.sbputc(sb, c)
+		;;
+	;;
+}
+
--- /dev/null
+++ b/lib/escfmt/test/escre.myr
@@ -1,0 +1,21 @@
+use std
+use escfmt
+use testr
+
+const main = {
+	testr.run([\
+		[.name="unchanged", .fn={ctx
+			var s = std.fmt("{}", escfmt.url("word"))
+			testr.check(ctx, std.sleq("word", s), std.fmt("mismatched escape {}", s))
+			std.slfree(s)
+		}],
+		[.name="randomcrud", .fn={ctx
+			var s = std.fmt("{}", escfmt.re("^:/?#[]@!$&'()*+,;=%"))
+			testr.check(ctx, \
+				std.sleq("\\^:/\\?#\\[\\]@!\\$&'\\(\\)\\*\\+,;=%", s), \
+				std.fmt("mismatched escape {}", s))
+			std.slfree(s)
+		}],
+	][:])
+}
+
--- a/lib/regex/compile.myr
+++ b/lib/regex/compile.myr
@@ -651,6 +651,7 @@
 	| 'r':	ret = `Some mk(re, `Chr '\r', idx)
 	| 'n':	ret = `Some mk(re, `Chr '\n', idx)
 	| 'b':	ret = `Some mk(re, `Chr '\b', idx)
+	| ')':	ret = `Some mk(re, `Chr ')', idx)
 	| 'u':	ret = unichar(re, idx)
 	| chr:	ret = `Err `Badescape chr
 	;;