Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix pathSubs for windows: --outdir:@projectpath/foo works cross platform, and without quoting needed #13407

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions compiler/commands.nim
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ proc testCompileOption*(conf: ConfigRef; switch: string, info: TLineInfo): bool

proc processPath(conf: ConfigRef; path: string, info: TLineInfo,
notRelativeToProj = false): AbsoluteDir =
let p = if os.isAbsolute(path) or '$' in path:
let p = if os.isAbsolute(path) or path.shouldPathSubs:
path
elif notRelativeToProj:
getCurrentDir() / path
Expand All @@ -325,7 +325,7 @@ proc processCfgPath(conf: ConfigRef; path: string, info: TLineInfo): AbsoluteDir
let path = if path.len > 0 and path[0] == '"': strutils.unescape(path)
else: path
let basedir = toFullPath(conf, info).splitFile().dir
let p = if os.isAbsolute(path) or '$' in path:
let p = if os.isAbsolute(path) or path.shouldPathSubs:
path
else:
basedir / path
Expand Down
17 changes: 13 additions & 4 deletions compiler/options.nim
Original file line number Diff line number Diff line change
Expand Up @@ -590,24 +590,33 @@ proc getNimcacheDir*(conf: ConfigRef): AbsoluteDir =
AbsoluteDir(getOsCacheDir() / splitFile(conf.projectName).name &
(if isDefined(conf, "release") or isDefined(conf, "danger"): "_r" else: "_d"))

const subs = {'$', '@'}

proc shouldPathSubs*(input: string): bool =
input.contains(subs + {'~'})

proc pathSubs*(conf: ConfigRef; p, config: string): string =
let home = removeTrailingDirSep(os.getHomeDir())
result = unixToNativePath(p % [
result = ""
result.addfCustom(p, subs = subs, [
"nim", getPrefixDir(conf).string,
"lib", conf.libpath.string,
"home", home,
"config", config,
"projectname", conf.projectName,
"projectpath", conf.projectPath.string,
"projectdir", conf.projectPath.string,
"nimcache", getNimcacheDir(conf).string]).expandTilde
"nimcache", getNimcacheDir(conf).string])
result = unixToNativePath(result).expandTilde

iterator nimbleSubs*(conf: ConfigRef; p: string): string =
let pl = p.toLowerAscii
if "$nimblepath" in pl or "$nimbledir" in pl:
if "$nimblepath" in pl or "$nimbledir" in pl or "@nimblepath" in pl or "@nimbledir" in pl:
for i in countdown(conf.nimblePaths.len-1, 0):
let nimblePath = removeTrailingDirSep(conf.nimblePaths[i].string)
yield p % ["nimblepath", nimblePath, "nimbledir", nimblePath]
var ret = ""
ret.addfCustom(p, subs = subs, ["nimblepath", nimblePath, "nimbledir", nimblePath])
yield ret
else:
yield p

