From 0261c679414fcd6b0ab459fb1428a113d73cda03 Mon Sep 17 00:00:00 2001 From: Eduardo Bart Date: Fri, 4 Sep 2020 10:37:46 -0300 Subject: [PATCH] Fix os.tmpname on mingw --- lib/os.nelua | 42 ++++++++++++++++++++++------------- lib/string.nelua | 7 +++--- nelua/ccompiler.lua | 30 ++++++++++++++++--------- nelua/cdefs.lua | 1 + spec/06-preprocessor_spec.lua | 2 +- 5 files changed, 52 insertions(+), 30 deletions(-) diff --git a/lib/os.nelua b/lib/os.nelua index d5e744d7..d974a443 100644 --- a/lib/os.nelua +++ b/lib/os.nelua @@ -34,9 +34,6 @@ local errno: cint ',nodecl> local function clock(): clock_t ',nodecl> end local function getenv(name: cstring): cstring ',nodecl> end local function exit(status: cint) ',nodecl> end -local function mkstemp(s: cstring): cint ',nodecl> end -local function close(fd: cint): cint ',nodecl> end -local function strncpy(dest: cstring, src: cstring, n: usize): cstring ',nodecl> end local function system(command: cstring): cint ',nodecl> end local function strerror(errnum: cint): cstring ',nodecl> end local function rename(old: cstring, new: cstring): cint ',nodecl> end @@ -62,7 +59,7 @@ function os.date(): string local ts: tm = localtime(&t) local buf: cchar[250] local size: csize = strftime(&buf[0], 250, "%c", &ts) - return &buf[0] + return tostring(&buf[0]) end function os.difftime(t1: integer, t2: integer): integer @@ -101,7 +98,7 @@ end function os.getenv(varname: stringview): string local s: cstring = getenv(varname) if s then - return s + return tostring(s) else return '' end @@ -137,7 +134,7 @@ function os.setlocale(locale: stringview, category: #[optional_concept(stringvie end local s: cstring = setlocale(cat, locale) if s then - return s + return tostring(s) else return '' end @@ -176,14 +173,29 @@ function os.time(desc: #[optional_concept(os_time_desc)]#): integer end function os.tmpname(): string - --TODO: windows implementation without POSIX - local TMPBUFSIZE = 32 + ## local ccdefs = require'nelua.ccompiler'.get_cc_defines() + ## if ccdefs._WIN32 then + local TMPBUFSIZE = 260 -- safe max value + local function tmpnam(s: cstring): cstring ',nodecl> end + ## else + -- is not safe to use `tmpname` on POSIX, use mkstemp + + local function mkstemp(s: cstring): cint ',nodecl> end + local function strncpy(dest: cstring, src: cstring, n: usize): cstring ',nodecl> end + local function close(fd: cint): cint ',nodecl> end + + local TMPBUFSIZE = 32 + local function tmpnam(buf: cstring) + strncpy(buf, "/tmp/lua_XXXXXX", TMPBUFSIZE) + local fd: cint = mkstemp(buf) + if fd == -1 then + error "os.tmpname: unable to generate a unique filename" + end + close(fd) + end + ## end + local buf: cchar[TMPBUFSIZE] - strncpy(&buf[0], "/tmp/lua_XXXXXX", TMPBUFSIZE) - local fd: cint = mkstemp(&buf[0]) - if fd == -1 then - error "os.tmpname: unable to generate a unique filename" - end - close(fd) - return &buf[0] + tmpnam(&buf[0]) + return tostring(&buf[0]) end diff --git a/lib/string.nelua b/lib/string.nelua index c9394e47..9ddd99fd 100644 --- a/lib/string.nelua +++ b/lib/string.nelua @@ -177,7 +177,10 @@ function string.char(c: byte): string end global function tostring(x: auto): string - ## if x.type.is_arithmetic or x.type.is_function or x.type.is_pointer then + ## if x.type.is_stringy then + -- use implicit conversion + return x + ## elseif x.type.is_arithmetic or x.type.is_function or x.type.is_pointer then local size: cint ##[[ local tyformat @@ -215,8 +218,6 @@ global function tostring(x: auto): string return 'true' end return 'false' - ## elseif x.type.is_stringy then - return x ## elseif x.type.is_niltype then return 'nil' ## elseif x.type.is_polyfunction then diff --git a/nelua/ccompiler.lua b/nelua/ccompiler.lua index 79276c8e..63b7a747 100644 --- a/nelua/ccompiler.lua +++ b/nelua/ccompiler.lua @@ -8,6 +8,7 @@ local sstream = require 'nelua.utils.sstream' local console = require 'nelua.utils.console' local config = require 'nelua.configer'.get() local cdefs = require 'nelua.cdefs' +local memoize = require 'nelua.utils.memoize' local compiler = {} @@ -46,11 +47,8 @@ local function get_compile_args(cfile, binfile, compileopts) return pegger.substitute('$(cc) -o "$(binfile)" "$(cfile)" $(cflags)', env) end -local last_ccinfos = {} -function compiler.get_cc_info() - local last_ccinfo = last_ccinfos[config.cc] - if last_ccinfo then return last_ccinfo end - local cccmd = string.format('%s -v', config.cc) +local function get_cc_info(cc) + local cccmd = string.format('%s -v', cc) local ok, ret, stdout, stderr = executor.execex(cccmd) except.assertraisef(ok and ret == 0, "failed to retrieve compiler information: %s", stderr) local text = stderr and stderr ~= '' and stderr or stdout @@ -58,28 +56,38 @@ function compiler.get_cc_info() target = text:match('Target: ([-_%w]+)'), thread_model = text:match('Thread model: ([-_%w]+)'), version = text:match('version ([.%d]+)'), - name = text:match('([-_%w]+) version') or config.cc, - exe = config.cc, + name = text:match('([-_%w]+) version') or cc, + exe = cc, text = text, is_emscripten = text:match('Emscripten') ~= nil } - last_ccinfos[config.cc] = ccinfo return ccinfo end +get_cc_info = memoize(get_cc_info) + +function compiler.get_cc_info() + return get_cc_info(config.cc) +end -function compiler.get_c_defines(headers) +local function get_cc_defines(cc, ...) local tmpname = fs.tmpname() local code = {} - for _,header in ipairs(headers) do + for i=1,select('#', ...) do + local header = select(i, ...) table.insert(code, '#include ' .. header) end fs.ewritefile(tmpname, table.concat(code)) - local cccmd = string.format('%s -x c -E -dM %s', config.cc, tmpname) + local cccmd = string.format('%s -x c -E -dM %s', cc, tmpname) local ok, ret, stdout, ccinfo = executor.execex(cccmd) fs.deletefile(tmpname) except.assertraisef(ok and ret == 0, "failed to retrieve compiler information: %s", ccinfo or '') return pegger.parse_c_defines(stdout) end +get_cc_defines = memoize(get_cc_defines) + +function compiler.get_cc_defines(...) + return get_cc_defines(config.cc, ...) +end function compiler.compile_code(ccode, outfile, compileopts) local cfile = outfile .. '.c' diff --git a/nelua/cdefs.lua b/nelua/cdefs.lua index 858a0c5d..4012cf25 100644 --- a/nelua/cdefs.lua +++ b/nelua/cdefs.lua @@ -17,6 +17,7 @@ cdefs.types_printf_format = { nluint32 = '"%" PRIu32', nluint64 = '"%" PRIu64', + nlcstring = '"%s"', nlcchar = '"%c"', nlcschar = '"%c"', nlcshort = '"%i"', diff --git a/spec/06-preprocessor_spec.lua b/spec/06-preprocessor_spec.lua index 5b8f5dec..e8670dd4 100644 --- a/spec/06-preprocessor_spec.lua +++ b/spec/06-preprocessor_spec.lua @@ -647,7 +647,7 @@ it("compiler information", function() assert.analyze_ast([=[##[[ local compiler = require 'nelua.ccompiler' assert(compiler.get_cc_info()) - local defs = compiler.get_c_defines({''}) + local defs = compiler.get_cc_defines('') assert(defs.bool == '_Bool') ]]]=]) end)