big repo cleanup
This commit is contained in:
parent
46c41e4369
commit
cd292568d7
246 changed files with 28 additions and 74652 deletions
257
compiler/nimconf.nim
Executable file
257
compiler/nimconf.nim
Executable file
|
|
@ -0,0 +1,257 @@
|
|||
#
|
||||
#
|
||||
# The Nimrod Compiler
|
||||
# (c) Copyright 2011 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
# This module handles the reading of the config file.
|
||||
|
||||
import
|
||||
llstream, nversion, commands, os, strutils, msgs, platform, condsyms, scanner,
|
||||
options, idents, wordrecg
|
||||
|
||||
proc LoadConfig*(project: string)
|
||||
proc LoadSpecialConfig*(configfilename: string)
|
||||
# implementation
|
||||
# ---------------- configuration file parser -----------------------------
|
||||
# we use Nimrod's scanner here to safe space and work
|
||||
|
||||
proc ppGetTok(L: var TLexer, tok: PToken) =
|
||||
# simple filter
|
||||
rawGetTok(L, tok[] )
|
||||
while (tok.tokType == tkInd) or (tok.tokType == tkSad) or
|
||||
(tok.tokType == tkDed) or (tok.tokType == tkComment):
|
||||
rawGetTok(L, tok[] )
|
||||
|
||||
proc parseExpr(L: var TLexer, tok: PToken): bool
|
||||
proc parseAtom(L: var TLexer, tok: PToken): bool =
|
||||
if tok.tokType == tkParLe:
|
||||
ppGetTok(L, tok)
|
||||
result = parseExpr(L, tok)
|
||||
if tok.tokType == tkParRi: ppGetTok(L, tok)
|
||||
else: lexMessage(L, errTokenExpected, "\')\'")
|
||||
elif tok.ident.id == ord(wNot):
|
||||
ppGetTok(L, tok)
|
||||
result = not parseAtom(L, tok)
|
||||
else:
|
||||
result = isDefined(tok.ident) #condsyms.listSymbols();
|
||||
#writeln(tok.ident.s + ' has the value: ', result);
|
||||
ppGetTok(L, tok)
|
||||
|
||||
proc parseAndExpr(L: var TLexer, tok: PToken): bool =
|
||||
var b: bool
|
||||
result = parseAtom(L, tok)
|
||||
while tok.ident.id == ord(wAnd):
|
||||
ppGetTok(L, tok) # skip "and"
|
||||
b = parseAtom(L, tok)
|
||||
result = result and b
|
||||
|
||||
proc parseExpr(L: var TLexer, tok: PToken): bool =
|
||||
var b: bool
|
||||
result = parseAndExpr(L, tok)
|
||||
while tok.ident.id == ord(wOr):
|
||||
ppGetTok(L, tok) # skip "or"
|
||||
b = parseAndExpr(L, tok)
|
||||
result = result or b
|
||||
|
||||
proc EvalppIf(L: var TLexer, tok: PToken): bool =
|
||||
ppGetTok(L, tok) # skip 'if' or 'elif'
|
||||
result = parseExpr(L, tok)
|
||||
if tok.tokType == tkColon: ppGetTok(L, tok)
|
||||
else: lexMessage(L, errTokenExpected, "\':\'")
|
||||
|
||||
var condStack: seq[bool]
|
||||
|
||||
condStack = @ []
|
||||
proc doEnd(L: var TLexer, tok: PToken) =
|
||||
if high(condStack) < 0: lexMessage(L, errTokenExpected, "@if")
|
||||
ppGetTok(L, tok) # skip 'end'
|
||||
setlen(condStack, high(condStack))
|
||||
|
||||
type
|
||||
TJumpDest = enum
|
||||
jdEndif, jdElseEndif
|
||||
|
||||
proc jumpToDirective(L: var TLexer, tok: PToken, dest: TJumpDest)
|
||||
proc doElse(L: var TLexer, tok: PToken) =
|
||||
if high(condStack) < 0: lexMessage(L, errTokenExpected, "@if")
|
||||
ppGetTok(L, tok)
|
||||
if tok.tokType == tkColon: ppGetTok(L, tok)
|
||||
if condStack[high(condStack)]: jumpToDirective(L, tok, jdEndif)
|
||||
|
||||
proc doElif(L: var TLexer, tok: PToken) =
|
||||
var res: bool
|
||||
if high(condStack) < 0: lexMessage(L, errTokenExpected, "@if")
|
||||
res = EvalppIf(L, tok)
|
||||
if condStack[high(condStack)] or not res: jumpToDirective(L, tok, jdElseEndif)
|
||||
else: condStack[high(condStack)] = true
|
||||
|
||||
proc jumpToDirective(L: var TLexer, tok: PToken, dest: TJumpDest) =
|
||||
var nestedIfs: int
|
||||
nestedIfs = 0
|
||||
while True:
|
||||
if (tok.ident != nil) and (tok.ident.s == "@"):
|
||||
ppGetTok(L, tok)
|
||||
case whichKeyword(tok.ident)
|
||||
of wIf:
|
||||
Inc(nestedIfs)
|
||||
of wElse:
|
||||
if (dest == jdElseEndif) and (nestedIfs == 0):
|
||||
doElse(L, tok)
|
||||
break
|
||||
of wElif:
|
||||
if (dest == jdElseEndif) and (nestedIfs == 0):
|
||||
doElif(L, tok)
|
||||
break
|
||||
of wEnd:
|
||||
if nestedIfs == 0:
|
||||
doEnd(L, tok)
|
||||
break
|
||||
if nestedIfs > 0: Dec(nestedIfs)
|
||||
else:
|
||||
nil
|
||||
ppGetTok(L, tok)
|
||||
elif tok.tokType == tkEof:
|
||||
lexMessage(L, errTokenExpected, "@end")
|
||||
else:
|
||||
ppGetTok(L, tok)
|
||||
|
||||
proc parseDirective(L: var TLexer, tok: PToken) =
|
||||
var
|
||||
res: bool
|
||||
key: string
|
||||
ppGetTok(L, tok) # skip @
|
||||
case whichKeyword(tok.ident)
|
||||
of wIf:
|
||||
setlen(condStack, len(condStack) + 1)
|
||||
res = EvalppIf(L, tok)
|
||||
condStack[high(condStack)] = res
|
||||
if not res:
|
||||
jumpToDirective(L, tok, jdElseEndif)
|
||||
of wElif:
|
||||
doElif(L, tok)
|
||||
of wElse:
|
||||
doElse(L, tok)
|
||||
of wEnd:
|
||||
doEnd(L, tok)
|
||||
of wWrite:
|
||||
ppGetTok(L, tok)
|
||||
msgs.MsgWriteln(tokToStr(tok))
|
||||
ppGetTok(L, tok)
|
||||
of wPutEnv:
|
||||
ppGetTok(L, tok)
|
||||
key = tokToStr(tok)
|
||||
ppGetTok(L, tok)
|
||||
os.putEnv(key, tokToStr(tok))
|
||||
ppGetTok(L, tok)
|
||||
of wPrependEnv:
|
||||
ppGetTok(L, tok)
|
||||
key = tokToStr(tok)
|
||||
ppGetTok(L, tok)
|
||||
os.putEnv(key, tokToStr(tok) & os.getenv(key))
|
||||
ppGetTok(L, tok)
|
||||
of wAppendenv:
|
||||
ppGetTok(L, tok)
|
||||
key = tokToStr(tok)
|
||||
ppGetTok(L, tok)
|
||||
os.putEnv(key, os.getenv(key) & tokToStr(tok))
|
||||
ppGetTok(L, tok)
|
||||
else: lexMessage(L, errInvalidDirectiveX, tokToStr(tok))
|
||||
|
||||
proc confTok(L: var TLexer, tok: PToken) =
|
||||
ppGetTok(L, tok)
|
||||
while (tok.ident != nil) and (tok.ident.s == "@"):
|
||||
parseDirective(L, tok) # else: give the token to the parser
|
||||
|
||||
proc checkSymbol(L: TLexer, tok: PToken) =
|
||||
if not (tok.tokType in {tkSymbol..pred(tkIntLit), tkStrLit..tkTripleStrLit}):
|
||||
lexMessage(L, errIdentifierExpected, tokToStr(tok))
|
||||
|
||||
proc parseAssignment(L: var TLexer, tok: PToken) =
|
||||
var
|
||||
s, val: string
|
||||
info: TLineInfo
|
||||
if (tok.ident.id == getIdent("-").id) or (tok.ident.id == getIdent("--").id):
|
||||
confTok(L, tok) # skip unnecessary prefix
|
||||
info = getLineInfo(L) # safe for later in case of an error
|
||||
checkSymbol(L, tok)
|
||||
s = tokToStr(tok)
|
||||
confTok(L, tok) # skip symbol
|
||||
val = ""
|
||||
while tok.tokType == tkDot:
|
||||
add(s, '.')
|
||||
confTok(L, tok)
|
||||
checkSymbol(L, tok)
|
||||
add(s, tokToStr(tok))
|
||||
confTok(L, tok)
|
||||
if tok.tokType == tkBracketLe:
|
||||
# BUGFIX: val, not s!
|
||||
# BUGFIX: do not copy '['!
|
||||
confTok(L, tok)
|
||||
checkSymbol(L, tok)
|
||||
add(val, tokToStr(tok))
|
||||
confTok(L, tok)
|
||||
if tok.tokType == tkBracketRi: confTok(L, tok)
|
||||
else: lexMessage(L, errTokenExpected, "\']\'")
|
||||
add(val, ']')
|
||||
if (tok.tokType == tkColon) or (tok.tokType == tkEquals):
|
||||
if len(val) > 0:
|
||||
add(val, ':') # BUGFIX
|
||||
confTok(L, tok) # skip ':' or '='
|
||||
checkSymbol(L, tok)
|
||||
add(val, tokToStr(tok))
|
||||
confTok(L, tok) # skip symbol
|
||||
while (tok.ident != nil) and (tok.ident.id == getIdent("&").id):
|
||||
confTok(L, tok)
|
||||
checkSymbol(L, tok)
|
||||
add(val, tokToStr(tok))
|
||||
confTok(L, tok)
|
||||
processSwitch(s, val, passPP, info)
|
||||
|
||||
proc readConfigFile(filename: string) =
|
||||
var
|
||||
L: TLexer
|
||||
tok: PToken
|
||||
stream: PLLStream
|
||||
new(tok)
|
||||
stream = LLStreamOpen(filename, fmRead)
|
||||
if stream != nil:
|
||||
openLexer(L, filename, stream)
|
||||
tok.tokType = tkEof # to avoid a pointless warning
|
||||
confTok(L, tok) # read in the first token
|
||||
while tok.tokType != tkEof: parseAssignment(L, tok)
|
||||
if len(condStack) > 0: lexMessage(L, errTokenExpected, "@end")
|
||||
closeLexer(L)
|
||||
if gVerbosity >= 1: rawMessage(hintConf, filename)
|
||||
|
||||
proc getConfigPath(filename: string): string =
|
||||
# try local configuration file:
|
||||
result = joinPath(getConfigDir(), filename)
|
||||
if not ExistsFile(result):
|
||||
# try standard configuration file (installation did not distribute files
|
||||
# the UNIX way)
|
||||
result = joinPath([getPrefixDir(), "config", filename])
|
||||
if not ExistsFile(result):
|
||||
result = "/etc/" & filename
|
||||
|
||||
proc LoadSpecialConfig(configfilename: string) =
|
||||
if not (optSkipConfigFile in gGlobalOptions):
|
||||
readConfigFile(getConfigPath(configfilename))
|
||||
|
||||
proc LoadConfig(project: string) =
|
||||
var conffile, prefix: string
|
||||
# set default value (can be overwritten):
|
||||
if libpath == "":
|
||||
# choose default libpath:
|
||||
prefix = getPrefixDir()
|
||||
if (prefix == "/usr"): libpath = "/usr/lib/nimrod"
|
||||
elif (prefix == "/usr/local"): libpath = "/usr/local/lib/nimrod"
|
||||
else: libpath = joinPath(prefix, "lib")
|
||||
LoadSpecialConfig("nimrod.cfg") # read project config file:
|
||||
if not (optSkipProjConfigFile in gGlobalOptions) and (project != ""):
|
||||
conffile = changeFileExt(project, "cfg")
|
||||
if existsFile(conffile): readConfigFile(conffile)
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue