summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author最萌小汐 <sumneko@hotmail.com>2020-05-13 17:09:50 +0800
committer最萌小汐 <sumneko@hotmail.com>2020-05-13 17:10:26 +0800
commit1d0a33637635a4f5a9a614c4bb0de17202c2d375 (patch)
tree828b2932ffc68f06c1f73921e9c62a3220e93b03
parentd7daade3a3b8f4a5e33bca3df7ec0656d93684c2 (diff)
downloadlua-language-server-1d0a33637635a4f5a9a614c4bb0de17202c2d375.zip
改成使用自己的 file-uri
-rw-r--r--script-beta/file-uri.lua5
-rw-r--r--script/3rd/lua-uri/uri.lua504
-rw-r--r--script/3rd/lua-uri/uri/_login.lua96
-rw-r--r--script/3rd/lua-uri/uri/_relative.lua81
-rw-r--r--script/3rd/lua-uri/uri/_util.lua128
-rw-r--r--script/3rd/lua-uri/uri/data.lua116
-rw-r--r--script/3rd/lua-uri/uri/file.lua72
-rw-r--r--script/3rd/lua-uri/uri/file/unix.lua26
-rw-r--r--script/3rd/lua-uri/uri/file/win32.lua34
-rw-r--r--script/3rd/lua-uri/uri/ftp.lua53
-rw-r--r--script/3rd/lua-uri/uri/http.lua32
-rw-r--r--script/3rd/lua-uri/uri/https.lua9
-rw-r--r--script/3rd/lua-uri/uri/pop.lua111
-rw-r--r--script/3rd/lua-uri/uri/rtsp.lua9
-rw-r--r--script/3rd/lua-uri/uri/rtspu.lua7
-rw-r--r--script/3rd/lua-uri/uri/telnet.lua38
-rw-r--r--script/3rd/lua-uri/uri/urn.lua131
-rw-r--r--script/3rd/lua-uri/uri/urn/isbn.lua67
-rw-r--r--script/3rd/lua-uri/uri/urn/issn.lua65
-rw-r--r--script/3rd/lua-uri/uri/urn/oid.lua62
-rw-r--r--script/file-uri.lua109
-rw-r--r--script/uri.lua24
-rw-r--r--test/crossfile/completion.lua2
-rw-r--r--test/crossfile/definition.lua2
-rw-r--r--test/crossfile/document_symbol.lua4
-rw-r--r--test/crossfile/hover.lua4
-rw-r--r--test/crossfile/references.lua4
27 files changed, 125 insertions, 1670 deletions
diff --git a/script-beta/file-uri.lua b/script-beta/file-uri.lua
index 8acd4f64..2576044b 100644
--- a/script-beta/file-uri.lua
+++ b/script-beta/file-uri.lua
@@ -66,8 +66,9 @@ function m.encode(path)
end
-- lower-case windows drive letters in /C:/fff or C:/fff
- if path:match '/%u:' then
- path = path:lower()
+ local start, finish, drive = path:find '/(%u):'
+ if drive then
+ path = path:sub(1, start) .. drive:lower() .. path:sub(finish, -1)
end
local uri = 'file://'
diff --git a/script/3rd/lua-uri/uri.lua b/script/3rd/lua-uri/uri.lua
deleted file mode 100644
index 395edcd9..00000000
--- a/script/3rd/lua-uri/uri.lua
+++ /dev/null
@@ -1,504 +0,0 @@
-local M = { _NAME = "uri", VERSION = "1.0" }
-M.__index = M
-
-local Util = require "uri._util"
-
-local _UNRESERVED = "A-Za-z0-9%-._~"
-local _GEN_DELIMS = ":/?#%[%]@"
-local _SUB_DELIMS = "!$&'()*+,;="
-local _RESERVED = _GEN_DELIMS .. _SUB_DELIMS
-local _USERINFO = "^[" .. _UNRESERVED .. "%%" .. _SUB_DELIMS .. ":]*$"
-local _REG_NAME = "^[" .. _UNRESERVED .. "%%" .. _SUB_DELIMS .. "]*$"
-local _IP_FUTURE_LITERAL = "^v[0-9A-Fa-f]+%." ..
- "[" .. _UNRESERVED .. _SUB_DELIMS .. "]+$"
-local _QUERY_OR_FRAG = "^[" .. _UNRESERVED .. "%%" .. _SUB_DELIMS .. ":@/?]*$"
-local _PATH_CHARS = "^[" .. _UNRESERVED .. "%%" .. _SUB_DELIMS .. ":@/]*$"
-
-local function _normalize_percent_encoding (s)
- if s:find("%%$") or s:find("%%.$") then
- error("unfinished percent encoding at end of URI '" .. s .. "'")
- end
-
- return s:gsub("%%(..)", function (hex)
- if not hex:find("^[0-9A-Fa-f][0-9A-Fa-f]$") then
- error("invalid percent encoding '%" .. hex ..
- "' in URI '" .. s .. "'")
- end
-
- -- Never percent-encode unreserved characters, and always use uppercase
- -- hexadecimal for percent encoding. RFC 3986 section 6.2.2.2.
- local char = string.char(tonumber("0x" .. hex))
- return char:find("^[" .. _UNRESERVED .. "]") and char or "%" .. hex:upper()
- end)
-end
-
-local function _is_ip4_literal (s)
- if not s:find("^[0-9]+%.[0-9]+%.[0-9]+%.[0-9]+$") then return false end
-
- for dec_octet in s:gmatch("[0-9]+") do
- if dec_octet:len() > 3 or dec_octet:find("^0.") or
- tonumber(dec_octet) > 255 then
- return false
- end
- end
-
- return true
-end
-
-local function _is_ip6_literal (s)
- local had_elipsis = false -- true when '::' found
- local num_chunks = 0
- while s ~= "" do
- num_chunks = num_chunks + 1
- local p1, p2 = s:find("::?")
- local chunk
- if p1 then
- chunk = s:sub(1, p1 - 1)
- s = s:sub(p2 + 1)
- if p2 ~= p1 then -- found '::'
- if had_elipsis then return false end -- two of '::'
- had_elipsis = true
- if chunk == "" then num_chunks = num_chunks - 1 end
- else
- if chunk == "" then return false end -- ':' at start
- if s == "" then return false end -- ':' at end
- end
- else
- chunk = s
- s = ""
- end
-
- -- Chunk is neither 4-digit hex num, nor IPv4address in last chunk.
- if (not chunk:find("^[0-9a-f]+$") or chunk:len() > 4) and
- (s ~= "" or not _is_ip4_literal(chunk)) and
- chunk ~= "" then
- return false
- end
-
- -- IPv4address in last position counts for two chunks of hex digits.
- if chunk:len() > 4 then num_chunks = num_chunks + 1 end
- end
-
- if had_elipsis then
- if num_chunks > 7 then return false end
- else
- if num_chunks ~= 8 then return false end
- end
-
- return true
-end
-
-local function _is_valid_host (host)
- if host:find("^%[.*%]$") then
- local ip_literal = host:sub(2, -2)
- if ip_literal:find("^v") then
- if not ip_literal:find(_IP_FUTURE_LITERAL) then
- return "invalid IPvFuture literal '" .. ip_literal .. "'"
- end
- else
- if not _is_ip6_literal(ip_literal) then
- return "invalid IPv6 address '" .. ip_literal .. "'"
- end
- end
- elseif not _is_ip4_literal(host) and not host:find(_REG_NAME) then
- return "invalid host value '" .. host .. "'"
- end
-
- return nil
-end
-
-local function _normalize_and_check_path (s, normalize)
- if not s:find(_PATH_CHARS) then return false end
- if not normalize then return s end
-
- -- Remove unnecessary percent encoding for path values.
- -- TODO - I think this should be HTTP-specific (probably file also).
- --s = Util.uri_decode(s, _SUB_DELIMS .. ":@")
-
- return Util.remove_dot_segments(s)
-end
-
-function M.new (class, uri, base)
- if not uri then error("usage: URI:new(uristring, [baseuri])") end
- if type(uri) ~= "string" then uri = tostring(uri) end
-
- if base then
- local uri, err = M.new(class, uri)
- if not uri then return nil, err end
- if type(base) ~= "table" then
- base, err = M.new(class, base)
- if not base then return nil, "error parsing base URI: " .. err end
- end
- if base:is_relative() then return nil, "base URI must be absolute" end
- local ok, err = pcall(uri.resolve, uri, base)
- if not ok then return nil, err end
- return uri
- end
-
- local s = _normalize_percent_encoding(uri)
-
- local _, p
- local scheme, authority, userinfo, host, port, path, query, fragment
-
- _, p, scheme = s:find("^([a-zA-Z][-+.a-zA-Z0-9]*):")
- if scheme then
- scheme = scheme:lower()
- s = s:sub(p + 1)
- end
-
- _, p, authority = s:find("^//([^/?#]*)")
- if authority then
- s = s:sub(p + 1)
-
- _, p, userinfo = authority:find("^([^@]*)@")
- if userinfo then
- if not userinfo:find(_USERINFO) then
- return nil, "invalid userinfo value '" .. userinfo .. "'"
- end
- authority = authority:sub(p + 1)
- end
-
- p, _, port = authority:find(":([0-9]*)$")
- if port then
- port = (port ~= "") and tonumber(port) or nil
- authority = authority:sub(1, p - 1)
- end
-
- host = authority:lower()
- local err = _is_valid_host(host)
- if err then return nil, err end
- end
-
- _, p, path = s:find("^([^?#]*)")
- if path ~= "" then
- local normpath = _normalize_and_check_path(path, scheme)
- if not normpath then return nil, "invalid path '" .. path .. "'" end
- path = normpath
- s = s:sub(p + 1)
- end
-
- _, p, query = s:find("^%?([^#]*)")
- if query then
- s = s:sub(p + 1)
- if not query:find(_QUERY_OR_FRAG) then
- return nil, "invalid query value '?" .. query .. "'"
- end
- end
-
- _, p, fragment = s:find("^#(.*)")
- if fragment then
- if not fragment:find(_QUERY_OR_FRAG) then
- return nil, "invalid fragment value '#" .. fragment .. "'"
- end
- end
-
- local o = {
- _scheme = scheme,
- _userinfo = userinfo,
- _host = host,
- _port = port,
- _path = path,
- _query = query,
- _fragment = fragment,
- }
- setmetatable(o, scheme and class or (require "uri._relative"))
-
- return o:init()
-end
-
-function M.uri (self, ...)
- local uri = self._uri
-
- if not uri then
- local scheme = self:scheme()
- if scheme then
- uri = scheme .. ":"
- else
- uri = ""
- end
-
- local host, port, userinfo = self:host(), self._port, self:userinfo()
- if host or port or userinfo then
- uri = uri .. "//"
- if userinfo then uri = uri .. userinfo .. "@" end
- if host then uri = uri .. host end
- if port then uri = uri .. ":" .. port end
- end
-
- local path = self:path()
- if uri == "" and path:find("^[^/]*:") then
- path = "./" .. path
- end
-
- uri = uri .. path
- if self:query() then uri = uri .. "?" .. self:query() end
- if self:fragment() then uri = uri .. "#" .. self:fragment() end
-
- self._uri = uri -- cache
- end
-
- if select("#", ...) > 0 then
- local new = ...
- if not new then error("URI can't be set to nil") end
- local newuri, err = M:new(new)
- if not newuri then
- error("new URI string is invalid (" .. err .. ")")
- end
- setmetatable(self, getmetatable(newuri))
- for k in pairs(self) do self[k] = nil end
- for k, v in pairs(newuri) do self[k] = v end
- end
-
- return uri
-end
-
-function M.__tostring (self) return self:uri() end
-
-function M.eq (a, b)
- if type(a) == "string" then a = assert(M:new(a)) end
- if type(b) == "string" then b = assert(M:new(b)) end
- return a:uri() == b:uri()
-end
-
-function M.scheme (self, ...)
- local old = self._scheme
-
- if select("#", ...) > 0 then
- local new = ...
- if not new then error("can't remove scheme from absolute URI") end
- if type(new) ~= "string" then new = tostring(new) end
- if not new:find("^[a-zA-Z][-+.a-zA-Z0-9]*$") then
- error("invalid scheme '" .. new .. "'")
- end
- Util.do_class_changing_change(self, M, "scheme", new,
- function (uri, new) uri._scheme = new end)
- end
-
- return old
-end
-
-function M.userinfo (self, ...)
- local old = self._userinfo
-
- if select("#", ...) > 0 then
- local new = ...
- if new then
- if not new:find(_USERINFO) then
- error("invalid userinfo value '" .. new .. "'")
- end
- new = _normalize_percent_encoding(new)
- end
- self._userinfo = new
- if new and not self._host then self._host = "" end
- self._uri = nil
- end
-
- return old
-end
-
-function M.host (self, ...)
- local old = self._host
-
- if select("#", ...) > 0 then
- local new = ...
- if new then
- new = tostring(new):lower()
- local err = _is_valid_host(new)
- if err then error(err) end
- else
- if self._userinfo or self._port then
- error("there must be a host if there is a userinfo or port," ..
- " although it can be the empty string")
- end
- end
- self._host = new
- self._uri = nil
- end
-
- return old
-end
-
-function M.port (self, ...)
- local old = self._port or self:default_port()
-
- if select("#", ...) > 0 then
- local new = ...
- if new then
- if type(new) == "string" then new = tonumber(new) end
- if new < 0 then error("port number must not be negative") end
- local newint = new - new % 1
- if newint ~= new then error("port number not integer") end
- if new == self:default_port() then new = nil end
- end
- self._port = new
- if new and not self._host then self._host = "" end
- self._uri = nil
- end
-
- return old
-end
-
-function M.path (self, ...)
- local old = self._path
-
- if select("#", ...) > 0 then
- local new = ... or ""
- new = _normalize_percent_encoding(new)
- new = Util.uri_encode(new, "^A-Za-z0-9%-._~%%!$&'()*+,;=:@/")
- if self._host then
- if new ~= "" and not new:find("^/") then
- error("path must begin with '/' when there is an authority")
- end
- else
- if new:find("^//") then new = "/%2F" .. new:sub(3) end
- end
- self._path = new
- self._uri = nil
- end
-
- return old
-end
-
-function M.query (self, ...)
- local old = self._query
-
- if select("#", ...) > 0 then
- local new = ...
- if new then
- new = Util.uri_encode(new, "^" .. _UNRESERVED .. "%%" .. _SUB_DELIMS .. ":@/?")
- end
- self._query = new
- self._uri = nil
- end
-
- return old
-end
-
-function M.fragment (self, ...)
- local old = self._fragment
-
- if select("#", ...) > 0 then
- local new = ...
- if new then
- new = Util.uri_encode(new, "^" .. _UNRESERVED .. "%%" .. _SUB_DELIMS .. ":@/?")
- end
- self._fragment = new
- self._uri = nil
- end
-
- return old
-end
-
-function M.init (self)
- local scheme_class
- = Util.attempt_require("uri." .. self._scheme:gsub("[-+.]", "_"))
- if scheme_class then
- setmetatable(self, scheme_class)
- if self._port and self._port == self:default_port() then
- self._port = nil
- end
- -- Call the subclass 'init' method, if it has its own.
- if scheme_class ~= M and self.init ~= M.init then
- return self:init()
- end
- end
- return self
-end
-
-function M.default_port () return nil end
-function M.is_relative () return false end
-function M.resolve () end -- only does anything in uri._relative
-
--- TODO - there should probably be an option or something allowing you to
--- choose between making a link relative whenever possible (always using a
--- relative path if the scheme and authority are the same as the base URI) or
--- just using a relative reference to make the link as small as possible, which
--- might meaning using a path of '/' instead if '../../../' or whatever.
--- This method's algorithm is loosely based on the one described here:
--- http://lists.w3.org/Archives/Public/uri/2007Sep/0003.html
-function M.relativize (self, base)
- if type(base) == "string" then base = assert(M:new(base)) end
-
- -- Leave it alone if we can't a relative URI, or if it would be a network
- -- path reference.
- if self._scheme ~= base._scheme or self._host ~= base._host or
- self._port ~= base._port or self._userinfo ~= base._userinfo then
- return
- end
-
- local basepath = base._path
- local oldpath = self._path
- -- This is to avoid trying to make a URN or something relative, which
- -- is likely to lead to grief.
- if not basepath:find("^/") or not oldpath:find("^/") then return end
-
- -- Turn it into a relative reference.
- self._uri = nil
- self._scheme = nil
- self._host = nil
- self._port = nil
- self._userinfo = nil
- setmetatable(self, require "uri._relative")
-
- -- Use empty path if the path in the base URI is already correct.
- if oldpath == basepath then
- if self._query or not base._query then
- self._path = ""
- else
- -- An empty URI reference leaves the query string in the base URI
- -- unchanged, so to get a result with no query part we have to
- -- have something in the relative path.
- local _, _, lastseg = oldpath:find("/([^/]+)$")
- if lastseg and lastseg:find(":") then lastseg = "./" .. lastseg end
- self._path = lastseg or "."
- end
- return
- end
-
- if oldpath == "/" or basepath == "/" then return end
-
- local basesegs = Util.split("/", basepath:sub(2))
- local oldsegs = Util.split("/", oldpath:sub(2))
-
- if oldsegs[1] ~= basesegs[1] then return end
-
- table.remove(basesegs)
-
- while #oldsegs > 1 and #basesegs > 0 and oldsegs[1] == basesegs[1] do
- table.remove(oldsegs, 1)
- table.remove(basesegs, 1)
- end
-
- local path_naked = true
- local newpath = ""
- while #basesegs > 0 do
- table.remove(basesegs, 1)
- newpath = newpath .. "../"
- path_naked = false
- end
-
- if path_naked and #oldsegs == 1 and oldsegs[1] == "" then
- newpath = "./"
- table.remove(oldsegs)
- end
-
- while #oldsegs > 0 do
- if path_naked then
- if oldsegs[1]:find(":") then
- newpath = newpath .. "./"
- elseif #oldsegs > 1 and oldsegs[1] == "" and oldsegs[2] == "" then
- newpath = newpath .. "/."
- end
- end
-
- newpath = newpath .. oldsegs[1]
- path_naked = false
- table.remove(oldsegs, 1)
- if #oldsegs > 0 then newpath = newpath .. "/" end
- end
-
- self._path = newpath
-end
-
-return M
--- vi:ts=4 sw=4 expandtab
diff --git a/script/3rd/lua-uri/uri/_login.lua b/script/3rd/lua-uri/uri/_login.lua
deleted file mode 100644
index 4e9e6844..00000000
--- a/script/3rd/lua-uri/uri/_login.lua
+++ /dev/null
@@ -1,96 +0,0 @@
-local M = { _NAME = "uri._login" }
-local Util = require "uri._util"
-local URI = require "uri"
-Util.subclass_of(M, URI)
-
--- Generic terminal logins. This is used as a base class for 'telnet' and
--- 'ftp' URL schemes.
-
-local function _valid_userinfo (userinfo)
- if userinfo then
- local colon = userinfo:find(":")
- if colon and userinfo:find(":", colon + 1) then
- return nil, "only one colon allowed in userinfo"
- end
- end
- return true
-end
-
--- TODO - this is a bit of a hack because currently subclasses are required
--- to know whether their superclass has one of these that needs calling.
--- It should be called from 'init' before anything more specific is done,
--- and it has the same calling convention.
--- According to RFC 1738 there should be at most one colon in the userinfo.
--- I apply that restriction for schemes where it's used for a username/password
--- pair.
-function M.init_base (self)
- local host = self:host()
- if not host or host == "" then
- return nil, "host missing from login URI"
- end
-
- local ok, err = _valid_userinfo(self:userinfo())
- if not ok then return nil, err end
-
- return self
-end
-
-function M.userinfo (self, ...)
- if select("#", ...) > 0 then
- local ok, err = _valid_userinfo(...)
- if not ok then error("invalid userinfo value (" .. err .. ")") end
- end
- return M._SUPER.userinfo(self, ...)
-end
-
-function M.username (self, ...)
- local info = M._SUPER.userinfo(self)
- local old, colon
- if info then
- local colon = info and info:find(":")
- old = colon and info:sub(1, colon - 1) or info
- old = Util.uri_decode(old)
- end
-
- if select('#', ...) > 0 then
- local pass = colon and info:sub(colon) or "" -- includes colon
- local new = ...
- if not new then
- M._SUPER.userinfo(self, nil)
- else
- -- Escape anything that's not allowed in a userinfo, and also
- -- colon, because that indicates the end of the username.
- new = Util.uri_encode(new, "^A-Za-z0-9%-._~!$&'()*+,;=")
- M._SUPER.userinfo(self, new .. pass)
- end
- end
-
- return old
-end
-
-function M.password (self, ...)
- local info = M._SUPER.userinfo(self)
- local old, colon
- if info then
- colon = info and info:find(":")
- old = colon and info:sub(colon + 1) or nil
- if old then old = Util.uri_decode(old) end
- end
-
- if select('#', ...) > 0 then
- local new = ...
- local user = colon and info:sub(1, colon - 1) or info
- if not new then
- M._SUPER.userinfo(self, user)
- else
- if not user then user = "" end
- new = Util.uri_encode(new, "^A-Za-z0-9%-._~!$&'()*+,;=")
- M._SUPER.userinfo(self, user .. ":" .. new)
- end
- end
-
- return old
-end
-
-return M
--- vi:ts=4 sw=4 expandtab
diff --git a/script/3rd/lua-uri/uri/_relative.lua b/script/3rd/lua-uri/uri/_relative.lua
deleted file mode 100644
index 8cd53ca7..00000000
--- a/script/3rd/lua-uri/uri/_relative.lua
+++ /dev/null
@@ -1,81 +0,0 @@
-local M = { _NAME = "uri._relative" }
-local Util = require "uri._util"
-local URI = require "uri"
-Util.subclass_of(M, URI)
-
--- There needs to be an 'init' method in this class, to because the base-class
--- one expects there to be a 'scheme' value.
-function M.init (self)
- return self
-end
-
-function M.scheme (self, ...)
- if select("#", ...) > 0 then
- error("relative URI references can't have a scheme, perhaps you" ..
- " need to resolve this against an absolute URI instead")
- end
- return nil
-end
-
-function M.is_relative () return true end
-
--- This implements the algorithm from RFC 3986 section 5.2.3
--- Note that this takes an additional argument which appears to be required
--- by the algorithm, but isn't shown when it is used in the RFC.
-local function _merge_paths (base, r, base_has_auth)
- if base_has_auth and base == "" then
- return "/" .. r
- end
-
- return base:gsub("[^/]+$", "", 1) .. r
-end
-
-local function _do_resolve (self, base)
- if type(base) == "string" then base = assert(URI:new(base)) end
- setmetatable(self, URI)
-
- if self:host() or self:userinfo() or self:port() then
- -- network path reference, just needs a scheme
- self:path(Util.remove_dot_segments(self:path()))
- self:scheme(base:scheme())
- return
- end
-
- local path = self:path()
- if path == "" then
- self:path(base:path())
- if not self:query() then self:query(base:query()) end
- else
- if path:find("^/") then
- self:path(Util.remove_dot_segments(path))
- else
- local base_has_auth = base:host() or base:userinfo() or base:port()
- local merged = _merge_paths(base:path(), path, base_has_auth)
- self:path(Util.remove_dot_segments(merged))
- end
- end
- self:host(base:host())
- self:userinfo(base:userinfo())
- self:port(base:port())
- self:scheme(base:scheme())
-end
-
-function M.resolve (self, base)
- local orig = tostring(self)
- local ok, result = pcall(_do_resolve, self, base)
- if ok then return end
-
- -- If the resolving causes an exception, it means that the resulting URI
- -- would be invalid, so we restore self to its original state and rethrow
- -- the exception.
- local restored = assert(URI:new(orig))
- for k in pairs(self) do self[k] = nil end
- for k, v in pairs(restored) do self[k] = v end
- setmetatable(self, getmetatable(restored))
- error("resolved URI reference would be invalid: " .. result)
-end
-
-function M.relativize (self, base) end -- already relative
-
-return M
--- vi:ts=4 sw=4 expandtab
diff --git a/script/3rd/lua-uri/uri/_util.lua b/script/3rd/lua-uri/uri/_util.lua
deleted file mode 100644
index 16a3b289..00000000
--- a/script/3rd/lua-uri/uri/_util.lua
+++ /dev/null
@@ -1,128 +0,0 @@
-local M = { _NAME = "uri._util" }
-
--- Build a char->hex map
-local escapes = {}
-for i = 0, 255 do
- escapes[string.char(i)] = string.format("%%%02X", i)
-end
-
-function M.uri_encode (text, patn)
- if not text then return end
- if not patn then
- -- Default unsafe characters. RFC 2732 ^(uric - reserved)
- -- TODO - this should be updated to the latest RFC.
- patn = "^A-Za-z0-9%-_.!~*'()"
- end
- return (text:gsub("([" .. patn .. "])",
- function (chr) return escapes[chr] end))
-end
-
-function M.uri_decode (str, patn)
- -- Note from RFC1630: "Sequences which start with a percent sign
- -- but are not followed by two hexadecimal characters are reserved
- -- for future extension"
- if not str then return end
- if patn then patn = "[" .. patn .. "]" end
- return (str:gsub("%%(%x%x)", function (hex)
- local char = string.char(tonumber(hex, 16))
- return (patn and not char:find(patn)) and "%" .. hex or char
- end))
-end
-
--- This is the remove_dot_segments algorithm from RFC 3986 section 5.2.4.
--- The input buffer is 's', the output buffer 'path'.
-function M.remove_dot_segments (s)
- local path = ""
-
- while s ~= "" do
- if s:find("^%.%.?/") then -- A
- s = s:gsub("^%.%.?/", "", 1)
- elseif s:find("^/%./") or s == "/." then -- B
- s = s:gsub("^/%./?", "/", 1)
- elseif s:find("^/%.%./") or s == "/.." then -- C
- s = s:gsub("^/%.%./?", "/", 1)
- if path:find("/") then
- path = path:gsub("/[^/]*$", "", 1)
- else
- path = ""
- end
- elseif s == "." or s == ".." then -- D
- s = ""
- else -- E
- local _, p, seg = s:find("^(/?[^/]*)")
- s = s:sub(p + 1)
- path = path .. seg
- end
- end
-
- return path
-end
-
--- TODO - wouldn't this be better as a method on string? s:split(patn)
-function M.split (patn, s, max)
- if s == "" then return {} end
-
- local i, j = 1, string.find(s, patn)
- if not j then return { s } end
-
- local list = {}
- while true do
- if #list + 1 == max then list[max] = s:sub(i); return list end
- list[#list + 1] = s:sub(i, j - 1)
- i = j + 1
- j = string.find(s, patn, i)
- if not j then
- list[#list + 1] = s:sub(i)
- break
- end
- end
- return list
-end
-
-function M.attempt_require (modname)
- local ok, result = pcall(require, modname)
- if ok then
- return result
- elseif type(result) == "string" and
- result:find("module '.*' not found") then
- return nil
- else
- error(result)
- end
-end
-
-function M.subclass_of (class, baseclass)
- class.__index = class
- class.__tostring = baseclass.__tostring
- class._SUPER = baseclass
- setmetatable(class, baseclass)
-end
-
-function M.do_class_changing_change (uri, baseclass, changedesc, newvalue,
- changefunc)
- local tmpuri = {}
- setmetatable(tmpuri, baseclass)
- for k, v in pairs(uri) do tmpuri[k] = v end
- changefunc(tmpuri, newvalue)
- tmpuri._uri = nil
-
- local foo, err = tmpuri:init()
- if not foo then
- error("URI not valid after " .. changedesc .. " changed to '" ..
- newvalue .. "': " .. err)
- end
-
- setmetatable(uri, getmetatable(tmpuri))
- for k in pairs(uri) do uri[k] = nil end
- for k, v in pairs(tmpuri) do uri[k] = v end
-end
-
-function M.uri_part_not_allowed (class, method)
- class[method] = function (self, new)
- if new then error(method .. " not allowed on this kind of URI") end
- return self["_" .. method]
- end
-end
-
-return M
--- vi:ts=4 sw=4 expandtab
diff --git a/script/3rd/lua-uri/uri/data.lua b/script/3rd/lua-uri/uri/data.lua
deleted file mode 100644
index c425621a..00000000
--- a/script/3rd/lua-uri/uri/data.lua
+++ /dev/null
@@ -1,116 +0,0 @@
-local M = { _NAME = "uri.data" }
-local Util = require "uri._util"
-local URI = require "uri"
-Util.subclass_of(M, URI)
-
--- This implements the 'data' scheme defined in RFC 2397.
-
-local Filter = Util.attempt_require("datafilter")
-
-local function _valid_base64 (data) return data:find("^[0-9a-zA-Z/+]*$") end
-
-local function _split_path (path)
- local _, _, mediatype, data = path:find("^([^,]*),(.*)")
- if not mediatype then return "must have comma in path" end
- local base64 = false
- if mediatype:find(";base64$") then
- base64 = true
- mediatype = mediatype:sub(1, -8)
- end
- if base64 and not _valid_base64(data) then
- return "illegal character in base64 encoding"
- end
- return nil, mediatype, base64, data
-end
-
-function M.init (self)
- if M._SUPER.host(self) then
- return nil, "data URIs may not have authority parts"
- end
- local err, mediatype, base64, data = _split_path(M._SUPER.path(self))
- if err then return nil, "invalid data URI (" .. err .. ")" end
- return self
-end
-
-function M.data_media_type (self, ...)
- local _, old, base64, data = _split_path(M._SUPER.path(self))
-
- if select('#', ...) > 0 then
- local new = ... or ""
- new = Util.uri_encode(new, "^A-Za-z0-9%-._~!$&'()*+;=:@/")
- if base64 then new = new .. ";base64" end
- M._SUPER.path(self, new .. "," .. data)
- end
-
- if old ~= "" then
- if old:find("^;") then old = "text/plain" .. old end
- return Util.uri_decode(old)
- else
- return "text/plain;charset=US-ASCII" -- default type
- end
-end
-
-local function _urienc_len (s)
- local num_unsafe_chars = s:gsub("[A-Za-z0-9%-._~!$&'()*+,;=:@/]", ""):len()
- local num_safe_chars = s:len() - num_unsafe_chars
- return num_safe_chars + num_unsafe_chars * 3
-end
-
-local function _base64_len (s)
- local num_blocks = (s:len() + 2) / 3
- num_blocks = num_blocks - num_blocks % 1
- return num_blocks * 4
- + 7 -- because of ";base64" marker
-end
-
-local function _do_filter (algorithm, input)
- return Filter[algorithm](input)
-end
-
-function M.data_bytes (self, ...)
- local _, mediatype, base64, old = _split_path(M._SUPER.path(self))
- if base64 then
- if not Filter then
- error("'datafilter' Lua module required to decode base64 data")
- end
- old = _do_filter("base64_decode", old)
- else
- old = Util.uri_decode(old)
- end
-
- if select('#', ...) > 0 then
- local new = ... or ""
- local urienc_len = _urienc_len(new)
- local base64_len = _base64_len(new)
- if base64_len < urienc_len and Filter then
- mediatype = mediatype .. ";base64"
- new = _do_filter("base64_encode", new)
- else
- new = new:gsub("%%", "%%25")
- end
- M._SUPER.path(self, mediatype .. "," .. new)
- end
-
- return old
-end
-
-function M.path (self, ...)
- local old = M._SUPER.path(self)
-
- if select('#', ...) > 0 then
- local new = ...
- if not new then error("there must be a path in a data URI") end
- local err = _split_path(new)
- if err then error("invalid data URI (" .. err .. ")") end
- M._SUPER.path(self, new)
- end
-
- return old
-end
-
-Util.uri_part_not_allowed(M, "userinfo")
-Util.uri_part_not_allowed(M, "host")
-Util.uri_part_not_allowed(M, "port")
-
-return M
--- vi:ts=4 sw=4 expandtab
diff --git a/script/3rd/lua-uri/uri/file.lua b/script/3rd/lua-uri/uri/file.lua
deleted file mode 100644
index 271cb3ed..00000000
--- a/script/3rd/lua-uri/uri/file.lua
+++ /dev/null
@@ -1,72 +0,0 @@
-local M = { _NAME = "uri.file" }
-local Util = require "uri._util"
-local URI = require "uri"
-Util.subclass_of(M, URI)
-
-function M.init (self)
- if self:userinfo() or self:port() then
- return nil, "usernames and passwords are not allowed in HTTP URIs"
- end
-
- local host = self:host()
- local path = self:path()
- if host then
- if host:lower() == "localhost" then self:host("") end
- else
- if not path:find("^/") then
- return nil, "file URIs must contain a host, even if it's empty"
- end
- self:host("")
- end
-
- if path == "" then self:path("/") end
-
- return self
-end
-
-function M.host (self, ...)
- local old = M._SUPER.host(self)
-
- if select('#', ...) > 0 then
- local new = ...
- if not new then error("file URIs must have an authority part") end
- if new:lower() == "localhost" then new = "" end
- M._SUPER.host(self, new)
- end
-
- return old
-end
-
-function M.path (self, ...)
- local old = M._SUPER.path(self)
-
- if select('#', ...) > 0 then
- local new = ...
- if not new or new == "" then new = "/" end
- M._SUPER.path(self, new)
- end
-
- return old
-end
-
-local function _os_implementation (os)
- local FileImpl = Util.attempt_require("uri.file." .. os:lower())
- if not FileImpl then
- error("no file URI implementation for operating system " .. os)
- end
- return FileImpl
-end
-
-function M.filesystem_path (self, os)
- return _os_implementation(os).filesystem_path(self)
-end
-
-function M.make_file_uri (path, os)
- return _os_implementation(os).make_file_uri(path)
-end
-
-Util.uri_part_not_allowed(M, "userinfo")
-Util.uri_part_not_allowed(M, "port")
-
-return M
--- vi:ts=4 sw=4 expandtab
diff --git a/script/3rd/lua-uri/uri/file/unix.lua b/script/3rd/lua-uri/uri/file/unix.lua
deleted file mode 100644
index 8bd4c942..00000000
--- a/script/3rd/lua-uri/uri/file/unix.lua
+++ /dev/null
@@ -1,26 +0,0 @@
-local M = { _NAME = "uri.file.unix" }
-local URI = require "uri"
-local Util = require "uri._util"
-
-function M.filesystem_path (uri)
- if uri:host() ~= "" then
- error("a file URI with a host name can't be converted to a Unix path")
- end
- local path = uri:path()
- if path:find("%%00") or path:find("%%2F") then
- error("Unix paths cannot contain encoded null bytes or slashes")
- end
- return Util.uri_decode(path)
-end
-
-function M.make_file_uri (path)
- if not path:find("^/") then
- error("Unix relative paths can't be converted to file URIs")
- end
- path = path:gsub("//+", "/")
- path = Util.uri_encode(path, "^A-Za-z0-9%-._~!$&'()*+,;=@/")
- return assert(URI:new("file://" .. path))
-end
-
-return M
--- vi:ts=4 sw=4 expandtab
diff --git a/script/3rd/lua-uri/uri/file/win32.lua b/script/3rd/lua-uri/uri/file/win32.lua
deleted file mode 100644
index d4e40243..00000000
--- a/script/3rd/lua-uri/uri/file/win32.lua
+++ /dev/null
@@ -1,34 +0,0 @@
-local M = { _NAME = "uri.file.win32" }
-local URI = require "uri"
-local Util = require "uri._util"
-
-function M.filesystem_path (uri)
- local host = uri:host()
- local path = Util.uri_decode(uri:path())
- if host ~= "" then path = "//" .. host .. path end
- if path:find("^/[A-Za-z]|/") or path:find("^/[A-Za-z]|$") then
- path = path:gsub("|", ":", 1)
- end
- if path:find("^/[A-Za-z]:/") then
- path = path:sub(2)
- elseif path:find("^/[A-Za-z]:$") then
- path = path:sub(2) .. "/"
- end
- path = path:gsub("/", "\\")
- return path
-end
-
-function M.make_file_uri (path)
- path = path:gsub("\\", "/")
- if path:find("^[A-Za-z]:$") then path = path .. "/" end
- local _, _, host, hostpath = path:find("^//([A-Za-z0-9.]+)/(.*)$")
- host = host or ""
- hostpath = hostpath or path
- hostpath = hostpath:gsub("//+", "/")
- hostpath = Util.uri_encode(hostpath, "^A-Za-z0-9%-._~!$&'()*+,;=@/")
- if not hostpath:find("^/") then hostpath = "/" .. hostpath end
- return assert(URI:new("file://" .. host .. hostpath))
-end
-
-return M
--- vi:ts=4 sw=4 expandtab
diff --git a/script/3rd/lua-uri/uri/ftp.lua b/script/3rd/lua-uri/uri/ftp.lua
deleted file mode 100644
index 2d9e3f6c..00000000
--- a/script/3rd/lua-uri/uri/ftp.lua
+++ /dev/null
@@ -1,53 +0,0 @@
-local M = { _NAME = "uri.ftp" }
-local Util = require "uri._util"
-local LoginURI = require "uri._login"
-Util.subclass_of(M, LoginURI)
-
-function M.default_port () return 21 end
-
-function M.init (self)
- self, err = M._SUPER.init_base(self)
- if not self then return nil, err end
-
- local host = self:host()
- if not host or host == "" then
- return nil, "FTP URIs must have a hostname"
- end
-
- -- I don't think there's any distinction in FTP URIs between empty path
- -- and the root directory, so probably best to normalize as we do for HTTP.
- if self:path() == "" then self:path("/") end
-
- return self
-end
-
-function M.path (self, ...)
- local old = M._SUPER.path(self)
-
- if select("#", ...) > 0 then
- local new = ...
- if not new or new == "" then new = "/" end
- M._SUPER.path(self, new)
- end
-
- return old
-end
-
-function M.ftp_typecode (self, ...)
- local path = M._SUPER.path(self)
- local _, _, withouttype, old = path:find("^(.*);type=(.*)$")
- if not withouttype then withouttype = path end
- if old == "" then old = nil end
-
- if select("#", ...) > 0 then
- local new = ...
- if not new then new = "" end
- if new ~= "" then new = ";type=" .. new end
- M._SUPER.path(self, withouttype .. new)
- end
-
- return old
-end
-
-return M
--- vi:ts=4 sw=4 expandtab
diff --git a/script/3rd/lua-uri/uri/http.lua b/script/3rd/lua-uri/uri/http.lua
deleted file mode 100644
index 91f7a57f..00000000
--- a/script/3rd/lua-uri/uri/http.lua
+++ /dev/null
@@ -1,32 +0,0 @@
-local M = { _NAME = "uri.http" }
-local Util = require "uri._util"
-local URI = require "uri"
-Util.subclass_of(M, URI)
-
--- This implementation is based on RFC 2616 section 3.2 and RFC 1738
--- section 3.3.
---
--- An HTTP URI with a 'userinfo' field is considered invalid, because it isn't
--- shown in the syntax given in RFC 2616, and is explicitly disallowed by
--- RFC 1738.
-
-function M.default_port () return 80 end
-
-function M.init (self)
- if self:userinfo() then
- return nil, "usernames and passwords are not allowed in HTTP URIs"
- end
-
- -- RFC 2616 section 3.2.3 says that this is OK, but not that using the
- -- redundant slash is canonical. I'm adding it because browsers tend to
- -- treat the version with the extra slash as the normalized form, and
- -- the initial slash is always present in an HTTP GET request.
- if self:path() == "" then self:path("/") end
-
- return self
-end
-
-Util.uri_part_not_allowed(M, "userinfo")
-
-return M
--- vi:ts=4 sw=4 expandtab
diff --git a/script/3rd/lua-uri/uri/https.lua b/script/3rd/lua-uri/uri/https.lua
deleted file mode 100644
index 0c4c8bc3..00000000
--- a/script/3rd/lua-uri/uri/https.lua
+++ /dev/null
@@ -1,9 +0,0 @@
-local M = { _NAME = "uri.https" }
-local Util = require "uri._util"
-local Http = require "uri.http"
-Util.subclass_of(M, Http)
-
-function M.default_port () return 443 end
-
-return M
--- vi:ts=4 sw=4 expandtab
diff --git a/script/3rd/lua-uri/uri/pop.lua b/script/3rd/lua-uri/uri/pop.lua
deleted file mode 100644
index e42d9d41..00000000
--- a/script/3rd/lua-uri/uri/pop.lua
+++ /dev/null
@@ -1,111 +0,0 @@
-local M = { _NAME = "uri.pop" }
-local URI = require "uri"
-local Util = require "uri._util"
-Util.subclass_of(M, URI)
-
--- This is the set of characters must be encoded in a POP userinfo, which
--- unlike for other schemes includes the ';' character.
-local _POP_USERINFO_ENCODE = "^A-Za-z0-9%-._~%%!$&'()*+,=:"
-
-function M.default_port () return 110 end
-
-local function _update_userinfo (self, old, new)
- if new then
- local _, _, user, auth = new:find("^(.*);[Aa][Uu][Tt][Hh]=(.*)$")
- if not user then user = new end
- if user == "" then return "pop user name must not be empty" end
- user = Util.uri_encode(user, _POP_USERINFO_ENCODE)
- if auth then
- if auth == "" then return "pop auth type must not be empty" end
- if auth == "*" then auth = nil end
- auth = Util.uri_encode(auth, _POP_USERINFO_ENCODE)
- end
- new = user .. (auth and ";auth=" .. auth or "")
- end
-
- if new ~= old then M._SUPER.userinfo(self, new) end
- return nil
-end
-
-function M.init (self)
- if M._SUPER.path(self) ~= "" then
- return nil, "pop URIs must have an empty path"
- end
-
- local userinfo = M._SUPER.userinfo(self)
- local err = _update_userinfo(self, userinfo, userinfo)
- if err then return nil, err end
-
- return self
-end
-
-function M.userinfo (self, ...)
- local old = M._SUPER.userinfo(self)
-
- if select('#', ...) > 0 then
- local new = ...
- local err = _update_userinfo(self, old, new)
- if err then error(err) end
- end
-
- return old
-end
-
-function M.path (self, new)
- if new and new ~= "" then error("POP URIs must have an empty path") end
- return ""
-end
-
-local function _decode_userinfo (self)
- local old = M._SUPER.userinfo(self)
- if not old then return nil, nil end
- local _, _, old_user, old_auth = old:find("^(.*);auth=(.*)$")
- if not old_user then old_user = old end
- return old_user, old_auth
-end
-
-function M.pop_user (self, ...)
- local old_user, old_auth = _decode_userinfo(self)
-
- if select('#', ...) > 0 then
- local new = ...
- if new == "" then error("pop user name must not be empty") end
- if not new and old_auth then
- error("pop user name required when an auth type is specified")
- end
- if new then
- new = Util.uri_encode(new, _POP_USERINFO_ENCODE)
- if old_auth then new = new .. ";auth=" .. old_auth end
- end
- M._SUPER.userinfo(self, new)
- end
-
- return Util.uri_decode(old_user)
-end
-
-function M.pop_auth (self, ...)
- local old_user, old_auth = _decode_userinfo(self)
-
- if select('#', ...) > 0 then
- local new = ...
- if not new or new == ""
- then error("pop auth type must not be empty")
- end
- if new == "*" then new = nil end
- if new and not old_user then
- error("pop auth type can't be specified without user name")
- end
- if new then
- new = old_user .. ";auth=" ..
- Util.uri_encode(new, _POP_USERINFO_ENCODE)
- else
- new = old_user
- end
- M._SUPER.userinfo(self, new)
- end
-
- return old_auth and Util.uri_decode(old_auth) or "*"
-end
-
-return M
--- vi:ts=4 sw=4 expandtab
diff --git a/script/3rd/lua-uri/uri/rtsp.lua b/script/3rd/lua-uri/uri/rtsp.lua
deleted file mode 100644
index 03c71485..00000000
--- a/script/3rd/lua-uri/uri/rtsp.lua
+++ /dev/null
@@ -1,9 +0,0 @@
-local M = { _NAME = "uri.rtsp" }
-local Util = require "uri._util"
-local HttpURI = require "uri.http"
-Util.subclass_of(M, HttpURI)
-
-function M.default_port () return 554 end
-
-return M
--- vi:ts=4 sw=4 expandtab
diff --git a/script/3rd/lua-uri/uri/rtspu.lua b/script/3rd/lua-uri/uri/rtspu.lua
deleted file mode 100644
index 16f5e3ee..00000000
--- a/script/3rd/lua-uri/uri/rtspu.lua
+++ /dev/null
@@ -1,7 +0,0 @@
-local M = { _NAME = "uri.rtspu" }
-local Util = require "uri._util"
-local RtspURI = require "uri.rtsp"
-Util.subclass_of(M, RtspURI)
-
-return M
--- vi:ts=4 sw=4 expandtab
diff --git a/script/3rd/lua-uri/uri/telnet.lua b/script/3rd/lua-uri/uri/telnet.lua
deleted file mode 100644
index 339e21ee..00000000
--- a/script/3rd/lua-uri/uri/telnet.lua
+++ /dev/null
@@ -1,38 +0,0 @@
-local M = { _NAME = "uri.telnet" }
-local Util = require "uri._util"
-local LoginURI = require "uri._login"
-Util.subclass_of(M, LoginURI)
-
-function M.default_port () return 23 end
-
-function M.init (self)
- self, err = M._SUPER.init_base(self)
- if not self then return nil, err end
-
- -- RFC 4248 does not discuss what a path longer than '/' might mean, and
- -- there are no examples with anything significant in the path, so I'm
- -- assuming that extra information in the path is not allowed.
- local path = M._SUPER.path(self)
- if path ~= "" and path ~= "/" then
- return nil, "superfluous information in path of telnet URI"
- end
-
- -- RFC 4248 section 2 says that the '/' can be omitted. I chose to
- -- normalize to having it there, since the example shown in the RFC has
- -- it, and this is consistent with the way I treat HTTP URIs.
- if path == "" then self:path("/") end
-
- return self
-end
-
--- The path is always '/', so setting it won't do anything, but we do throw
--- an exception on an attempt to set it to anything invalid.
-function M.path (self, new)
- if new and new ~= "" and new ~= "/" then
- error("invalid path for telnet URI")
- end
- return "/"
-end
-
-return M
--- vi:ts=4 sw=4 expandtab
diff --git a/script/3rd/lua-uri/uri/urn.lua b/script/3rd/lua-uri/uri/urn.lua
deleted file mode 100644
index aa4b1776..00000000
--- a/script/3rd/lua-uri/uri/urn.lua
+++ /dev/null
@@ -1,131 +0,0 @@
-local M = { _NAME = "uri.urn" }
-local Util = require "uri._util"
-local URI = require "uri"
-Util.subclass_of(M, URI)
-
--- This implements RFC 2141, and attempts to change the class of the URI object
--- to one of its subclasses for further validation and normalization of the
--- namespace-specific string.
-
--- Check NID syntax matches RFC 2141 section 2.1.
-local function _valid_nid (nid)
- if nid == "" then return nil, "missing completely" end
- if nid:len() > 32 then return nil, "too long" end
- if not nid:find("^[A-Za-z0-9][-A-Za-z0-9]*$") then
- return nil, "contains illegal character"
- end
- if nid:lower() == "urn" then return nil, "'urn' is reserved" end
- return true
-end
-
--- Check NSS syntax matches RFC 2141 section 2.2.
-local function _valid_nss (nss)
- if nss == "" then return nil, "can't be empty" end
- if nss:find("[^A-Za-z0-9()+,%-.:=@;$_!*'/%%]") then
- return nil, "contains illegal character"
- end
- return true
-end
-
-local function _validate_and_normalize_path (path)
- local _, _, nid, nss = path:find("^([^:]+):(.*)$")
- if not nid then return nil, "illegal path syntax for URN" end
-
- local ok, msg = _valid_nid(nid)
- if not ok then
- return nil, "invalid namespace identifier (" .. msg .. ")"
- end
- ok, msg = _valid_nss(nss)
- if not ok then
- return nil, "invalid namespace specific string (" .. msg .. ")"
- end
-
- return nid:lower() .. ":" .. nss
-end
-
--- TODO - this should check that percent-encoded bytes are valid UTF-8
-function M.init (self)
- if M._SUPER.query(self) then
- return nil, "URNs may not have query parts"
- end
- if M._SUPER.host(self) then
- return nil, "URNs may not have authority parts"
- end
-
- local path, msg = _validate_and_normalize_path(self:path())
- if not path then return nil, msg end
- M._SUPER.path(self, path)
-
- local nid_class
- = Util.attempt_require("uri.urn." .. self:nid():gsub("%-", "_"))
- if nid_class then
- setmetatable(self, nid_class)
- if self.init ~= M.init then return self:init() end
- end
-
- return self
-end
-
-function M.nid (self, new)
- local _, _, old = self:path():find("^([^:]+)")
-
- if new then
- new = new:lower()
- if new ~= old then
- local ok, msg = _valid_nid(new)
- if not ok then
- error("invalid namespace identifier (" .. msg .. ")")
- end
- end
- Util.do_class_changing_change(self, M, "NID", new, function (uri, new)
- M._SUPER.path(uri, new .. ":" .. uri:nss())
- end)
- end
-
- return old
-end
-
-function M.nss (self, new)
- local _, _, old = self:path():find(":(.*)")
-
- if new and new ~= old then
- local ok, msg = _valid_nss(new)
- if not ok then
- error("invalid namespace specific string (" .. msg .. ")")
- end
- M._SUPER.path(self, self:nid() .. ":" .. new)
- end
-
- return old
-end
-
-function M.path (self, new)
- local old = M._SUPER.path(self)
-
- if new and new ~= old then
- local path, msg = _validate_and_normalize_path(new)
- if not path then
- error("invalid path for URN '" .. new .. "' (" ..msg .. ")")
- end
- local _, _, newnid, newnss = path:find("^([^:]+):(.*)")
- if not newnid then error("bad path for URN, no NID part found") end
- local ok, msg = _valid_nid(newnid)
- if not ok then error("invalid namespace identifier (" .. msg .. ")") end
- if newnid:lower() == self:nid() then
- self:nss(newnss)
- else
- Util.do_class_changing_change(self, M, "path", path,
- function (uri, new) M._SUPER.path(uri, new) end)
- end
- end
-
- return old
-end
-
-Util.uri_part_not_allowed(M, "userinfo")
-Util.uri_part_not_allowed(M, "host")
-Util.uri_part_not_allowed(M, "port")
-Util.uri_part_not_allowed(M, "query")
-
-return M
--- vi:ts=4 sw=4 expandtab
diff --git a/script/3rd/lua-uri/uri/urn/isbn.lua b/script/3rd/lua-uri/uri/urn/isbn.lua
deleted file mode 100644
index 5f0bdb69..00000000
--- a/script/3rd/lua-uri/uri/urn/isbn.lua
+++ /dev/null
@@ -1,67 +0,0 @@
-local M = { _NAME = "uri.urn.isbn" }
-local Util = require "uri._util"
-local URN = require "uri.urn"
-Util.subclass_of(M, URN)
-
--- This implements the 'isbn' NID defined in RFC 3187, and is consistent
--- with the same NID suggested in RFC 2288.
-
-local function _valid_isbn (isbn)
- if not isbn:find("^[-%d]+[%dXx]$") then return nil, "invalid character" end
- local ISBN = Util.attempt_require("isbn")
- if ISBN then return ISBN:new(isbn) end
- return isbn
-end
-
-local function _normalize_isbn (isbn)
- isbn = isbn:gsub("%-", ""):upper()
- local ISBN = Util.attempt_require("isbn")
- if ISBN then return tostring(ISBN:new(isbn)) end
- return isbn
-end
-
-function M.init (self)
- local nss = self:nss()
- local ok, msg = _valid_isbn(nss)
- if not ok then return nil, "invalid ISBN value (" .. msg .. ")" end
- self:nss(_normalize_isbn(nss))
- return self
-end
-
-function M.nss (self, new)
- local old = M._SUPER.nss(self)
-
- if new then
- local ok, msg = _valid_isbn(new)
- if not ok then
- error("bad ISBN value '" .. new .. "' (" .. msg .. ")")
- end
- M._SUPER.nss(self, _normalize_isbn(new))
- end
-
- return old
-end
-
-function M.isbn_digits (self, new)
- local old = self:nss():gsub("%-", "")
-
- if new then
- local ok, msg = _valid_isbn(new)
- if not ok then
- error("bad ISBN value '" .. new .. "' (" .. msg .. ")")
- end
- self._SUPER.nss(self, _normalize_isbn(new))
- end
-
- return old
-end
-
-function M.isbn (self, new)
- local ISBN = require "isbn"
- local old = ISBN:new(self:nss())
- if new then self:nss(tostring(new)) end
- return old
-end
-
-return M
--- vi:ts=4 sw=4 expandtab
diff --git a/script/3rd/lua-uri/uri/urn/issn.lua b/script/3rd/lua-uri/uri/urn/issn.lua
deleted file mode 100644
index c5f37f8c..00000000
--- a/script/3rd/lua-uri/uri/urn/issn.lua
+++ /dev/null
@@ -1,65 +0,0 @@
-local M = { _NAME = "uri.urn.issn" }
-local Util = require "uri._util"
-local URN = require "uri.urn"
-Util.subclass_of(M, URN)
-
-local function _parse_issn (issn)
- local _, _, nums1, nums2, checksum
- = issn:find("^(%d%d%d%d)-?(%d%d%d)([%dxX])$")
- if checksum == "x" then checksum = "X" end
- return nums1, nums2, checksum
-end
-
-local function _valid_issn (issn)
- local nums1, nums2, actual_checksum = _parse_issn(issn)
- if not nums1 then return nil, "invalid ISSN syntax" end
- local nums = nums1 .. nums2
-
- local expected_checksum = 0
- for i = 1, 7 do
- expected_checksum = expected_checksum + tonumber(nums:sub(i, i)) * (9 - i)
- end
- expected_checksum = (11 - expected_checksum % 11) % 11
- expected_checksum = (expected_checksum == 10) and "X"
- or tostring(expected_checksum)
- if actual_checksum ~= expected_checksum then
- return nil, "wrong checksum, expected " .. expected_checksum
- end
-
- return true
-end
-
-local function _normalize_issn (issn)
- local nums1, nums2, checksum = _parse_issn(issn)
- return nums1 .. "-" .. nums2 .. checksum
-end
-
-function M.init (self)
- local nss = self:nss()
- local ok, msg = _valid_issn(nss)
- if not ok then return nil, "bad NSS value for ISSN URI (" .. msg .. ")" end
- M._SUPER.nss(self, _normalize_issn(nss))
- return self
-end
-
-function M.nss (self, new)
- local old = M._SUPER.nss(self)
-
- if new then
- local ok, msg = _valid_issn(new)
- if not ok then
- error("bad ISSN value '" .. new .. "' (" .. msg .. ")")
- end
- M._SUPER.nss(self, _normalize_issn(new))
- end
-
- return old
-end
-
-function M.issn_digits (self, new)
- local old = self:nss(new)
- return old:sub(1, 4) .. old:sub(6, 9)
-end
-
-return M
--- vi:ts=4 sw=4 expandtab
diff --git a/script/3rd/lua-uri/uri/urn/oid.lua b/script/3rd/lua-uri/uri/urn/oid.lua
deleted file mode 100644
index 37110cda..00000000
--- a/script/3rd/lua-uri/uri/urn/oid.lua
+++ /dev/null
@@ -1,62 +0,0 @@
-local M = { _NAME = "uri.urn.oid" }
-local Util = require "uri._util"
-local URN = require "uri.urn"
-Util.subclass_of(M, URN)
-
--- This implements RFC 3061.
-
-local function _valid_oid (oid)
- if oid == "" then return nil, "OID can't be zero-length" end
- if not oid:find("^[.0-9]*$") then return nil, "bad character in OID" end
- if oid:find("%.%.") then return nil, "missing number in OID" end
- if oid:find("^0[^.]") or oid:find("%.0[^.]") then
- return nil, "OID numbers shouldn't have leading zeros"
- end
- return true
-end
-
-function M.init (self)
- local nss = self:nss()
- local ok, msg = _valid_oid(nss)
- if not ok then return nil, "bad NSS value for OID URI (" .. msg .. ")" end
- return self
-end
-
-function M.nss (self, new)
- local old = M._SUPER.nss(self)
-
- if new then
- local ok, msg = _valid_oid(new)
- if not ok then
- error("bad OID value '" .. new .. "' (" .. msg .. ")")
- end
- M._SUPER.nss(self, new)
- end
-
- return old
-end
-
-function M.oid_numbers (self, new)
- local old = Util.split("%.", self:nss())
- for i = 1, #old do old[i] = tonumber(old[i]) end
-
- if new then
- if type(new) ~= "table" then error("expected array of numbers") end
- local nss = ""
- for _, n in ipairs(new) do
- if type(n) == "string" and n:find("^%d+$") then n = tonumber(n) end
- if type(n) ~= "number" then error("bad type for number in OID") end
- n = n - n % 1
- if n < 0 then error("negative numbers not allowed in OID") end
- if nss ~= "" then nss = nss .. "." end
- nss = nss .. n
- end
- if nss == "" then error("no numbers in new OID value") end
- self:nss(nss)
- end
-
- return old
-end
-
-return M
--- vi:ts=4 sw=4 expandtab
diff --git a/script/file-uri.lua b/script/file-uri.lua
new file mode 100644
index 00000000..2576044b
--- /dev/null
+++ b/script/file-uri.lua
@@ -0,0 +1,109 @@
+local platform = require 'bee.platform'
+
+local esc = {
+ [':'] = '%3A',
+ ['/'] = '%2F',
+ ['?'] = '%3F',
+ ['#'] = '%23',
+ ['['] = '%5B',
+ [']'] = '%5D',
+ ['@'] = '%40',
+
+ ['!'] = '%21', -- sub-delims
+ ['$'] = '%24',
+ ['&'] = '%26',
+ ["'"] = '%27',
+ ['('] = '%28',
+ [')'] = '%29',
+ ['*'] = '%2A',
+ ['+'] = '%2B',
+ [','] = '%2C',
+ [';'] = '%3B',
+ ['='] = '%3D',
+
+ [' '] = '%20',
+}
+
+local escPatt = '[^%w%-%.%_%~%/]'
+
+local function normalize(str)
+ return str:gsub('%%(%x%x)', function (n)
+ return string.char(tonumber(n, 16))
+ end)
+end
+
+local m = {}
+
+-- c:\my\files --> file:///c%3A/my/files
+-- /usr/home --> file:///usr/home
+-- \\server\share\some\path --> file://server/share/some/path
+
+--- path -> uri
+---@param path string
+---@return string uri
+function m.encode(path)
+ local authority = ''
+ if platform.OS == 'Windows' then
+ path = path:gsub('\\', '/')
+ end
+
+ if path:sub(1, 2) == '//' then
+ local idx = path:find('/', 3)
+ if idx then
+ authority = path:sub(3, idx)
+ path = path:sub(idx + 1)
+ if path == '' then
+ path = '/'
+ end
+ else
+ authority = path:sub(3)
+ path = '/'
+ end
+ end
+
+ if path:sub(1, 1) ~= '/' then
+ path = '/' .. path
+ end
+
+ -- lower-case windows drive letters in /C:/fff or C:/fff
+ local start, finish, drive = path:find '/(%u):'
+ if drive then
+ path = path:sub(1, start) .. drive:lower() .. path:sub(finish, -1)
+ end
+
+ local uri = 'file://'
+ .. authority:gsub(escPatt, esc)
+ .. path:gsub(escPatt, esc)
+ return uri
+end
+
+-- file:///c%3A/my/files --> c:\my\files
+-- file:///usr/home --> /usr/home
+-- file://server/share/some/path --> \\server\share\some\path
+
+--- uri -> path
+---@param uri string
+---@return string path
+function m.decode(uri)
+ local scheme, authority, path = uri:match('([^:]*):?/?/?([^/]*)(.*)')
+ if not scheme then
+ return ''
+ end
+ scheme = normalize(scheme)
+ authority = normalize(authority)
+ path = normalize(path)
+ local value
+ if scheme == 'file' and #authority > 0 and #path > 1 then
+ value = '//' .. authority .. path
+ elseif path:match '/%a:' then
+ value = path:sub(2, 2):lower() .. path:sub(3)
+ else
+ value = path
+ end
+ if platform.OS == 'Windows' then
+ value = value:gsub('/', '\\')
+ end
+ return value
+end
+
+return m
diff --git a/script/uri.lua b/script/uri.lua
index e00b7138..8f570daf 100644
--- a/script/uri.lua
+++ b/script/uri.lua
@@ -1,26 +1,12 @@
local fs = require 'bee.filesystem'
-local platform = require 'bee.platform'
-local sandbox = require 'sandbox'
-local luaUriPath = (ROOT / 'script' / '3rd' / 'lua-uri'):string()
-local URI = sandbox('uri.lua', luaUriPath, io.open)
-local URI_FILE = sandbox('uri/file.lua', luaUriPath, io.open)
-local OS = platform.OS == 'Windows' and 'win32' or 'unix'
+local furi = require 'file-uri'
-local function decode(uri)
- local obj = URI:new(uri)
- if not obj.filesystem_path then
- return nil
- end
- local fullPath = obj:filesystem_path(OS)
- local path = fs.path(fullPath)
- return path
+local function encode(path)
+ return furi.encode(path:string())
end
-local function encode(path)
- local fullPath = fs.absolute(ROOT / path)
- local obj = URI_FILE.make_file_uri(fullPath:string(), OS)
- local uri = obj:uri()
- return uri
+local function decode(uri)
+ return fs.path(furi.decode(uri))
end
return {
diff --git a/test/crossfile/completion.lua b/test/crossfile/completion.lua
index cb9f2f65..ab017716 100644
--- a/test/crossfile/completion.lua
+++ b/test/crossfile/completion.lua
@@ -72,7 +72,7 @@ function TEST(data)
local mainBuf
local pos
for _, info in ipairs(data) do
- local uri = uric.encode(fs.path(info.path))
+ local uri = uric.encode(ROOT / fs.path(info.path))
local script = info.content
if info.main then
pos = script:find('$', 1, true) - 1
diff --git a/test/crossfile/definition.lua b/test/crossfile/definition.lua
index c765d98a..02209609 100644
--- a/test/crossfile/definition.lua
+++ b/test/crossfile/definition.lua
@@ -52,7 +52,7 @@ function TEST(datas)
local sourceList, sourceUri
for i, data in ipairs(datas) do
- local uri = uric.encode(fs.path(data.path))
+ local uri = uric.encode(ROOT / fs.path(data.path))
local new, list = catch_target(data.content, '!')
if new ~= data.content or data.target then
if data.target then
diff --git a/test/crossfile/document_symbol.lua b/test/crossfile/document_symbol.lua
index 997d42c5..23bd6af3 100644
--- a/test/crossfile/document_symbol.lua
+++ b/test/crossfile/document_symbol.lua
@@ -68,8 +68,8 @@ function TEST(data)
local ws = workspace(lsp, 'test')
lsp.workspace = ws
- local targetUri = uric.encode(fs.path(data[1].path))
- local sourceUri = uric.encode(fs.path(data[2].path))
+ local targetUri = uric.encode(ROOT / fs.path(data[1].path))
+ local sourceUri = uric.encode(ROOT / fs.path(data[2].path))
lsp:saveText(sourceUri, 1, data[2].content)
ws:addFile(uric.decode(sourceUri))
diff --git a/test/crossfile/hover.lua b/test/crossfile/hover.lua
index b0e5a55f..f2560673 100644
--- a/test/crossfile/hover.lua
+++ b/test/crossfile/hover.lua
@@ -61,10 +61,10 @@ function TEST(data)
ws.root = ROOT
local targetScript = data[1].content
- local targetUri = uric.encode(fs.path(data[1].path))
+ local targetUri = uric.encode(ROOT / fs.path(data[1].path))
local sourceScript, sourceList = catch_target(data[2].content, '?')
- local sourceUri = uric.encode(fs.path(data[2].path))
+ local sourceUri = uric.encode(ROOT / fs.path(data[2].path))
lsp:saveText(targetUri, 1, targetScript)
ws:addFile(uric.decode(targetUri))
diff --git a/test/crossfile/references.lua b/test/crossfile/references.lua
index 9f81707c..87577770 100644
--- a/test/crossfile/references.lua
+++ b/test/crossfile/references.lua
@@ -80,11 +80,11 @@ function TEST(data)
local pos
local expect = {}
for _, info in ipairs(data) do
- local uri = uric.encode(fs.path(info.path))
+ local uri = uric.encode(ROOT / fs.path(info.path))
ws:addFile(uric.decode(uri))
end
for _, info in ipairs(data) do
- local uri = uric.encode(fs.path(info.path))
+ local uri = uric.encode(ROOT / fs.path(info.path))
local script = info.content
local list = catch_target(script)
for _, location in ipairs(list) do