luat-env.lua /size: 6293 b    last modification: 2024-01-16 09:02
1
 if not modules then modules = { } end modules ['luat-env'] = {
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-- A former version provided functionality for non embeded core scripts i.e. runtime
10-- library loading. Given the amount of Lua code we use now, this no longer makes
11-- sense. Much of this evolved before bytecode arrays were available and so a lot of
12-- code has disappeared already.
13
14local rawset, loadfile = rawset, loadfile
15local gsub = string.gsub
16
17local trace_locating = false  trackers.register("resolvers.locating", function(v) trace_locating = v end)
18
19local report_lua = logs.reporter("resolvers","lua")
20
21local luautilities = utilities.lua
22local luasuffixes  = luautilities.suffixes
23
24local texgettoks   = tex and tex.gettoks
25
26environment        = environment or { }
27local environment  = environment
28
29-- environment
30
31local mt = {
32    __index = function(_,k)
33        if k == "version" then
34            local version = texgettoks and texgettoks("contextversiontoks")
35            if version and version ~= "" then
36                rawset(environment,"version",version)
37                return version
38            else
39                return "unknown"
40            end
41        elseif k == "jobname" or k == "formatname" then
42            local name = tex and tex[k]
43            if name or name== "" then
44                rawset(environment,k,name)
45                return name
46            else
47                return "unknown"
48            end
49        elseif k == "outputfilename" then
50            local name = environment.jobname
51            rawset(environment,k,name)
52            return name
53        end
54    end
55}
56
57setmetatable(environment,mt)
58
59-- weird place ... depends on a not yet loaded module
60
61function environment.texfile(filename)
62    return resolvers.findfile(filename,'tex')
63end
64
65function environment.luafile(filename) -- needs checking
66
67    if CONTEXTLMTXMODE and CONTEXTLMTXMODE > 0 and file.suffix(filename) == "lua" then
68        -- no "tex", as that's pretty slow when not found (suffixes get appended, shouldn't happen)
69     -- trackers.enable("resolvers.*")
70        local resolved = resolvers.findfile(file.replacesuffix(filename,"lmt")) or ""
71     -- trackers.disable("resolvers.*")
72        if resolved ~= "" then
73            return resolved
74        end
75    end
76
77    local resolved = resolvers.findfile(filename,'tex') or ""
78    if resolved ~= "" then
79        return resolved
80    end
81    resolved = resolvers.findfile(filename,'texmfscripts') or ""
82    if resolved ~= "" then
83        return resolved
84    end
85    return resolvers.findfile(filename,'luatexlibs') or ""
86end
87
88-- local function checkstrip(filename)
89--     local modu = modules[file.nameonly(filename)]
90--     return modu and modu.dataonly
91-- end
92
93local stripindeed = false  directives.register("system.compile.strip", function(v) stripindeed = v end)
94
95local function strippable(filename)
96    if stripindeed then
97        local modu = modules[file.nameonly(filename)]
98        return modu and modu.dataonly
99    else
100        return false
101    end
102end
103
104function environment.luafilechunk(filename,silent,macros,optional) -- used for loading lua bytecode in the format
105    filename = file.replacesuffix(filename, "lua")
106    local fullname = environment.luafile(filename)
107    if fullname and fullname ~= "" then
108        local data = luautilities.loadedluacode(fullname,strippable,filename,macros)
109        if not silent then
110            report_lua("loading file %a %s",fullname,not data and "failed" or "succeeded")
111        end
112        return data
113    else
114        if not optional and not silent then
115            report_lua("unknown file %a",filename)
116        end
117        return nil
118    end
119end
120
121-- the next ones can use the previous ones / combine
122
123function environment.loadluafile(filename, version)
124    local lucname, luaname, chunk
125    local basename = file.removesuffix(filename)
126    if basename == filename then
127        luaname = file.addsuffix(basename,luasuffixes.lua)
128        lucname = file.addsuffix(basename,luasuffixes.luc)
129    else
130        luaname = filename -- forced suffix
131        lucname = nil
132    end
133    -- when not overloaded by explicit suffix we look for a luc file first
134    local fullname = (lucname and environment.luafile(lucname)) or ""
135    if fullname ~= "" then
136        if trace_locating then
137            report_lua("loading %a",fullname)
138        end
139        -- maybe: package.loaded[file.nameonly(fullname)] = true
140        chunk = loadfile(fullname) -- this way we don't need a file exists check
141    end
142    if chunk then
143        chunk()
144        if version then
145            -- we check of the version number of this chunk matches
146            local v = version -- can be nil
147            if modules and modules[filename] then
148                v = modules[filename].version -- new method
149            elseif versions and versions[filename] then
150                v = versions[filename]        -- old method
151            end
152            if v == version then
153                return true
154            else
155                if trace_locating then
156                    report_lua("version mismatch for %a, lua version %a, luc version %a",filename,v,version)
157                end
158                environment.loadluafile(filename)
159            end
160        else
161            return true
162        end
163    end
164    fullname = (luaname and environment.luafile(luaname)) or ""
165    if fullname ~= "" then
166        if trace_locating then
167            report_lua("loading %a",fullname)
168        end
169        chunk = loadfile(fullname) -- this way we don't need a file exists check
170        if not chunk then
171            if trace_locating then
172                report_lua("unknown file %a",filename)
173            end
174        else
175            chunk()
176            return true
177        end
178    end
179    return false
180end
181
182environment.filenames = setmetatable( { }, {
183    __index = function(t,k)
184        local v = environment.files[k]
185        if v then
186            return (gsub(v,"%.+$",""))
187        end
188    end,
189    __newindex = function(t,k)
190        -- nothing
191    end,
192    __len = function(t)
193        return #environment.files
194    end,
195} )
196