Expand Down
2 changes: 1 addition & 1 deletion compiler/scriptconfig.nim
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ proc setupVM*(module: PSym; cache: IdentCache; scriptName: string;
cbconf patchFile:
let key = a.getString(0) & "_" & a.getString(1)
var val = a.getString(2).addFileExt(NimExt)
if {'$', '~'} in val:
if val.shouldPathSubs:
val = pathSubs(conf, val, vthisDir)
elif not isAbsolute(val):
val = vthisDir / val
Expand Down
109 changes: 60 additions & 49 deletions lib/pure/strutils.nim
Original file line number Diff line number Diff line change
Expand Up @@ -2623,69 +2623,80 @@ proc findNormalized(x: string, inArray: openArray[string]): int =
proc invalidFormatString() {.noinline.} =
raise newException(ValueError, "invalid format string")

proc addf*(s: var string, formatstr: string, a: varargs[string, `$`]) {.
noSideEffect, rtl, extern: "nsuAddf".} =
proc addfCustom*(s: var string, formatstr: string, subs = {'$'}, a: varargs[string, `$`]) {.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just make an addfCustom for the compiler only then...

noSideEffect, rtl, extern: "nsuAddf2".} =
## The same as ``add(s, formatstr % a)``, but more efficient.
runnableExamples:
var s = "start:"
s.addfCustom("$foo @bar $$ @@ $", subs = {'$', '@'}, ["foo", "FOO", "bar", "BAR"])
doAssert s == "start:FOO BAR $ @ $"

const PatternChars = {'a'..'z', 'A'..'Z', '0'..'9', '\128'..'\255', '_'}
var i = 0
var num = 0
while i < len(formatstr):
if formatstr[i] == '$' and i+1 < len(formatstr):
case formatstr[i+1]
of '#':
if num > a.high: invalidFormatString()
add s, a[num]
inc i, 2
inc num
of '$':
add s, '$'
if formatstr[i] in subs and i+1 < len(formatstr):
if formatstr[i+1] == formatstr[i]:
add s, formatstr[i]
inc(i, 2)
of '1'..'9', '-':
var j = 0
inc(i) # skip $
var negative = formatstr[i] == '-'
if negative: inc i
while i < formatstr.len and formatstr[i] in Digits:
j = j * 10 + ord(formatstr[i]) - ord('0')
inc(i)
let idx = if not negative: j-1 else: a.len-j
if idx < 0 or idx > a.high: invalidFormatString()
add s, a[idx]
of '{':
var j = i+2
var k = 0
var negative = formatstr[j] == '-'
if negative: inc j
var isNumber = 0
while j < formatstr.len and formatstr[j] notin {'\0', '}'}:
if formatstr[j] in Digits:
k = k * 10 + ord(formatstr[j]) - ord('0')
if isNumber == 0: isNumber = 1
else:
isNumber = -1
inc(j)
if isNumber == 1:
let idx = if not negative: k-1 else: a.len-k
else:
Copy link
Member Author

@timotheecour timotheecour Feb 13, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note to reviewer: you can check the diff manually, but this is pure re-indentation below here

case formatstr[i+1]
of '#':
if num > a.high: invalidFormatString()
add s, a[num]
inc i, 2
inc num
of '1'..'9', '-':
var j = 0
inc(i) # skip subs
var negative = formatstr[i] == '-'
if negative: inc i
while i < formatstr.len and formatstr[i] in Digits:
j = j * 10 + ord(formatstr[i]) - ord('0')
inc(i)
let idx = if not negative: j-1 else: a.len-j
if idx < 0 or idx > a.high: invalidFormatString()
add s, a[idx]
else:
var x = findNormalized(substr(formatstr, i+2, j-1), a)
of '{':
var j = i+2
var k = 0
var negative = formatstr[j] == '-'
if negative: inc j
var isNumber = 0
while j < formatstr.len and formatstr[j] notin {'\0', '}'}:
if formatstr[j] in Digits:
k = k * 10 + ord(formatstr[j]) - ord('0')
if isNumber == 0: isNumber = 1
else:
isNumber = -1
inc(j)
if isNumber == 1:
let idx = if not negative: k-1 else: a.len-k
if idx < 0 or idx > a.high: invalidFormatString()
add s, a[idx]
else:
var x = findNormalized(substr(formatstr, i+2, j-1), a)
if x >= 0 and x < high(a): add s, a[x+1]
else: invalidFormatString()
i = j+1
of 'a'..'z', 'A'..'Z', '\128'..'\255', '_':
var j = i+1
while j < formatstr.len and formatstr[j] in PatternChars: inc(j)
var x = findNormalized(substr(formatstr, i+1, j-1), a)
if x >= 0 and x < high(a): add s, a[x+1]
else: invalidFormatString()
i = j+1
of 'a'..'z', 'A'..'Z', '\128'..'\255', '_':
var j = i+1
while j < formatstr.len and formatstr[j] in PatternChars: inc(j)
var x = findNormalized(substr(formatstr, i+1, j-1), a)
if x >= 0 and x < high(a): add s, a[x+1]
else: invalidFormatString()
i = j
else:
invalidFormatString()
i = j
else:
invalidFormatString()
else:
add s, formatstr[i]
inc(i)

proc addf*(s: var string, formatstr: string, a: varargs[string, `$`]) {.
noSideEffect, rtl, extern: "nsuAddf".} =
## Wrapper around `addfCustom` with subs = {'$'}
addfCustom(s, formatstr, subs = {'$'}, a)

proc `%` *(formatstr: string, a: openArray[string]): string {.noSideEffect,
rtl, extern: "nsuFormatOpenArray".} =
## Interpolates a format string with the values from `a`.
Expand Down