diff options
| author | Khaled Hosny <khaledhosny@eglug.org> | 2010-03-22 17:49:04 +0200 | 
|---|---|---|
| committer | Khaled Hosny <khaledhosny@eglug.org> | 2010-03-22 17:49:04 +0200 | 
| commit | 22fa4cc9381179fdd43ca8a251cb49dd2703079d (patch) | |
| tree | a222ca028b0f3bec9f4057424623323602174c29 | |
| parent | 87f7676bed961c8de29cc7fd2bebb41fe106f678 (diff) | |
| download | lualibs-22fa4cc9381179fdd43ca8a251cb49dd2703079d.tar.gz | |
Sync with ConTeXt
| -rw-r--r-- | luaextra-aux.lua | 38 | ||||
| -rw-r--r-- | luaextra-dimen.lua | 20 | ||||
| -rw-r--r-- | luaextra-dir.lua | 8 | ||||
| -rw-r--r-- | luaextra-file.lua | 79 | ||||
| -rw-r--r-- | luaextra-lpeg.lua | 120 | ||||
| -rw-r--r-- | luaextra-os.lua | 217 | ||||
| -rw-r--r-- | luaextra-table.lua | 3 | ||||
| -rw-r--r-- | luaextra-url.lua | 40 | 
8 files changed, 367 insertions, 158 deletions
| diff --git a/luaextra-aux.lua b/luaextra-aux.lua index 1ff5c08..7950a03 100644 --- a/luaextra-aux.lua +++ b/luaextra-aux.lua @@ -6,19 +6,30 @@ if not modules then modules = { } end modules ['l-aux'] = {      license   = "see context related readme files"  } +-- for inline, no store split : for s in string.gmatch(str,",* *([^,]+)") do .. end +  aux = aux or { }  local concat, format, gmatch = table.concat, string.format, string.gmatch  local tostring, type = tostring, type  local lpegmatch = lpeg.match +local P, R, V = lpeg.P, lpeg.R, lpeg.V + +local escape, left, right = P("\\"), P('{'), P('}') + +lpeg.patterns.balanced = P { +    [1] = ((escape * (left+right)) + (1 - (left+right)) + V(2))^0, +    [2] = left * V(1) * right +} +  local space     = lpeg.P(' ')  local equal     = lpeg.P("=")  local comma     = lpeg.P(",")  local lbrace    = lpeg.P("{")  local rbrace    = lpeg.P("}")  local nobrace   = 1 - (lbrace+rbrace) -local nested    = lpeg.P{ lbrace * (nobrace + lpeg.V(1))^0 * rbrace } +local nested    = lpeg.P { lbrace * (nobrace + lpeg.V(1))^0 * rbrace }  local spaces    = space^0  local value     = lpeg.P(lbrace * lpeg.C((nobrace + nested)^0) * rbrace) + lpeg.C((nested + (1-comma))^0) @@ -98,6 +109,8 @@ local pattern   = lpeg.Ct(value*(separator*value)^0)  aux.settings_to_array_pattern = pattern +-- we could use a weak table as cache +  function aux.settings_to_array(str)      if not str or str == "" then          return { } @@ -182,21 +195,14 @@ end  -- temporary here -local digit    = lpeg.R("09") -local period   = lpeg.P(".") -local zero     = lpeg.P("0") - ---~ local finish   = lpeg.P(-1) ---~ local nodigit  = (1-digit) + finish ---~ local case_1   = (period * zero^1 * #nodigit)/"" -- .000 ---~ local case_2   = (period * (1-(zero^0/"") * #nodigit)^1 * (zero^0/"") * nodigit) -- .010 .10 .100100 - +local digit         = lpeg.R("09") +local period        = lpeg.P(".") +local zero          = lpeg.P("0")  local trailingzeros = zero^0 * -digit -- suggested by Roberto R -local case_1 = period * trailingzeros / "" -local case_2 = period * (digit - trailingzeros)^1 * (trailingzeros / "") - -local number   = digit^1 * (case_1 + case_2) -local stripper = lpeg.Cs((number + 1)^0) +local case_1        = period * trailingzeros / "" +local case_2        = period * (digit - trailingzeros)^1 * (trailingzeros / "") +local number        = digit^1 * (case_1 + case_2) +local stripper      = lpeg.Cs((number + 1)^0)  --~ local sample = "bla 11.00 bla 11 bla 0.1100 bla 1.00100 bla 0.00 bla 0.001 bla 1.1100 bla 0.100100100 bla 0.00100100100"  --~ collectgarbage("collect") @@ -205,6 +211,8 @@ local stripper = lpeg.Cs((number + 1)^0)  --~ lpegmatch(stripper,str)  --~ print(#str, os.clock()-ts, lpegmatch(stripper,sample)) +lpeg.patterns.strip_zeros = stripper +  function aux.strip_zeros(str)      return lpegmatch(stripper,str)  end diff --git a/luaextra-dimen.lua b/luaextra-dimen.lua index e15e294..a8faa27 100644 --- a/luaextra-dimen.lua +++ b/luaextra-dimen.lua @@ -16,7 +16,7 @@ table.</p>  --ldx]]--  local format, match, gsub, type, setmetatable = string.format, string.match, string.gsub, type, setmetatable -local lpegmatch = lpeg.match +local P, S, R, Cc, lpegmatch = lpeg.P, lpeg.S, lpeg.R, lpeg.Cc, lpeg.match  number = number or { } @@ -100,6 +100,7 @@ end  <p>We collect a bunch of converters in the <type>number</type> namespace.</p>  --ldx]]-- +number.maxdimen     = 1073741823  number.todimen      = todimen  number.dimenfactors = dimenfactors @@ -124,10 +125,12 @@ a number and optionally a unit. When no unit is given a constant  capture takes place.</p>  --ldx]]-- -local amount = (lpeg.S("+-")^0 * lpeg.R("09")^0 * lpeg.P(".")^0 * lpeg.R("09")^0) + lpeg.Cc("0") -local unit   = lpeg.R("az")^1 +local amount = (S("+-")^0 * R("09")^0 * P(".")^0 * R("09")^0) + Cc("0") +local unit   = R("az")^1 -local pattern = amount/tonumber * (unit^1/dimenfactors + lpeg.Cc(1)) -- tonumber is new +local pattern = amount/tonumber * (unit^1/dimenfactors + Cc(1)) -- tonumber is new + +lpeg.patterns.dimenpair = pattern  --[[ldx--  <p>We use a metatable to intercept errors. When no key is found in @@ -147,11 +150,18 @@ function string:todimen()          return self      else          local value, unit = lpegmatch(pattern,self) -        print(value,unit)          return value/unit      end  end +local amount = S("+-")^0 * R("09")^0 * S(".,")^0 * R("09")^0 +local unit   = P("pt") + P("cm") + P("mm") + P("sp") + P("bp") + P("in")  + +               P("pc") + P("dd") + P("cc") + P("nd") + P("nc") + +local pattern = amount * unit + +lpeg.patterns.validdimen = pattern +  --[[ldx--  <p>This converter accepts calls like:</p> diff --git a/luaextra-dir.lua b/luaextra-dir.lua index 3760db2..0d08362 100644 --- a/luaextra-dir.lua +++ b/luaextra-dir.lua @@ -6,6 +6,8 @@ if not modules then modules = { } end modules ['l-dir'] = {      license   = "see context related readme files"  } +-- dir.expand_name will be merged with cleanpath and collapsepath +  local type = type  local find, gmatch, match, gsub = string.find, string.gmatch, string.match, string.gsub  local lpegmatch = lpeg.match @@ -174,7 +176,7 @@ end  local make_indeed = true -- false -if string.find(os.getenv("PATH"),";") then +if string.find(os.getenv("PATH"),";") then -- os.type == "windows"      function dir.mkdirs(...)          local str, pth = "", "" @@ -241,7 +243,7 @@ if string.find(os.getenv("PATH"),";") then  --~         print(dir.mkdirs("///a/b/c"))  --~         print(dir.mkdirs("a/bbb//ccc/")) -    function dir.expand_name(str) +    function dir.expand_name(str) -- will be merged with cleanpath and collapsepath          local first, nothing, last = match(str,"^(//)(//*)(.*)$")          if first then              first = lfs.currentdir() .. "/" @@ -323,7 +325,7 @@ else  --~         print(dir.mkdirs("///a/b/c"))  --~         print(dir.mkdirs("a/bbb//ccc/")) -    function dir.expand_name(str) +    function dir.expand_name(str) -- will be merged with cleanpath and collapsepath          if not find(str,"^/") then              str = lfs.currentdir() .. "/" .. str          end diff --git a/luaextra-file.lua b/luaextra-file.lua index c95ef65..6f5f5d0 100644 --- a/luaextra-file.lua +++ b/luaextra-file.lua @@ -11,7 +11,7 @@ if not modules then modules = { } end modules ['l-file'] = {  file = file or { }  local concat = table.concat -local find, gmatch, match, gsub, sub = string.find, string.gmatch, string.match, string.gsub, string.sub +local find, gmatch, match, gsub, sub, char = string.find, string.gmatch, string.match, string.gsub, string.sub, string.char  local lpegmatch = lpeg.match  function file.removesuffix(filename) @@ -19,7 +19,9 @@ function file.removesuffix(filename)  end  function file.addsuffix(filename, suffix) -    if not find(filename,"%.[%a%d]+$") then +    if not suffix or suffix == "" then +        return filename +    elseif not find(filename,"%.[%a%d]+$") then          return filename .. "." .. suffix      else          return filename @@ -48,14 +50,33 @@ end  file.suffix = file.extname ---~ print(file.join("x/","/y")) ---~ print(file.join("http://","/y")) ---~ print(file.join("http://a","/y")) ---~ print(file.join("http:///a","/y")) ---~ print(file.join("//nas-1","/y")) +--~ function file.join(...) +--~     local pth = concat({...},"/") +--~     pth = gsub(pth,"\\","/") +--~     local a, b = match(pth,"^(.*://)(.*)$") +--~     if a and b then +--~         return a .. gsub(b,"//+","/") +--~     end +--~     a, b = match(pth,"^(//)(.*)$") +--~     if a and b then +--~         return a .. gsub(b,"//+","/") +--~     end +--~     return (gsub(pth,"//+","/")) +--~ end + +local trick_1 = char(1) +local trick_2 = "^" .. trick_1 .. "/+"  function file.join(...) -    local pth = concat({...},"/") +    local lst = { ... } +    local a, b = lst[1], lst[2] +    if a == "" then +        lst[1] = trick_1 +    elseif b and find(a,"^/+$") and find(b,"^/") then +        lst[1] = "" +        lst[2] = gsub(b,"^/+","") +    end +    local pth = concat(lst,"/")      pth = gsub(pth,"\\","/")      local a, b = match(pth,"^(.*://)(.*)$")      if a and b then @@ -65,9 +86,20 @@ function file.join(...)      if a and b then          return a .. gsub(b,"//+","/")      end +    pth = gsub(pth,trick_2,"")      return (gsub(pth,"//+","/"))  end +--~ print(file.join("//","/y")) +--~ print(file.join("/","/y")) +--~ print(file.join("","/y")) +--~ print(file.join("/x/","/y")) +--~ print(file.join("x/","/y")) +--~ print(file.join("http://","/y")) +--~ print(file.join("http://a","/y")) +--~ print(file.join("http:///a","/y")) +--~ print(file.join("//nas-1","/y")) +  function file.iswritable(name)      local a = lfs.attributes(name) or lfs.attributes(file.dirname(name,"."))      return a and sub(a.permissions,2,2) == "w" @@ -106,16 +138,22 @@ function file.join_path(tab)      return concat(tab,io.pathseparator) -- can have trailing //  end +-- we can hash them weakly +  function file.collapse_path(str) -    str = gsub(str,"/%./","/") -    local n, m = 1, 1 -    while n > 0 or m > 0 do -        str, n = gsub(str,"[^/%.]+/%.%.$","") -        str, m = gsub(str,"[^/%.]+/%.%./","") +    str = gsub(str,"\\","/") +    if find(str,"/") then +        str = gsub(str,"^%./",(gsub(lfs.currentdir(),"\\","/")) .. "/") -- ./xx in qualified +        str = gsub(str,"/%./","/") +        local n, m = 1, 1 +        while n > 0 or m > 0 do +            str, n = gsub(str,"[^/%.]+/%.%.$","") +            str, m = gsub(str,"[^/%.]+/%.%./","") +        end +        str = gsub(str,"([^/])/$","%1") +    --  str = gsub(str,"^%./","") -- ./xx in qualified +        str = gsub(str,"/%.$","")      end -    str = gsub(str,"([^/])/$","%1") -    str = gsub(str,"^%./","") -    str = gsub(str,"/%.$","")      if str == "" then str = "." end      return str  end @@ -265,3 +303,12 @@ end  -- test { "c:", "c:aa", "c:aa/bb", "c:aa/bb/cc", "c:aa/bb/cc.dd", "c:aa/bb/cc.dd.ee" }  -- test { "/aa", "/aa/bb", "/aa/bb/cc", "/aa/bb/cc.dd", "/aa/bb/cc.dd.ee" }  -- test { "aa", "aa/bb", "aa/bb/cc", "aa/bb/cc.dd", "aa/bb/cc.dd.ee" } + +--~ -- todo: +--~ +--~ if os.type == "windows" then +--~     local currentdir = lfs.currentdir +--~     function lfs.currentdir() +--~         return (gsub(currentdir(),"\\","/")) +--~     end +--~ end diff --git a/luaextra-lpeg.lua b/luaextra-lpeg.lua index 9e761e4..2e366a9 100644 --- a/luaextra-lpeg.lua +++ b/luaextra-lpeg.lua @@ -6,55 +6,58 @@ if not modules then modules = { } end modules ['l-lpeg'] = {      license   = "see context related readme files"  } -lpeg = require("lpeg") +local lpeg = require("lpeg") -local P, R, S, Ct, C, Cs, Cc = lpeg.P, lpeg.R, lpeg.S, lpeg.Ct, lpeg.C, lpeg.Cs, lpeg.Cc -local match = lpeg.match - ---~ l-lpeg.lua : +lpeg.patterns  = lpeg.patterns or { } -- so that we can share +local patterns = lpeg.patterns ---~ lpeg.digit         = lpeg.R('09')^1 ---~ lpeg.sign          = lpeg.S('+-')^1 ---~ lpeg.cardinal      = lpeg.P(lpeg.sign^0 * lpeg.digit^1) ---~ lpeg.integer       = lpeg.P(lpeg.sign^0 * lpeg.digit^1) ---~ lpeg.float         = lpeg.P(lpeg.sign^0 * lpeg.digit^0 * lpeg.P('.') * lpeg.digit^1) ---~ lpeg.number        = lpeg.float + lpeg.integer ---~ lpeg.oct           = lpeg.P("0") * lpeg.R('07')^1 ---~ lpeg.hex           = lpeg.P("0x") * (lpeg.R('09') + lpeg.R('AF'))^1 ---~ lpeg.uppercase     = lpeg.P("AZ") ---~ lpeg.lowercase     = lpeg.P("az") - ---~ lpeg.eol           = lpeg.S('\r\n\f')^1 -- includes formfeed ---~ lpeg.space         = lpeg.S(' ')^1 ---~ lpeg.nonspace      = lpeg.P(1-lpeg.space)^1 ---~ lpeg.whitespace    = lpeg.S(' \r\n\f\t')^1 ---~ lpeg.nonwhitespace = lpeg.P(1-lpeg.whitespace)^1 +local P, R, S, Ct, C, Cs, Cc, V = lpeg.P, lpeg.R, lpeg.S, lpeg.Ct, lpeg.C, lpeg.Cs, lpeg.Cc, lpeg.V +local match = lpeg.match -local hash = { } +local digit, sign      = R('09'), S('+-') +local cr, lf, crlf     = P("\r"), P("\n"), P("\r\n") +local utf8byte         = R("\128\191") + +patterns.utf8byte      = utf8byte +patterns.utf8one       = R("\000\127") +patterns.utf8two       = R("\194\223") * utf8byte +patterns.utf8three     = R("\224\239") * utf8byte * utf8byte +patterns.utf8four      = R("\240\244") * utf8byte * utf8byte * utf8byte + +patterns.digit         = digit +patterns.sign          = sign +patterns.cardinal      = sign^0 * digit^1 +patterns.integer       = sign^0 * digit^1 +patterns.float         = sign^0 * digit^0 * P('.') * digit^1 +patterns.number        = patterns.float + patterns.integer +patterns.oct           = P("0") * R("07")^1 +patterns.octal         = patterns.oct +patterns.HEX           = P("0x") * R("09","AF")^1 +patterns.hex           = P("0x") * R("09","af")^1 +patterns.hexadecimal   = P("0x") * R("09","AF","af")^1 +patterns.lowercase     = R("az") +patterns.uppercase     = R("AZ") +patterns.letter        = patterns.lowercase + patterns.uppercase +patterns.space         = S(" ") +patterns.eol           = S("\n\r") +patterns.spacer        = S(" \t\f\v")  -- + string.char(0xc2, 0xa0) if we want utf (cf mail roberto) +patterns.newline       = crlf + cr + lf +patterns.nonspace      = 1 - patterns.space +patterns.nonspacer     = 1 - patterns.spacer +patterns.whitespace    = patterns.eol + patterns.spacer +patterns.nonwhitespace = 1 - patterns.whitespace +patterns.utf8          = patterns.utf8one + patterns.utf8two + patterns.utf8three + patterns.utf8four +patterns.utfbom        = P('\000\000\254\255') + P('\255\254\000\000') + P('\255\254') + P('\254\255') + P('\239\187\191')  function lpeg.anywhere(pattern) --slightly adapted from website -    return P { P(pattern) + 1 * lpeg.V(1) } -end - -function lpeg.startswith(pattern) --slightly adapted -    return P(pattern) +    return P { P(pattern) + 1 * V(1) } -- why so complex?  end  function lpeg.splitter(pattern, action)      return (((1-P(pattern))^1)/action+1)^0  end --- variant: - ---~ local parser = lpeg.Ct(lpeg.splitat(newline)) - -local crlf     = P("\r\n") -local cr       = P("\r") -local lf       = P("\n") -local space    = S(" \t\f\v")  -- + string.char(0xc2, 0xa0) if we want utf (cf mail roberto) -local newline  = crlf + cr + lf -local spacing  = space^0 * newline - +local spacing  = patterns.spacer^0 * patterns.newline -- sort of strip  local empty    = spacing * Cc("")  local nonempty = Cs((1-spacing)^1) * spacing^-1  local content  = (empty + nonempty)^1 @@ -65,7 +68,7 @@ function string:splitlines()      return match(capture,self)  end -lpeg.linebyline = content -- better make a sublibrary +patterns.textline = content  --~ local p = lpeg.splitat("->",false)  print(match(p,"oeps->what->more"))  -- oeps what more  --~ local p = lpeg.splitat("->",true)   print(match(p,"oeps->what->more"))  -- oeps what->more @@ -121,45 +124,20 @@ end  --~     local p = pp  --~     for l=1,#list do  --~         if p then ---~             p = p + lpeg.P(list[l]) +--~             p = p + P(list[l])  --~         else ---~             p = lpeg.P(list[l]) +--~             p = P(list[l])  --~         end  --~     end  --~     return p  --~ end  --~ from roberto's site: ---~ ---~ -- decode a two-byte UTF-8 sequence ---~ local function f2 (s) ---~   local c1, c2 = string.byte(s, 1, 2) ---~   return c1 * 64 + c2 - 12416 ---~ end ---~ ---~ -- decode a three-byte UTF-8 sequence ---~ local function f3 (s) ---~   local c1, c2, c3 = string.byte(s, 1, 3) ---~   return (c1 * 64 + c2) * 64 + c3 - 925824 ---~ end ---~ ---~ -- decode a four-byte UTF-8 sequence ---~ local function f4 (s) ---~   local c1, c2, c3, c4 = string.byte(s, 1, 4) ---~   return ((c1 * 64 + c2) * 64 + c3) * 64 + c4 - 63447168 ---~ end ---~ ---~ local cont = lpeg.R("\128\191")   -- continuation byte ---~ ---~ local utf8 = lpeg.R("\0\127") / string.byte ---~            + lpeg.R("\194\223") * cont / f2 ---~            + lpeg.R("\224\239") * cont * cont / f3 ---~            + lpeg.R("\240\244") * cont * cont * cont / f4 ---~ ---~ local decode_pattern = lpeg.Ct(utf8^0) * -1 - -local cont = R("\128\191")   -- continuation byte +local f1 = string.byte -lpeg.utf8 = R("\0\127") + R("\194\223") * cont + R("\224\239") * cont * cont + R("\240\244") * cont * cont * cont +local function f2(s) local c1, c2         = f1(s,1,2) return   c1 * 64 + c2                       -    12416 end +local function f3(s) local c1, c2, c3     = f1(s,1,3) return  (c1 * 64 + c2) * 64 + c3            -   925824 end +local function f4(s) local c1, c2, c3, c4 = f1(s,1,4) return ((c1 * 64 + c2) * 64 + c3) * 64 + c4 - 63447168 end +patterns.utf8byte = patterns.utf8one/f1 + patterns.utf8two/f2 + patterns.utf8three/f3 + patterns.utf8four/f4 diff --git a/luaextra-os.lua b/luaextra-os.lua index b60dfb7..4f0c0c1 100644 --- a/luaextra-os.lua +++ b/luaextra-os.lua @@ -8,7 +8,7 @@ if not modules then modules = { } end modules ['l-os'] = {  -- maybe build io.flush in os.execute -local find, format = string.find, string.format +local find, format, gsub = string.find, string.format, string.gsub  local random, ceil = math.random, math.ceil  local execute, spawn, exec, ioflush = os.execute, os.spawn or os.execute, os.exec or os.execute, io.flush @@ -43,6 +43,12 @@ end  os.type = os.type or (io.pathseparator == ";"       and "windows") or "unix"  os.name = os.name or (os.type          == "windows" and "mswin"  ) or "linux" +if os.type == "windows" then +    os.libsuffix, os.binsuffix = 'dll', 'exe' +else +    os.libsuffix, os.binsuffix = 'so', '' +end +  function os.launch(str)      if os.type == "windows" then          os.execute("start " .. str) -- os.spawn ? @@ -51,10 +57,6 @@ function os.launch(str)      end  end -if not os.setenv then -    function os.setenv() return false end -end -  if not os.times then      -- utime  = user time      -- stime  = system time @@ -86,63 +88,182 @@ end  -- no need for function anymore as we have more clever code and helpers now -os.platform  = os.name or os.type or "linux" -os.libsuffix = 'so' -os.binsuffix = '' +os.resolvers = os.resolvers or { } -local name = os.name +local resolvers = os.resolvers -if name == "windows" or name == "mswin" or name == "win32" or name == "msdos" or os.type == "windows" then -    if os.getenv("PROCESSOR_ARCHITECTURE") == "AMD64" then -        os.platform = "mswin-64" -    else -        os.platform = "mswin" +local osmt = getmetatable(os) or { __index = function(t,k) t[k] = "unset" return "unset" end } +local osix = osmt.__index + +osmt.__index = function(t,k) +    return (resolvers[k] or osix)(t,k) +end + +setmetatable(os,osmt) + +if not os.setenv then + +    -- we still store them but they won't be seen in +    -- child processes although we might pass them some day +    -- using command concatination + +    local env, getenv = { }, os.getenv + +    function os.setenv(k,v) +        env[k] = v      end -    os.libsuffix = 'dll' -    os.binsuffix = 'exe' -else -    local architecture = os.getenv("HOSTTYPE") or "" -    if architecture == "" then -        architecture = os.resultof("uname -m") or "" + +    function os.getenv(k) +        return env[k] or getenv(k)      end -    if architecture == "" then -        local architecture = os.resultof("echo $HOSTTYPE") + +end + +-- we can use HOSTTYPE on some platforms + +local name, platform = os.name or "linux", os.getenv("MTX_PLATFORM") or "" + +local function guess() +    local architecture = os.resultof("uname -m") or "" +    if architecture ~= "" then +        return architecture +    end +    architecture = os.getenv("HOSTTYPE") or "" +    if architecture ~= "" then +        return architecture +    end +    return os.resultof("echo $HOSTTYPE") or "" +end + +if platform ~= "" then + +    os.platform = platform + +elseif os.type == "windows" then + +    -- we could set the variable directly, no function needed here + +    function os.resolvers.platform(t,k) +        local platform, architecture = "", os.getenv("PROCESSOR_ARCHITECTURE") or "" +        if find(architecture,"AMD64") then +            platform = "mswin-64" +        else +            platform = "mswin" +        end +        os.setenv("MTX_PLATFORM",platform) +        os.platform = platform +        return platform      end -    if name == "linux" then + +elseif name == "linux" then + +    function os.resolvers.platform(t,k) +        -- we sometims have HOSTTYPE set so let's check that first +        local platform, architecture = "", os.getenv("HOSTTYPE") or os.resultof("uname -m") or ""          if find(architecture,"x86_64") then -            os.platform = "linux-64" +            platform = "linux-64"          elseif find(architecture,"ppc") then -            os.platform = "linux-ppc" +            platform = "linux-ppc"          else -            os.platform = "linux" +            platform = "linux"          end -    elseif name == "macosx" then -        if find(architecture,"i386") then -            os.platform = "osx-intel" +        os.setenv("MTX_PLATFORM",platform) +        os.platform = platform +        return platform +    end + +elseif name == "macosx" then + +    --[[ +        Identifying the architecture of OSX is quite a mess and this +        is the best we can come up with. For some reason $HOSTTYPE is +        a kind of pseudo environment variable, not known to the current +        environment. And yes, uname cannot be trusted either, so there +        is a change that you end up with a 32 bit run on a 64 bit system. +        Also, some proper 64 bit intel macs are too cheap (low-end) and +        therefore not permitted to run the 64 bit kernel. +      ]]-- + +    function os.resolvers.platform(t,k) +     -- local platform, architecture = "", os.getenv("HOSTTYPE") or "" +     -- if architecture == "" then +     --     architecture = os.resultof("echo $HOSTTYPE") or "" +     -- end +        local platform, architecture = "", os.resultof("echo $HOSTTYPE") or "" +        if architecture == "" then +         -- print("\nI have no clue what kind of OSX you're running so let's assume an 32 bit intel.\n") +            platform = "osx-intel" +        elseif find(architecture,"i386") then +            platform = "osx-intel"          elseif find(architecture,"x86_64") then -            os.platform = "osx-64" +            platform = "osx-64"          else -            os.platform = "osx-ppc" +            platform = "osx-ppc"          end -    elseif name == "sunos" then +        os.setenv("MTX_PLATFORM",platform) +        os.platform = platform +        return platform +    end + +elseif name == "sunos" then + +    function os.resolvers.platform(t,k) +        local platform, architecture = "", os.resultof("uname -m") or ""          if find(architecture,"sparc") then -            os.platform = "solaris-sparc" +            platform = "solaris-sparc"          else -- if architecture == 'i86pc' -            os.platform = "solaris-intel" +            platform = "solaris-intel"          end -    elseif name == "freebsd" then +        os.setenv("MTX_PLATFORM",platform) +        os.platform = platform +        return platform +    end + +elseif name == "freebsd" then + +    function os.resolvers.platform(t,k) +        local platform, architecture = "", os.resultof("uname -m") or ""          if find(architecture,"amd64") then -            os.platform = "freebsd-amd64" +            platform = "freebsd-amd64"          else -            os.platform = "freebsd" +            platform = "freebsd"          end -    else -        os.platform = 'linux' +        os.setenv("MTX_PLATFORM",platform) +        os.platform = platform +        return platform      end + +elseif name == "kfreebsd" then + +    function os.resolvers.platform(t,k) +        -- we sometims have HOSTTYPE set so let's check that first +        local platform, architecture = "", os.getenv("HOSTTYPE") or os.resultof("uname -m") or "" +        if find(architecture,"x86_64") then +            platform = "kfreebsd-64" +        else +            platform = "kfreebsd-i386" +        end +        os.setenv("MTX_PLATFORM",platform) +        os.platform = platform +        return platform +    end + +else + +    -- platform = "linux" +    -- os.setenv("MTX_PLATFORM",platform) +    -- os.platform = platform + +    function os.resolvers.platform(t,k) +        local platform = "linux" +        os.setenv("MTX_PLATFORM",platform) +        os.platform = platform +        return platform +    end +  end  -- beware, we set the randomseed ---  -- from wikipedia: Version 4 UUIDs use a scheme relying only on random numbers. This algorithm sets the  -- version number as well as two reserved bits. All other bits are set using a random or pseudorandom @@ -151,7 +272,6 @@ end  --  -- as we don't call this function too often there is not so much risk on repetition -  local t = { 8, 9, "a", "b" }  function os.uuid() @@ -163,3 +283,18 @@ function os.uuid()          random(0xFFFF),random(0xFFFF),random(0xFFFF)      )  end + +local d + +function os.timezone(delta) +    d = d or tonumber(tonumber(os.date("%H")-os.date("!%H"))) +    if delta then +        if d > 0 then +            return format("+%02i:00",d) +        else +            return format("-%02i:00",-d) +        end +    else +        return 1 +    end +end diff --git a/luaextra-table.lua b/luaextra-table.lua index 70a901e..e8f72ed 100644 --- a/luaextra-table.lua +++ b/luaextra-table.lua @@ -12,6 +12,7 @@ local concat, sort, insert, remove = table.concat, table.sort, table.insert, tab  local format, find, gsub, lower, dump, match = string.format, string.find, string.gsub, string.lower, string.dump, string.match  local getmetatable, setmetatable = getmetatable, setmetatable  local type, next, tostring, tonumber, ipairs, pairs = type, next, tostring, tonumber, ipairs, pairs +local unpack = unpack or table.unpack  function table.strip(tab)      local lst = { } @@ -28,7 +29,7 @@ end  function table.keys(t)      local k = { } -    for key,_ in next, t do +    for key, _ in next, t do          k[#k+1] = key      end      return k diff --git a/luaextra-url.lua b/luaextra-url.lua index 1d282a1..e3e6f81 100644 --- a/luaextra-url.lua +++ b/luaextra-url.lua @@ -32,7 +32,9 @@ local hexdigit  = lpeg.R("09","AF","af")  local plus      = lpeg.P("+")  local escaped   = (plus / " ") + (percent * lpeg.C(hexdigit * hexdigit) / tochar) -local scheme    =                 lpeg.Cs((escaped+(1-colon-slash-qmark-hash))^0) * colon + lpeg.Cc("") +-- we assume schemes with more than 1 character (in order to avoid problems with windows disks) + +local scheme    =                 lpeg.Cs((escaped+(1-colon-slash-qmark-hash))^2) * colon + lpeg.Cc("")  local authority = slash * slash * lpeg.Cs((escaped+(1-      slash-qmark-hash))^0)         + lpeg.Cc("")  local path      = slash *         lpeg.Cs((escaped+(1-            qmark-hash))^0)         + lpeg.Cc("")  local query     = qmark         * lpeg.Cs((escaped+(1-                  hash))^0)         + lpeg.Cc("") @@ -40,22 +42,48 @@ local fragment  = hash          * lpeg.Cs((escaped+(1-           endofstring))^0  local parser = lpeg.Ct(scheme * authority * path * query * fragment) +-- todo: reconsider Ct as we can as well have five return values (saves a table) +-- so we can have two parsers, one with and one without +  function url.split(str)      return (type(str) == "string" and lpegmatch(parser,str)) or str  end +-- todo: cache them +  function url.hashed(str)      local s = url.split(str) +    local somescheme = s[1] ~= ""      return { -        scheme = (s[1] ~= "" and s[1]) or "file", +        scheme    = (somescheme and s[1]) or "file",          authority = s[2], -        path = s[3], -        query = s[4], -        fragment = s[5], -        original = str +        path      = s[3], +        query     = s[4], +        fragment  = s[5], +        original  = str, +        noscheme  = not somescheme,      }  end +function url.hasscheme(str) +    return url.split(str)[1] ~= "" +end + +function url.addscheme(str,scheme) +    return (url.hasscheme(str) and str) or ((scheme or "file:///") .. str) +end + +function url.construct(hash) +    local fullurl = hash.sheme .. "://".. hash.authority .. hash.path +    if hash.query then +        fullurl = fullurl .. "?".. hash.query +    end +    if hash.fragment then +        fullurl = fullurl .. "?".. hash.fragment +    end +    return fullurl +end +  function url.filename(filename)      local t = url.hashed(filename)      return (t.scheme == "file" and (gsub(t.path,"^/([a-zA-Z])([:|])/)","%1:"))) or filename | 
