Skip to content

Commit 931a9f5

Browse files
committed
fix(Lib/errno): #ifdef wrongly inserted(missing in fact)...
previous ifdef exists in emit of a macro, so just ignored ... fixes errno cannot compile on Windows
1 parent 4727f8d commit 931a9f5

File tree

3 files changed

+55
-19
lines changed

3 files changed

+55
-19
lines changed

src/pylib/Lib/errno_impl/private/errorcodeInit.nim

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import ./errnos
44
import ./loopErrno
5+
import ./clike
56
export errnos
67

78
import std/enumutils
@@ -13,12 +14,34 @@ macro initErrorcodeMap*(K, V; res: untyped, initFunc: typed) =
1314
let N = newLit ErrnoCount
1415
result.add quote do:
1516
var `res` = `initFunc`[`K`, `V`](`N`)
16-
forErrno e:
17-
let
18-
errName = symbolName e
19-
errNameNode = newLit errName
20-
errId = ident errName
21-
result.add quote do:
22-
`res`[`errId`] = `errNameNode`
17+
#[
18+
XXX: NIM-BUG: if using `let` in forErrno loop (in Windows):
19+
errorcodeInit.nim(18, 7) Error: redefinition of 'errName'; previous declaration here: errorcodeInit.nim(18, 7)
20+
]#
21+
var
22+
errName: string
23+
errNameNode, errId: NimNode
24+
result.forErrno e:
25+
errName = symbolName e
26+
errNameNode = newLit errName
27+
errId = ident errName
28+
let addErrnoId = genSym(nskProc, errName)
29+
when CLike:
30+
# NOTE: just wrap in `res`[`errId`] = `errNameNode` directly in `#ifdef`
31+
# doesn't work, as `#ifdef .. #endif` will not be placed right
32+
# around stmt, but
33+
# very early in the C file.
34+
# so we use a proc.
35+
result.add quote do:
36+
proc `addErrnoId`(){.inline.} =
37+
{.emit: "\n#ifdef " & `errNameNode` & '\n'.}
38+
`res`[`errId`] = `errNameNode`
39+
{.emit: "\n#endif\n".}
40+
result.add newCall(addErrnoId)
41+
else:
42+
result.add quote do:
43+
`res`[`errId`] = `errNameNode`
2344

24-
template declErrorcodeWith*[K, V](initFunc: typed) = initErrorcodeMap K, V,errorcode, initFunc
45+
template declErrorcodeWith*[K, V](initFunc: typed) =
46+
bind initErrorcodeMap
47+
initErrorcodeMap K, V,errorcode, initFunc

src/pylib/Lib/errno_impl/private/exportUtils.nim

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ template eno(E) =
1616

1717
macro exportAllErrnosViaEnumOrImportc*() =
1818
result = newStmtList()
19-
forErrno e:
19+
result.forErrno e:
2020
result.add newCall(bindSym"eno", ident symbolName e)
2121

2222

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,30 @@
1+
import std/macros
2+
import std/enumutils
13
import ./clike
24
import ./errnos
3-
template whenDefErrno*(err; body) =
4-
bind CLike
5-
when not CLike: body
5+
6+
template emitPragma(body: string): NimNode =
7+
nnkPragma.newTree(
8+
nnkExprColonExpr.newTree(
9+
newIdentNode("emit"),
10+
newLit(body)
11+
)
12+
)
13+
14+
template whenDefErrno*(res: NimNode; errnoName: string; body): untyped{.dirty.} =
15+
bind CLike, add, quote, emitPragma
16+
when CLike:
17+
# hint: following takes the responsibility to make declaration of errnoName
18+
# to be wrapped by `#ifdef`
19+
res.add emitPragma "\n#ifdef " & errnoName & '\n'
20+
body
21+
res.add emitPragma "\n#endif\n"
622
else:
7-
const errS = astToStr(err)
8-
{.emit: "\n#ifdef " & errS & '\n'.}
923
body
10-
{.emit: "\n#endif\n".}
1124

12-
template forErrno*(err; body) =
25+
template forErrno*(res: NimNode; err; body) =
1326
bind whenDefErrno, Errno
14-
for err{.inject.} in Errno:
15-
if err == Errno.E_SUCCESS: continue
16-
whenDefErrno err:
27+
for err{.inject.} in succ(Errno.E_SUCCESS)..high(Errno):
28+
#if err == Errno.E_SUCCESS: continue
29+
result.whenDefErrno symbolName err:
1730
body

0 commit comments

Comments
 (0)