summaryrefslogtreecommitdiff
path: root/cpp/src/Slice/Parser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/src/Slice/Parser.cpp')
-rw-r--r--cpp/src/Slice/Parser.cpp64
1 files changed, 64 insertions, 0 deletions
diff --git a/cpp/src/Slice/Parser.cpp b/cpp/src/Slice/Parser.cpp
index abdffefb7e1..b8980cec70e 100644
--- a/cpp/src/Slice/Parser.cpp
+++ b/cpp/src/Slice/Parser.cpp
@@ -9,6 +9,7 @@
#include <IceUtil/Functional.h>
#include <IceUtil/InputUtil.h>
+#include <IceUtil/FileUtil.h>
#include <IceUtil/StringUtil.h>
#include <IceUtil/Unicode.h>
#include <Slice/Parser.h>
@@ -19,6 +20,9 @@
#ifdef _WIN32
# include <io.h>
+#else
+# include <climits> // For PATH_MAX
+# include <unistd.h> // For readlink()
#endif
using namespace std;
@@ -5657,6 +5661,56 @@ Slice::Unit::nextLine()
_currentLine++;
}
+#ifndef _WIN32
+namespace
+{
+string
+readLink(const string& orig)
+{
+ string result = orig;
+ string::size_type beg = 0;
+ string::size_type next = string::npos;
+ do
+ {
+ string subpath;
+ next = result.find('/', beg + 1);
+ if(next == string::npos)
+ {
+ subpath = result;
+ }
+ else
+ {
+ subpath = result.substr(0, next);
+ }
+
+ char buf[PATH_MAX + 1];
+ int len = static_cast<int>(readlink(subpath.c_str(), buf, sizeof(buf)));
+ if(len > 0)
+ {
+ buf[len] = '\0';
+ string linkpath = buf;
+ if(!IceUtilInternal::isAbsolutePath(linkpath)) // Path relative to the location of the link
+ {
+ string::size_type pos = subpath.rfind('/');
+ assert(pos != string::npos);
+ linkpath = subpath.substr(0, pos + 1) + linkpath;
+ }
+ result = normalizePath(linkpath) + (next != string::npos ? result.substr(next) : string());
+ beg = 0;
+ next = 0;
+ }
+ else
+ {
+ beg = next;
+ }
+ }
+ while(next != string::npos);
+ return result;
+}
+
+}
+#endif
+
bool
Slice::Unit::scanPosition(const char* s)
{
@@ -5702,6 +5756,16 @@ Slice::Unit::scanPosition(const char* s)
LineType type = File;
+ //
+ // We need to compare the file targets as one could be a symbolic link.
+ //
+#ifndef _WIN32
+ if(readLink(currentFile) == readLink(_topLevelFile))
+ {
+ currentFile = _topLevelFile;
+ }
+#endif
+
if(_currentLine == 0)
{
if(_currentIncludeLevel > 0 || currentFile != _topLevelFile)