summaryrefslogtreecommitdiff
path: root/cpp/src/slice2cpp/Gen.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/src/slice2cpp/Gen.cpp')
-rw-r--r--cpp/src/slice2cpp/Gen.cpp194
1 files changed, 135 insertions, 59 deletions
diff --git a/cpp/src/slice2cpp/Gen.cpp b/cpp/src/slice2cpp/Gen.cpp
index 8f73cf9a373..21345c09093 100644
--- a/cpp/src/slice2cpp/Gen.cpp
+++ b/cpp/src/slice2cpp/Gen.cpp
@@ -7,15 +7,22 @@
//
// **********************************************************************
+#include <IceUtil/DisableWarnings.h>
#include <Gen.h>
#include <Slice/Util.h>
#include <Slice/CPlusPlusUtil.h>
#include <IceUtil/Functional.h>
#include <IceUtil/Iterator.h>
#include <Slice/Checksum.h>
+#include <Slice/FileTracker.h>
+#include <Slice/Preprocessor.h>
#include <limits>
+
#include <sys/stat.h>
+#include <string.h>
+
+#include <iostream> //TODO
using namespace std;
using namespace Slice;
@@ -34,17 +41,19 @@ getDeprecateSymbol(const ContainedPtr& p1, const ContainedPtr& p2)
return deprecateSymbol;
}
-Slice::Gen::Gen(const string& name, const string& base, const string& headerExtension,
- const string& sourceExtension, const vector<string>& extraHeaders, const string& include,
+Slice::Gen::Gen(const string& base, const string& headerExtension, const string& sourceExtension,
+ const vector<string>& extraHeaders, const string& include,
const vector<string>& includePaths, const string& dllExport, const string& dir,
bool imp, bool checksum, bool stream, bool ice) :
_base(base),
_headerExtension(headerExtension),
+ _implHeaderExtension(headerExtension),
_sourceExtension(sourceExtension),
_extraHeaders(extraHeaders),
_include(include),
_includePaths(includePaths),
_dllExport(dllExport),
+ _dir(dir),
_impl(imp),
_checksum(checksum),
_stream(stream),
@@ -60,42 +69,74 @@ Slice::Gen::Gen(const string& name, const string& base, const string& headerExte
{
_base.erase(0, pos + 1);
}
+}
+
+Slice::Gen::~Gen()
+{
+ H << "\n\n#endif\n";
+ C << '\n';
+
+ if(_impl)
+ {
+ implH << "\n\n#endif\n";
+ implC << '\n';
+ }
+}
+
+void
+Slice::Gen::generate(const UnitPtr& p)
+{
+
+ //
+ // Check the header-ext global meta data if is not empty we override _headerExtension
+ //
+ string headerExtension = getHeaderExt(p->modules());
+ if(!headerExtension.empty())
+ {
+ _headerExtension = headerExtension;
+ }
if(_impl)
{
- string fileImplH = _base + "I." + _headerExtension;
+ string fileImplH = _base + "I." + _implHeaderExtension;
string fileImplC = _base + "I." + _sourceExtension;
- if(!dir.empty())
+ if(!_dir.empty())
{
- fileImplH = dir + '/' + fileImplH;
- fileImplC = dir + '/' + fileImplC;
+ fileImplH = _dir + '/' + fileImplH;
+ fileImplC = _dir + '/' + fileImplC;
}
struct stat st;
if(stat(fileImplH.c_str(), &st) == 0)
{
- cerr << name << ": `" << fileImplH << "' already exists - will not overwrite" << endl;
- return;
+ ostringstream os;
+ os << fileImplH << "' already exists - will not overwrite";
+ throw FileException(__FILE__, __LINE__, os.str());
}
if(stat(fileImplC.c_str(), &st) == 0)
{
- cerr << name << ": `" << fileImplC << "' already exists - will not overwrite" << endl;
- return;
+ ostringstream os;
+ os << fileImplC << "' already exists - will not overwrite";
+ throw FileException(__FILE__, __LINE__, os.str());
}
implH.open(fileImplH.c_str());
if(!implH)
{
- cerr << name << ": can't open `" << fileImplH << "' for writing" << endl;
- return;
+ ostringstream os;
+ os << "cannot open `" << fileImplH << "': " << strerror(errno);
+ throw FileException(__FILE__, __LINE__, os.str());
}
+ FileTracker::instance()->addFile(fileImplH);
implC.open(fileImplC.c_str());
if(!implC)
{
- cerr << name << ": can't open `" << fileImplC << "' for writing" << endl;
- return;
+ ostringstream os;
+ os << "cannot open `" << fileImplC << "': " << strerror(errno);
+ throw FileException(__FILE__, __LINE__, os.str());
}
+ FileTracker::instance()->addFile(fileImplC);
string s = fileImplH;
if(_include.size())
@@ -110,25 +151,29 @@ Slice::Gen::Gen(const string& name, const string& base, const string& headerExte
string fileH = _base + "." + _headerExtension;
string fileC = _base + "." + _sourceExtension;
- if(!dir.empty())
+ if(!_dir.empty())
{
- fileH = dir + '/' + fileH;
- fileC = dir + '/' + fileC;
+ fileH = _dir + '/' + fileH;
+ fileC = _dir + '/' + fileC;
}
H.open(fileH.c_str());
if(!H)
{
- cerr << name << ": can't open `" << fileH << "' for writing" << endl;
- return;
+ ostringstream os;
+ os << "cannot open `" << fileH << "': " << strerror(errno);
+ throw FileException(__FILE__, __LINE__, os.str());
}
+ FileTracker::instance()->addFile(fileH);
C.open(fileC.c_str());
if(!C)
{
- cerr << name << ": can't open `" << fileC << "' for writing" << endl;
- return;
+ ostringstream os;
+ os << "cannot open `" << fileC << "': " << strerror(errno);
+ throw FileException(__FILE__, __LINE__, os.str());
}
+ FileTracker::instance()->addFile(fileC);
printHeader(H);
printHeader(C);
@@ -144,37 +189,7 @@ Slice::Gen::Gen(const string& name, const string& base, const string& headerExte
H << "\n#ifndef __" << s << "__";
H << "\n#define __" << s << "__";
H << '\n';
-}
-
-Slice::Gen::~Gen()
-{
- H << "\n\n#endif\n";
- C << '\n';
- if(_impl)
- {
- implH << "\n\n#endif\n";
- implC << '\n';
- }
-}
-
-bool
-Slice::Gen::operator!() const
-{
- if(!H || !C)
- {
- return true;
- }
- if(_impl && (!implH || !implC))
- {
- return true;
- }
- return false;
-}
-
-void
-Slice::Gen::generate(const UnitPtr& p)
-{
validateMetaData(p);
writeExtraHeaders(C);
@@ -193,6 +208,7 @@ Slice::Gen::generate(const UnitPtr& p)
}
C << _base << "." << _headerExtension << ">";
+
H << "\n#include <Ice/LocalObjectF.h>";
H << "\n#include <Ice/ProxyF.h>";
H << "\n#include <Ice/ObjectF.h>";
@@ -224,6 +240,7 @@ Slice::Gen::generate(const UnitPtr& p)
}
else if(p->hasNonLocalClassDecls())
{
+
H << "\n#include <Ice/Object.h>";
}
@@ -274,7 +291,12 @@ Slice::Gen::generate(const UnitPtr& p)
for(StringList::const_iterator q = includes.begin(); q != includes.end(); ++q)
{
- H << "\n#include <" << changeInclude(*q, _includePaths) << "." << _headerExtension << ">";
+ string extension = getHeaderExt((*q), p->modules());
+ if(extension.empty())
+ {
+ extension = _headerExtension;
+ }
+ H << "\n#include <" << changeInclude(*q, _includePaths) << "." << extension << ">";
}
H << "\n#include <Ice/UndefSysMacros.h>";
@@ -339,7 +361,7 @@ Slice::Gen::generate(const UnitPtr& p)
{
implH << _include << '/';
}
- implH << _base << ".h>";
+ implH << _base << "." << _headerExtension << ">";
writeExtraHeaders(implC);
@@ -348,7 +370,7 @@ Slice::Gen::generate(const UnitPtr& p)
{
implC << _include << '/';
}
- implC << _base << "I.h>";
+ implC << _base << "I." << _implHeaderExtension << ">";
ImplVisitor implVisitor(implH, implC, _dllExport);
p->visit(&implVisitor, false);
@@ -3835,7 +3857,7 @@ Slice::Gen::ObjectVisitor::visitClassDefEnd(const ClassDefPtr& p)
H << sp << nl << scoped << " _init;";
H << eb << ';';
_doneStaticSymbol = true;
- H << sp << nl << "static " << scoped << "__staticInit _" << p->name() << "_init;";
+ H << sp << nl << "static " << p->name() << "__staticInit _" << p->name() << "_init;";
}
if(p->isLocal())
@@ -5641,6 +5663,8 @@ Slice::Gen::MetaDataVisitor::visitModuleStart(const ModulePtr& p)
StringList globalMetaData = dc->getMetaData();
string file = dc->filename();
static const string prefix = "cpp:";
+
+ int headerExtension = 0;
for(StringList::const_iterator q = globalMetaData.begin(); q != globalMetaData.end(); ++q)
{
string s = *q;
@@ -5653,7 +5677,15 @@ Slice::Gen::MetaDataVisitor::visitModuleStart(const ModulePtr& p)
{
continue;
}
- cout << file << ": warning: ignoring invalid global metadata `" << s << "'" << endl;
+ else if(ss.find("header-ext:") == 0)
+ {
+ headerExtension++;
+ if(headerExtension == 1)
+ {
+ continue;
+ }
+ }
+ cerr << file << ": warning: ignoring invalid global metadata `" << s << "', the cpp:header-ext global metadata can only appear once per file." << endl;
}
_history.insert(s);
}
@@ -5724,7 +5756,7 @@ Slice::Gen::MetaDataVisitor::visitOperation(const OperationPtr& p)
{
if(!cl->isLocal())
{
- cout << p->definitionContext()->filename() << ":" << p->line()
+ cerr << p->definitionContext()->filename() << ":" << p->line()
<< ": warning: metadata directive `UserException' applies only to local operations "
<< "but enclosing " << (cl->isInterface() ? "interface" : "class") << "`" << cl->name()
<< "' is not local" << endl;
@@ -5743,7 +5775,7 @@ Slice::Gen::MetaDataVisitor::visitOperation(const OperationPtr& p)
{
if(q->find("cpp:type:", 0) == 0 || q->find("cpp:array", 0) == 0 || q->find("cpp:range", 0) == 0)
{
- cout << p->definitionContext()->filename() << ":" << p->line()
+ cerr << p->definitionContext()->filename() << ":" << p->line()
<< ": warning: invalid metadata for operation" << endl;
break;
}
@@ -5836,7 +5868,7 @@ Slice::Gen::MetaDataVisitor::validate(const SyntaxTreeBasePtr& cont, const Strin
continue;
}
- cout << file << ":" << line << ": warning: ignoring invalid metadata `" << s << "'" << endl;
+ cerr << file << ":" << line << ": warning: ignoring invalid metadata `" << s << "'" << endl;
}
_history.insert(s);
}
@@ -5866,3 +5898,47 @@ Slice::Gen::resetUseWstring(list<bool>& hist)
hist.pop_back();
return use;
}
+
+string
+Slice::Gen::getHeaderExt(const string& file, const ModuleList& modules)
+{
+ string ext = "";
+ if(!modules.empty()) // Just in case the Slice file has no definitions
+ {
+ for(ModuleList::const_iterator i = modules.begin(); i != modules.end(); ++i)
+ {
+ if((*i)->definitionContext()->filename() == file)
+ {
+ string meta = (*i)->definitionContext()->findMetaData("cpp:header-ext");
+ string::size_type index = meta.find_last_of(":");
+ if(index != string::npos && index + 1 < meta.size())
+ {
+ ext = meta.substr(index + 1, meta.size() - index - 1);
+ }
+ }
+ }
+ }
+ return ext;
+}
+
+string
+Slice::Gen::getHeaderExt(const ModuleList& modules)
+{
+ string ext = "";
+ if(!modules.empty()) // Just in case the Slice file has no definitions
+ {
+ for(ModuleList::const_iterator i = modules.begin(); i != modules.end(); ++i)
+ {
+ if((*i)->definitionContext()->includeLevel() == 0)
+ {
+ string meta = (*i)->definitionContext()->findMetaData("cpp:header-ext");
+ string::size_type index = meta.find_last_of(":");
+ if(index != string::npos && index + 1 < meta.size())
+ {
+ ext = meta.substr(index + 1, meta.size() - index - 1);
+ }
+ }
+ }
+ }
+ return ext;
+}