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
;;