annotate support/casc/platform.lua @ 69:5165c2d211dd

Added tag v6.0.3-1 for changeset 840c9f09a707
author Jerome Vuarand <jerome.vuarand@gmail.com>
date Fri, 31 Oct 2014 13:26:19 +0000
parents 8b8b0bade520
children
rev   line source
jerome@65 1 local M, assert, getenv = {}, assert, os.getenv
jerome@65 2
jerome@65 3 local function maybe(m)
jerome@65 4 local ok, v = pcall(require, m)
jerome@65 5 return ok and v
jerome@65 6 end
jerome@65 7 local lfs = maybe("lfs") -- LuaFileSystem; http://keplerproject.github.io/luafilesystem/
jerome@65 8 local zlib = maybe("zlib") -- lzlib; https://github.com/LuaDist/lzlib
jerome@65 9 local bit = maybe("bit") -- Lua BitOp; http://bitop.luajit.org
jerome@65 10 local socket = maybe("socket.http") -- LuaSocket; http://w3.impa.br/~diego/software/luasocket/home.html
jerome@65 11
jerome@65 12 local function shellEscape(s)
jerome@65 13 return '"' .. s:gsub('"', '"\\\\""') .. '"'
jerome@65 14 end
jerome@65 15 local function readAndDeleteFile(path)
jerome@65 16 local h, err = io.open(path, "rb")
jerome@65 17 if h then
jerome@65 18 local c = h:read("*a")
jerome@65 19 h:close()
jerome@65 20 h, err = c, nil
jerome@65 21 end
jerome@65 22 os.remove(path)
jerome@65 23 return h, err
jerome@65 24 end
jerome@65 25
jerome@65 26 local dir_sep = package and package.config and package.config:sub(1,1) or "/"
jerome@65 27 do -- M.path(a, b, ...)
jerome@65 28 M.path = function(a, b, ...)
jerome@65 29 if a and b then
jerome@65 30 return M.path(a .. (a:sub(-1) ~= dir_sep and dir_sep or "") .. b, ...)
jerome@65 31 end
jerome@65 32 return a
jerome@65 33 end
jerome@65 34 end
jerome@65 35 M.url = function(a, b, ...)
jerome@65 36 if a and b then
jerome@65 37 return M.url(a .. ((a:sub(-1) == "/" or b:sub(1,1) == "/") and "" or "/") .. b, ...)
jerome@65 38 end
jerome@65 39 return a
jerome@65 40 end
jerome@65 41
jerome@65 42 M.commands =
jerome@65 43 dir_sep == '/' and {toDevNull=' 2>/dev/null', ls='ls %s', mkdir='mkdir -p %s', gzip='gzip -dcq %s'} or
jerome@65 44 dir_sep == '\\' and {toDevNull=' 2>NUL', ls='(for %%a in (%s) do @echo %%~fa)', mkdir='mkdir %s', gzip='gzip -dcq %s', TMP=os.getenv('TMP') or os.getenv('TEMP')}
jerome@65 45
jerome@65 46 M.tmpname = function()
jerome@65 47 local tn = os.tmpname()
jerome@65 48 return (M.commands and M.commands.TMP or "") .. tn
jerome@65 49 end
jerome@65 50
jerome@65 51 M.decompress = zlib and zlib.decompress or function(compressed)
jerome@65 52 assert(type(compressed) == "string", 'Syntax: casc.platform.decompress("compressed")')
jerome@65 53 assert(M.commands and M.commands.gzip and M.commands.toDevNull, 'unsupported platform')
jerome@65 54
jerome@65 55 local f, f2 = M.tmpname(), M.tmpname()
jerome@65 56 local h = io.open(f, "wb")
jerome@65 57 h:write('\31\139\8\0\0\0\0\0')
jerome@65 58 h:write(compressed)
jerome@65 59 h:close()
jerome@65 60
jerome@65 61 os.execute(M.commands.gzip:format(shellEscape(f)) .. " 1>" .. f2 .. " " .. M.commands.toDevNull)
jerome@65 62 os.remove(f)
jerome@65 63
jerome@65 64 return readAndDeleteFile(f2)
jerome@65 65 end
jerome@65 66
jerome@65 67 M.mkdir = lfs and lfs.mkdir or function(path)
jerome@65 68 assert(type(path) == 'string', 'Syntax: casc.platform.mkdir("path")')
jerome@65 69 assert(M.commands and M.commands.mkdir, 'unsupported platform')
jerome@65 70
jerome@65 71 return os.execute(M.commands.mkdir:format(shellEscape(path)))
jerome@65 72 end
jerome@65 73
jerome@65 74 M.files = lfs and function(dir, glob)
jerome@65 75 assert(type(dir) == "string" and type(glob) == 'string', 'Syntax: casc.platform.files("dir", "glob")')
jerome@65 76 local pat = "^" .. glob:gsub("%.%-%+", "%%%0"):gsub("%*", ".*") .. "$"
jerome@65 77 local t, ni = {}, 1
jerome@65 78 for f in lfs.dir(dir) do
jerome@65 79 if f ~= "." and f ~= ".." and f:match(pat) then
jerome@65 80 t[ni], ni = M.path(dir, f), ni + 1
jerome@65 81 end
jerome@65 82 end
jerome@65 83 return pairs(t)
jerome@65 84 end or function(dir, glob)
jerome@65 85 assert(type(dir) == "string" and type(glob) == 'string', 'Syntax: casc.platform.files("dir", "glob")')
jerome@65 86 assert(M.commands and M.commands.ls, 'unsupported platform')
jerome@65 87
jerome@65 88 local dir, files = glob:match("^(.-)([^" .. dir_sep .. "]+)$")
jerome@65 89 local t, ni, h = {}, 1, io.popen(M.commands.ls:format(shellEscape(dir) .. files), "r")
jerome@65 90 for l in h:lines() do
jerome@65 91 t[ni], ni = l, ni + 1
jerome@65 92 end
jerome@65 93 h:close()
jerome@65 94 return pairs(t)
jerome@65 95 end
jerome@65 96
jerome@65 97 local floor = math.floor
jerome@65 98 M.rol = bit and bit.rol or function(n, b)
jerome@65 99 local n, e2 = n % 2^32, 2^(32-b)
jerome@65 100 return ((n % e2) * 2^b + floor(n/e2)) % 2^32
jerome@65 101 end
jerome@65 102
jerome@65 103 M.bxor = bit and bit.bxor or function(a, b)
jerome@65 104 local out, m, lm = 0, 1
jerome@65 105 for i=1,32 do
jerome@65 106 m, lm = m+m, m
jerome@65 107 local am, bm = a % m, b % m
jerome@65 108 out, a, b = out + (am == bm and 0 or lm), a-am, b-bm
jerome@65 109 if a == 0 or b == 0 then
jerome@65 110 return (out + b + a) % 2^32
jerome@65 111 end
jerome@65 112 end
jerome@65 113 return out
jerome@65 114 end
jerome@65 115
jerome@65 116 if socket then
jerome@65 117 socket.USERAGENT, socket.TIMEOUT = "lcasc/1.1", 5
jerome@65 118 local ltn12, RETRIES = require("ltn12"), 3
jerome@65 119 M.http = function(url, h)
jerome@65 120 for i=1,RETRIES do
jerome@65 121 local sink = {}
jerome@65 122 local ok, status, head = socket.request({url=url, sink=ltn12.sink.table(sink), headers=h})
jerome@65 123 if ok then
jerome@65 124 local cnt = table.concat(sink, "")
jerome@65 125 return status >= 200 and status < 300 and cnt, status, head, cnt
jerome@65 126 elseif i == RETRIES then
jerome@65 127 error("HTTP request failed: " .. tostring(status) .. "\nURL: " .. tostring(url))
jerome@65 128 end
jerome@65 129 end
jerome@65 130 end
jerome@65 131 else
jerome@65 132 M.http = function(url, h)
jerome@65 133 local c, of = "curl -s -S -A 'luacasc/1.1+curl'", M.tmpname()
jerome@65 134 if type(h) == "table" then
jerome@65 135 for k,v in pairs(h) do
jerome@65 136 c = c .. ' -H ' .. shellEscape(k .. ": " .. v)
jerome@65 137 end
jerome@65 138 end
jerome@65 139 c = c .. ' -o ' .. shellEscape(of)
jerome@65 140 c = c .. ' ' .. shellEscape(url)
jerome@65 141 if os.execute(c) == 0 then
jerome@65 142 return readAndDeleteFile(of)
jerome@65 143 end
jerome@65 144 os.remove(of)
jerome@65 145 end
jerome@65 146 end
jerome@65 147
jerome@65 148 return M