From 81095dd1bf20eb5f7e126adbdc8047f940504180 Mon Sep 17 00:00:00 2001 From: Hans Hagen Date: Mon, 20 Jul 2020 11:09:33 +0200 Subject: 2020-07-20 10:42:00 --- tex/context/base/mkiv/mlib-fio.lmt | 191 +++++++++++++++++++++++++++++++++++++ 1 file changed, 191 insertions(+) create mode 100644 tex/context/base/mkiv/mlib-fio.lmt (limited to 'tex/context/base/mkiv/mlib-fio.lmt') diff --git a/tex/context/base/mkiv/mlib-fio.lmt b/tex/context/base/mkiv/mlib-fio.lmt new file mode 100644 index 000000000..4290537dd --- /dev/null +++ b/tex/context/base/mkiv/mlib-fio.lmt @@ -0,0 +1,191 @@ +if not modules then modules = { } end modules ['mlib-run'] = { + version = 1.001, + comment = "companion to mlib-ctx.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files", +} + +local type = type +local find = string.find +local concat = table.concat + +local trace_terminal = false trackers.register("metapost.terminal", function(v) trace_terminal = v end) + +local report_metapost = logs.reporter("metapost") +local report_terminal = logs.reporter("metapost","terminal") +local report_logger = logs.reporter("metapost","log") +local report_error = logs.reporter("metapost","error") + +mplib.realtimelogging = false + +local l, nl, dl = { }, 0, false +local t, nt, dt = { }, 0, false +local e, ne, de = { }, 0, false + +local function logger(target,str) + if target == 1 then + -- log + elseif target == 2 or target == 3 then + -- term + if str == "\n" then + mplib.realtimelogging = true + if nl > 0 then + report_logger(concat(l,"",1,nl)) + nl, dl = 0, false + elseif not dl then + report_logger("") + dl = true + end + else + nl = nl + 1 + l[nl] = str + end + elseif target == 4 then + report_error(str) + end +end + +local finders = { } +mplib.finders = finders -- also used in meta-lua.lua + +local new_instance = mplib.new + +local function validftype(ftype) + if ftype == "mp" then + return "mp" + else + return nil + end +end + +finders.file = function(specification,name,mode,ftype) + return resolvers.findfile(name,validftype(ftype)) +end + +local findtexfile = resolvers.findtexfile +local opentexfile = resolvers.opentexfile +local splitlines = string.splitlines + +local function writetoterminal(terminaldata,maxterm,d) + local t = type(d) + local n = 0 + if t == "string" then + d = splitlines(d) + n = #d + for i=1,#d do + maxterm = maxterm + 1 + terminaldata[maxterm] = d[i] + end + elseif t == "table" then + for i=1,#d do + local l = d[i] + if find(l,"[\n\r]") then + local s = splitlines(l) + local m = #s + for i=1,m do + maxterm = maxterm + 1 + terminaldata[maxterm] = s[i] + end + n = n + m + else + maxterm = maxterm + 1 + terminaldata[maxterm] = d[i] + n = 1 + end + end + end + if trace_terminal then + report_metapost("writing %i lines, in cache %s",n,maxterm) + end + return maxterm +end + +local function readfromterminal(terminaldata,maxterm,nowterm) + if nowterm >= maxterm then + terminaldata[nowterm] = false + maxterm = 0 + nowterm = 0 + if trace_terminal then + report_metapost("resetting, maxcache %i",#terminaldata) + end + return maxterm, nowterm, nil + else + if nowterm > 0 then + terminaldata[nowterm] = false + end + nowterm = nowterm + 1 + local s = terminaldata[nowterm] + if trace_terminal then + report_metapost("reading line %i: %s",nowterm,s) + end + return maxterm, nowterm, s + end +end + +local function fileopener() + + -- these can go into the table itself + + local terminaldata = { } + local maxterm = 0 + local nowterm = 0 + + local terminal = { + name = "terminal", + close = function() + -- terminal = { } + -- maxterm = 0 + -- nowterm = 0 + end, + reader = function() + local line + maxterm, nowterm, line = readfromterminal(terminaldata,maxterm,nowterm) + return line + end, + writer = function(d) + maxterm = writetoterminal(terminaldata,maxterm,d) + end, + } + + return function(name,mode,kind) + if name == "terminal" then + -- report_metapost("opening terminal") + return terminal + elseif mode == "w" then + local f = io.open(name,"wb") + if f then + -- report_metapost("opening file %a for writing",full) + return { + name = full, + writer = function(s) return f:write(s) end, -- io.write(f,s) + close = function() f:close() end, + } + end + else + local full = findtexfile(name,validftype(ftype)) + if full then + -- report_metapost("opening file %a for reading",full) + return opentexfile(full) + end + end + end + +end + +local function finder(name,mode,kind) + return findtexfile(name,kind) +end + +function mplib.new(specification) + local openfile = fileopener() + specification.find_file = finder + specification.run_logger = logger + specification.open_file = openfile + specification.interaction = "silent" + specification.halt_on_error = true + local instance = new_instance(specification) + return instance, openfile("terminal") +end + +mplib.finder = finder -- cgit v1.2.3