luat-cod.lua /size: 8109 b    last modification: 2021-10-28 13:50
1if not modules then modules = { } end modules ['luat-cod'] = {
2    version   = 1.001,
3    comment   = "companion to luat-cod.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
9local type, loadfile, tonumber = type, loadfile, tonumber
10local match, gsub, find, format, gmatch = string.match, string.gsub, string.find, string.format, string.gmatch
11
12local texconfig, lua = texconfig, lua
13
14-- maybe pick up from commandline:
15--
16-- texconfig.interaction: 0=batchmode 1=nonstopmode 2=scrollmode 3=errornonstopmode 4=normal
17
18-- some basic housekeeping
19
20texconfig.kpse_init       = false
21texconfig.shell_escape    = 't'
22
23texconfig.error_line      =     250
24texconfig.expand_depth    =   10000
25texconfig.half_error_line =     125
26texconfig.max_in_open     =    1000
27texconfig.max_print_line  =  100000
28texconfig.max_strings     =  500000
29texconfig.nest_size       =    1000
30texconfig.param_size      =   25000
31texconfig.save_size       =  100000
32texconfig.stack_size      =   10000
33texconfig.function_size   =   32768
34texconfig.properties_size =   10000
35texconfig.fix_mem_init    = 1000000
36
37-- registering bytecode chunks
38
39local bytedata    = lua.bytedata or { }
40local bytedone    = lua.bytedone or { }
41
42---.bytecode      = bytecode
43lua.bytedata      = bytedata
44lua.bytedone      = bytedone
45
46local setbytecode = lua.setbytecode
47----- getbytecode = lua.getbytecode
48
49lua.firstbytecode = 501
50lua.lastbytecode  = lua.lastbytecode or (lua.firstbytecode - 1) -- as we load ourselves again ... maybe return earlier
51
52function lua.registeredcodes()
53    return lua.lastbytecode - lua.firstbytecode + 1
54end
55
56-- no file.* and utilities.parsers.* functions yet
57
58local strip = false if arg then for i=-1,#arg do if arg[i] == "--c:strip" then strip = true break end end end
59
60function lua.registercode(filename,options)
61    local barename = gsub(filename,"%.[%a%d]+$","")
62    local basename = match(barename,"^.+[/\\](.-)$") or barename
63    if not bytedone[basename] then
64        local opts = { }
65        if type(options) == "string" and options ~= "" then
66            for s in gmatch(options,"([a-z]+)") do
67                opts[s] = true
68            end
69        end
70        if barename == filename then
71            filename = filename .. ".lua"
72        end
73        local code = environment.luafilechunk(filename,false,opts.optimize)
74        if code then
75            bytedone[basename] = true
76            if environment.initex and not opts.initexonly then
77                local n = lua.lastbytecode + 1
78                bytedata[n] = { name = barename, options = opts }
79                if strip or opts.strip then
80                    setbytecode(n,code,true)
81                else
82                    setbytecode(n,code)
83                end
84                lua.lastbytecode = n
85            end
86        elseif environment.initex then
87            texio.write_nl(format("\nerror loading file: %s (aborting)",filename))
88            os.exit()
89        end
90    end
91end
92
93-- A first start with environments. This will be overloaded later.
94
95environment       = environment or { }
96local environment = environment
97
98-- no string.unquoted yet
99
100local sourcefile = gsub(arg and arg[1] or "","^\"(.*)\"$","%1")
101local sourcepath = find(sourcefile,"/",1,true) and gsub(sourcefile,"/[^/]+$","") or ""
102local targetpath = "."
103
104-- delayed (via metatable):
105--
106-- environment.jobname = tex.jobname
107-- environment.version = tostring(tex.toks.contextversiontoks)
108
109-- traditionally the revision has been a one character string and only
110-- pdftex went beyond "9" but anyway we test for it
111
112if LUATEXENGINE == nil then
113    LUATEXENGINE = status.luatex_engine and string.lower(status.luatex_engine)
114                or (find(status.banner,"LuajitTeX",1,true) and "luajittex" or "luatex")
115end
116
117if LUATEXVERSION == nil then
118    LUATEXVERSION = status.luatex_version/100
119                  + tonumber(status.luatex_revision)/10000
120end
121
122if CONTEXTLMTXMODE == nil then
123    CONTEXTLMTXMODE = 0
124end
125
126if LUATEXFUNCTIONALITY == nil then
127    LUATEXFUNCTIONALITY = status.development_id or 6346
128end
129
130if LUATEXFORMATID == nil then
131    LUATEXFORMATID = status.format_id or 0
132end
133
134if JITSUPPORTED == nil then
135    JITSUPPORTED = LUATEXENGINE == "luajittex" or jit -- "or jit" can go
136end
137
138if INITEXMODE == nil then
139    INITEXMODE = status.ini_version
140end
141
142environment.luatexengine        = LUATEXENGINE
143environment.luatexversion       = LUATEXVERSION
144environment.luatexfunctionality = LUATEXFUNCTIONALITY
145environment.jitsupported        = JITSUPPORTED
146environment.initex              = INITEXMODE
147environment.initexmode          = INITEXMODE
148
149if INITEXMODE then
150
151    local finalizers = { }
152
153    function lua.registerinitexfinalizer(f,comment)
154        comment = comment or "unknown"
155        if type(f) == "function" then
156            finalizers[#finalizers+1] = { action = f, comment = comment }
157        else
158            print(format("\nfatal error: invalid finalizer, action: %s\n",comment))
159            os.exit()
160        end
161    end
162
163    function lua.finalizeinitex(logger)
164        for i=1,#finalizers do
165            local finalizer = finalizers[i]
166            finalizer.action()
167            if logger then
168                logger("finalize action: %s",finalizer.comment)
169            end
170        end
171    end
172
173else
174
175    function lua.registerinitexfinalizer() end
176    function lua.finalizeinitex         () end
177
178end
179
180
181if not environment.luafilechunk then
182
183    function environment.luafilechunk(filename)
184        local fullname = filename
185        if sourcepath ~= "" then
186            fullname = sourcepath .. "/" .. filename
187        end
188        local data = loadfile(fullname)
189        texio.write("term and log","<",data and "+ " or "- ",fullname,">")
190        if data then
191-- package.loaded[gsub(filename,"%..-$"] =
192            data()
193        end
194        return data
195    end
196
197end
198
199if not environment.engineflags then -- raw flags
200
201    local engineflags = { }
202
203    for i=-10,#arg do
204        local a = arg[i]
205        if a then
206            local flag, content = match(a,"^%-%-([^=]+)=?(.-)$")
207            if flag then
208                engineflags[flag] = content or ""
209            end
210        end
211    end
212
213    environment.engineflags = engineflags
214
215end
216
217-- We need a few premature callbacks in the format generator. We
218-- also do this when the format is loaded as otherwise we get
219-- a kpse error when disabled. This is an engine issue that will
220-- be sorted out in due time.
221
222if not lfs.isfile then
223
224    local attributes = lfs.attributes
225
226    function lfs.isdir(name)
227        return attributes(name,"mode") == "directory"
228    end
229
230    function lfs.isfile(name)
231        local a = attributes(name,"mode")
232        return a == "file" or a == "link" or nil
233    end
234
235end
236
237local isfile = lfs.isfile
238
239local function source_file(name)
240    local fullname = sourcepath .. "/" .. name
241    if isfile(fullname) then
242        return fullname
243    end
244    fullname = fullname .. ".tex"
245    if isfile(fullname) then
246        return fullname
247    end
248    if isfile(name) then
249        return name
250    end
251    name = name .. ".tex"
252    if isfile(name) then
253        return name
254    end
255    return nil
256end
257
258local function target_file(name)
259    return targetpath .. "/" .. name
260end
261
262local function find_read_file(id,name)
263    return source_file(name)
264end
265
266local function find_write_file(id,name)
267    return target_file(name)
268end
269
270local function find_log_file(name)
271    return target_file(name)
272end
273
274local function open_read_file(name)
275    local f = io.open(name,'rb')
276    return {
277        reader = function()
278            return f:read("*line")
279        end
280    }
281end
282
283local function find_data_file(name)
284    return source_file(name)
285end
286
287local open_data_file = open_read_file
288
289callback.register('find_read_file' , find_read_file )
290callback.register('open_read_file' , open_read_file )
291callback.register('find_write_file', find_write_file)
292callback.register('find_log_file',   find_log_file)
293
294callback.register('find_data_file' , find_data_file )
295callback.register('open_data_file' , open_data_file )
296