summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/cgen.nim15
-rw-r--r--compiler/importer.nim2
-rw-r--r--compiler/nversion.nim2
-rw-r--r--compiler/options.nim13
-rw-r--r--compiler/rodread.nim14
-rw-r--r--compiler/rodwrite.nim9
-rw-r--r--doc/nimrodc.txt3
-rw-r--r--tests/manyloc/packages/noconflicts.nim16
-rw-r--r--tests/manyloc/packages/noconflicts.nimrod.cfg1
-rw-r--r--tests/manyloc/packages/os.nim5
-rw-r--r--tests/manyloc/packages/package1/strutils.nim5
-rw-r--r--tests/manyloc/packages/package2/strutils.nim5
-rw-r--r--todo.txt2
13 files changed, 74 insertions, 18 deletions
diff --git a/compiler/cgen.nim b/compiler/cgen.nim
index c82c3887c..d61d3055e 100644
--- a/compiler/cgen.nim
+++ b/compiler/cgen.nim
@@ -992,12 +992,15 @@ proc genMainProc(m: BModule) =
         gBreakpoints, mainModInit, toRope(m.labels)])
   if optNoMain notin gGlobalOptions:
     appcg(m, m.s[cfsProcs], otherMain, [])
-  
-proc getInitName(m: PSym): PRope = 
-  result = ropeff("$1Init", "@$1Init", [toRope(m.name.s)])
 
-proc getDatInitName(m: PSym): PRope =
-  result = ropeff("$1DatInit", "@$1DatInit", [toRope(m.name.s)])
+proc getSomeInitName(m: PSym, suffix: string): PRope =
+  if {sfSystemModule, sfMainModule} * m.flags == {}:
+    result = m.info.toFullPath.getPackageName.mangle.toRope
+  result.app m.name.s
+  result.app suffix
+  
+proc getInitName(m: PSym): PRope = getSomeInitName(m, "Init")
+proc getDatInitName(m: PSym): PRope = getSomeInitName(m, "DatInit")
 
 proc registerModuleToMain(m: PSym) = 
   var
@@ -1167,7 +1170,7 @@ proc resetCgenModules* =
   for m in cgenModules(): resetModule(m)
 
 proc rawNewModule(module: PSym): BModule =
-  result = rawNewModule(module, module.filename)
+  result = rawNewModule(module, module.position.int32.toFullPath)
 
 proc newModule(module: PSym): BModule =
   # we should create only one cgen module for each module sym
diff --git a/compiler/importer.nim b/compiler/importer.nim
index 54ffb1947..8b854bcc6 100644
--- a/compiler/importer.nim
+++ b/compiler/importer.nim
@@ -48,7 +48,7 @@ proc getModuleName*(n: PNode): string =
 proc checkModuleName*(n: PNode): int32 =
   # This returns the full canonical path for a given module import
   let modulename = n.getModuleName
-  let fullPath = findModule(modulename)
+  let fullPath = findModule(modulename, n.info.toFullPath)
   if fullPath.len == 0:
     LocalError(n.info, errCannotOpenFile, modulename)
     result = InvalidFileIDX
diff --git a/compiler/nversion.nim b/compiler/nversion.nim
index 498f418ab..db38354ce 100644
--- a/compiler/nversion.nim
+++ b/compiler/nversion.nim
@@ -18,5 +18,5 @@ const
   VersionPatch* = 3
   VersionAsString* = $VersionMajor & "." & $VersionMinor & "." & $VersionPatch
 
-  RodFileVersion* = "1212"       # modify this if the rod-format changes!
+  RodFileVersion* = "1214"       # modify this if the rod-format changes!
 
diff --git a/compiler/options.nim b/compiler/options.nim
index 2b607a48b..bd6bc1a09 100644
--- a/compiler/options.nim
+++ b/compiler/options.nim
@@ -209,7 +209,7 @@ proc getGeneratedPath: string =
   result = if nimcacheDir.len > 0: nimcacheDir else: gProjectPath.shortenDir /
                                                          genSubDir
 
-proc getPackageName(path: string): string =
+proc getPackageName*(path: string): string =
   var q = 1
   var b = 0
   if path[len(path)-1] in {dirsep, altsep}: q = 2
