From 2fbee483b2f2539c50325284937b49b76ed3db83 Mon Sep 17 00:00:00 2001 From: XeonSquared Date: Sun, 7 Jun 2020 23:29:26 +1000 Subject: [PATCH] move actual preproc lib into folder rather than symlinking to the version in lib/, a better solution will be considered later --- preproc.lua | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 69 insertions(+), 1 deletion(-) mode change 120000 => 100644 preproc.lua diff --git a/preproc.lua b/preproc.lua deleted file mode 120000 index fdc06ae..0000000 --- a/preproc.lua +++ /dev/null @@ -1 +0,0 @@ -lib/preproc.lua \ No newline at end of file diff --git a/preproc.lua b/preproc.lua new file mode 100644 index 0000000..1cdac5a --- /dev/null +++ b/preproc.lua @@ -0,0 +1,69 @@ +local preproc = {} +preproc.directives = {} + +function preproc.parsewords(line) -- string -- table -- Returns a table of words from the string *line*, parsing quotes and escapes. + local rt = {""} + local escaped, quoted = false, false + for c in line:gmatch(".") do + if escaped then + rt[#rt] = rt[#rt]..c + elseif c == '"' or c == "'" then + quoted = not quoted + elseif c == "\\" then + escaped = true + elseif c:match("%s") and not quoted and rt[#rt]:len() > 0 then + rt[#rt+1] = "" + else + rt[#rt] = rt[#rt]..c + end + end + return rt +end + +function preproc.line(line) -- string -- -- Returns either a function - which can be called to get lines until it returns nil - or a string from processing *line* using preprocessor directives. + if line:match("^%-%-#") then + local directive, args = line:match("^%-%-#(%S+)%s(.+)") + print(directive,args) + local args = preproc.parsewords(args) + if preproc.directives[directive] then + return preproc.directives[directive](table.unpack(args)) + else + error("unknown preprocessor directive: "..directive) + end + else + return line + end +end + +function preproc.preproc(...) -- string -- string -- Returns the output from preprocessing the files listed in *...*. + local tA = {...} + local output = "" + for _,fname in ipairs(tA) do + local f,e = io.open(fname) + if not f then error("unable to open file "..fname..": "..e) end + for line in f:lines() do + local r = preproc.line(line) + if type(r) == "function" then + while true do + local rs = r() + if not rs then break end + output = output .. rs .. "\n" + end + else + output = output .. r .. "\n" + end + end + end + return output +end + +preproc.directives.include = preproc.preproc + +return setmetatable(preproc,{__call=function(_,...) + local tA = {...} + local out = table.remove(tA,#tA) + local f,e = io.open(out,"wb") + if not f then error("unable to open file "..out..": "..e) end + f:write(preproc.preproc(table.unpack(tA))) + f:close() +end})