summaryrefslogtreecommitdiff
path: root/macros/luatex/generic/lualibs/lualibs-os.lua
diff options
context:
space:
mode:
Diffstat (limited to 'macros/luatex/generic/lualibs/lualibs-os.lua')
-rw-r--r--macros/luatex/generic/lualibs/lualibs-os.lua748
1 files changed, 382 insertions, 366 deletions
diff --git a/macros/luatex/generic/lualibs/lualibs-os.lua b/macros/luatex/generic/lualibs/lualibs-os.lua
index c7584ccce9..faae76881a 100644
--- a/macros/luatex/generic/lualibs/lualibs-os.lua
+++ b/macros/luatex/generic/lualibs/lualibs-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-arm"
+ 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