@@ -221,10 +221,11 @@ proc getPackageName(path: string): string =
         case x.normalize
         of "lib", "src", "source", "package", "pckg", "library": b = i
         else: return x
+  result = ""
 
 proc withPackageName*(path: string): string =
   let x = path.getPackageName
-  if x.isNil:
+  if x.len == 0:
     result = path
   else:
     let (p, file, ext) = path.splitFile
@@ -282,9 +283,13 @@ proc FindFile*(f: string): string {.procvar.} =
       if result.len == 0:
         result = f.toLower.rawFindFile2
 
-proc findModule*(modulename: string): string {.inline.} =
+proc findModule*(modulename, currentModule: string): string =
   # returns path to module
-  result = FindFile(AddFileExt(modulename, nimExt))
+  let m = addFileExt(modulename, nimExt)
+  let currentPath = currentModule.splitFile.dir
+  result = currentPath / m
+  if not existsFile(result):
+    result = FindFile(m)
 
 proc libCandidates*(s: string, dest: var seq[string]) = 
   var le = strutils.find(s, '(')
diff --git a/compiler/rodread.nim b/compiler/rodread.nim
index a2ec2b4af..6e6b83260 100644
--- a/compiler/rodread.nim
+++ b/compiler/rodread.nim
@@ -140,6 +140,7 @@ type
     memfile: TMemFile    # unfortunately there is no point in time where we
                          # can close this! XXX
     methods*: TSymSeq
+    origFile: string
     inViewMode: bool
   
   PRodReader* = ref TRodReader
@@ -558,6 +559,9 @@ proc processRodFile(r: PRodReader, crc: TCrc32) =
       inc(r.pos)              # skip ':'
       r.moduleID = decodeVInt(r.s, r.pos)
       setID(r.moduleID)
+    of "ORIGFILE":
+      inc(r.pos)
+      r.origFile = decodeStr(r.s, r.pos)
     of "OPTIONS": 
       inc(r.pos)              # skip ':'
       r.options = cast[TOptions](int32(decodeVInt(r.s, r.pos)))
@@ -585,7 +589,7 @@ proc processRodFile(r: PRodReader, crc: TCrc32) =
       inc(r.line)
       while r.s[r.pos] != ')':
         let relativePath = decodeStr(r.s, r.pos)
-        let resolvedPath = relativePath.findModule
+        let resolvedPath = relativePath.findModule(r.origFile)
         let finalPath = if resolvedPath.len > 0: resolvedPath else: relativePath
         r.files.add(finalPath.fileInfoIdx)
         inc(r.pos)            # skip #10
@@ -1036,6 +1040,10 @@ proc viewFile(rodfile: string) =
       r.moduleID = decodeVInt(r.s, r.pos)
       setID(r.moduleID)
       outf.writeln("ID:", $r.moduleID)
+    of "ORIGFILE":
+      inc(r.pos)
+      r.origFile = decodeStr(r.s, r.pos)
+      outf.writeln("ORIGFILE:", r.origFile)
     of "OPTIONS":
       inc(r.pos)              # skip ':'
       r.options = cast[TOptions](int32(decodeVInt(r.s, r.pos)))
@@ -1058,13 +1066,13 @@ proc viewFile(rodfile: string) =
         outf.write(" ", w)
         if r.s[r.pos] == ' ': inc(r.pos)
       outf.write("\n")
-    of "FILES": 
+    of "FILES":
       inc(r.pos, 2)           # skip "(\10"
       inc(r.line)
       outf.write("FILES(\n")
       while r.s[r.pos] != ')':
         let relativePath = decodeStr(r.s, r.pos)
-        let resolvedPath = relativePath.findModule
+        let resolvedPath = relativePath.findModule(r.origFile)
         let finalPath = if resolvedPath.len > 0: resolvedPath else: relativePath
         r.files.add(finalPath.fileInfoIdx)
         inc(r.pos)            # skip #10
diff --git a/compiler/rodwrite.nim b/compiler/rodwrite.nim
index 34e890fd9..2e52aeaa7 100644
--- a/compiler/rodwrite.nim
+++ b/compiler/rodwrite.nim
@@ -34,6 +34,7 @@ type
     sstack: TSymSeq          # a stack of symbols to process
     tstack: TTypeSeq         # a stack of types to process
     files: TStringSeq
+    origFile: string
 
   PRodWriter = ref TRodWriter
 
