diff options
author | Araq <rumpf_a@web.de> | 2011-04-12 01:13:42 +0200 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2011-04-12 01:13:42 +0200 |
commit | cd292568d775d55d9abb51e962882ecda12c03a9 (patch) | |
tree | 85451f0e1f17dc0463350915f12bdd0a82a73455 /nim/nimconf.pas | |
parent | 46c41e43690cba9bc1caff6a994bb6915df8a1b7 (diff) | |
download | Nim-cd292568d775d55d9abb51e962882ecda12c03a9.tar.gz |
big repo cleanup
Diffstat (limited to 'nim/nimconf.pas')
-rwxr-xr-x | nim/nimconf.pas | 361 |
1 files changed, 0 insertions, 361 deletions
diff --git a/nim/nimconf.pas b/nim/nimconf.pas deleted file mode 100755 index 69c6f7618..000000000 --- a/nim/nimconf.pas +++ /dev/null @@ -1,361 +0,0 @@ -// -// -// The Nimrod Compiler -// (c) Copyright 2008 Andreas Rumpf -// -// See the file "copying.txt", included in this -// distribution, for details about the copyright. -// - -unit nimconf; - -// This module handles the reading of the config file. -{$include 'config.inc'} - -interface - -uses - nsystem, llstream, nversion, commands, nos, strutils, msgs, platform, - condsyms, scanner, options, idents, wordrecg; - -procedure LoadConfig(const project: string); - -procedure LoadSpecialConfig(const configfilename: string); - -implementation - - -// ---------------- configuration file parser ----------------------------- -// we use Nimrod's scanner here to safe space and work - -procedure ppGetTok(var L: TLexer; tok: PToken); -begin - // simple filter - rawGetTok(L, tok^); - while (tok.tokType = tkInd) or (tok.tokType = tkSad) - or (tok.tokType = tkDed) or (tok.tokType = tkComment) do - rawGetTok(L, tok^) -end; - -// simple preprocessor: -function parseExpr(var L: TLexer; tok: PToken): bool; forward; - -function parseAtom(var L: TLexer; tok: PToken): bool; -begin - if tok.tokType = tkParLe then begin - ppGetTok(L, tok); - result := parseExpr(L, tok); - if tok.tokType = tkParRi then ppGetTok(L, tok) - else lexMessage(L, errTokenExpected, ''')''') - end - else if tok.ident.id = ord(wNot) then begin - ppGetTok(L, tok); - result := not parseAtom(L, tok) - end - else begin - result := isDefined(tok.ident); - //condsyms.listSymbols(); - //writeln(tok.ident.s + ' has the value: ', result); - ppGetTok(L, tok) - end; -end; - -function parseAndExpr(var L: TLexer; tok: PToken): bool; -var - b: bool; -begin - result := parseAtom(L, tok); - while tok.ident.id = ord(wAnd) do begin - ppGetTok(L, tok); // skip "and" - b := parseAtom(L, tok); - result := result and b; - end -end; - -function parseExpr(var L: TLexer; tok: PToken): bool; -var - b: bool; -begin - result := parseAndExpr(L, tok); - while tok.ident.id = ord(wOr) do begin - ppGetTok(L, tok); // skip "or" - b := parseAndExpr(L, tok); - result := result or b; - end -end; - -function EvalppIf(var L: TLexer; tok: PToken): bool; -begin - ppGetTok(L, tok); // skip 'if' or 'elif' - result := parseExpr(L, tok); - if tok.tokType = tkColon then ppGetTok(L, tok) - else lexMessage(L, errTokenExpected, ''':''') -end; - -var - condStack: array of bool; - -{@emit - condStack := @[]; -} - -procedure doEnd(var L: TLexer; tok: PToken); -begin - if high(condStack) < 0 then lexMessage(L, errTokenExpected, '@if'); - ppGetTok(L, tok); // skip 'end' - setLength(condStack, high(condStack)) -end; - -type - TJumpDest = (jdEndif, jdElseEndif); - -procedure jumpToDirective(var L: TLexer; tok: PToken; dest: TJumpDest); forward; - -procedure doElse(var L: TLexer; tok: PToken); -begin - if high(condStack) < 0 then - lexMessage(L, errTokenExpected, '@if'); - ppGetTok(L, tok); - if tok.tokType = tkColon then ppGetTok(L, tok); - if condStack[high(condStack)] then - jumpToDirective(L, tok, jdEndif) -end; - -procedure doElif(var L: TLexer; tok: PToken); -var - res: bool; -begin - if high(condStack) < 0 then - lexMessage(L, errTokenExpected, '@if'); - res := EvalppIf(L, tok); - if condStack[high(condStack)] or not res then - jumpToDirective(L, tok, jdElseEndif) - else - condStack[high(condStack)] := true -end; - -procedure jumpToDirective(var L: TLexer; tok: PToken; dest: TJumpDest); -var - nestedIfs: int; -begin - nestedIfs := 0; - while True do begin - if (tok.ident <> nil) and (tok.ident.s = '@'+'') then begin - ppGetTok(L, tok); - case whichKeyword(tok.ident) of - wIf: Inc(nestedIfs); - wElse: begin - if (dest = jdElseEndif) and (nestedIfs = 0) then begin - doElse(L, tok); - break - end - end; - wElif: begin - if (dest = jdElseEndif) and (nestedIfs = 0) then begin - doElif(L, tok); - break - end - end; - wEnd: begin - if nestedIfs = 0 then begin - doEnd(L, tok); - break - end; - if nestedIfs > 0 then Dec(nestedIfs) - end; - else begin end; - end; - ppGetTok(L, tok) - end - else if tok.tokType = tkEof then - lexMessage(L, errTokenExpected, '@end') - else - ppGetTok(L, tok) - end -end; - -procedure parseDirective(var L: TLexer; tok: PToken); -var - res: bool; - key: string; -begin - ppGetTok(L, tok); // skip @ - case whichKeyword(tok.ident) of - wIf: begin - setLength(condStack, length(condStack)+1); - res := EvalppIf(L, tok); - condStack[high(condStack)] := res; - if not res then // jump to "else", "elif" or "endif" - jumpToDirective(L, tok, jdElseEndif) - end; - wElif: doElif(L, tok); - wElse: doElse(L, tok); - wEnd: doEnd(L, tok); - wWrite: begin - ppGetTok(L, tok); - msgs.MessageOut(tokToStr(tok)); - ppGetTok(L, tok) - end; - wPutEnv: begin - ppGetTok(L, tok); - key := tokToStr(tok); - ppGetTok(L, tok); - nos.putEnv(key, tokToStr(tok)); - ppGetTok(L, tok) - end; - wPrependEnv: begin - ppGetTok(L, tok); - key := tokToStr(tok); - ppGetTok(L, tok); - nos.putEnv(key, tokToStr(tok) +{&} nos.getenv(key)); - ppGetTok(L, tok) - end; - wAppendenv: begin - ppGetTok(L, tok); - key := tokToStr(tok); - ppGetTok(L, tok); - nos.putEnv(key, nos.getenv(key) +{&} tokToStr(tok)); - ppGetTok(L, tok) - end - else - lexMessage(L, errInvalidDirectiveX, tokToStr(tok)) - end -end; - -procedure confTok(var L: TLexer; tok: PToken); -begin - ppGetTok(L, tok); - while (tok.ident <> nil) and (tok.ident.s = '@'+'') do - parseDirective(L, tok) - // else: give the token to the parser -end; - -// ----------- end of preprocessor ---------------------------------------- - -procedure checkSymbol(const L: TLexer; tok: PToken); -begin - if not (tok.tokType in [tkSymbol..pred(tkIntLit), - tkStrLit..tkTripleStrLit]) then - lexMessage(L, errIdentifierExpected, tokToStr(tok)) -end; - -procedure parseAssignment(var L: TLexer; tok: PToken); -var - s, val: string; - info: TLineInfo; -begin - if (tok.ident.id = getIdent('-'+'').id) - or (tok.ident.id = getIdent('--').id) then - 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 do begin - addChar(s, '.'); - confTok(L, tok); - checkSymbol(L, tok); - add(s, tokToStr(tok)); - confTok(L, tok) - end; - if tok.tokType = tkBracketLe then begin - // 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 then confTok(L, tok) - else lexMessage(L, errTokenExpected, ''']'''); - addChar(val, ']'); - end; - if (tok.tokType = tkColon) or (tok.tokType = tkEquals) then begin - if length(val) > 0 then addChar(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) do begin - confTok(L, tok); - checkSymbol(L, tok); - add(val, tokToStr(tok)); - confTok(L, tok) - end - end; - processSwitch(s, val, passPP, info) -end; - -procedure readConfigFile(const filename: string); -var - L: TLexer; - tok: PToken; - stream: PLLStream; -begin - new(tok); -{@ignore} - fillChar(tok^, sizeof(tok^), 0); - fillChar(L, sizeof(L), 0); -{@emit} - stream := LLStreamOpen(filename, fmRead); - if stream <> nil then begin - openLexer(L, filename, stream); - tok.tokType := tkEof; // to avoid a pointless warning - confTok(L, tok); // read in the first token - while tok.tokType <> tkEof do - parseAssignment(L, tok); - if length(condStack) > 0 then - lexMessage(L, errTokenExpected, '@end'); - closeLexer(L); - if gVerbosity >= 1 then rawMessage(hintConf, filename); - end -end; - -// ------------------------------------------------------------------------ - -function getConfigPath(const filename: string): string; -begin - // try local configuration file: - result := joinPath(getConfigDir(), filename); - if not ExistsFile(result) then begin - // try standard configuration file (installation did not distribute files - // the UNIX way) - result := joinPath([getPrefixDir(), 'config', filename]); - if not ExistsFile(result) then begin - result := '/etc/' +{&} filename - end - end -end; - -procedure LoadSpecialConfig(const configfilename: string); -begin - if not (optSkipConfigFile in gGlobalOptions) then - readConfigFile(getConfigPath(configfilename)); -end; - -procedure LoadConfig(const project: string); -var - conffile, prefix: string; -begin - // set default value (can be overwritten): - if libpath = '' then begin - // choose default libpath: - prefix := getPrefixDir(); - if (prefix = '/usr') then - libpath := '/usr/lib/nimrod' - else if (prefix = '/usr/local') then - libpath := '/usr/local/lib/nimrod' - else - libpath := joinPath(prefix, 'lib') - end; - // read default config file: - LoadSpecialConfig('nimrod.cfg'); - // read project config file: - if not (optSkipProjConfigFile in gGlobalOptions) and (project <> '') then begin - conffile := changeFileExt(project, 'cfg'); - if existsFile(conffile) then - readConfigFile(conffile) - end -end; - -end. |