Hello, the following PlainTeX example demonstrates some differences between LuaTeX and plain Lua concerning the "error"-function: -------------------------------------------------------------------- %&luatex \directlua0{error()} % A % \directlua0{error('')} % B \end (A) results in: This is LuaTeX, Version snapshot-0.25.2-2008041019 (Web2C 7.5.6) (Error.tex ! LuaTeX error ^^@?V[^^@^^@. l.4 \directlua0{error()} % A ? (B) results in: This is LuaTeX, Version snapshot-0.25.2-2008041019 (Web2C 7.5.6) (Error.tex ! LuaTeX error [string "luas[0]"]:1: . l.5 \directlua0{error('')} % B ? Compare with Lua ("error('')" only): jonathansauer$ lua Lua 5.1.2 Copyright (C) 1994-2007 Lua.org, PUC-Rio
error('') stdin:1: stack traceback: [C]: in function 'error' stdin:1: in main chunk [C]: ?
-------------------------------------------------------------------- So there are two issues here: 1. When called in LuaTeX and with no parameters, <error> creates quite a creative error message. 2. When called in LuaTeX and with an error message, <error> does not display a stack traceback (contrary to the Lua interpreter). The first one seems to be some kind of invalid pointer error (the error message is read from somewhere in memory instead of being omitted). The missing stacktrace is strange though. Jonathan
Jonathan Sauer wrote:
(A) results in:
This is LuaTeX, Version snapshot-0.25.2-2008041019 (Web2C 7.5.6) (Error.tex ! LuaTeX error ^^@?V[^^@^^@.
Thanks, fixed this (in repos). The code assumed that there always was a message.
(B) results in:
This is LuaTeX, Version snapshot-0.25.2-2008041019 (Web2C 7.5.6) (Error.tex ! LuaTeX error [string "luas[0]"]:1: . l.5 \directlua0{error('')} % B ?
I've added the stack traceback to the output. It does not become less confusing, though: This is LuaTeX, Version snapshot-0.25.3-2008042911 (Web2C 7.5.6) (error.tex ! LuaTeX error [string "luas[0]"]:1: test error stack traceback: [C]: in function 'error' [string "luas[0]"]:1: in main chunk. l.4 \directlua0{error('test error')} % B ? ) Best wishes, Taco
Hello,
I've added the stack traceback to the output. It does not become less confusing, though:
This is LuaTeX, Version snapshot-0.25.3-2008042911 (Web2C 7.5.6) (error.tex ! LuaTeX error [string "luas[0]"]:1: test error stack traceback: [C]: in function 'error' [string "luas[0]"]:1: in main chunk. l.4 \directlua0{error('test error')} % B ? )
Well, the example was a bit contrived, but when deep inside a call hierarchy, I do not find above traceback confusing. It simply outputs the name of the chunk (or [C] in native code) and the function in the chunk. BTW: loadstring can be passed a chunk name. Is it be possible to do the same with \directlua? (to replace "[string "luas[0]"]" above)
Best wishes, Taco
Jonathan
Jonathan Sauer wrote:
Hello,
I've added the stack traceback to the output. It does not become less confusing, though:
This is LuaTeX, Version snapshot-0.25.3-2008042911 (Web2C 7.5.6) (error.tex ! LuaTeX error [string "luas[0]"]:1: test error stack traceback: [C]: in function 'error' [string "luas[0]"]:1: in main chunk. l.4 \directlua0{error('test error')} % B ? )
Well, the example was a bit contrived, but when deep inside a call hierarchy, I do not find above traceback confusing. It simply outputs the name of the chunk (or [C] in native code) and the function in the chunk.
BTW: loadstring can be passed a chunk name. Is it be possible to do the same with \directlua? (to replace "[string "luas[0]"]" above)
Something like \directlua callback chunk {...} you mean?
Best wishes, Taco
Jonathan
_______________________________________________ dev-luatex mailing list dev-luatex@ntg.nl http://www.ntg.nl/mailman/listinfo/dev-luatex
Hello,
BTW: loadstring can be passed a chunk name. Is it be possible to do the same with \directlua? (to replace "[string "luas[0]"]" above)
Something like \directlua callback chunk {...} you mean?
Yes. Maybe \directlua cname {My chunk name} {...} (since it is the name of the chunk, not specifically the name used in the callback/traceback). Jonathan
Jonathan Sauer wrote:
Hello,
BTW: loadstring can be passed a chunk name. Is it be possible to do the same with \directlua? (to replace "[string "luas[0]"]" above) Something like \directlua callback chunk {...} you mean?
Yes. Maybe \directlua cname {My chunk name} {...} (since it is the name of the chunk, not specifically the name used in the callback/traceback).
This idea is very interesting. I have committed an experimental patch that extends \directlua syntax so that besides \directlua <number> <general text> it also allows a keyword prefix: \directlua name <general text> <number> <general text> This allows you to do stuff like this: \directlua name {\jobname-\the\inputlineno} 0 {error('test')} Because it is experimental, it only works for \directlua, not yet for \latelua. Best wishes, Taco
Hello,
[setting \directlua's chunk name]
This allows you to do stuff like this:
\directlua name {\jobname-\the\inputlineno} 0 {error('test')}
Great! Thanks! I'll try it this evening (your example is especially intriguing).
Well, I tried it, and apart from some minor nitpicks it works
perfectly, as does <error>'s stack traceback:
--------------------------------------------------------------
%&luatex
% \directlua0{error()} % A
% \directlua0{error('')} % B
\directlua name{Test} 0{ % C
function a() b() end
function b() c() end
function c() d() end
function d() error('') end
a()
}
\end
--------------------------------------------------------------
(A) results in:
This is LuaTeX, Version snapshot-0.25.3-2008042918 (Web2C 7.5.6)
(Error2.tex
! LuaTeX error .
l.4 \directlua0{error()}
% A
?
(B) results in:
This is LuaTeX, Version snapshot-0.25.3-2008042918 (Web2C 7.5.6)
(Error2.tex
! LuaTeX error [string "\directlua0"]:1:
stack traceback:
[C]: in function 'e
rror'
[string "\directlua0"]:1: in main chunk.
l.5 \directlua0{error('')}
% B
?
Of course, (A) is not a really relevant case, since no-one in their
right mind would call <error> without an appropriate message. Still,
it is a bit puzzling why there is no traceback.
Also note how the traceback is wrapped in a slightly weird way. Most
likely this is because it is written using
else { /* out = [string] */
202c202 < bufflen -= sizeof(" [string \"...\"] "); ---
bufflen -= sizeof(" [...] ");
204c204 < strcpy(out, "[string \""); ---
strcpy(out, "[");
211c211 < strcat(out, "\"]"); ---
strcat(out, "]");
This results in: This is LuaTeX, Version snapshot-0.25.3-2008042921 (Web2C 7.5.6) (Error2.tex ! LuaTeX error [Test]:1: stack traceback: [C]: in function 'error' [Test]:1: in function 'd' [Test]:1: in function 'c' [Test]:1: in function 'b' [Test]: 1: in function 'a' [Test]:1: in main chunk. l.14 } ? What do you think? Jonathan
Jonathan Sauer wrote:
Of course, (A) is not a really relevant case, since no-one in their right mind would call <error> without an appropriate message. Still, it is a bit puzzling why there is no traceback.
This is also true in lua interpreter itself, I just copied the code. lua.exe is a bit weird: error() does not generate an interactive error, even though it does set a non-zero return value: [taco@ntg Taco_Test]$ lua -e 'error()' [taco@ntg Taco_Test]$ echo $? 1 [taco@ntg Taco_Test]$
Also note how the traceback is wrapped in a slightly weird way. Most likely this is because it is written using
, which does not reset its line length counter at a \r.
Yes, I have to fix that.
This is LuaTeX, Version snapshot-0.25.3-2008042921 (Web2C 7.5.6) (Error2.tex ! LuaTeX error [Test]:1: stack traceback: [C]: in function 'error' [Test]:1: in function 'd' [Test]:1: in function 'c' [Test]:1: in function 'b' [Test]:1: in function 'a' [Test]:1: in main chunk. l.14 }
This looks a lot better, but I would opt to keep the quotes, or output text in <>'s, like Knuth does sometimes (no strong feelings about that though. The literal "string" is definately overkill). I will also try if I can some equivalent of line numbers, maybe like so: stack traceback: [C]: in function 'error' <Test>:4: in function 'd' <Test>:3: in function 'c' <Test>:2: in function 'b' <Test>:1: in function 'a' <Test>:6: in main Actual input line numbers probably won't work because there can be code-generated token lists etc., but relative line numbers like this would definately be better than always '1'. Cheers, Taco
Hello,
Of course, (A) is not a really relevant case, since no-one in their right mind would call <error> without an appropriate message. Still,
it is a bit puzzling why there is no traceback.
This is also true in lua interpreter itself, I just copied the code.
lua.exe is a bit weird: error() does not generate an interactive error, even though it does set a non-zero return value:
[taco@ntg Taco_Test]$ lua -e 'error()' [taco@ntg Taco_Test]$ echo $? 1 [taco@ntg Taco_Test]$
That is weird indeed. I noticed that it also does not stop the program.
This is LuaTeX, Version snapshot-0.25.3-2008042921 (Web2C 7.5.6) (Error2.tex ! LuaTeX error [Test]:1: stack traceback: [C]: in function 'error' [Test]:1: in function 'd' [Test]:1: in function 'c' [Test]:1: in function 'b' [Test]:1: in function 'a' [Test]:1: in main chunk. l.14 }
This looks a lot better, but I would opt to keep the quotes, or output text in <>'s, like Knuth does sometimes (no strong feelings about that though. The literal "string" is definately overkill).
Maybe <> would be better, because there is less chance to confuse it with native code's "[C]".
I will also try if I can some equivalent of line numbers, maybe like so:
stack traceback: [C]: in function 'error' <Test>:4: in function 'd' <Test>:3: in function 'c' <Test>:2: in function 'b' <Test>:1: in function 'a' <Test>:6: in main
Actual input line numbers probably won't work because there can be code-generated token lists etc., but relative line numbers like this would definately be better than always '1'.
I'm not sure if that is possible, since TeX's input processor converts line endings to spaces when reading \directlua's <general text>, so Lua's loadstring only sees a single long line (which is also why Lua comments do not work inside \directlua). You would have to modify this behaviour to keep the line endings (maybe temporarily change the catcode of ^^M to "other"?). But maybe this is better handled by a macro package by switching to an appropriate catcode table. OTOH, due to the assignment, this macro would not be completely expandable, like \directlua is: % Assume \directlua@cct is the appropriate catcode table % #1 = Options + Lua state, #2 = Code \protected\def\mydirectlua{% \begingroup% \catcodetable\directlua@cct% \mydirectlua@% } \long\def\mydirectlua@#1#2{% \endgroup% \directlua#1{#2}% } (of course, \catcode`^^M=12 might be easier than a dedicated catcode table, especially on memory consumption) What do you think?
Cheers, Taco
Jonathan
Jonathan Sauer wrote:
I will also try if I can some equivalent of line numbers, maybe like so:
stack traceback: [C]: in function 'error' <Test>:4: in function 'd' <Test>:3: in function 'c' <Test>:2: in function 'b' <Test>:1: in function 'a' <Test>:6: in main
Actual input line numbers probably won't work because there can be code-generated token lists etc., but relative line numbers like this would definately be better than always '1'.
I'm not sure if that is possible, since TeX's input processor converts line endings to spaces when reading \directlua's <general text>, so Lua's loadstring only sees a single long line (which is also why Lua comments do not work inside \directlua).
Actually, \endlinechar = 10 \directlua ... already does the job, that is how I generated the example. You are right, I will have to leave this to the macro programmer. Cheers, Taco
Hello, a few modifications to the manual (additions, mostly) as well as a small sample file illustrating the point made below: %&luatex \endlinechar=10 \directlua name{@test} 0 { -- Fail right away print('foo') assert(false) } \end While the stack backtrace for code created using \directlua is now very readable, IMO the same cannot be said for code loaded via loadfile, at least when kpathsearch is involved. Then the stack backtrace contains the absolute path of each Lua file, making it quite a mouthfull. I have created a patch for lobject.c that modifies the file name(s) contained in a stack backtrace by removing everything but the last path component, i.e. instead of "/absolute/path/to/the/lua/file/somewhere/in/texmf/file.lua", only "file.lua" is shown. What do you think? 190a191,202
/* get the last path component of the source */ for (;;) { const char* fn = strstr(source, LUA_DIRSEP); if (fn) { /* move past the directory separator and try again */ source = fn + strlen(LUA_DIRSEP); } else { /* no further directory separator: Done */ break; } }
Incidentally, I noticed that the code lua.bytecode[n] = loadfile(kpse.find_file(filename)) when used in IniTeX (to preload a complete Lua file) stores the file's complete path in the compiled Lua code (for the stack backtrace) which is then dumped into the format file. Since it is possible that the path contains private information, i.e. the user name, this private information would then be stored in the format file. OTOH, I do not think that this is a problem, since the format file will either be generated on the computer LuaTeX is installed on, and/or the preloaded Lua files will reside in the texmf tree which does not contain a user name et.al. Maybe a note in the manual (contained in the attached .diff) Jonathan
Jonathan Sauer wrote:
While the stack backtrace for code created using \directlua is now very readable, IMO the same cannot be said for code loaded via loadfile, at least when kpathsearch is involved. Then the stack backtrace contains the absolute path of each Lua file, making it quite a mouthfull.
But this could actually be useful, right?
Incidentally, I noticed that the code
lua.bytecode[n] = loadfile(kpse.find_file(filename))
when used in IniTeX (to preload a complete Lua file) stores the file's complete path in the compiled Lua code (for the stack backtrace) which is then dumped into the format file. Since it is possible that the path contains private information, i.e. the user name, this private information would then be stored in the format file.
I am not worried about this. If you can read an fmt file on a particular machine, you can almost certainly read some /etc/passwd on that same network as well. There is a limit to how far I am willing to cater for paranoia. But I have applied to manual patch including the remark about this. Best wishes, Taco
Hello,
While the stack backtrace for code created using \directlua is now very readable, IMO the same cannot be said for code loaded via loadfile, at least when kpathsearch is involved. Then the stack backtrace contains the absolute path of each Lua file, making it quite a mouthfull.
But this could actually be useful, right?
Possibly, yes. Anyway, it is possible to shorten the file name in Lua, so no change is required in LuaTeX itself: function loadstring(file, chunkname) local f, e = io.open(file) if not f then return f, e end local contents = f:read("*a") f:close() return loadstring(contents, "@" .. (chunkname or file)) end (if the chunkname starts with "@", Lua thinks it is a file name when displaying it in a stack backtrace) Jonathan
Hi, Taco Hoekwater a écrit :
Jonathan Sauer wrote:
While the stack backtrace for code created using \directlua is now very readable, IMO the same cannot be said for code loaded via loadfile, at least when kpathsearch is involved. Then the stack backtrace contains the absolute path of each Lua file, making it quite a mouthfull.
But this could actually be useful, right?
This can be very useful, in case you have different versions of the same file in various texmf trees, and you're not enough an expert in kpse to know which one is actually used (or you just forgot about that version). Manuel.
Hi (especially Jonathan), Taco Hoekwater wrote:
Jonathan Sauer wrote:
Hello,
BTW: loadstring can be passed a chunk name. Is it be possible to do the same with \directlua? (to replace "[string "luas[0]"]" above) Something like \directlua callback chunk {...} you mean? Yes. Maybe \directlua cname {My chunk name} {...} (since it is the name of the chunk, not specifically the name used in the callback/traceback).
This idea is very interesting. I have committed an experimental patch that extends \directlua syntax so that besides
\directlua <number> <general text>
it also allows a keyword prefix:
\directlua name <general text> <number> <general text>
This allows you to do stuff like this:
\directlua name {\jobname-\the\inputlineno} 0 {error('test')}
Because it is experimental, it only works for \directlua, not yet for \latelua.
I have just committed code that implements this same extension for \latexlua (#1300). Some small tests seem to indicate it works, but I have not been exhaustive so it would be nice if you could do some tests as well. That same commit also introduces a lua array named lua.instancename that allows lua.instancename[0] = "scratch" so that you can set a global default name for the lua instance. Explicit chunk names take precedence, of course. Best wishes, Taco
Hello,
I have just committed code that implements this same extension for \latexlua (#1300). Some small tests seem to indicate it works, but I have not been exhaustive so it would be nice if you could do some tests as well.
I tested it using the following PlainTeX file: %&luatex % \pdfoutput=1 % A \def\llua#1{% \latelua name{\jobname-\the\inputlineno}0{#1}% } \def\dlua#1{% \directlua name{\jobname-\the\inputlineno}0{#1}% } \def\test{foo} \dlua{error("dlua 1")} Line 1 \llua{error("llua 1: \test")} Line 2 \llua{error("llua 2: \test")} Line 3 \llua{error("llua 3: \test")} Line 4 \llua{error("llua 4: \test")} Line 5 \dlua{error("dlua 2")} \def\test{bar} \bye This results in: This is LuaTeX, Version snapshot-0.25.3-2008060319 (Web2C 7.5.6) (LateLuaTest.tex ! LuaTeX error <LateLuaTest-12>:1: dlua 1 stack traceback: [C]: in function 'error' <LateLuaTest-12>:1: in main chunk. \dlua ...a name{\jobname -\the \inputlineno }0{#1} l.12 \dlua{error("dlua 1")} ? ! pdfTeX error (\latelua): not allowed in DVI mode (\pdfoutput <= 0). \llua #1->\latelua name{\jobname -\the \inputlineno }0{#1} l.15 \llua{error("llua 1")} No pages of output. Transcript written on LateLuaTest.log. (note that this is independent on whether a chunk name is specified or not) After uncommenting line (A) to enable PDF mode, everything worked perfectly. Two points: (1) The manual states that \latelua is similar to \pdfliteral, so this might be the expected behaviour. OTOH, \latelua is also useful to access information only available in the output routine, such as the current page number (i.e. when implementing cross references in Lua). (2) IMO, \latelua should be modeled after \write, which (of course) also works in DVI mode but which also delays expansion of its argument to shipout. \latelua expands its argument completely when issued, as demonstrated above by displaying "foo" in the error message instead of "bar". (the chunk name should still be expanded when the command is issued, in order to get the then-current input line number) What do you think?
Best wishes, Taco
Jonathan
Jonathan Sauer wrote:
(2) IMO, \latelua should be modeled after \write, which (of course) also works in DVI mode but which also delays expansion of its argument to shipout. \latelua expands its argument completely when issued, as demonstrated above by displaying "foo" in the error message instead of "bar".
(the chunk name should still be expanded when the command is issued, in order to get the then-current input line number)
What do you think?
fyi: \latelua started as an experiment to manipulate (influence) the pdf stream and as such is a rather experimental command; for the moment you should not depend on it too much because its behaviour may change; the same is true for what actions are permitted when using it (e.g. pdf.print does not always make sense) concerning writes and similar whatsits ... at some point these may also be overhauled (for instance more control is needed ... think of copying boxes with writes and only one such write (say a toc entry) makes sense) Hans ----------------------------------------------------------------- Hans Hagen | PRAGMA ADE Ridderstraat 27 | 8061 GH Hasselt | The Netherlands tel: 038 477 53 69 | fax: 038 477 53 74 | www.pragma-ade.com | www.pragma-pod.nl -----------------------------------------------------------------
participants (4)
-
Hans Hagen
-
Jonathan Sauer
-
Manuel Pégourié-Gonnard
-
Taco Hoekwater