Skip to content

Commit 0eca821

Browse files
committed
Fixed errors getting printed to stdout instead of stderr.
CL: Fixed additional stack overflow error when there's an error in the "fileerror" message handler.
1 parent 65669d4 commit 0eca821

2 files changed

Lines changed: 74 additions & 54 deletions

File tree

preprocess-cl.lua

Lines changed: 40 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ local args = arg
144144

145145
local major, minor = _VERSION:match"Lua (%d+)%.(%d+)"
146146
if not major then
147-
print("[LuaPreprocess] Warning: Could not detect Lua version.") -- Note: This line does not obey the --silent option.
147+
io.stderr:write("[LuaPreprocess] Warning: Could not detect Lua version.\n") -- Note: This line does not obey the --silent option.
148148
else
149149
major = tonumber(major)
150150
minor = tonumber(minor)
@@ -177,10 +177,10 @@ local validate = true
177177
--==============================================================
178178
--= Local Functions ============================================
179179
--==============================================================
180-
local errorline
180+
local errorLine
181181
local F, formatBytes, formatInt
182182
local loadLuaFile
183-
local printf, printfNoise
183+
local printf, printfNoise, printError, printfError
184184

185185
F = string.format
186186
function formatBytes(n)
@@ -210,8 +210,15 @@ function printf(s, ...)
210210
end
211211
printfNoise = printf
212212

213-
function errorline(err)
214-
print("Error: "..tostring(err))
213+
function printError(s)
214+
io.stderr:write(s, "\n")
215+
end
216+
function printfError(s, ...)
217+
io.stderr:write(s:format(...), "\n")
218+
end
219+
220+
function errorLine(err)
221+
printError("Error: "..tostring(err))
215222
os.exit(1)
216223
end
217224

@@ -283,16 +290,16 @@ for _, arg in ipairs(args) do
283290

284291
elseif arg:find"^%-%-outputextension=" then
285292
if hasOutputPaths then
286-
errorline("Cannot specify both --outputextension and --outputpaths")
293+
errorLine("Cannot specify both --outputextension and --outputpaths")
287294
end
288295
hasOutputExtension = true
289296
outputExtension = arg:match"^%-%-outputextension=(.*)$"
290297

291298
elseif arg == "--outputpaths" or arg == "-o" then
292299
if hasOutputExtension then
293-
errorline("Cannot specify both --outputpaths and --outputextension")
300+
errorLine("Cannot specify both --outputpaths and --outputextension")
294301
elseif pathsIn[1] then
295-
errorline(arg.." must appear before any paths.")
302+
errorLine(arg.." must appear before any path.")
296303
end
297304
hasOutputPaths = true
298305

@@ -303,7 +310,7 @@ for _, arg in ipairs(args) do
303310
silent = true
304311

305312
else
306-
errorline("Unknown option '"..arg:gsub("=.*", "").."'.")
313+
errorLine("Unknown option '"..arg:gsub("=.*", "").."'.")
307314
end
308315
end
309316

