|
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192 |
- 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
-
- function preproc.directives.includelib(file, name) -- string string -- string -- Returns a preprocessed inlined library
- return string.format("package.loaded['%s'] = (function()\n%s\nend)()", name, preproc.preproc(file))
- end
-
- function preproc.directives.includepkgfile(package, file)
- if (_OSVERSION or ""):sub(1,7) == "PsychOS" then
- return preproc.preproc(string.format("/pkg/%s", file))
- else
- for path in (os.getenv("PSYCHOSPACKAGES") or "../PsychOSPackages"):gmatch("[^:]+") do
- local f = io.open(string.format("%s/%s/%s", path, package, file), "r")
- if f then
- f:close()
- return preproc.preproc(string.format("%s/%s/%s", path, package, file))
- end
- end
- end
- error(string.format("unable to locate file %s from package %s", file, package))
- end
-
- function preproc.directives.includepkglib(package, file, name) -- string string -- string -- Returns a preprocessed inlined library
- return string.format("package.loaded['%s'] = (function()\n%s\nend)()", name, preproc.directives.includepkgfile(package, file))
- end
-
- 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})
|