diff options
Diffstat (limited to 'tex/context/base/trac-deb.lua')
-rw-r--r-- | tex/context/base/trac-deb.lua | 247 |
1 files changed, 122 insertions, 125 deletions
diff --git a/tex/context/base/trac-deb.lua b/tex/context/base/trac-deb.lua index 97753f3e9..51bbb8812 100644 --- a/tex/context/base/trac-deb.lua +++ b/tex/context/base/trac-deb.lua @@ -6,182 +6,179 @@ if not modules then modules = { } end modules ['trac-deb'] = { license = "see context related readme files" } -if not lmx then lmx = { } end -if not lmx.variables then lmx.variables = { } end +local lpegmatch = lpeg.match +local format, concat = string.format, table.concat +local tonumber, tostring = tonumber, tostring +local texdimen, textoks, texcount = tex.dimen, tex.toks, tex.count -lmx.htmfile = function(name) return environment.jobname .. "-status.html" end -lmx.lmxfile = function(name) return resolvers.find_file(name,'tex') end +local tracers = namespaces.private("tracers") + +local report_system = logs.new("system") -if not tracers then tracers = { } end -if not tracers.list then tracers.list = { } end -if not tracers.strings then tracers.strings = { } end +tracers.lists = { } +tracers.strings = { } tracers.strings.undefined = "undefined" -local splitter = lpeg.splitat(":") -local lpegmatch = lpeg.match +tracers.lists.scratch = { + 0, 2, 4, 6, 8 +} -function tracers.split(csname) - return lpegmatch(splitter,csname) -end +tracers.lists.internals = { + 'p:hsize', 'p:parindent', 'p:leftskip','p:rightskip', + 'p:vsize', 'p:parskip', 'p:baselineskip', 'p:lineskip', 'p:topskip' +} + +tracers.lists.context = { + 'd:lineheight', + 'c:realpageno', 'c:pageno', 'c:subpageno' +} + +local types = { + ['d'] = tracers.dimen, + ['c'] = tracers.count, + ['t'] = tracers.toks, + ['p'] = tracers.primitive +} + +local splitboth = lpeg.splitat(":") +local splittype = lpeg.firstofsplit(":") +local splitname = lpeg.secondofsplit(":") function tracers.type(csname) - tag, name = tracers.split(csname) - if tag then return tag else return nil end + return lpegmatch(splittype,csname) end function tracers.name(csname) - tag, name = tracers.split(csname) - if tag then return name else return csname end + return lpegmatch(splitname,csname) or csname end function tracers.cs(csname) - tag, name = tracers.split(csname) - if tracers.types[tag] then - return tracers.types[tag](name) + local tag, name = lpegmatch(splitboth,csname) + if name and types[tag] then + return types[tag](name) else return tracers.primitive(csname) end end function tracers.dimen(name) - return (tex.dimen[name] and number.topoints(tex.dimen[name])) or tracers.strings.undefined + local d = texdimen[name] + return d and number.topoints(d) or tracers.strings.undefined end function tracers.count(name) - return tex.count[name] or tracers.strings.undefined + return texcount[name] or tracers.strings.undefined end -function tracers.toks(name) - return (tex.toks[name] and string.limit(tex.toks[name],40)) or tracers.strings.undefined +function tracers.toks(name,limit) + local t = textoks[name] + return t and string.limit(t,tonumber(limit) or 40) or tracers.strings.undefined end function tracers.primitive(name) return tex[name] or tracers.strings.undefined end -tracers.types = { - ['d'] = tracers.dimen, - ['c'] = tracers.count, - ['t'] = tracers.toks, - ['p'] = tracers.primitive -} - function tracers.knownlist(name) - return tracers.list[name] and #tracers.list[name] > 0 + local l = tracers.lists[name] + return l and #l > 0 end -function tracers.showdebuginfo() - local variables = { - ['title'] = 'ConTeXt Debug Information', - ['color-background-one'] = lmx.get('color-background-green'), - ['color-background-two'] = lmx.get('color-background-blue'), - } - lmx.show('context-debug.lmx',variables) -end - -function tracers.showerror() - local filename = status.filename - local linenumber = tonumber(status.linenumber or "0") - local variables = { - ['title'] = 'ConTeXt Error Information', - ['errormessage'] = status.lasterrorstring, - ['linenumber'] = status.linenumber, - ['color-background-one'] = lmx.get('color-background-yellow'), - ['color-background-two'] = lmx.get('color-background-purple'), - } - if not filename then - variables.filename, variables.errorcontext = 'unknown', 'error in filename' - elseif type(filename) == "number" then - variables.filename, variables.errorcontext = "<read " .. filename .. ">", 'unknown error' - elseif io.exists(filename) then - -- todo: use an input opener so that we also catch utf16 an reencoding - lines = io.lines(filename) - if lines then - local context = { } - n, m = 1, linenumber - b, e = m-10, m+10 - s = string.len(tostring(e)) - for line in lines do - if n > e then - break - elseif n > b then - if n == m then - context[#context+1] = string.format("%" .. s .. "d",n) .. " >> " .. line - else - context[#context+1] = string.format("%" .. s .. "d",n) .. " " .. line - end - end - n = n + 1 - end - variables.filename, variables.errorcontext = filename, table.concat(context,"\n") +function tracers.showlines(filename,linenumber,offset) + local data = io.loaddata(filename) + local lines = data and string.splitlines(data) + if lines and #lines > 0 then + offset = tonumber(offset) or 10 + linenumber = tonumber(linenumber) or 10 + local start = math.max(linenumber - offset,1) + local stop = math.min(linenumber + offset,#lines) + if stop > #lines then + return "<linenumber past end of file>" else - variables.filename, variables.errorcontext = filename, "" + local result, fmt = { }, "%" .. #tostring(stop) .. "d %s %s" + for n=start,stop do + result[#result+1] = format(fmt,n,n == linenumber and ">>" or " ",lines[n]) + end + return concat(result,"\n") end else - variables.filename, variables.errorcontext = filename, 'file not found' + return "<empty file>" end - lmx.show('context-error.lmx',variables) end -function tracers.overloaderror() - callback.register('show_error_hook', tracers.showerror) +function tracers.printerror(offset) + local filename, linenumber = status.filename, tonumber(status.linenumber) or 0 + if not filename then + report_system("error not related to input file: %s ...",status.lasterrorstring) + elseif type(filename) == "number" then + report_system("error on line %s of filehandle %s: %s ...",linenumber,filename,status.lasterrorstring) + else + -- currently we still get the error message printed to the log/console so we + -- add a bit of spacing around our variant + texio.write_nl("\n") + report_system("error on line %s in file %s: %s ...\n",linenumber,filename,status.lasterrorstring or "?") -- lua error? + texio.write_nl(tracers.showlines(filename,linenumber,offset),"\n") + end end -tracers.list['scratch'] = { - 0, 2, 4, 6, 8 -} - -tracers.list['internals'] = { - 'p:hsize', 'p:parindent', 'p:leftskip','p:rightskip', - 'p:vsize', 'p:parskip', 'p:baselineskip', 'p:lineskip', 'p:topskip' -} +directives.register("system.errorcontext", function(v) + if v then + callback.register('show_error_hook', function() tracers.printerror(v) end) + else + callback.register('show_error_hook', nil) + end +end) -tracers.list['context'] = { - 'd:lineheight', - 'c:realpageno', 'c:pageno', 'c:subpageno' -} +-- this might move --- dumping the hash +local lmx = namespaces.private("lmx") --- \starttext --- \ctxlua{tracers.dump_hash()} --- \stoptext +if not lmx.variables then lmx.variables = { } end -local saved = { } +lmx.htmfile = function(name) return environment.jobname .. "-status.html" end +lmx.lmxfile = function(name) return resolvers.find_file(name,'tex') end -function tracers.save_hash() - saved = tex.hashtokens() +function lmx.showdebuginfo(lmxname) + local variables = { + ['title'] = 'ConTeXt Debug Information', + ['color-background-one'] = lmx.get('color-background-green'), + ['color-background-two'] = lmx.get('color-background-blue'), + } + if lmxname == false then + return variables + else + lmx.show(lmxname or 'context-debug.lmx',variables) + end end -function tracers.dump_hash(filename,delta) - filename = filename or tex.jobname .. "-hash.log" - local list = { } - local hash = tex.hashtokens() - local command_name = token.command_name - for name, token in next, hash do - if not delta or not saved[name] then - -- token: cmd, chr, csid -- combination cmd,chr determines name - local kind = command_name(token) - local dk = list[kind] - if not dk then - -- a bit funny names but this sorts better (easier to study) - dk = { names = { }, found = 0, code = token[1] } - list[kind] = dk - end - dk.names[name] = { token[2], token[3] } - dk.found = dk.found + 1 - end +function lmx.showerror(lmxname) + local filename, linenumber, errorcontext = status.filename, tonumber(status.linenumber) or 0, "" + if not filename then + filename, errorcontext = 'unknown', 'error in filename' + elseif type(filename) == "number" then + filename, errorcontext = format("<read %s>",filename), 'unknown error' + else + errorcontext = tracers.showlines(filename,linenumber,offset) + end + local variables = { + ['title'] = 'ConTeXt Error Information', + ['errormessage'] = status.lasterrorstring, + ['linenumber'] = linenumber, + ['color-background-one'] = lmx.get('color-background-yellow'), + ['color-background-two'] = lmx.get('color-background-purple'), + ['filename'] = filename, + ['errorcontext'] = errorcontext, + } + if lmxname == false then + return variables + else + lmx.show(lmxname or 'context-error.lmx',variables) end - io.savedata(filename,table.serialize(list,true)) end -function tracers.register_dump_hash(delta) - if delta then - tracers.save_hash() - end - main.register_stop_actions(1,function() tracers.dump_hash(nil,true) end) -- at front +function lmx.overloaderror() + callback.register('show_error_hook', function() lmx.showerror() end) -- prevents arguments being passed end -directives.register("system.dumphash", function() tracers.register_dump_hash(false) end) -directives.register("system.dumpdelta", function() tracers.register_dump_hash(true ) end) +directives.register("system.showerror", lmx.overloaderror) |