diff options
Diffstat (limited to 'Master/texmf-dist/tex/context/base/mkiv/l-os.lua')
-rw-r--r-- | Master/texmf-dist/tex/context/base/mkiv/l-os.lua | 748 |
1 files changed, 382 insertions, 366 deletions
diff --git a/Master/texmf-dist/tex/context/base/mkiv/l-os.lua b/Master/texmf-dist/tex/context/base/mkiv/l-os.lua index 73841074c46..faae76881ac 100644 --- a/Master/texmf-dist/tex/context/base/mkiv/l-os.lua +++ b/Master/texmf-dist/tex/context/base/mkiv/l-os.lua @@ -26,22 +26,27 @@ if not modules then modules = { } end modules ['l-os'] = { -- math.randomseed(tonumber(string.sub(string.reverse(tostring(math.floor(socket.gettime()*10000))),1,6))) local os = os -local date, time = os.date, os.time +local date, time, difftime = os.date, os.time, os.difftime local find, format, gsub, upper, gmatch = string.find, string.format, string.gsub, string.upper, string.gmatch local concat = table.concat -local random, ceil, randomseed = math.random, math.ceil, math.randomseed +local random, ceil, randomseed, modf = math.random, math.ceil, math.randomseed, math.modf local type, setmetatable, tonumber, tostring = type, setmetatable, tonumber, tostring -- This check needs to happen real early on. Todo: we can pick it up from the commandline -- if we pass --binpath= (which is useful anyway) do + local selfdir = os.selfdir + if selfdir == "" then selfdir = nil end + if not selfdir then + -- We need a fallback plan so let's see what we get. + if arg then -- passed by mtx-context ... saves network access for i=1,#arg do @@ -52,6 +57,7 @@ do end end end + if not selfdir then selfdir = os.selfbin or "luatex" if find(selfdir,"[/\\]") then @@ -92,11 +98,16 @@ do end end end + -- let's hope we're okay now + os.selfdir = selfdir or "." + end + + -- print(os.selfdir) os.exit() + end --- print(os.selfdir) os.exit() -- The following code permits traversing the environment table, at least in luatex. Internally all -- environment names are uppercase. @@ -157,7 +168,7 @@ if not os.__getenv__ then end function os.getenv(k) - local K = upper(k) + local K = upper(k) -- hm utf local v = osenv[K] or osgetenv(K) or osgetenv(k) if v == "" then return nil @@ -183,32 +194,14 @@ end -- end of environment hack -local execute = os.execute -local iopopen = io.popen - -local function resultof(command) - local handle = iopopen(command,"r") -- already has flush - if handle then - local result = handle:read("*all") or "" - handle:close() - return result - else - return "" - end -end - -os.resultof = resultof - -function os.pipeto(command) - return iopopen(command,"w") -- already has flush -end - if not io.fileseparator then + if find(os.getenv("PATH"),";",1,true) then io.fileseparator, io.pathseparator, os.type = "\\", ";", os.type or "windows" else io.fileseparator, io.pathseparator, os.type = "/" , ":", os.type or "unix" end + end os.type = os.type or (io.pathseparator == ";" and "windows") or "unix" @@ -220,351 +213,370 @@ else os.libsuffix, os.binsuffix, os.binsuffixes = 'so', '', { '' } end -local launchers = { - windows = "start %s", - macosx = "open %s", - unix = "xdg-open %s &> /dev/null &", -} +do -function os.launch(str) - local command = format(launchers[os.name] or launchers.unix,str) - -- todo: pcall --- print(command) - execute(command) -end + local execute = os.execute + local iopopen = io.popen + local ostype = os.type + + local function resultof(command) + -- already has flush, b is new and we need it to pipe xz output + local handle = iopopen(command,ostype == "windows" and "rb" or "r") + if handle then + local result = handle:read("*all") or "" + handle:close() + return result + else + return "" + end + end -local gettimeofday = os.gettimeofday or os.clock -os.gettimeofday = gettimeofday + os.resultof = resultof -local startuptime = gettimeofday() + function os.pipeto(command) + return iopopen(command,"w") -- already has flush + end -function os.runtime() - return gettimeofday() - startuptime -end + local launchers = { + windows = "start %s", + macosx = "open %s", + unix = "xdg-open %s &> /dev/null &", + } + + function os.launch(str) + local command = format(launchers[os.name] or launchers.unix,str) + -- todo: pcall + -- print(command) + execute(command) + end --- print(os.gettimeofday()-os.time()) --- os.sleep(1.234) --- print (">>",os.runtime()) --- print(os.date("%H:%M:%S",os.gettimeofday())) --- print(os.date("%H:%M:%S",os.time())) +end --- no need for function anymore as we have more clever code and helpers now --- this metatable trickery might as well disappear +do -local resolvers = os.resolvers or { } -os.resolvers = resolvers + local gettimeofday = os.gettimeofday or os.clock + os.gettimeofday = gettimeofday -setmetatable(os, { __index = function(t,k) - local r = resolvers[k] - return r and r(t,k) or nil -- no memoize -end }) + local startuptime = gettimeofday() --- we can use HOSTTYPE on some platforms + function os.runtime() + return gettimeofday() - startuptime + end -local name, platform = os.name or "linux", os.getenv("MTX_PLATFORM") or "" + -- print(os.gettimeofday()-os.time()) + -- os.sleep(1.234) + -- print (">>",os.runtime()) + -- print(os.date("%H:%M:%S",os.gettimeofday())) + -- print(os.date("%H:%M:%S",os.time())) --- local function guess() --- local architecture = resultof("uname -m") or "" --- if architecture ~= "" then --- return architecture --- end --- architecture = os.getenv("HOSTTYPE") or "" --- if architecture ~= "" then --- return architecture --- end --- return resultof("echo $HOSTTYPE") or "" --- end +end +-- We can use HOSTTYPE on some platforms (but not consistently on e.g. Linux). +-- -- os.bits = 32 | 64 +-- +-- os.uname() : return { +-- machine = "x86_64", +-- nodename = "MYLAPTOP", +-- release = "build 9200", +-- sysname = "Windows", +-- version = "6.02", +-- } --- os.uname() --- sysname --- machine --- release --- version --- nodename - -if platform ~= "" then +do - os.platform = platform + local name = os.name or "linux" + local platform = os.getenv("MTX_PLATFORM") or "" + local architecture = os.uname and os.uname().machine -- lmtx + local bits = os.getenv("MTX_BITS") or find(platform,"64") and 64 or 32 -elseif os.type == "windows" then + if platform ~= "" then - -- we could set the variable directly, no function needed here + -- we're okay already - -- PROCESSOR_ARCHITECTURE : binary platform - -- PROCESSOR_ARCHITEW6432 : OS platform + elseif os.type == "windows" then - -- mswin-64 is now win64 + -- PROCESSOR_ARCHITECTURE : binary platform + -- PROCESSOR_ARCHITEW6432 : OS platform - function resolvers.platform(t,k) - local architecture = os.getenv("PROCESSOR_ARCHITECTURE") or "" - local platform = "" - if find(architecture,"AMD64",1,true) then - platform = "win64" + architecture = string.lower(architecture or os.getenv("PROCESSOR_ARCHITECTURE") or "") + if architecture == "x86_64" then + bits, platform = 64, "win64" + elseif find(architecture,"amd64") then + bits, platform = 64, "win64" + elseif find(architecture,"arm64") then + bits, platform = 64, "windows-arm64" + elseif find(architecture,"arm32") then + bits, platform = 32, "windows-arm32" else - platform = "mswin" + bits, platform = 32, "mswin" end - os.setenv("MTX_PLATFORM",platform) - os.platform = platform - return platform - end -elseif name == "linux" then - - function resolvers.platform(t,k) - -- we sometimes have HOSTTYPE set so let's check that first - local architecture = os.getenv("HOSTTYPE") or resultof("uname -m") or "" - local platform = os.getenv("MTX_PLATFORM") or "" - local musl = find(os.selfdir or "","linuxmusl") - if platform ~= "" then - -- we're done - elseif find(architecture,"x86_64",1,true) then - platform = musl and "linuxmusl" or "linux-64" - elseif find(architecture,"ppc",1,true) then - platform = "linux-ppc" + elseif name == "linux" then + + -- There is no way to detect if musl is used because there is no __MUSL__ + -- and it looks like there never will be. Folks don't care about cases where + -- one ships multipe binaries (as with TeX distibutions) and want to select + -- the right one. So probably it expects users to compile locally in which + -- case we don't care to much as they can then sort it out. + + architecture = architecture or os.getenv("HOSTTYPE") or resultof("uname -m") or "" + local musl = find(os.selfdir or "","linuxmusl") + if find(architecture,"x86_64") then + bits, platform = 64, musl and "linuxmusl" or "linux-64" + elseif find(architecture,"ppc") then + bits, platform = 32, "linux-ppc" -- this will be dropped else - platform = musl and "linuxmusl" or "linux" + bits, platform = 32, musl and "linuxmusl" or "linux" end - 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 resolvers.platform(t,k) - -- local platform = "" - -- local architecture = os.getenv("HOSTTYPE") or "" - -- if architecture == "" then - -- architecture = resultof("echo $HOSTTYPE") or "" - -- end - local architecture = resultof("echo $HOSTTYPE") or "" - local platform = "" + 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. + + architecture = architecture or 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",1,true) then - platform = "osx-intel" - elseif find(architecture,"x86_64",1,true) then - platform = "osx-64" - elseif find(architecture,"arm64",1,true) then - platform = "osx-64" + bits, platform = 64, "osx-intel" + elseif find(architecture,"i386") then + bits, platform = 64, "osx-intel" + elseif find(architecture,"x86_64") then + bits, platform = 64, "osx-64" + elseif find(architecture,"arm64") then + bits, platform = 64, "osx-arm" else - platform = "osx-ppc" + bits, platform = 32, "osx-ppc" end - os.setenv("MTX_PLATFORM",platform) - os.platform = platform - return platform - end -elseif name == "sunos" then + elseif name == "sunos" then - function resolvers.platform(t,k) - local architecture = resultof("uname -m") or "" - local platform = "" - if find(architecture,"sparc",1,true) then - platform = "solaris-sparc" + architecture = architecture or resultof("uname -m") or "" + if find(architecture,"sparc") then + bits, platform = 32, "solaris-sparc" else -- if architecture == 'i86pc' - platform = "solaris-intel" + bits, platform = 32, "solaris-intel" end - os.setenv("MTX_PLATFORM",platform) - os.platform = platform - return platform - end -elseif name == "freebsd" then + elseif name == "freebsd" then - function resolvers.platform(t,k) - local architecture = resultof("uname -m") or "" - local platform = "" - if find(architecture,"amd64",1,true) then - platform = "freebsd-amd64" + architecture = architecture or os.getenv("MACHTYPE") or resultof("uname -m") or "" + if find(architecture,"amd64") or find(architecture,"AMD64") then + bits, platform = 64, "freebsd-amd64" else - platform = "freebsd" + bits, platform = 32, "freebsd" end - os.setenv("MTX_PLATFORM",platform) - os.platform = platform - return platform - end -elseif name == "kfreebsd" then + elseif name == "kfreebsd" then - function resolvers.platform(t,k) - -- we sometimes have HOSTTYPE set so let's check that first - local architecture = os.getenv("HOSTTYPE") or resultof("uname -m") or "" - local platform = "" - if find(architecture,"x86_64",1,true) then - platform = "kfreebsd-amd64" + architecture = architecture or os.getenv("HOSTTYPE") or resultof("uname -m") or "" + if architecture == "x86_64" then + bits, platform = 64, "kfreebsd-amd64" else - platform = "kfreebsd-i386" + bits, platform = 32, "kfreebsd-i386" end - os.setenv("MTX_PLATFORM",platform) - os.platform = platform - return platform - end -else + else - -- platform = "linux" - -- os.setenv("MTX_PLATFORM",platform) - -- os.platform = platform + architecture = architecture or resultof("uname -m") or "" + + if find(architecture,"aarch64") then + bits, platform = "linux-aarch64" + elseif find(architecture,"armv7l") then + -- linux-armel + bits, platform = 32, "linux-armhf" + elseif find(architecture,"mips64") or find(architecture,"mips64el") then + bits, platform = 64, "linux-mipsel" + elseif find(architecture,"mipsel") or find(architecture,"mips") then + bits, platform = 32, "linux-mipsel" + else + bits, platform = 64, "linux-64" -- was 32, "linux" + end - function resolvers.platform(t,k) - local platform = "linux" - os.setenv("MTX_PLATFORM",platform) - os.platform = platform - return platform end -end + os.setenv("MTX_PLATFORM",platform) + os.setenv("MTX_BITS", bits) -os.newline = name == "windows" and "\013\010" or "\010" -- crlf or lf + os.platform = platform + os.bits = bits + os.newline = name == "windows" and "\013\010" or "\010" -- crlf or lf -function resolvers.bits(t,k) - local bits = find(os.platform,"64",1,true) and 64 or 32 - os.bits = bits - return bits 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 --- data source. Version 4 UUIDs have the form xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx with hexadecimal --- digits x and hexadecimal digits 8, 9, A, or B for y. e.g. f47ac10b-58cc-4372-a567-0e02b2c3d479. --- --- 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() - return format("%04x%04x-4%03x-%s%03x-%04x-%04x%04x%04x", - random(0xFFFF),random(0xFFFF), - random(0x0FFF), - t[ceil(random(4))] or 8,random(0x0FFF), - random(0xFFFF), - random(0xFFFF),random(0xFFFF),random(0xFFFF) - ) +-- 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 data source. Version 4 UUIDs have the form +-- xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx with hexadecimal digits x and hexadecimal +-- digits 8, 9, A, or B for y. e.g. f47ac10b-58cc-4372-a567-0e02b2c3d479. As we don't +-- call this function too often there is not so much risk on repetition. + +do + + local t = { 8, 9, "a", "b" } + + function os.uuid() + return format("%04x%04x-4%03x-%s%03x-%04x-%04x%04x%04x", + random(0xFFFF),random(0xFFFF), + random(0x0FFF), + t[ceil(random(4))] or 8,random(0x0FFF), + random(0xFFFF), + random(0xFFFF),random(0xFFFF),random(0xFFFF) + ) + end + end -local d +do -function os.timezone(delta) - d = d or ((tonumber(date("%H")) or 0) - (tonumber(date("!%H")) or 0)) - if delta then - if d > 0 then - return format("+%02i:00",d) + -- this is fragile because it depends on time and so we only check once during + -- a run (the computer doesn't move zones) .. Michal Vlasák made a better one + + -- local d + -- + -- function os.timezone() + -- d = d or ((tonumber(date("%H")) or 0) - (tonumber(date("!%H")) or 0)) + -- if d > 0 then + -- return format("+%02i:00",d) + -- else + -- return format("-%02i:00",-d) + -- end + -- end + + local hour, min + + function os.timezone(difference) + if not hour then + -- somehow looks too complex: + local current = time() + local utcdate = date("!*t", current) + local localdate = date("*t", current) + localdate.isdst = false + local timediff = difftime(time(localdate), time(utcdate)) + hour, min = modf(timediff / 3600) + min = min * 60 + end + if difference then + return hour, min else - return format("-%02i:00",-d) + return format("%+03d:%02d",hour,min) -- %+ means: always show sign end - else - return 1 end -end -local timeformat = format("%%s%s",os.timezone(true)) -local dateformat = "!%Y-%m-%d %H:%M:%S" -local lasttime = nil -local lastdate = nil - -function os.fulltime(t,default) - t = t and tonumber(t) or 0 - if t > 0 then - -- valid time - elseif default then - return default - else - t = time() - end - if t ~= lasttime then - lasttime = t - lastdate = format(timeformat,date(dateformat)) + -- localtime with timezone: 2021-10-22 10:22:54+02:00 + + local timeformat = format("%%s%s",os.timezone()) + local dateformat = "%Y-%m-%d %H:%M:%S" + local lasttime = nil + local lastdate = nil + + function os.fulltime(t,default) + t = t and tonumber(t) or 0 + if t > 0 then + -- valid time + elseif default then + return default + else + t = time() + end + if t ~= lasttime then + lasttime = t + lastdate = format(timeformat,date(dateformat)) + end + return lastdate end - return lastdate -end -local dateformat = "%Y-%m-%d %H:%M:%S" -local lasttime = nil -local lastdate = nil + -- localtime without timezone: 2021-10-22 10:22:54 -function os.localtime(t,default) - t = t and tonumber(t) or 0 - if t > 0 then - -- valid time - elseif default then - return default - else - t = time() + local dateformat = "%Y-%m-%d %H:%M:%S" + local lasttime = nil + local lastdate = nil + + function os.localtime(t,default) + t = t and tonumber(t) or 0 + if t > 0 then + -- valid time + elseif default then + return default + else + t = time() + end + if t ~= lasttime then + lasttime = t + lastdate = date(dateformat,t) + end + return lastdate end - if t ~= lasttime then - lasttime = t - lastdate = date(dateformat,t) + + function os.converttime(t,default) + local t = tonumber(t) + if t and t > 0 then + return date(dateformat,t) + else + return default or "-" + end end - return lastdate -end -function os.converttime(t,default) - local t = tonumber(t) - if t and t > 0 then - return date(dateformat,t) - else - return default or "-" + -- table with values + + function os.today() + return date("!*t") + end + + -- utc time without timezone: 2021-10-22 08:22:54 + + function os.now() + return date("!%Y-%m-%d %H:%M:%S") end + end -local memory = { } - -local function which(filename) - local fullname = memory[filename] - if fullname == nil then - local suffix = file.suffix(filename) - local suffixes = suffix == "" and os.binsuffixes or { suffix } - for directory in gmatch(os.getenv("PATH"),"[^" .. io.pathseparator .."]+") do - local df = file.join(directory,filename) - for i=1,#suffixes do - local dfs = file.addsuffix(df,suffixes[i]) - if io.exists(dfs) then - fullname = dfs - break +do + + local cache = { } + + local function which(filename) + local fullname = cache[filename] + if fullname == nil then + local suffix = file.suffix(filename) + local suffixes = suffix == "" and os.binsuffixes or { suffix } + for directory in gmatch(os.getenv("PATH"),"[^" .. io.pathseparator .."]+") do + local df = file.join(directory,filename) + for i=1,#suffixes do + local dfs = file.addsuffix(df,suffixes[i]) + if io.exists(dfs) then + fullname = dfs + break + end end end + if not fullname then + fullname = false + end + cache[filename] = fullname end - if not fullname then - fullname = false - end - memory[filename] = fullname + return fullname end - return fullname -end -os.which = which -os.where = which + os.which = which + os.where = which -function os.today() - return date("!*t") -- table with values -end + -- print(os.which("inkscape.exe")) + -- print(os.which("inkscape")) + -- print(os.which("gs.exe")) + -- print(os.which("ps2pdf")) -function os.now() - return date("!%Y-%m-%d %H:%M:%S") -- 2011-12-04 14:59:12 end --- if not os.sleep and socket then --- os.sleep = socket.sleep --- end - if not os.sleep then + local socket = socket + function os.sleep(n) if not socket then -- so we delay ... if os.sleep is really needed then one should also @@ -573,101 +585,105 @@ if not os.sleep then end socket.sleep(n) end -end - --- print(os.which("inkscape.exe")) --- print(os.which("inkscape")) --- print(os.which("gs.exe")) --- print(os.which("ps2pdf")) - --- These are moved from core-con.lua (as I needed them elsewhere). -local function isleapyear(year) -- timed for bram's cs practicum - -- return (year % 400 == 0) or (year % 100 ~= 0 and year % 4 == 0) -- 3:4:1600:1900 = 9.9 : 8.2 : 5.0 : 6.8 (29.9) - return (year % 4 == 0) and (year % 100 ~= 0 or year % 400 == 0) -- 3:4:1600:1900 = 5.1 : 6.5 : 8.1 : 10.2 (29.9) - -- return (year % 4 == 0) and (year % 400 == 0 or year % 100 ~= 0) -- 3:4:1600:1900 = 5.2 : 8.5 : 6.8 : 10.1 (30.6) end -os.isleapyear = isleapyear +-- These are moved from core-con.lua (as I needed them elsewhere). --- nicer: --- --- local days = { --- [false] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, --- [true] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } --- } --- --- local function nofdays(year,month) --- return days[isleapyear(year)][month] --- return month == 2 and isleapyear(year) and 29 or days[month] --- end --- --- more efficient: +do -local days = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } + local function isleapyear(year) -- timed for bram's cs practicum + -- return (year % 400 == 0) or (year % 100 ~= 0 and year % 4 == 0) -- 3:4:1600:1900 = 9.9 : 8.2 : 5.0 : 6.8 (29.9) + return (year % 4 == 0) and (year % 100 ~= 0 or year % 400 == 0) -- 3:4:1600:1900 = 5.1 : 6.5 : 8.1 : 10.2 (29.9) + -- return (year % 4 == 0) and (year % 400 == 0 or year % 100 ~= 0) -- 3:4:1600:1900 = 5.2 : 8.5 : 6.8 : 10.1 (30.6) + end -local function nofdays(year,month,day) - if not month then - return isleapyear(year) and 365 or 364 - elseif not day then - return month == 2 and isleapyear(year) and 29 or days[month] - else - for i=1,month-1 do - day = day + days[i] - end - if month > 2 and isleapyear(year) then - day = day + 1 + os.isleapyear = isleapyear + + -- nicer: + -- + -- local days = { + -- [false] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, + -- [true] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } + -- } + -- + -- local function nofdays(year,month) + -- return days[isleapyear(year)][month] + -- return month == 2 and isleapyear(year) and 29 or days[month] + -- end + -- + -- more efficient: + + local days = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } + + local function nofdays(year,month,day) + if not month then + return isleapyear(year) and 365 or 364 + elseif not day then + return month == 2 and isleapyear(year) and 29 or days[month] + else + for i=1,month-1 do + day = day + days[i] + end + if month > 2 and isleapyear(year) then + day = day + 1 + end + return day end - return day end -end - -os.nofdays = nofdays -function os.weekday(day,month,year) - return date("%w",time { year = year, month = month, day = day }) + 1 -end + os.nofdays = nofdays -function os.validdate(year,month,day) - -- we assume that all three values are set - -- year is always ok, even if lua has a 1970 time limit - if month < 1 then - month = 1 - elseif month > 12 then - month = 12 + function os.weekday(day,month,year) + return date("%w",time { year = year, month = month, day = day }) + 1 end - if day < 1 then - day = 1 - else - local max = nofdays(year,month) - if day > max then - day = max + + function os.validdate(year,month,day) + -- we assume that all three values are set + -- year is always ok, even if lua has a 1970 time limit + if month < 1 then + month = 1 + elseif month > 12 then + month = 12 end + if day < 1 then + day = 1 + else + local max = nofdays(year,month) + if day > max then + day = max + end + end + return year, month, day end - return year, month, day -end -function os.date(fmt,...) - if not fmt then - -- otherwise differences between unix, mingw and msvc - fmt = "%Y-%m-%d %H:%M" + function os.date(fmt,...) + if not fmt then + -- otherwise differences between unix, mingw and msvc + fmt = "%Y-%m-%d %H:%M" + end + return date(fmt,...) end - return date(fmt,...) + end -local osexit = os.exit -local exitcode = nil +do -function os.setexitcode(code) - exitcode = code -end + local osexit = os.exit + local exitcode = nil -function os.exit(c) - if exitcode ~= nil then - return osexit(exitcode) + function os.setexitcode(code) + exitcode = code end - if c ~= nil then - return osexit(c) + + function os.exit(c) + if exitcode ~= nil then + return osexit(exitcode) + end + if c ~= nil then + return osexit(c) + end + return osexit() end - return osexit() + end |