@@ -317,7 +324,7 @@ printfNoise("%s", header)
317324
printfNoise(("="):rep(#header))
318325

319326
if hasOutputPaths and #pathsOut < #pathsIn then
320-
errorline("Missing output path for "..pathsIn[#pathsIn])
327+
errorLine("Missing output path for "..pathsIn[#pathsIn])
321328
end
322329

323330

@@ -370,7 +377,7 @@ if messageHandlerPath ~= "" then
370377
-- This way the message handler can easily define globals that the metaprogram uses.
371378
local mainChunk, err = loadLuaFile(messageHandlerPath, pp.metaEnvironment)
372379
if not mainChunk then
373-
errorline("Could not load message handler: "..err)
380+
errorLine("Could not load message handler...\n"..pp.tryToFormatError(err))
374381
end
375382

376383
messageHandler = mainChunk()
@@ -380,13 +387,13 @@ if messageHandlerPath ~= "" then
380387
elseif type(messageHandler) == "table" then
381388
for message, _messageHandler in pairs(messageHandler) do
382389
if type(message) ~= "string" then
383-
errorline(messageHandlerPath..": Table of handlers must only contain messages as keys.")
390+
errorLine(messageHandlerPath..": Table of handlers must only contain messages as keys.")
384391
elseif type(_messageHandler) ~= "function" then
385-
errorline(messageHandlerPath..": Table of handlers must only contain functions as values.")
392+
errorLine(messageHandlerPath..": Table of handlers must only contain functions as values.")
386393
end
387394
end
388395
else
389-
errorline(messageHandlerPath..": File did not return a table or a function.")
396+
errorLine(messageHandlerPath..": File did not return a table or a function.")
390397
end
391398
end
392399

@@ -402,20 +409,20 @@ if not hasOutputPaths then
402409
end
403410

404411
if not pathsIn[1] then
405-
errorline("No path(s) specified.")
412+
errorLine("No path(s) specified.")
406413
elseif #pathsIn ~= #pathsOut then
407-
errorline(F("Number of input and output paths differ. (%d in, %d out)", #pathsIn, #pathsOut))
414+
errorLine(F("Number of input and output paths differ. (%d in, %d out)", #pathsIn, #pathsOut))
408415
end
409416

410417
local pathsSetIn = {}
411418
local pathsSetOut = {}
412419
for i = 1, #pathsIn do
413-
if pathsSetIn [pathsIn [i]] then errorline("Duplicate input path: " ..pathsIn [i]) end
414-
if pathsSetOut[pathsOut[i]] then errorline("Duplicate output path: "..pathsOut[i]) end
420+
if pathsSetIn [pathsIn [i]] then errorLine("Duplicate input path: " ..pathsIn [i]) end
421+
if pathsSetOut[pathsOut[i]] then errorLine("Duplicate output path: "..pathsOut[i]) end
415422
pathsSetIn [pathsIn [i]] = true
416423
pathsSetOut[pathsOut[i]] = true
417-
if pathsSetOut[pathsIn [i]] then errorline("Path is both input and output: "..pathsIn [i]) end
418-
if pathsSetIn [pathsOut[i]] then errorline("Path is both input and output: "..pathsOut[i]) end
424+
if pathsSetOut[pathsIn [i]] then errorLine("Path is both input and output: "..pathsIn [i]) end
425+
if pathsSetIn [pathsOut[i]] then errorLine("Path is both input and output: "..pathsOut[i]) end
419426
end
420427

421428

@@ -444,7 +451,7 @@ for i, pathIn in ipairs(pathsIn) do
444451
pathMeta = nil
445452
end
446453

447-
local info = pp.processFile{
454+
local info, err = pp.processFile{
448455
pathIn = pathIn,
449456
pathMeta = pathMeta,
450457
pathOut = pathOut,
@@ -485,13 +492,10 @@ for i, pathIn in ipairs(pathsIn) do
485492
lua = luaModified
486493

487494
elseif luaModified ~= nil then
488-
local err = F(
495+
error(F(
489496
"%s: Message handler did not return a string for 'aftermeta'. (Got %s)",
490497
messageHandlerPath, type(luaModified)
491-
)
492-
print("Error @ "..err)
493-
sendMessage("fileerror", pathIn, err)
494-
os.exit(1)
498+
))
495499
end
496500

497501
return lua
@@ -502,15 +506,20 @@ for i, pathIn in ipairs(pathsIn) do
502506
end,
503507

504508
onError = function(err)
505-
sendMessage("fileerror", pathIn, err)
509+
xpcall(function()
510+
sendMessage("fileerror", pathIn, err)
511+
end, function(err)
512+
io.stderr:write("Additional error in 'fileerror' message handler...\n", pp.tryToFormatError(tostring(err)), "\n")
513+
end)
506514
os.exit(1)
507515
end,
508516
}
517+
assert(info, err) -- The onError() handler above should have been called and we should have exited already.
509518

510-
byteCount = byteCount+info.processedByteCount
511-
lineCount = lineCount+info.lineCount
512-
lineCountCode = lineCountCode+info.linesOfCode
513-
tokenCount = tokenCount+info.tokenCount
519+
byteCount = byteCount + info.processedByteCount
520+
lineCount = lineCount + info.lineCount
521+
lineCountCode = lineCountCode + info.linesOfCode
522+
tokenCount = tokenCount + info.tokenCount
514523

515524
if processingInfoPath ~= "" then
516525

preprocess.lua

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ local isToken, isTokenAndNotNil
216216
local loadLuaString, loadLuaFile
217217
local outputLineNumber, maybeOutputLineNumber
218218
local pack, unpack
219-
local printf, printTokens, printTraceback
219+
local printf, printTokens, printError, printfError, printErrorTraceback
220220
local pushErrorHandler, pushErrorHandlerIfOverridingDefault, popErrorHandler
221221
local serialize, toLua
222222

@@ -256,18 +256,25 @@ function printTokens(tokens, filter)
256256
end
257257
end
258258

259-
function printTraceback(message, level)
260-
print(message)
261-
print("stack traceback:")
259+
function printError(s)
260+
io.stderr:write(s, "\n")
261+
end
262+
function printfError(s, ...)
263+
io.stderr:write(s:format(...), "\n")
264+
end
265+
266+
function printErrorTraceback(message, level)
267+
printError(message)
268+
printError("stack traceback:")
262269

263270
for level = 1+(level or 1), 1/0 do
264271
local info = debug.getinfo(level, "nSl")
265272
if not info then break end
266273

267-
-- print(level, "source ", info.source)
268-
-- print(level, "short_src", info.short_src)
269-
-- print(level, "name ", info.name)
270-
-- print(level, "what ", info.what)
274+
-- printError(level, "source ", info.source)
275+
-- printError(level, "short_src", info.short_src)
276+
-- printError(level, "name ", info.name)
277+
-- printError(level, "what ", info.what)
271278

272279
local where = info.source:match"^@(.+)" or info.short_src
273280
local lnStr = info.currentline > 0 and ":"..info.currentline or ""
@@ -279,7 +286,7 @@ function printTraceback(message, level)
279286
or info.what == "tail" and "tail call"
280287
or "?"
281288

282-
print("\t"..where..lnStr.." ("..name..")")
289+
printError("\t"..where..lnStr.." ("..name..")")
283290
end
284291
end
285292

@@ -288,21 +295,21 @@ end
288295
function error(err, level)
289296
-- @Check: Should we prepend the path? And, in all or just some cases?
290297
level = 1+(level or 1)
291-
printTraceback(tryToFormatError(err), level)
298+
printErrorTraceback(tryToFormatError(err), level)
292299
currentErrorHandler(err, level)
293300
end
294301

295302
function errorLine(err)
296-
print(tryToFormatError(err))
303+
printError(tryToFormatError(err))
297304
currentErrorHandler(err, 2)
298305
end
299306

300307
function errorOnLine(path, ln, agent, s, ...)
301308
s = s:format(...)
302309
if agent then
303-
printf("Error @ %s:%d: [%s] %s\n", path, ln, agent, s)
310+
printfError("Error @ %s:%d: [%s] %s\n", path, ln, agent, s)
304311
else
305-
printf("Error @ %s:%d: %s\n", path, ln, s)
312+
printfError("Error @ %s:%d: %s\n", path, ln, s)
306313
end
307314
currentErrorHandler(s, 2)
308315
return s
@@ -336,7 +343,7 @@ do
336343
local linePre1End = findEndOfLine(contents, linePre1Start-1)
337344
local linePre2Start = findStartOfLine(contents, linePre1Start-1, false)
338345
local linePre2End = findEndOfLine(contents, linePre2Start-1)
339-
-- printf("pos %d | lines %d..%d, %d..%d, %d..%d", pos, linePre2Start,linePre2End+1, linePre1Start,linePre1End+1, lineStart,lineEnd+1) -- DEBUG
346+
-- printfError("pos %d | lines %d..%d, %d..%d, %d..%d", pos, linePre2Start,linePre2End+1, linePre1Start,linePre1End+1, lineStart,lineEnd+1) -- DEBUG
340347

341348
local contextStr = F(">\n%s%s%s>-%s^",
342349
(linePre2Start < linePre1Start and linePre2Start <= linePre2End) and F("> %s\n", (contents:sub(linePre2Start, linePre2End):gsub("\t", " "))) or "",
@@ -346,8 +353,8 @@ do
346353
nil
347354
)
348355

349-
if agent then printf("Error @ %s:%d: [%s] %s\n%s", path, ln, agent, s, contextStr)
350-
else printf("Error @ %s:%d: %s", path, ln, s, contextStr)
356+
if agent then printfError("Error @ %s:%d: [%s] %s\n%s", path, ln, agent, s, contextStr)
357+
else printfError("Error @ %s:%d: %s", path, ln, s, contextStr)
351358
end
352359

353360
currentErrorHandler(s, 2)
@@ -904,7 +911,8 @@ end
904911

905912

906913

907-
-- luaString, error = toLua( value )
914+
-- luaString = toLua( value )
915+
-- Returns nil and a message on error.
908916
function toLua(v)
909917
local buffer = {}
910918

@@ -1140,7 +1148,7 @@ metaFuncs.printf = printf
11401148

11411149
-- getFileContents()
11421150
-- Get the entire contents of a binary file or text file. Returns nil and a message on error.
1143-
-- contents, error = getFileContents( path [, isTextFile=false ] )
1151+
-- contents = getFileContents( path [, isTextFile=false ] )
11441152
metaFuncs.getFileContents = getFileContents
11451153

11461154
-- fileExists()
@@ -1150,8 +1158,8 @@ metaFuncs.fileExists = fileExists
11501158

11511159
-- toLua()
11521160
-- Convert a value to a Lua literal. Does not work with certain types, like functions or userdata.
1153-
-- Returns nil and a message if an error ocurred.
1154-
-- luaString, error = toLua( value )
1161+
-- Returns nil and a message on error.
1162+
-- luaString = toLua( value )
11551163
metaFuncs.toLua = toLua
11561164

11571165
-- serialize()
@@ -1295,7 +1303,7 @@ end
12951303

12961304
-- tokenize()
12971305
-- Convert Lua code to tokens. Returns nil and a message on error. (See newToken() for token types.)
1298-
-- tokens, error = tokenize( luaString [, allowPreprocessorCode=false ] )
1306+
-- tokens = tokenize( luaString [, allowPreprocessorCode=false ] )
12991307
-- token = {
13001308
-- type=tokenType, representation=representation, value=value,
13011309
-- line=lineNumber, lineEnd=lineNumber, position=bytePosition, file=filePath,
@@ -1557,6 +1565,9 @@ function metaFuncs.concatTokens(tokens)
15571565
return _concatTokens(tokens)
15581566
end
15591567

1568+
-- Extra stuff used by the command line program:
1569+
metaFuncs.tryToFormatError = tryToFormatError
1570+
15601571

15611572

15621573
for k, v in pairs(metaFuncs) do metaEnv[k] = v end
@@ -1872,7 +1883,7 @@ local function doExpansions(tokensRaw, fileBuffers, params, stats)
18721883
local startTok = depthStack[#depthStack].startToken
18731884
errorAtToken(
18741885
fileBuffers, tok, nil, "Macro",
1875-
"Expected '%s' (to end '%s' %s) but got '%s'.",
1886+
"Expected '%s' (to close '%s' %s) but got '%s'.",
18761887
depthStack[#depthStack][2], startTok.value, getRelativeLocationText(startTok, tok), tok.value
18771888
)
18781889
end
@@ -2473,7 +2484,7 @@ local function processFileOrString(params, isFile)
24732484
errorToReturn = err
24742485

24752486
if not levelFromOurError then
2476-
printTraceback(tryToFormatError(err), 2)
2487+
printErrorTraceback(tryToFormatError(err), 2)
24772488
end
24782489

24792490
if params.onError then params.onError(errorToReturn) end

0 commit comments

Comments
 (0)