Skip to content

Commit

Permalink
Fix os.tmpname on mingw
Browse files Browse the repository at this point in the history
  • Loading branch information
edubart committed Sep 4, 2020
1 parent 16f2816 commit 0261c67
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 30 deletions.
42 changes: 27 additions & 15 deletions lib/os.nelua
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,6 @@ local errno: cint <cimport,cinclude'<errno.h>',nodecl>
local function clock(): clock_t <cimport,cinclude'<time.h>',nodecl> end
local function getenv(name: cstring): cstring <cimport,cinclude'<stdlib.h>',nodecl> end
local function exit(status: cint) <cimport,cinclude'<stdlib.h>',nodecl> end
local function mkstemp(s: cstring): cint <cimport,cinclude'<stdlib.h>',nodecl> end
local function close(fd: cint): cint <cimport,cinclude'<unistd.h>',nodecl> end
local function strncpy(dest: cstring, src: cstring, n: usize): cstring <cimport,cinclude'<string.h>',nodecl> end
local function system(command: cstring): cint <cimport,cinclude'<stdlib.h>',nodecl> end
local function strerror(errnum: cint): cstring <cimport,cinclude'<string.h>',nodecl> end
local function rename(old: cstring, new: cstring): cint <cimport,cinclude'<stdio.h>',nodecl> end
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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 <comptime> = 32
## local ccdefs = require'nelua.ccompiler'.get_cc_defines()
## if ccdefs._WIN32 then
local TMPBUFSIZE <comptime> = 260 -- safe max value
local function tmpnam(s: cstring): cstring <cimport,cinclude'<stdio.h>',nodecl> end
## else
-- is not safe to use `tmpname` on POSIX, use mkstemp

local function mkstemp(s: cstring): cint <cimport,cinclude'<stdlib.h>',nodecl> end
local function strncpy(dest: cstring, src: cstring, n: usize): cstring <cimport,cinclude'<string.h>',nodecl> end
local function close(fd: cint): cint <cimport,cinclude'<unistd.h>',nodecl> end

local TMPBUFSIZE <comptime> = 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
7 changes: 4 additions & 3 deletions lib/string.nelua
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
30 changes: 19 additions & 11 deletions nelua/ccompiler.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {}

Expand Down Expand Up @@ -46,40 +47,47 @@ 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
local ccinfo = {
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'
Expand Down
1 change: 1 addition & 0 deletions nelua/cdefs.lua
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ cdefs.types_printf_format = {
nluint32 = '"%" PRIu32',
nluint64 = '"%" PRIu64',

nlcstring = '"%s"',
nlcchar = '"%c"',
nlcschar = '"%c"',
nlcshort = '"%i"',
Expand Down
2 changes: 1 addition & 1 deletion spec/06-preprocessor_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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({'<stdbool.h>'})
local defs = compiler.get_cc_defines('<stdbool.h>')
assert(defs.bool == '_Bool')
]]]=])
end)
Expand Down

0 comments on commit 0261c67

Please sign in to comment.