ref: 0b7b8cf380ced404a763a81e86db439ee4915393
parent: a61a1f51567f27ec605986354a28f8360abb1bda
author: Ori Bernstein <ori@eigenstate.org>
date: Thu Sep 8 19:08:12 EDT 2016
Add url escaping.
--- a/lib/escfmt/bld.sub
+++ b/lib/escfmt/bld.sub
@@ -1,7 +1,8 @@
lib escfmt =
escsh.myr
eschtml.myr
+ escurl.myr
lib ../std:std
- lib ../sys:sys
+ lib ../sys:sys
;;
--- /dev/null
+++ b/lib/escfmt/escurl.myr
@@ -1,0 +1,52 @@
+use std
+
+pkg escfmt =
+ type escurl = byte[:]
+
+ const url : (s : byte[:] -> escurl)
+;;
+
+const __init__ = {+ var s = ("" : escurl)+ std.fmtinstall(std.typeof(s), urlfmt, [][:])
+}
+
+const url = {s+ -> (s : escurl)
+}
+
+const urlfmt = {sb, ap, args+ var s : byte[:]
+
+ s = std.vanext(ap)
+ for b in s
+ match (b : char)
+ | ':': std.sbfmt(sb, "%{x}", b)+ | '/': std.sbfmt(sb, "%{x}", b)+ | '?': std.sbfmt(sb, "%{x}", b)+ | '#': std.sbfmt(sb, "%{x}", b)+ | '[': std.sbfmt(sb, "%{x}", b)+ | ']': std.sbfmt(sb, "%{x}", b)+ | '@': std.sbfmt(sb, "%{x}", b)+ | '!': std.sbfmt(sb, "%{x}", b)+ | '$': std.sbfmt(sb, "%{x}", b)+ | '&': std.sbfmt(sb, "%{x}", b)+ | '\'': std.sbfmt(sb, "%{x}", b)+ | '(': std.sbfmt(sb, "%{x}", b)+ | ')': std.sbfmt(sb, "%{x}", b)+ | '*': std.sbfmt(sb, "%{x}", b)+ | '+': std.sbfmt(sb, "%{x}", b)+ | ',': std.sbfmt(sb, "%{x}", b)+ | ';': std.sbfmt(sb, "%{x}", b)+ | '=': std.sbfmt(sb, "%{x}", b)+ | '%': std.sbfmt(sb, "%{x}", b)+ | c:
+ if b >= 0x80
+ std.sbfmt(sb, "%{x}", b)+ else
+ std.sbfmt(sb, "{}", c)+ ;;
+
+ ;;
+ ;;
+}
--- /dev/null
+++ b/lib/escfmt/test/escurl.myr
@@ -1,0 +1,28 @@
+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="allspecials", .fn={ctx+ var s = std.fmt("{}", escfmt.url(":/?#[]@!$&'()*+,;=%"))+ testr.check(ctx, \
+ std.sleq("%3a%2f%3f%23%5b%5d%40%21%24%26%27%28%29%2a%2b%2c%3b%3d%25", s), \+ std.fmt("mismatched escape {}", s))+ std.slfree(s)
+ }],
+ [.name="unicodes", .fn={ctx+ var s = std.fmt("{}", escfmt.url("᚛᚛ᚉᚑᚅᚔᚉᚉᚔ"))+ testr.check(ctx, \
+ std.sleq("%e1%9a%9b%e1%9a%9b%e1%9a%89%e1%9a%91%e1%9a%85%e1%9a%94%e1%9a%89%e1%9a%89%e1%9a%94", s), \+ std.fmt("mismatched escape {}", s))+ std.slfree(s)
+ }],
+ ][:])
+}
+
--
⑨