mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-28 17:04:41 +00:00
The Nim manual says that an implicit conversion to cstring will
eventually not be allowed [1]:
A Nim `string` is implicitly convertible to `cstring` for convenience.
[...]
Even though the conversion is implicit, it is not *safe*: The garbage collector
does not consider a `cstring` to be a root and may collect the underlying
memory. For this reason, the implicit conversion will be removed in future
releases of the Nim compiler. Certain idioms like conversion of a `const` string
to `cstring` are safe and will remain to be allowed.
And from Nim 1.6.0, such a conversion triggers a warning [2]:
A dangerous implicit conversion to `cstring` now triggers a `[CStringConv]` warning.
This warning will become an error in future versions! Use an explicit conversion
like `cstring(x)` in order to silence the warning.
However, some files in this repo produced such a warning. For example,
before this commit, compiling `parsejson.nim` would produce:
/foo/Nim/lib/pure/parsejson.nim(221, 37) Warning: implicit conversion to 'cstring' from a non-const location: my.buf; this will become a compile time error in the future [CStringConv]
/foo/Nim/lib/pure/parsejson.nim(231, 39) Warning: implicit conversion to 'cstring' from a non-const location: my.buf; this will become a compile time error in the future [CStringConv]
This commit resolves the most visible `CStringConv` warnings, making the
cstring conversions explicit.
[1] https://github.com/nim-lang/Nim/blob/d2318d9ccfe6/doc/manual.md#cstring-type
[2] https://github.com/nim-lang/Nim/blob/d2318d9ccfe6/changelogs/changelog_1_6_0.md#type-system
90 lines
2.8 KiB
Nim
90 lines
2.8 KiB
Nim
#
|
|
#
|
|
# The Nim Compiler
|
|
# (c) Copyright 2012 Andreas Rumpf
|
|
#
|
|
# See the file "copying.txt", included in this
|
|
# distribution, for details about the copyright.
|
|
#
|
|
|
|
import
|
|
os, strutils, options, msgs, tinyc, lineinfos, sequtils
|
|
|
|
const tinyPrefix = "dist/nim-tinyc-archive".unixToNativePath
|
|
const nimRoot = currentSourcePath.parentDir.parentDir
|
|
const tinycRoot = nimRoot / tinyPrefix
|
|
when not dirExists(tinycRoot):
|
|
static: doAssert false, $(tinycRoot, "requires: ./koch installdeps tinyc")
|
|
{.compile: tinycRoot / "tinyc/libtcc.c".}
|
|
|
|
var
|
|
gConf: ConfigRef # ugly but can be cleaned up if this is revived
|
|
|
|
proc tinyCErrorHandler(closure: pointer, msg: cstring) {.cdecl.} =
|
|
rawMessage(gConf, errGenerated, $msg)
|
|
|
|
proc initTinyCState: PccState =
|
|
result = openCCState()
|
|
setErrorFunc(result, nil, tinyCErrorHandler)
|
|
|
|
var
|
|
gTinyC = initTinyCState()
|
|
libIncluded = false
|
|
|
|
proc addFile(filename: string) =
|
|
if addFile(gTinyC, filename) != 0'i32:
|
|
rawMessage(gConf, errCannotOpenFile, filename)
|
|
|
|
proc setupEnvironment =
|
|
when defined(amd64):
|
|
defineSymbol(gTinyC, "__x86_64__", nil)
|
|
elif defined(i386):
|
|
defineSymbol(gTinyC, "__i386__", nil)
|
|
when defined(linux):
|
|
defineSymbol(gTinyC, "__linux__", nil)
|
|
defineSymbol(gTinyC, "__linux", nil)
|
|
|
|
var nimDir = getPrefixDir(gConf).string
|
|
var tinycRoot = nimDir / tinyPrefix
|
|
let libpath = nimDir / "lib"
|
|
|
|
addIncludePath(gTinyC, cstring(libpath))
|
|
when defined(windows):
|
|
addSysincludePath(gTinyC, cstring(tinycRoot / "tinyc/win32/include"))
|
|
addSysincludePath(gTinyC, cstring(tinycRoot / "tinyc/include"))
|
|
when defined(windows):
|
|
defineSymbol(gTinyC, "_WIN32", nil)
|
|
# we need Mingw's headers too:
|
|
var gccbin = getConfigVar("gcc.path") % ["nim", tinycRoot]
|
|
addSysincludePath(gTinyC, cstring(gccbin /../ "include"))
|
|
#addFile(tinycRoot / r"tinyc\win32\wincrt1.o")
|
|
addFile(tinycRoot / r"tinyc\win32\alloca86.o")
|
|
addFile(tinycRoot / r"tinyc\win32\chkstk.o")
|
|
#addFile(tinycRoot / r"tinyc\win32\crt1.o")
|
|
|
|
#addFile(tinycRoot / r"tinyc\win32\dllcrt1.o")
|
|
#addFile(tinycRoot / r"tinyc\win32\dllmain.o")
|
|
addFile(tinycRoot / r"tinyc\win32\libtcc1.o")
|
|
|
|
#addFile(tinycRoot / r"tinyc\win32\lib\crt1.c")
|
|
#addFile(tinycRoot / r"tinyc\lib\libtcc1.c")
|
|
else:
|
|
addSysincludePath(gTinyC, "/usr/include")
|
|
when defined(amd64):
|
|
addSysincludePath(gTinyC, "/usr/include/x86_64-linux-gnu")
|
|
|
|
proc compileCCode*(ccode: string, conf: ConfigRef) =
|
|
gConf = conf
|
|
if not libIncluded:
|
|
libIncluded = true
|
|
setupEnvironment()
|
|
discard compileString(gTinyC, ccode)
|
|
|
|
proc run*(conf: ConfigRef, args: string) =
|
|
doAssert gConf == conf
|
|
var s = @[cstring(conf.projectName)] & map(split(args), proc(x: string): cstring = cstring(x))
|
|
var err = tinyc.run(gTinyC, cint(s.len), cast[cstringArray](addr(s[0]))) != 0'i32
|
|
closeCCState(gTinyC)
|
|
if err: rawMessage(conf, errUnknown, "")
|
|
|