Merge branch 'master' of github.com:Araq/Nimrod
This commit is contained in:
commit
d46380e718
6 changed files with 96 additions and 34 deletions
|
|
@ -463,9 +463,9 @@ proc getCompileOptions: string =
|
||||||
proc getLinkOptions: string =
|
proc getLinkOptions: string =
|
||||||
result = linkOptions
|
result = linkOptions
|
||||||
for linkedLib in items(cLinkedLibs):
|
for linkedLib in items(cLinkedLibs):
|
||||||
result.add(cc[ccompiler].linkLibCmd % linkedLib.quoteIfContainsWhite)
|
result.add(cc[ccompiler].linkLibCmd % linkedLib.quoteShell)
|
||||||
for libDir in items(cLibs):
|
for libDir in items(cLibs):
|
||||||
result.add([cc[ccompiler].linkDirCmd, libDir.quoteIfContainsWhite])
|
result.add([cc[ccompiler].linkDirCmd, libDir.quoteShell])
|
||||||
|
|
||||||
proc needsExeExt(): bool {.inline.} =
|
proc needsExeExt(): bool {.inline.} =
|
||||||
result = (optGenScript in gGlobalOptions and targetOS == osWindows) or
|
result = (optGenScript in gGlobalOptions and targetOS == osWindows) or
|
||||||
|
|
@ -485,10 +485,10 @@ proc getCompileCFileCmd*(cfilename: string, isExternal = false): string =
|
||||||
var includeCmd, compilePattern: string
|
var includeCmd, compilePattern: string
|
||||||
if not noAbsolutePaths():
|
if not noAbsolutePaths():
|
||||||
# compute include paths:
|
# compute include paths:
|
||||||
includeCmd = cc[c].includeCmd & quoteIfContainsWhite(libpath)
|
includeCmd = cc[c].includeCmd & quoteShell(libpath)
|
||||||
|
|
||||||
for includeDir in items(cIncludes):
|
for includeDir in items(cIncludes):
|
||||||
includeCmd.add([cc[c].includeCmd, includeDir.quoteIfContainsWhite])
|
includeCmd.add([cc[c].includeCmd, includeDir.quoteShell])
|
||||||
|
|
||||||
compilePattern = JoinPath(ccompilerpath, exe)
|
compilePattern = JoinPath(ccompilerpath, exe)
|
||||||
else:
|
else:
|
||||||
|
|
@ -501,17 +501,17 @@ proc getCompileCFileCmd*(cfilename: string, isExternal = false): string =
|
||||||
toObjFile(cfile)
|
toObjFile(cfile)
|
||||||
else:
|
else:
|
||||||
completeCFilePath(toObjFile(cfile))
|
completeCFilePath(toObjFile(cfile))
|
||||||
cfile = quoteIfContainsWhite(AddFileExt(cfile, cExt))
|
cfile = quoteShell(AddFileExt(cfile, cExt))
|
||||||
objfile = quoteIfContainsWhite(objfile)
|
objfile = quoteShell(objfile)
|
||||||
result = quoteIfContainsWhite(compilePattern % [
|
result = quoteShell(compilePattern % [
|
||||||
"file", cfile, "objfile", objfile, "options", options,
|
"file", cfile, "objfile", objfile, "options", options,
|
||||||
"include", includeCmd, "nimrod", getPrefixDir(), "lib", libpath])
|
"include", includeCmd, "nimrod", getPrefixDir(), "lib", libpath])
|
||||||
add(result, ' ')
|
add(result, ' ')
|
||||||
addf(result, cc[c].compileTmpl, [
|
addf(result, cc[c].compileTmpl, [
|
||||||
"file", cfile, "objfile", objfile,
|
"file", cfile, "objfile", objfile,
|
||||||
"options", options, "include", includeCmd,
|
"options", options, "include", includeCmd,
|
||||||
"nimrod", quoteIfContainsWhite(getPrefixDir()),
|
"nimrod", quoteShell(getPrefixDir()),
|
||||||
"lib", quoteIfContainsWhite(libpath)])
|
"lib", quoteShell(libpath)])
|
||||||
|
|
||||||
proc footprint(filename: string): TCrc32 =
|
proc footprint(filename: string): TCrc32 =
|
||||||
result = crcFromFile(filename) ><
|
result = crcFromFile(filename) ><
|
||||||
|
|
@ -590,7 +590,7 @@ proc CallCCompiler*(projectfile: string) =
|
||||||
while it != nil:
|
while it != nil:
|
||||||
let objFile = if noAbsolutePaths(): it.data.extractFilename else: it.data
|
let objFile = if noAbsolutePaths(): it.data.extractFilename else: it.data
|
||||||
add(objfiles, ' ')
|
add(objfiles, ' ')
|
||||||
add(objfiles, quoteIfContainsWhite(
|
add(objfiles, quoteShell(
|
||||||
addFileExt(objFile, cc[ccompiler].objExt)))
|
addFileExt(objFile, cc[ccompiler].objExt)))
|
||||||
it = PStrEntry(it.next)
|
it = PStrEntry(it.next)
|
||||||
|
|
||||||
|
|
@ -602,8 +602,8 @@ proc CallCCompiler*(projectfile: string) =
|
||||||
var linkerExe = getConfigVar(c, ".linkerexe")
|
var linkerExe = getConfigVar(c, ".linkerexe")
|
||||||
if len(linkerExe) == 0: linkerExe = cc[c].linkerExe
|
if len(linkerExe) == 0: linkerExe = cc[c].linkerExe
|
||||||
if needsExeExt(): linkerExe = addFileExt(linkerExe, "exe")
|
if needsExeExt(): linkerExe = addFileExt(linkerExe, "exe")
|
||||||
if noAbsolutePaths(): linkCmd = quoteIfContainsWhite(linkerExe)
|
if noAbsolutePaths(): linkCmd = quoteShell(linkerExe)
|
||||||
else: linkCmd = quoteIfContainsWhite(JoinPath(ccompilerpath, linkerExe))
|
else: linkCmd = quoteShell(JoinPath(ccompilerpath, linkerExe))
|
||||||
if optGenGuiApp in gGlobalOptions: buildGui = cc[c].buildGui
|
if optGenGuiApp in gGlobalOptions: buildGui = cc[c].buildGui
|
||||||
else: buildGui = ""
|
else: buildGui = ""
|
||||||
var exefile: string
|
var exefile: string
|
||||||
|
|
@ -617,17 +617,17 @@ proc CallCCompiler*(projectfile: string) =
|
||||||
exefile = options.outFile
|
exefile = options.outFile
|
||||||
if not noAbsolutePaths():
|
if not noAbsolutePaths():
|
||||||
exefile = joinPath(splitFile(projectFile).dir, exefile)
|
exefile = joinPath(splitFile(projectFile).dir, exefile)
|
||||||
exefile = quoteIfContainsWhite(exefile)
|
exefile = quoteShell(exefile)
|
||||||
let linkOptions = getLinkOptions()
|
let linkOptions = getLinkOptions()
|
||||||
linkCmd = quoteIfContainsWhite(linkCmd % ["builddll", builddll,
|
linkCmd = quoteShell(linkCmd % ["builddll", builddll,
|
||||||
"buildgui", buildgui, "options", linkOptions, "objfiles", objfiles,
|
"buildgui", buildgui, "options", linkOptions, "objfiles", objfiles,
|
||||||
"exefile", exefile, "nimrod", getPrefixDir(), "lib", libpath])
|
"exefile", exefile, "nimrod", getPrefixDir(), "lib", libpath])
|
||||||
linkCmd.add ' '
|
linkCmd.add ' '
|
||||||
addf(linkCmd, cc[c].linkTmpl, ["builddll", builddll,
|
addf(linkCmd, cc[c].linkTmpl, ["builddll", builddll,
|
||||||
"buildgui", buildgui, "options", linkOptions,
|
"buildgui", buildgui, "options", linkOptions,
|
||||||
"objfiles", objfiles, "exefile", exefile,
|
"objfiles", objfiles, "exefile", exefile,
|
||||||
"nimrod", quoteIfContainsWhite(getPrefixDir()),
|
"nimrod", quoteShell(getPrefixDir()),
|
||||||
"lib", quoteIfContainsWhite(libpath)])
|
"lib", quoteShell(libpath)])
|
||||||
if optCompileOnly notin gGlobalOptions: execExternalProgram(linkCmd)
|
if optCompileOnly notin gGlobalOptions: execExternalProgram(linkCmd)
|
||||||
else:
|
else:
|
||||||
linkCmd = ""
|
linkCmd = ""
|
||||||
|
|
|
||||||
|
|
@ -13,9 +13,9 @@ when defined(gcc) and defined(windows):
|
||||||
else:
|
else:
|
||||||
{.link: "icons/nimrod_icon.o".}
|
{.link: "icons/nimrod_icon.o".}
|
||||||
|
|
||||||
import
|
import
|
||||||
commands, lexer, condsyms, options, msgs, nversion, nimconf, ropes,
|
commands, lexer, condsyms, options, msgs, nversion, nimconf, ropes,
|
||||||
extccomp, strutils, os, platform, main, parseopt, service
|
extccomp, strutils, os, osproc, platform, main, parseopt, service
|
||||||
|
|
||||||
when hasTinyCBackend:
|
when hasTinyCBackend:
|
||||||
import tccgen
|
import tccgen
|
||||||
|
|
@ -23,7 +23,7 @@ when hasTinyCBackend:
|
||||||
when defined(profiler) or defined(memProfiler):
|
when defined(profiler) or defined(memProfiler):
|
||||||
{.hint: "Profiling support is turned on!".}
|
{.hint: "Profiling support is turned on!".}
|
||||||
import nimprof
|
import nimprof
|
||||||
|
|
||||||
proc prependCurDir(f: string): string =
|
proc prependCurDir(f: string): string =
|
||||||
when defined(unix):
|
when defined(unix):
|
||||||
if os.isAbsolute(f): result = f
|
if os.isAbsolute(f): result = f
|
||||||
|
|
@ -61,11 +61,11 @@ proc HandleCmdLine() =
|
||||||
tccgen.run()
|
tccgen.run()
|
||||||
if optRun in gGlobalOptions:
|
if optRun in gGlobalOptions:
|
||||||
if gCmd == cmdCompileToJS:
|
if gCmd == cmdCompileToJS:
|
||||||
var ex = quoteIfContainsWhite(
|
var ex = quoteShell(
|
||||||
completeCFilePath(changeFileExt(gProjectFull, "js").prependCurDir))
|
completeCFilePath(changeFileExt(gProjectFull, "js").prependCurDir))
|
||||||
execExternalProgram("node " & ex & ' ' & service.arguments)
|
execExternalProgram("node " & ex & ' ' & service.arguments)
|
||||||
else:
|
else:
|
||||||
var ex = quoteIfContainsWhite(
|
var ex = quoteShell(
|
||||||
changeFileExt(gProjectFull, exeExt).prependCurDir)
|
changeFileExt(gProjectFull, exeExt).prependCurDir)
|
||||||
execExternalProgram(ex & ' ' & service.arguments)
|
execExternalProgram(ex & ' ' & service.arguments)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,10 +33,10 @@ proc openDefaultBrowser*(url: string) =
|
||||||
else:
|
else:
|
||||||
discard ShellExecuteA(0'i32, "open", url, nil, nil, SW_SHOWNORMAL)
|
discard ShellExecuteA(0'i32, "open", url, nil, nil, SW_SHOWNORMAL)
|
||||||
elif defined(macosx):
|
elif defined(macosx):
|
||||||
discard execShellCmd("open " & quoteIfContainsWhite(url))
|
discard execShellCmd("open " & quoteShell(url))
|
||||||
else:
|
else:
|
||||||
const attempts = ["gnome-open ", "kde-open ", "xdg-open "]
|
const attempts = ["gnome-open ", "kde-open ", "xdg-open "]
|
||||||
var u = quoteIfContainsWhite(url)
|
var u = quoteShell(url)
|
||||||
for a in items(attempts):
|
for a in items(attempts):
|
||||||
if execShellCmd(a & u) == 0: return
|
if execShellCmd(a & u) == 0: return
|
||||||
for b in getEnv("BROWSER").string.split(PathSep):
|
for b in getEnv("BROWSER").string.split(PathSep):
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,58 @@ type
|
||||||
poStdErrToStdOut, ## merge stdout and stderr to the stdout stream
|
poStdErrToStdOut, ## merge stdout and stderr to the stdout stream
|
||||||
poParentStreams ## use the parent's streams
|
poParentStreams ## use the parent's streams
|
||||||
|
|
||||||
|
proc quoteShellWindows*(s: string): string {.noSideEffect, rtl, extern: "nosp$1".} =
|
||||||
|
## Quote s, so it can be safely passed to Windows API.
|
||||||
|
## Based on Python's subprocess.list2cmdline
|
||||||
|
## See http://msdn.microsoft.com/en-us/library/17w5ykft.aspx
|
||||||
|
let needQuote = {' ', '\t'} in s or s.len == 0
|
||||||
|
|
||||||
|
result = ""
|
||||||
|
var backslashBuff = ""
|
||||||
|
if needQuote:
|
||||||
|
result.add("\"")
|
||||||
|
|
||||||
|
for c in s:
|
||||||
|
if c == '\\':
|
||||||
|
backslashBuff.add(c)
|
||||||
|
elif c == '\"':
|
||||||
|
result.add(backslashBuff)
|
||||||
|
result.add(backslashBuff)
|
||||||
|
backslashBuff.setLen(0)
|
||||||
|
result.add("\\\"")
|
||||||
|
else:
|
||||||
|
if backslashBuff.len != 0:
|
||||||
|
result.add(backslashBuff)
|
||||||
|
backslashBuff.setLen(0)
|
||||||
|
result.add(c)
|
||||||
|
|
||||||
|
if needQuote:
|
||||||
|
result.add("\"")
|
||||||
|
|
||||||
|
proc quoteShellPosix*(s: string): string {.noSideEffect, rtl, extern: "nosp$1".} =
|
||||||
|
## Quote s, so it can be safely passed to POSIX shell.
|
||||||
|
## Based on Python's pipes.quote
|
||||||
|
const safeUnixChars = {'%', '+', '-', '.', '/', '_', ':', '=', '@',
|
||||||
|
'0'..'9', 'A'..'Z', 'a'..'z'}
|
||||||
|
if s.len == 0:
|
||||||
|
return "''"
|
||||||
|
|
||||||
|
let safe = s.allCharsInSet(safeUnixChars)
|
||||||
|
|
||||||
|
if safe:
|
||||||
|
return s
|
||||||
|
else:
|
||||||
|
return "'" & s.replace("'", "'\"'\"'") & "'"
|
||||||
|
|
||||||
|
proc quoteShell*(s: string): string {.noSideEffect, rtl, extern: "nosp$1".} =
|
||||||
|
## Quote s, so it can be safely passed to shell.
|
||||||
|
when defined(Windows):
|
||||||
|
return quoteShellWindows(s)
|
||||||
|
elif defined(posix):
|
||||||
|
return quoteShellPosix(s)
|
||||||
|
else:
|
||||||
|
{.error:"quoteShell is not supported on your system".}
|
||||||
|
|
||||||
proc execProcess*(command: string,
|
proc execProcess*(command: string,
|
||||||
options: set[TProcessOption] = {poStdErrToStdOut,
|
options: set[TProcessOption] = {poStdErrToStdOut,
|
||||||
poUseShell}): TaintedString {.
|
poUseShell}): TaintedString {.
|
||||||
|
|
@ -307,10 +359,10 @@ when defined(Windows) and not defined(useNimRtl):
|
||||||
result.writeDataImpl = hsWriteData
|
result.writeDataImpl = hsWriteData
|
||||||
|
|
||||||
proc buildCommandLine(a: string, args: openarray[string]): cstring =
|
proc buildCommandLine(a: string, args: openarray[string]): cstring =
|
||||||
var res = quoteIfContainsWhite(a)
|
var res = quoteShell(a)
|
||||||
for i in 0..high(args):
|
for i in 0..high(args):
|
||||||
res.add(' ')
|
res.add(' ')
|
||||||
res.add(quoteIfContainsWhite(args[i]))
|
res.add(quoteShell(args[i]))
|
||||||
result = cast[cstring](alloc0(res.len+1))
|
result = cast[cstring](alloc0(res.len+1))
|
||||||
copyMem(result, cstring(res), res.len)
|
copyMem(result, cstring(res), res.len)
|
||||||
|
|
||||||
|
|
@ -510,10 +562,10 @@ elif not defined(useNimRtl):
|
||||||
writeIdx = 1
|
writeIdx = 1
|
||||||
|
|
||||||
proc addCmdArgs(command: string, args: openarray[string]): string =
|
proc addCmdArgs(command: string, args: openarray[string]): string =
|
||||||
result = quoteIfContainsWhite(command)
|
result = quoteShell(command)
|
||||||
for i in 0 .. high(args):
|
for i in 0 .. high(args):
|
||||||
add(result, " ")
|
add(result, " ")
|
||||||
add(result, quoteIfContainsWhite(args[i]))
|
add(result, quoteShell(args[i]))
|
||||||
|
|
||||||
proc toCStringArray(b, a: openarray[string]): cstringArray =
|
proc toCStringArray(b, a: openarray[string]): cstringArray =
|
||||||
result = cast[cstringArray](alloc0((a.len + b.len + 1) * sizeof(cstring)))
|
result = cast[cstringArray](alloc0((a.len + b.len + 1) * sizeof(cstring)))
|
||||||
|
|
@ -792,5 +844,14 @@ proc execCmdEx*(command: string, options: set[TProcessOption] = {
|
||||||
close(p)
|
close(p)
|
||||||
|
|
||||||
when isMainModule:
|
when isMainModule:
|
||||||
var x = execProcess("gcc -v")
|
assert quoteShellWindows("aaa") == "aaa"
|
||||||
echo "ECHO ", x
|
assert quoteShellWindows("aaa\"") == "aaa\\\""
|
||||||
|
assert quoteShellWindows("") == "\"\""
|
||||||
|
|
||||||
|
assert quoteShellPosix("aaa") == "aaa"
|
||||||
|
assert quoteShellPosix("aaa a") == "'aaa a'"
|
||||||
|
assert quoteShellPosix("") == "''"
|
||||||
|
assert quoteShellPosix("a'a") == "'a'\"'\"'a'"
|
||||||
|
|
||||||
|
when defined(posix):
|
||||||
|
assert quoteShell("") == "''"
|
||||||
|
|
|
||||||
|
|
@ -709,9 +709,11 @@ proc rfind*(s, sub: string, start: int = -1): int {.noSideEffect.} =
|
||||||
if result != -1: return
|
if result != -1: return
|
||||||
return -1
|
return -1
|
||||||
|
|
||||||
proc quoteIfContainsWhite*(s: string): string =
|
proc quoteIfContainsWhite*(s: string): string {.deprecated.} =
|
||||||
## returns ``'"' & s & '"'`` if `s` contains a space and does not
|
## returns ``'"' & s & '"'`` if `s` contains a space and does not
|
||||||
## start with a quote, else returns `s`
|
## start with a quote, else returns `s`
|
||||||
|
## DEPRECATED as it was confused for shell quoting function.
|
||||||
|
## For this application use osproc.quoteShell.
|
||||||
if find(s, {' ', '\t'}) >= 0 and s[0] != '"':
|
if find(s, {' ', '\t'}) >= 0 and s[0] != '"':
|
||||||
result = '"' & s & '"'
|
result = '"' & s & '"'
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ when haveZipLib:
|
||||||
import zipfiles
|
import zipfiles
|
||||||
|
|
||||||
import
|
import
|
||||||
os, strutils, parseopt, parsecfg, strtabs, streams, debcreation
|
os, osproc, strutils, parseopt, parsecfg, strtabs, streams, debcreation
|
||||||
|
|
||||||
const
|
const
|
||||||
maxOS = 20 # max number of OSes
|
maxOS = 20 # max number of OSes
|
||||||
|
|
@ -486,7 +486,7 @@ proc setupDist(c: var TConfigData) =
|
||||||
if c.innoSetup.path.len == 0:
|
if c.innoSetup.path.len == 0:
|
||||||
c.innoSetup.path = "iscc.exe"
|
c.innoSetup.path = "iscc.exe"
|
||||||
var outcmd = if c.outdir.len == 0: "build" else: c.outdir
|
var outcmd = if c.outdir.len == 0: "build" else: c.outdir
|
||||||
var cmd = "$# $# /O$# $#" % [quoteIfContainsWhite(c.innoSetup.path),
|
var cmd = "$# $# /O$# $#" % [quoteShell(c.innoSetup.path),
|
||||||
c.innoSetup.flags, outcmd, n]
|
c.innoSetup.flags, outcmd, n]
|
||||||
echo(cmd)
|
echo(cmd)
|
||||||
if execShellCmd(cmd) == 0:
|
if execShellCmd(cmd) == 0:
|
||||||
|
|
@ -587,4 +587,3 @@ if actionZip in c.actions:
|
||||||
quit("libzip is not installed")
|
quit("libzip is not installed")
|
||||||
if actionDeb in c.actions:
|
if actionDeb in c.actions:
|
||||||
debDist(c)
|
debDist(c)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue