summaryrefslogtreecommitdiff
path: root/cpp/src/Slice/PythonUtil.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/src/Slice/PythonUtil.cpp')
-rw-r--r--cpp/src/Slice/PythonUtil.cpp81
1 files changed, 78 insertions, 3 deletions
diff --git a/cpp/src/Slice/PythonUtil.cpp b/cpp/src/Slice/PythonUtil.cpp
index ace5a9db9b1..92560601189 100644
--- a/cpp/src/Slice/PythonUtil.cpp
+++ b/cpp/src/Slice/PythonUtil.cpp
@@ -2850,6 +2850,78 @@ Slice::Python::CodeVisitor::writeDocstring(const OperationPtr& op, DocstringMode
_out << nl << "\"\"\"";
}
+string
+Slice::Python::getPackageDirectory(const string& file, const UnitPtr& unit)
+{
+ //
+ // file must be a fully-qualified path name.
+ //
+
+ //
+ // Check if the file contains the python:pkgdir global metadata.
+ //
+ DefinitionContextPtr dc = unit->findDefinitionContext(file);
+ assert(dc);
+ const string prefix = "python:pkgdir:";
+ string pkgdir = dc->findMetaData(prefix);
+ if(!pkgdir.empty())
+ {
+ //
+ // The metadata is present, so the generated file was placed in the specified directory.
+ //
+ pkgdir = pkgdir.substr(prefix.size());
+ assert(!pkgdir.empty()); // This situation should have been caught by MetaDataVisitor.
+ }
+ return pkgdir;
+}
+
+string
+Slice::Python::getImportFileName(const string& file, const UnitPtr& unit, const vector<string>& includePaths)
+{
+ //
+ // The file and includePaths arguments must be fully-qualified path names.
+ //
+
+ //
+ // Check if the file contains the python:pkgdir global metadata.
+ //
+ string pkgdir = getPackageDirectory(file, unit);
+ if(!pkgdir.empty())
+ {
+ //
+ // The metadata is present, so the generated file was placed in the specified directory.
+ //
+ vector<string> names;
+ IceUtilInternal::splitString(pkgdir, "/", names);
+ assert(!names.empty());
+ pkgdir = "";
+ for(vector<string>::iterator p = names.begin(); p != names.end(); ++p)
+ {
+ if(p != names.begin())
+ {
+ pkgdir += ".";
+ }
+ pkgdir += fixIdent(*p);
+ }
+ string::size_type pos = file.rfind('/');
+ assert(pos != string::npos);
+ string name = file.substr(pos + 1); // Get the name of the file without the leading path.
+ assert(!name.empty());
+ replace(name.begin(), name.end(), '.', '_'); // Convert .ice to _ice
+ return pkgdir + "." + name;
+ }
+ else
+ {
+ //
+ // The metadata is not present, so we transform the file name using the include paths (-I)
+ // given to the compiler.
+ //
+ string name = changeInclude(file, includePaths);
+ replace(name.begin(), name.end(), '/', '_');
+ return name + "_ice";
+ }
+}
+
void
Slice::Python::generate(const UnitPtr& un, bool all, bool checksum, const vector<string>& includePaths,
Output& out)
@@ -2871,9 +2943,7 @@ Slice::Python::generate(const UnitPtr& un, bool all, bool checksum, const vector
StringList includes = un->includeFiles();
for(StringList::const_iterator q = includes.begin(); q != includes.end(); ++q)
{
- string file = changeInclude(*q, paths);
- replace(file.begin(), file.end(), '/', '_');
- out << nl << "import " << file << "_ice";
+ out << nl << "import " << getImportFileName(*q, un, paths);
}
}
@@ -3028,6 +3098,11 @@ Slice::Python::MetaDataVisitor::visitUnitStart(const UnitPtr& p)
{
continue;
}
+ static const string pkgdirPrefix = "python:pkgdir:";
+ if(s.find(pkgdirPrefix) == 0 && s.size() > pkgdirPrefix.size())
+ {
+ continue;
+ }
dc->warning(InvalidMetaData, file, "", "ignoring invalid global metadata `" + s + "'");
globalMetaData.remove(s);