l-lua.lua /size: 6546 b    last modification: 2025-02-21 11:03
1if not modules then modules = { } end modules ['l-lua'] = {
2    version   = 1.001,
3    comment   = "companion to luat-lib.mkiv",
4    author    = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
5    copyright = "PRAGMA ADE / ConTeXt Development Team",
6    license   = "see context related readme files"
7}
8
9-- potential issues with 5.3:
10
11-- i'm not sure yet if the int/float change is good for luatex
12
13-- math.min
14-- math.max
15-- tostring
16-- tonumber
17-- utf.*
18-- bit32
19
20local next, type, tonumber = next, type, tonumber
21
22-- compatibility hacks and helpers
23
24LUAMAJORVERSION, LUAMINORVERSION = string.match(_VERSION,"^[^%d]+(%d+)%.(%d+).*$")
25
26LUAMAJORVERSION = tonumber(LUAMAJORVERSION) or 5
27LUAMINORVERSION = tonumber(LUAMINORVERSION) or 1
28LUAVERSION      = LUAMAJORVERSION + LUAMINORVERSION/10
29---VERSION      = status and status.lua_format or (LUAMAJORVERSION + LUAMINORVERSION/10)
30LUAFORMAT       = status and status.lua_format or 0
31
32if LUAVERSION < 5.2 and jit then
33    --
34    -- we want loadstring cum suis to behave like 5.2
35    --
36    MINORVERSION = 2
37    LUAVERSION   = 5.2
38end
39
40-- this is lmtx only:
41
42-- if lua and lua.openfile then
43--     io.open = lua.openfile
44-- end
45
46-- lpeg
47
48if not lpeg then
49    lpeg = require("lpeg")
50end
51
52-- if utf8 then
53--     utf8lua = utf8
54--     utf8    = nil
55-- end
56
57-- basics:
58
59if loadstring then
60
61    local loadnormal = load
62
63    function load(first,...)
64        if type(first) == "string" then
65            return loadstring(first,...)
66        else
67            return loadnormal(first,...)
68        end
69    end
70
71else
72
73    loadstring = load
74
75end
76
77-- table:
78
79-- At some point it was announced that i[pairs would be dropped, which makes
80-- sense. As we already used the for loop and # in most places the impact on
81-- ConTeXt was not that large; the remaining ipairs already have been replaced.
82-- Hm, actually ipairs was retained, but we no longer use it anyway (nor
83-- pairs).
84--
85-- Just in case, we provide the fallbacks as discussed in Programming
86-- in Lua (http://www.lua.org/pil/7.3.html):
87
88if not ipairs then
89
90    -- for k, v in ipairs(t) do                ... end
91    -- for k=1,#t            do local v = t[k] ... end
92
93    local function iterate(a,i)
94        i = i + 1
95        local v = a[i]
96        if v ~= nil then
97            return i, v --, nil
98        end
99    end
100
101    function ipairs(a)
102        return iterate, a, 0
103    end
104
105end
106
107if not pairs then
108
109    -- for k, v in pairs(t) do ... end
110    -- for k, v in next, t  do ... end
111
112    function pairs(t)
113        return next, t -- , nil
114    end
115
116end
117
118-- The unpack function has been moved to the table table, and for compatiility
119-- reasons we provide both now.
120
121if not table.unpack then
122
123    table.unpack = _G.unpack
124
125elseif not unpack then
126
127    _G.unpack = table.unpack
128
129end
130
131-- package:
132
133-- if not package.seachers then
134--
135--     package.searchers = package.loaders -- 5.2
136--
137-- elseif not package.loaders then
138--
139--     package.loaders = package.searchers
140--
141-- end
142
143if not package.loaders then -- brr, searchers is a special "loadlib function" userdata type
144
145    package.loaders = package.searchers
146
147end
148
149-- moved from util-deb to here:
150
151local print, select, tostring = print, select, tostring
152
153local inspectors = { }
154
155function setinspector(kind,inspector) -- global function
156    inspectors[kind] = inspector
157end
158
159function inspect(...) -- global function
160    for s=1,select("#",...) do
161        local value = select(s,...)
162        if value == nil then
163            print("nil")
164        else
165            local done  = false
166            -- type driven (table)
167            local kind      = type(value)
168            local inspector = inspectors[kind]
169            if inspector then
170                done = inspector(value)
171                if done then
172                    break
173                end
174            end
175            -- whatever driven (token, node, ...)
176            for kind, inspector in next, inspectors do
177                done = inspector(value)
178                if done then
179                    break
180                end
181            end
182            if not done then
183                print(tostring(value))
184            end
185        end
186    end
187end
188
189--
190
191local dummy = function() end
192
193function optionalrequire(...)
194    local ok, result = xpcall(require,dummy,...)
195    if ok then
196        return result
197    end
198end
199
200local flush = io.flush
201
202if flush then
203
204    local execute = os.execute if execute then function os.execute(...) flush() return execute(...) end end
205    local exec    = os.exec    if exec    then function os.exec   (...) flush() return exec   (...) end end
206    local spawn   = os.spawn   if spawn   then function os.spawn  (...) flush() return spawn  (...) end end
207    local popen   = io.popen   if popen   then function io.popen  (...) flush() return popen  (...) end end
208
209end
210
211-- new
212
213FFISUPPORTED = type(ffi) == "table" and ffi.os ~= "" and ffi.arch ~= "" and ffi.load
214
215if not FFISUPPORTED then
216
217    -- Maybe we should check for LUATEXENGINE but that's also a bit tricky as we still
218    -- can have a weird ffi library laying around. Checking for presence of 'jit' is
219    -- also not robust. So for now we hope for the best.
220
221    local okay ; okay, ffi = pcall(require,"ffi")
222
223    FFISUPPORTED = type(ffi) == "table" and ffi.os ~= "" and ffi.arch ~= "" and ffi.load
224
225end
226
227if not FFISUPPORTED then
228    ffi = nil
229elseif not ffi.number then
230    ffi.number = tonumber
231end
232
233-- if not bit32 then -- and utf8 then
234--  -- bit32 = load ( [[ -- replacement code with 5.3 syntax so that 5.2 doesn't bark on it ]] )
235--     bit32 = require("l-bit32")
236-- end
237
238-- We need this due a bug in luatex socket loading:
239
240-- local loaded = package.loaded
241--
242-- if not loaded["socket"] then loaded["socket"] = loaded["socket.core"] end
243-- if not loaded["mime"]   then loaded["mime"]   = loaded["mime.core"]   end
244--
245-- if not socket.mime then socket.mime = package.loaded["mime"] end
246--
247-- if not loaded["socket.mime"] then loaded["socket.mime"] = socket.mime end
248-- if not loaded["socket.http"] then loaded["socket.http"] = socket.http end
249-- if not loaded["socket.ftp"]  then loaded["socket.ftp"]  = socket.ftp  end
250-- if not loaded["socket.smtp"] then loaded["socket.smtp"] = socket.smtp end
251-- if not loaded["socket.tp"]   then loaded["socket.tp"]   = socket.tp   end
252-- if not loaded["socket.url"]  then loaded["socket.url"]  = socket.url  end
253
254if LUAVERSION > 5.3 then
255 -- collectgarbage("collect")
256 -- collectgarbage("generational") -- crashes on unix
257end
258
259if status and os.setenv then
260    os.setenv("engine",string.lower(status.luatex_engine or "unknown"))
261end
262