@@ -81,6 +82,7 @@ proc newRodWriter(crc: TCrc32, module: PSym): PRodWriter =
   result.converters = ""
   result.methods = ""
   result.init = ""
+  result.origFile = module.info.toFilename
   result.data = newStringOfCap(12_000)
   
 proc addModDep(w: PRodWriter, dep: string) =
@@ -91,7 +93,7 @@ const
   rodNL = "\x0A"
 
 proc addInclDep(w: PRodWriter, dep: string) =
-  var resolved = dep.findModule
+  var resolved = dep.findModule(w.module.info.toFullPath)
   encodeVInt(fileIdx(w, dep), w.inclDeps)
   add(w.inclDeps, " ")
   encodeVInt(crcFromFile(resolved), w.inclDeps)
@@ -434,6 +436,11 @@ proc writeRod(w: PRodWriter) =
   encodeVInt(w.module.id, id)
   f.write(id)
   f.write(rodNL)
+
+  var orig = "ORIGFILE:"
+  encodeStr(w.origFile, orig)
+  f.write(orig)
+  f.write(rodNL)
   
   var crc = "CRC:"
   encodeVInt(w.crc, crc)
diff --git a/doc/nimrodc.txt b/doc/nimrodc.txt
index 72ee78d68..d494a0922 100644
--- a/doc/nimrodc.txt
+++ b/doc/nimrodc.txt
@@ -134,7 +134,8 @@ directory structure looks like this::
 
 And ``main`` imports ``x``, ``foo/x`` is imported. If ``other`` imports ``x``
 then both ``$lib/x.nim`` and ``$lib/bar/x.nim`` match and so the compiler
-rejects it.
+should reject it. Currently however this check is not implemented and instead
+the first matching file is used.
 

 

 Generated C code directory

diff --git a/tests/manyloc/packages/noconflicts.nim b/tests/manyloc/packages/noconflicts.nim
new file mode 100644
index 000000000..2183d01a8
--- /dev/null
+++ b/tests/manyloc/packages/noconflicts.nim
@@ -0,0 +1,16 @@
+discard """
+  output: '''package1/strutils
+package2/strutils
+noconflicts
+new os.nim'''
+"""
+
+import package1/strutils as su1
+import package2.strutils as su2
+
+import os
+
+su1.foo()
+su2.foo()
+echo "noconflicts"
+yay()
diff --git a/tests/manyloc/packages/noconflicts.nimrod.cfg b/tests/manyloc/packages/noconflicts.nimrod.cfg
new file mode 100644
index 000000000..88974ab8c
--- /dev/null
+++ b/tests/manyloc/packages/noconflicts.nimrod.cfg
@@ -0,0 +1 @@
+# Mark noconflicts as project file
\ No newline at end of file
diff --git a/tests/manyloc/packages/os.nim b/tests/manyloc/packages/os.nim
new file mode 100644
index 000000000..8a59612f9
--- /dev/null
+++ b/tests/manyloc/packages/os.nim
@@ -0,0 +1,5 @@
+
+# Overrides lib/pure/os.nim
+
+proc yay* = echo "new os.nim"
+
diff --git a/tests/manyloc/packages/package1/strutils.nim b/tests/manyloc/packages/package1/strutils.nim
new file mode 100644
index 000000000..b283600ea
--- /dev/null
+++ b/tests/manyloc/packages/package1/strutils.nim
@@ -0,0 +1,5 @@
+
+# Overrides lib/pure/os.nim
+
+proc foo* = echo "package1/strutils"
+
diff --git a/tests/manyloc/packages/package2/strutils.nim b/tests/manyloc/packages/package2/strutils.nim
new file mode 100644
index 000000000..1fb4abd41
--- /dev/null
+++ b/tests/manyloc/packages/package2/strutils.nim
@@ -0,0 +1,5 @@
+
+# Overrides lib/pure/os.nim
+
+proc foo* = echo "package2/strutils"
+
diff --git a/todo.txt b/todo.txt
index ff015aae3..302a5eeaf 100644
--- a/todo.txt
+++ b/todo.txt
@@ -1,7 +1,7 @@
 version 0.9.4
 =============
 
-- change search path algorithm to care about packages
+- add the code from the talk to examples or run tests
 - new VM:
   - implement the glue to replace evals.nim
   - implement missing magics