1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
#
#
# The Nim Compiler
# (c) Copyright 2015 Andreas Rumpf
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
#
## Implements the new configuration system for Nim. Uses Nim as a scripting
## language.
import
ast, modules, passes, passaux, condsyms,
options, nimconf, lists, sem, semdata, llstream, vm, vmdef, commands, msgs,
os, times
# we support 'cmpIgnoreStyle' natively for efficiency:
from strutils import cmpIgnoreStyle
proc listDirs(a: VmArgs, filter: set[PathComponent]) =
let dir = getString(a, 0)
var result: seq[string] = @[]
for kind, path in walkDir(dir):
if kind in filter: result.add path
setResult(a, result)
proc setupVM*(module: PSym; scriptName: string): PEvalContext =
# For Nimble we need to export 'setupVM'.
result = newCtx(module)
result.mode = emRepl
registerAdditionalOps(result)
# captured vars:
var errorMsg: string
var vthisDir = scriptName.splitFile.dir
template cbconf(name, body) {.dirty.} =
result.registerCallback "stdlib.system." & astToStr(name),
proc (a: VmArgs) =
body
template cbos(name, body) {.dirty.} =
result.registerCallback "stdlib.system." & astToStr(name),
proc (a: VmArgs) =
try:
body
except OSError:
errorMsg = getCurrentExceptionMsg()
# Idea: Treat link to file as a file, but ignore link to directory to prevent
# endless recursions out of the box.
cbos listFiles:
listDirs(a, {pcFile, pcLinkToFile})
cbos listDirs:
listDirs(a, {pcDir})
cbos removeDir:
os.removeDir getString(a, 0)
cbos removeFile:
os.removeFile getString(a, 0)
cbos createDir:
os.createDir getString(a, 0)
cbos getOsError:
setResult(a, errorMsg)
cbos setCurrentDir:
os.setCurrentDir getString(a, 0)
cbos getCurrentDir:
setResult(a, os.getCurrentDir())
cbos moveFile:
os.moveFile(getString(a, 0), getString(a, 1))
cbos getLastModificationTime:
setResult(a, toSeconds(getLastModificationTime(getString(a, 0))))
cbconf thisDir:
setResult(a, vthisDir)
cbconf put:
options.setConfigVar(getString(a, 0), getString(a, 1))
cbconf get:
setResult(a, options.getConfigVar(a.getString 0))
cbconf exists:
setResult(a, options.existsConfigVar(a.getString 0))
cbconf nimcacheDir:
setResult(a, options.getNimcacheDir())
cbconf paramStr:
setResult(a, os.paramStr(int a.getInt 0))
cbconf paramCount:
setResult(a, os.paramCount())
cbconf cmpIgnoreStyle:
setResult(a, strutils.cmpIgnoreStyle(a.getString 0, a.getString 1))
cbconf setCommand:
options.command = a.getString 0
cbconf getCommand:
setResult(a, options.command)
cbconf switch:
processSwitch(a.getString 0, a.getString 1, passPP, unknownLineInfo())
proc runNimScript*(scriptName: string) =
passes.gIncludeFile = includeModule
passes.gImportModule = importModule
initDefines()
defineSymbol("nimscript")
defineSymbol("nimconfig")
registerPass(semPass)
registerPass(evalPass)
appendStr(searchPaths, options.libpath)
var m = makeModule(scriptName)
incl(m.flags, sfMainModule)
vm.globalCtx = setupVM(m, scriptName)
compileSystemModule()
processModule(m, llStreamOpen(scriptName, fmRead), nil)
# ensure we load 'system.nim' again for the real non-config stuff!
resetAllModulesHard()
vm.globalCtx = nil
initDefines()
|