summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2012-12-07 17:20:51 +0100
committerAraq <rumpf_a@web.de>2012-12-07 17:20:51 +0100
commit1dc362dcd4e4752fce4d81800d965da8381790c8 (patch)
treeb564b553a424672e937be48daa1107241293cb69 /compiler
parent05b05be9f8554adc3081b71eb378940cb75428fd (diff)
downloadNim-1dc362dcd4e4752fce4d81800d965da8381790c8.tar.gz
compiler support for babel
Diffstat (limited to 'compiler')
-rw-r--r--compiler/babelcmd.nim76
-rwxr-xr-xcompiler/commands.nim27
-rwxr-xr-xcompiler/lists.nim9
3 files changed, 93 insertions, 19 deletions
diff --git a/compiler/babelcmd.nim b/compiler/babelcmd.nim
new file mode 100644
index 000000000..99513e58b
--- /dev/null
+++ b/compiler/babelcmd.nim
@@ -0,0 +1,76 @@
+#
+#
+#           The Nimrod Compiler
+#        (c) Copyright 2012 Andreas Rumpf
+#
+#    See the file "copying.txt", included in this
+#    distribution, for details about the copyright.
+#
+
+## Implements some helper procs for Babel (Nimrod's package manager) support.
+
+import parseutils, strtabs, os, options, msgs, lists
+
+proc addPath*(path: string, info: TLineInfo) = 
+  if not contains(options.searchPaths, path): 
+    lists.PrependStr(options.searchPaths, path)
+
+proc versionSplitPos(s: string): int =
+  result = s.len-2
+  while result > 1 and s[result] in {'0'..'9', '.'}: dec result
+  if s[result] != '-': result = s.len
+
+const
+  latest = "head"
+
+proc `<.`(a, b: string): bool = 
+  # wether a has a smaller version than b:
+  if a == latest: return false
+  var i = 0
+  var j = 0
+  var verA = 0
+  var verB = 0
+  while true:
+    let ii = parseInt(a, verA, i)
+    let jj = parseInt(b, verB, j)
+    # if A has no number left, but B has, B is prefered:  0.8 vs 0.8.3
+    if ii <= 0 or jj <= 0: return jj > 0
+    if verA < verB: return true
+    elif verA > verB: return false
+    # else: same version number; continue:
+    inc i, ii
+    inc j, jj
+    if a[i] == '.': inc i
+    if b[j] == '.': inc j
+
+proc addPackage(packages: PStringTable, p: string) =
+  let x = versionSplitPos(p)
+  let name = p.subStr(0, x-1)
+  if x < p.len:
+    let version = p.subStr(x+1)
+    if packages[name] <. version:
+      packages[name] = version
+  else:
+    packages[name] = latest
+
+iterator chosen(packages: PStringTable): string =
+  for key, val in pairs(packages):
+    let res = if val == latest: key else: key & '-' & val
+    yield res
+
+proc addPathRec(dir: string, info: TLineInfo) =
+  var packages = newStringTable(modeStyleInsensitive)
+  var pos = dir.len-1
+  if dir[pos] in {DirSep, AltSep}: inc(pos)
+  for k,p in os.walkDir(dir):
+    if k == pcDir and p[pos] != '.':
+      addPackage(packages, p)
+
+  for p in packages.chosen:
+    if not contains(options.searchPaths, p):
+      Message(info, hintPath, p)
+      lists.PrependStr(options.searchPaths, p)
+
+proc babelPath*(path: string, info: TLineInfo) =
+  addPathRec(path, info)
+  addPath(path, info)
diff --git a/compiler/commands.nim b/compiler/commands.nim
index ad5f2b7e7..4a72e25f3 100755
--- a/compiler/commands.nim
+++ b/compiler/commands.nim
@@ -11,7 +11,7 @@
 
 import 
   os, msgs, options, nversion, condsyms, strutils, extccomp, platform, lists, 
-  wordrecg, parseutils
+  wordrecg, parseutils, babelcmd
 
 proc writeCommandLineUsage*()
 
@@ -193,19 +193,6 @@ proc processPath(path: string): string =
     "projectname", options.gProjectName,
     "projectpath", options.gProjectPath])
 
-proc addPath(path: string, info: TLineInfo) = 
-  if not contains(options.searchPaths, path): 
-    lists.PrependStr(options.searchPaths, path)
-
-proc addPathRec(dir: string, info: TLineInfo) =
-  var pos = dir.len-1
-  if dir[pos] in {DirSep, AltSep}: inc(pos)
-  for k,p in os.walkDir(dir):
-    if k == pcDir and p[pos] != '.':
-      if not contains(options.searchPaths, p): 
-        #Message(info, hintPath, p)
-        lists.PrependStr(options.searchPaths, p)
-
 proc track(arg: string, info: TLineInfo) = 
   var a = arg.split(',')
   if a.len != 3: LocalError(info, errTokenExpected, "FILE,LINE,COLUMN")
@@ -225,11 +212,15 @@ proc processSwitch(switch, arg: string, pass: TCmdlinePass, info: TLineInfo) =
   of "path", "p": 
     expectArg(switch, arg, pass, info)
     addPath(processPath(arg), info)
-  of "shallowpath":
+  of "babelpath":
+    if pass in {passCmd2, passPP}:
+      expectArg(switch, arg, pass, info)
+      let path = processPath(arg)
+      babelpath(path, info)
+  of "excludepath":
     expectArg(switch, arg, pass, info)
-    var path = processPath(arg)
-    addPathRec(path, info)
-    addPath(path, info)
+    let path = processPath(arg)
+    lists.ExcludeStr(options.searchPaths, path)
   of "nimcache":
     expectArg(switch, arg, pass, info)
     options.nimcacheDir = processPath(arg)
diff --git a/compiler/lists.nim b/compiler/lists.nim
index 1998581ce..9da4db177 100755
--- a/compiler/lists.nim
+++ b/compiler/lists.nim
@@ -89,7 +89,14 @@ proc Remove*(list: var TLinkedList, entry: PListEntry) =
     list.head = entry.next
   if entry.next != nil: entry.next.prev = entry.prev
   if entry.prev != nil: entry.prev.next = entry.next
-  
+
+proc ExcludeStr*(list: var TLinkedList, data: string) =
+  var it = list.head
+  while it != nil:
+    let nxt = it.next
+    if PStrEntry(it).data == data: remove(list, it)
+    it = nxt
+
 proc Find*(list: TLinkedList, fn: TCompareProc, closure: Pointer): PListEntry = 
   result = list.head
   while result != nil: