diff options
author | Joe George <joe@zeroc.com> | 2016-03-17 11:44:37 -0400 |
---|---|---|
committer | Joe George <joe@zeroc.com> | 2016-03-17 11:44:37 -0400 |
commit | db1006f76622d1dd995bc1e2c1fc761c6ac7d7c2 (patch) | |
tree | 3c05d7f841a1585360d0a6450748fd6dc26b050c /cpp/src | |
parent | fixing .gitignore in checksum test (diff) | |
parent | Update Ice Builder for Gradle version to 1.2.1 (diff) | |
download | ice-db1006f76622d1dd995bc1e2c1fc761c6ac7d7c2.tar.bz2 ice-db1006f76622d1dd995bc1e2c1fc761c6ac7d7c2.tar.xz ice-db1006f76622d1dd995bc1e2c1fc761c6ac7d7c2.zip |
Merge remote-tracking branch 'origin/3.6'
Diffstat (limited to 'cpp/src')
33 files changed, 803 insertions, 205 deletions
diff --git a/cpp/src/FreezeScript/.gitignore b/cpp/src/FreezeScript/.gitignore new file mode 100644 index 00000000000..720f44c7047 --- /dev/null +++ b/cpp/src/FreezeScript/.gitignore @@ -0,0 +1,5 @@ +// Generated by makegitignore.py + +// IMPORTANT: Do not edit this file -- any edits made here will be lost! +.depend +.depend diff --git a/cpp/src/Glacier2/.gitignore b/cpp/src/Glacier2/.gitignore index 7cc85ffc850..093e464bbf3 100644 --- a/cpp/src/Glacier2/.gitignore +++ b/cpp/src/Glacier2/.gitignore @@ -1,5 +1,7 @@ // Generated by makegitignore.py // IMPORTANT: Do not edit this file -- any edits made here will be lost! +.depend +.depend Instrumentation.cpp Instrumentation.h diff --git a/cpp/src/Glacier2CryptPermissionsVerifier/.gitignore b/cpp/src/Glacier2CryptPermissionsVerifier/.gitignore new file mode 100644 index 00000000000..720f44c7047 --- /dev/null +++ b/cpp/src/Glacier2CryptPermissionsVerifier/.gitignore @@ -0,0 +1,5 @@ +// Generated by makegitignore.py + +// IMPORTANT: Do not edit this file -- any edits made here will be lost! +.depend +.depend diff --git a/cpp/src/Glacier2Lib/.gitignore b/cpp/src/Glacier2Lib/.gitignore index f4cc829053e..95b4c5cf67d 100644 --- a/cpp/src/Glacier2Lib/.gitignore +++ b/cpp/src/Glacier2Lib/.gitignore @@ -1,6 +1,8 @@ // Generated by makegitignore.py // IMPORTANT: Do not edit this file -- any edits made here will be lost! +.depend +.depend Metrics.cpp PermissionsVerifierF.cpp PermissionsVerifier.cpp diff --git a/cpp/src/Ice/.gitignore b/cpp/src/Ice/.gitignore index 39ff616d0f3..0254d46a775 100644 --- a/cpp/src/Ice/.gitignore +++ b/cpp/src/Ice/.gitignore @@ -1,82 +1,84 @@ // Generated by makegitignore.py // IMPORTANT: Do not edit this file -- any edits made here will be lost! +.depend +.depend BuiltinSequences.cpp -CommunicatorF.cpp Communicator.cpp -ConnectionF.cpp +CommunicatorF.cpp Connection.cpp +ConnectionF.cpp Current.cpp Endpoint.cpp EndpointF.cpp EndpointTypes.cpp FacetMap.cpp Identity.cpp -ImplicitContextF.cpp ImplicitContext.cpp +ImplicitContextF.cpp +Instrumentation.cpp +InstrumentationF.cpp LocalException.cpp -LocatorF.cpp Locator.cpp -LoggerF.cpp +LocatorF.cpp Logger.cpp +LoggerF.cpp Metrics.cpp -ObjectAdapterF.cpp ObjectAdapter.cpp -ObjectFactoryF.cpp +ObjectAdapterF.cpp ObjectFactory.cpp -Instrumentation.cpp -InstrumentationF.cpp -PluginF.cpp +ObjectFactoryF.cpp Plugin.cpp -ProcessF.cpp +PluginF.cpp Process.cpp -PropertiesF.cpp -PropertiesAdmin.cpp +ProcessF.cpp Properties.cpp +PropertiesAdmin.cpp +PropertiesF.cpp RemoteLogger.cpp -RouterF.cpp Router.cpp -ServantLocatorF.cpp +RouterF.cpp ServantLocator.cpp +ServantLocatorF.cpp SliceChecksumDict.cpp ValueFactory.cpp Version.cpp BuiltinSequences.h -CommunicatorF.h Communicator.h -ConnectionF.h +CommunicatorF.h Connection.h +ConnectionF.h Current.h Endpoint.h EndpointF.h EndpointTypes.h FacetMap.h Identity.h -ImplicitContextF.h ImplicitContext.h +ImplicitContextF.h +Instrumentation.h +InstrumentationF.h LocalException.h -LocatorF.h Locator.h -LoggerF.h +LocatorF.h Logger.h +LoggerF.h Metrics.h -ObjectAdapterF.h ObjectAdapter.h -ObjectFactoryF.h +ObjectAdapterF.h ObjectFactory.h -Instrumentation.h -InstrumentationF.h -PluginF.h +ObjectFactoryF.h Plugin.h -ProcessF.h +PluginF.h Process.h -PropertiesF.h -PropertiesAdmin.h +ProcessF.h Properties.h +PropertiesAdmin.h +PropertiesF.h RemoteLogger.h -RouterF.h Router.h -ServantLocatorF.h +RouterF.h ServantLocator.h +ServantLocatorF.h SliceChecksumDict.h Version.h diff --git a/cpp/src/IceBox/.gitignore b/cpp/src/IceBox/.gitignore index 03d4ede8a70..c483621af47 100644 --- a/cpp/src/IceBox/.gitignore +++ b/cpp/src/IceBox/.gitignore @@ -1,5 +1,7 @@ // Generated by makegitignore.py // IMPORTANT: Do not edit this file -- any edits made here will be lost! +.depend +.depend IceBox.cpp IceBox.h diff --git a/cpp/src/IceDiscovery/.gitignore b/cpp/src/IceDiscovery/.gitignore index 7ba1aabfc02..07790f7db33 100644 --- a/cpp/src/IceDiscovery/.gitignore +++ b/cpp/src/IceDiscovery/.gitignore @@ -1,5 +1,7 @@ // Generated by makegitignore.py // IMPORTANT: Do not edit this file -- any edits made here will be lost! +.depend +.depend IceDiscovery.cpp IceDiscovery.h diff --git a/cpp/src/IceGrid/.gitignore b/cpp/src/IceGrid/.gitignore index 41d881d4e8a..0115ebcad98 100644 --- a/cpp/src/IceGrid/.gitignore +++ b/cpp/src/IceGrid/.gitignore @@ -1,11 +1,11 @@ // Generated by makegitignore.py // IMPORTANT: Do not edit this file -- any edits made here will be lost! -DBTypes.cpp -DBTypes.h -IceLocatorDiscovery.cpp -IceLocatorDiscovery.h +.depend +.depend Internal.cpp +IceLocatorDiscovery.cpp +DBTypes.cpp Internal.h DBTypes.h DBTypes.cpp diff --git a/cpp/src/IceGrid/IceGridDB.cpp b/cpp/src/IceGrid/IceGridDB.cpp index 8eb7cb0e629..f6d4317df5b 100644 --- a/cpp/src/IceGrid/IceGridDB.cpp +++ b/cpp/src/IceGrid/IceGridDB.cpp @@ -251,8 +251,7 @@ Client::run(int argc, char* argv[]) return EXIT_FAILURE; } - StringSeq files = IcePatch2Internal::readDirectory(dbPath); - if(!files.empty()) + if(!IceUtilInternal::isEmptyDirectory(dbPath)) { cerr << argv[0] << ": output directory is not empty: " << dbPath << endl; return EXIT_FAILURE; diff --git a/cpp/src/IceGridLib/.gitignore b/cpp/src/IceGridLib/.gitignore index 2a86c159391..9d7a58ce79a 100644 --- a/cpp/src/IceGridLib/.gitignore +++ b/cpp/src/IceGridLib/.gitignore @@ -1,27 +1,27 @@ // Generated by makegitignore.py // IMPORTANT: Do not edit this file -- any edits made here will be lost! +.depend +.depend Admin.cpp -Discovery.cpp +Descriptor.cpp Exception.cpp FileParser.cpp Locator.cpp +Observer.cpp +PluginFacade.cpp Query.cpp Registry.cpp Session.cpp -Observer.cpp -Descriptor.cpp UserAccountMapper.cpp -PluginFacade.cpp Admin.h -Discovery.h +Descriptor.h Exception.h FileParser.h Locator.h +Observer.h +PluginFacade.h Query.h Registry.h Session.h -Observer.h -Descriptor.h UserAccountMapper.h -PluginFacade.h diff --git a/cpp/src/IceLocatorDiscovery/.gitignore b/cpp/src/IceLocatorDiscovery/.gitignore index fb1f34c05a4..45e29d8dd2d 100644 --- a/cpp/src/IceLocatorDiscovery/.gitignore +++ b/cpp/src/IceLocatorDiscovery/.gitignore @@ -1,5 +1,7 @@ // Generated by makegitignore.py // IMPORTANT: Do not edit this file -- any edits made here will be lost! +.depend +.depend IceLocatorDiscovery.cpp IceLocatorDiscovery.h diff --git a/cpp/src/IcePatch2/.gitignore b/cpp/src/IcePatch2/.gitignore new file mode 100644 index 00000000000..720f44c7047 --- /dev/null +++ b/cpp/src/IcePatch2/.gitignore @@ -0,0 +1,5 @@ +// Generated by makegitignore.py + +// IMPORTANT: Do not edit this file -- any edits made here will be lost! +.depend +.depend diff --git a/cpp/src/IcePatch2Lib/.gitignore b/cpp/src/IcePatch2Lib/.gitignore index 1364efc1d87..a6ba57e6121 100644 --- a/cpp/src/IcePatch2Lib/.gitignore +++ b/cpp/src/IcePatch2Lib/.gitignore @@ -1,6 +1,8 @@ // Generated by makegitignore.py // IMPORTANT: Do not edit this file -- any edits made here will be lost! +.depend +.depend FileInfo.cpp FileServer.cpp FileInfo.h diff --git a/cpp/src/IceSSL/.gitignore b/cpp/src/IceSSL/.gitignore index 88e034bad9d..981999c07ba 100644 --- a/cpp/src/IceSSL/.gitignore +++ b/cpp/src/IceSSL/.gitignore @@ -1,7 +1,9 @@ // Generated by makegitignore.py // IMPORTANT: Do not edit this file -- any edits made here will be lost! -EndpointInfo.cpp +.depend +.depend ConnectionInfo.cpp -EndpointInfo.h +EndpointInfo.cpp ConnectionInfo.h +EndpointInfo.h diff --git a/cpp/src/IceStorm/.gitignore b/cpp/src/IceStorm/.gitignore index 4fad7b4af9d..9acac8d9ebe 100644 --- a/cpp/src/IceStorm/.gitignore +++ b/cpp/src/IceStorm/.gitignore @@ -1,17 +1,20 @@ // Generated by makegitignore.py // IMPORTANT: Do not edit this file -- any edits made here will be lost! -DBTypes.h -DBTypes.cpp -Instrumentation.cpp +.depend +.depend Election.cpp IceStormInternal.cpp +Instrumentation.cpp +LinkRecord.cpp LLURecord.cpp SubscriberRecord.cpp LinkRecord.cpp Instrumentation.h Election.h IceStormInternal.h +Instrumentation.h +LinkRecord.h LLURecord.h SubscriberRecord.h LinkRecord.h diff --git a/cpp/src/IceStorm/IceStormDB.cpp b/cpp/src/IceStorm/IceStormDB.cpp index 2c661b4531c..d6d29630fa5 100644 --- a/cpp/src/IceStorm/IceStormDB.cpp +++ b/cpp/src/IceStorm/IceStormDB.cpp @@ -152,8 +152,7 @@ Client::run(int argc, char* argv[]) return EXIT_FAILURE; } - StringSeq files = IcePatch2Internal::readDirectory(dbPath); - if(!files.empty()) + if(!IceUtilInternal::isEmptyDirectory(dbPath)) { cerr << argv[0] << ": output directory is not empty: " << dbPath << endl; return EXIT_FAILURE; diff --git a/cpp/src/IceStormLib/.gitignore b/cpp/src/IceStormLib/.gitignore index 4ac7fbb48ef..798077a2149 100644 --- a/cpp/src/IceStormLib/.gitignore +++ b/cpp/src/IceStormLib/.gitignore @@ -1,6 +1,8 @@ // Generated by makegitignore.py // IMPORTANT: Do not edit this file -- any edits made here will be lost! +.depend +.depend IceStorm.cpp Metrics.cpp IceStorm.h diff --git a/cpp/src/IceUtil/.gitignore b/cpp/src/IceUtil/.gitignore new file mode 100644 index 00000000000..720f44c7047 --- /dev/null +++ b/cpp/src/IceUtil/.gitignore @@ -0,0 +1,5 @@ +// Generated by makegitignore.py + +// IMPORTANT: Do not edit this file -- any edits made here will be lost! +.depend +.depend diff --git a/cpp/src/IceUtil/FileUtil.cpp b/cpp/src/IceUtil/FileUtil.cpp index ea7fc606e65..4e3dc407804 100644 --- a/cpp/src/IceUtil/FileUtil.cpp +++ b/cpp/src/IceUtil/FileUtil.cpp @@ -17,8 +17,12 @@ #ifdef _WIN32 # include <process.h> # include <io.h> +# ifndef ICE_OS_WINRT +# include <Shlwapi.h> +# endif #else # include <unistd.h> +# include <dirent.h> #endif using namespace std; @@ -90,6 +94,41 @@ IceUtilInternal::directoryExists(const string& path) } // +// Determine if a directory exists and is empty. +// +#ifndef ICE_OS_WINRT +bool +IceUtilInternal::isEmptyDirectory(const string& path) +{ +# ifdef _WIN32 + return PathIsDirectoryEmptyW(IceUtil::stringToWstring(path, IceUtil::getProcessStringConverter()).c_str()); +# else + struct dirent* d; + DIR* dir = opendir(path.c_str()); + if(dir) + { + bool empty = true; + while((d = readdir(dir))) + { + string name(d->d_name); + if(name != "." && name != "..") + { + empty = false; + break; + } + } + closedir(dir); + return empty; + } + else + { + return false; + } +# endif +} +#endif + +// // Determine if a regular file exists. // bool diff --git a/cpp/src/IceXML/.gitignore b/cpp/src/IceXML/.gitignore new file mode 100644 index 00000000000..720f44c7047 --- /dev/null +++ b/cpp/src/IceXML/.gitignore @@ -0,0 +1,5 @@ +// Generated by makegitignore.py + +// IMPORTANT: Do not edit this file -- any edits made here will be lost! +.depend +.depend diff --git a/cpp/src/Slice/.gitignore b/cpp/src/Slice/.gitignore new file mode 100644 index 00000000000..720f44c7047 --- /dev/null +++ b/cpp/src/Slice/.gitignore @@ -0,0 +1,5 @@ +// Generated by makegitignore.py + +// IMPORTANT: Do not edit this file -- any edits made here will be lost! +.depend +.depend diff --git a/cpp/src/Slice/PythonUtil.cpp b/cpp/src/Slice/PythonUtil.cpp index 23b95898317..d471f3448e5 100644 --- a/cpp/src/Slice/PythonUtil.cpp +++ b/cpp/src/Slice/PythonUtil.cpp @@ -165,7 +165,27 @@ private: void collectClassMembers(const ClassDefPtr&, MemberInfoList&, bool); void collectExceptionMembers(const ExceptionPtr&, MemberInfoList&, bool); - string editComment(const string&); + typedef vector<string> StringVec; + + StringVec stripMarkup(const string&); + + void writeDocstring(const string&, const string& = ""); + void writeDocstring(const string&, const DataMemberList&); + void writeDocstring(const string&, const EnumeratorList&); + + typedef map<string, string> StringMap; + struct OpComment + { + StringVec description; + StringMap params; + string returns; + StringMap exceptions; + }; + bool parseOpComment(const string&, OpComment&); + + enum DocstringMode { DocSync, DocAsyncBegin, DocAsyncEnd, DocDispatch, DocAsyncDispatch }; + + void writeDocstring(const OperationPtr&, DocstringMode, bool); Output& _out; set<string>& _moduleHistory; @@ -352,11 +372,7 @@ Slice::Python::CodeVisitor::visitModuleStart(const ModulePtr& p) } _out << nl << "__name__ = '" << abs << "'"; - string comment = p->comment(); - if(!comment.empty()) - { - _out << nl << "_M_" << abs << ".__doc__ = '''" << editComment(comment) << "'''"; - } + writeDocstring(p->comment(), "_M_" + abs + ".__doc__ = "); _moduleStack.push_front(abs); return true; @@ -449,11 +465,7 @@ Slice::Python::CodeVisitor::visitClassDefStart(const ClassDefPtr& p) _out.inc(); - string comment = p->comment(); - if(!comment.empty()) - { - _out << nl << "'''" << editComment(comment) << "'''"; - } + writeDocstring(p->comment(), p->dataMembers()); // // __init__ @@ -582,11 +594,9 @@ Slice::Python::CodeVisitor::visitClassDefStart(const ClassDefPtr& p) } _out << "):"; _out.inc(); - comment = (*oli)->comment(); - if(!comment.empty()) - { - _out << nl << "'''" << editComment(comment) << "'''"; - } + + writeDocstring(*oli, DocAsyncDispatch, false); + _out << nl << "pass"; _out.dec(); } @@ -609,11 +619,7 @@ Slice::Python::CodeVisitor::visitClassDefStart(const ClassDefPtr& p) } _out << "):"; _out.inc(); - comment = (*oli)->comment(); - if(!comment.empty()) - { - _out << nl << "'''" << editComment(comment) << "'''"; - } + writeDocstring(*oli, DocDispatch, p->isLocal()); _out << nl << "pass"; _out.dec(); } @@ -680,17 +686,8 @@ Slice::Python::CodeVisitor::visitClassDefStart(const ClassDefPtr& p) } } - comment = (*oli)->comment(); - if(!comment.empty()) - { - comment = "'''" + editComment(comment) + "'''"; - } - _out << sp; - if(!comment.empty()) - { - _out << nl << comment; - } + writeDocstring(*oli, DocSync, false); _out << nl << "def " << fixedOpName << "(self"; if(!inParams.empty()) { @@ -710,10 +707,7 @@ Slice::Python::CodeVisitor::visitClassDefStart(const ClassDefPtr& p) // Async operations. // _out << sp; - if(!comment.empty()) - { - _out << nl << comment; - } + writeDocstring(*oli, DocAsyncBegin, false); _out << nl << "def begin_" << (*oli)->name() << "(self"; if(!inParams.empty()) { @@ -730,10 +724,7 @@ Slice::Python::CodeVisitor::visitClassDefStart(const ClassDefPtr& p) _out.dec(); _out << sp; - if(!comment.empty()) - { - _out << nl << comment; - } + writeDocstring(*oli, DocAsyncEnd, false); _out << nl << "def end_" << (*oli)->name() << "(self, _r):"; _out.inc(); _out << nl << "return _M_" << abs << "._op_" << (*oli)->name() << ".end(self, _r)"; @@ -1032,14 +1023,10 @@ Slice::Python::CodeVisitor::visitExceptionStart(const ExceptionPtr& p) _out << "):"; _out.inc(); - string comment = p->comment(); - if(!comment.empty()) - { - _out << nl << "'''" << editComment(comment) << "'''"; - } - DataMemberList members = p->dataMembers(); + writeDocstring(p->comment(), members); + // // __init__ // @@ -1160,10 +1147,10 @@ Slice::Python::CodeVisitor::visitStructStart(const StructPtr& p) string scoped = p->scoped(); string abs = getAbsolute(p); string name = fixIdent(p->name()); + DataMemberList members = p->dataMembers(); MemberInfoList memberList; { - DataMemberList members = p->dataMembers(); for(DataMemberList::iterator q = members.begin(); q != members.end(); ++q) { memberList.push_back(MemberInfo()); @@ -1179,11 +1166,7 @@ Slice::Python::CodeVisitor::visitStructStart(const StructPtr& p) _out << nl << "class " << name << "(object):"; _out.inc(); - string comment = p->comment(); - if(!comment.empty()) - { - _out << nl << "'''" << editComment(comment) << "'''"; - } + writeDocstring(p->comment(), members); _out << nl << "def __init__(self"; writeConstructorParams(memberList); @@ -1513,11 +1496,7 @@ Slice::Python::CodeVisitor::visitEnum(const EnumPtr& p) _out << nl << "class " << name << "(Ice.EnumBase):"; _out.inc(); - string comment = p->comment(); - if(!comment.empty()) - { - _out << nl << "'''" << editComment(comment) << "'''"; - } + writeDocstring(p->comment(), enums); _out << sp << nl << "def __init__(self, _n, _v):"; _out.inc(); @@ -2136,25 +2115,25 @@ Slice::Python::CodeVisitor::collectExceptionMembers(const ExceptionPtr& p, Membe } } -string -Slice::Python::CodeVisitor::editComment(const string& comment) +Slice::Python::CodeVisitor::StringVec +Slice::Python::CodeVisitor::stripMarkup(const string& comment) { // // Strip HTML markup and javadoc links. // - string result = comment; + string text = comment; string::size_type pos = 0; do { - pos = result.find('<', pos); + pos = text.find('<', pos); if(pos != string::npos) { - string::size_type endpos = result.find('>', pos); + string::size_type endpos = text.find('>', pos); if(endpos == string::npos) { break; } - result.erase(pos, endpos - pos + 1); + text.erase(pos, endpos - pos + 1); } } while(pos != string::npos); @@ -2162,18 +2141,18 @@ Slice::Python::CodeVisitor::editComment(const string& comment) pos = 0; do { - pos = result.find(link, pos); + pos = text.find(link, pos); if(pos != string::npos) { - result.erase(pos, link.size()); - string::size_type endpos = result.find('}', pos); + text.erase(pos, link.size()); + string::size_type endpos = text.find('}', pos); if(endpos != string::npos) { - string::size_type identpos = result.find_first_not_of(" \t#", pos); + string::size_type identpos = text.find_first_not_of(" \t#", pos); if(identpos != string::npos && identpos < endpos) { - string ident = result.substr(identpos, endpos - identpos); - result.replace(pos, endpos - pos + 1, fixIdent(ident)); + string ident = text.substr(identpos, endpos - identpos); + text.replace(pos, endpos - pos + 1, fixIdent(ident)); } } } @@ -2190,160 +2169,639 @@ Slice::Python::CodeVisitor::editComment(const string& comment) // Look for the next @ and delete up to that, or // to the end of the string, if not found. // - pos = result.find(seeTag, pos); + pos = text.find(seeTag, pos); if(pos != string::npos) { - string::size_type next = result.find('@', pos + seeTag.size()); + string::size_type next = text.find('@', pos + seeTag.size()); if(next != string::npos) { - result.erase(pos, next - pos); + text.erase(pos, next - pos); } else { - result.erase(pos, string::npos); + text.erase(pos, string::npos); } } } while(pos != string::npos); // - // Reformat @param, @return, and @throws. + // Escape triple quotes. // - static const string paramTag = "@param"; + static const string singleQuotes = "'''"; pos = 0; - bool first = true; - do + while((pos = text.find(singleQuotes, pos)) != string::npos) { - pos = result.find(paramTag, pos); - if(pos != string::npos) + text.insert(pos, "\\"); + pos += singleQuotes.size() + 1; + } + static const string doubleQuotes = "\"\"\""; + pos = 0; + while((pos = text.find(doubleQuotes, pos)) != string::npos) + { + text.insert(pos, "\\"); + pos += doubleQuotes.size() + 1; + } + + // + // Fold multiple empty lines. + // + pos = 0; + while(true) + { + pos = text.find('\n', pos); + if(pos == string::npos) + { + break; + } + + // + // Skip the next LF or CR/LF, if present. + // + if(pos < text.size() - 1 && text[pos + 1] == '\n') + { + pos += 2; + } + else if(pos < text.size() - 2 && text[pos + 1] == '\r' && text[pos + 2] == '\n') + { + pos += 3; + } + else + { + ++pos; + continue; + } + + // + // Erase any more CR/LF characters. + // + string::size_type next = text.find_first_not_of("\r\n", pos); + if(next != string::npos) + { + text.erase(pos, next - pos); + } + } + + // + // Remove trailing whitespace. + // + pos = text.find_last_not_of(" \t\r\n"); + if(pos != string::npos) + { + text.erase(pos + 1, text.size() - pos - 1); + } + + // + // Split text into lines. + // + StringVec lines; + if(!text.empty()) + { + string::size_type start = 0; + while(start != string::npos) { - result.replace(pos, paramTag.size() + 1, " "); + string::size_type nl = text.find_first_of("\r\n", start); + string line; + if(nl != string::npos) + { + line = text.substr(start, nl - start); + start = nl; + } + else + { + line = text.substr(start); + start = text.size(); + } + + lines.push_back(line); + + start = text.find_first_not_of("\r\n", start); + } + } - if(first) + return lines; +} + +void +Slice::Python::CodeVisitor::writeDocstring(const string& comment, const string& prefix) +{ + StringVec lines = stripMarkup(comment); + if(lines.empty()) + { + return; + } + + _out << nl << prefix << "\"\"\""; + + for(StringVec::const_iterator q = lines.begin(); q != lines.end(); ++q) + { + if(q != lines.begin()) + { + _out << nl; + } + _out << *q; + } + + _out << "\"\"\""; +} + +void +Slice::Python::CodeVisitor::writeDocstring(const string& comment, const DataMemberList& members) +{ + StringVec lines = stripMarkup(comment); + if(lines.empty()) + { + return; + } + + _out << nl << "\"\"\""; + + for(StringVec::const_iterator q = lines.begin(); q != lines.end(); ++q) + { + if(q != lines.begin()) + { + _out << nl; + } + _out << *q; + } + + if(!members.empty()) + { + // + // Collect docstrings (if any) for the members. + // + map<string, StringVec> docs; + for(DataMemberList::const_iterator m = members.begin(); m != members.end(); ++m) + { + StringVec doc = stripMarkup((*m)->comment()); + if(!doc.empty()) { - string::size_type bol = result.rfind('\n', pos); - if(bol == string::npos) - { - bol = 0; - } - else + docs[(*m)->name()] = doc; + } + } + // + // Only emit members if there's a docstring for at least one member. + // + if(!docs.empty()) + { + _out << nl << "Members:"; + for(DataMemberList::const_iterator m = members.begin(); m != members.end(); ++m) + { + _out << nl << fixIdent((*m)->name()) << " -- "; + map<string, StringVec>::iterator p = docs.find((*m)->name()); + if(p != docs.end()) { - bol++; + for(StringVec::const_iterator q = p->second.begin(); q != p->second.end(); ++q) + { + if(q != p->second.begin()) + { + _out << nl; + } + _out << *q; + } } - result.insert(bol, "Arguments:\n"); - first = false; } } - } while(pos != string::npos); + } - static const string returnTag = "@return"; - pos = result.find(returnTag); - first = true; - if(pos != string::npos) + _out << "\"\"\""; +} + +void +Slice::Python::CodeVisitor::writeDocstring(const string& comment, const EnumeratorList& enums) +{ + StringVec lines = stripMarkup(comment); + if(lines.empty()) { - result.replace(pos, returnTag.size() + 1, " "); - string::size_type bol = result.rfind('\n', pos); - if(bol == string::npos) + return; + } + + _out << nl << "\"\"\""; + + for(StringVec::const_iterator q = lines.begin(); q != lines.end(); ++q) + { + if(q != lines.begin()) { - bol = 0; + _out << nl; } - else + _out << *q; + } + + if(!enums.empty()) + { + // + // Collect docstrings (if any) for the enumerators. + // + map<string, StringVec> docs; + for(EnumeratorList::const_iterator e = enums.begin(); e != enums.end(); ++e) { - bol++; + StringVec doc = stripMarkup((*e)->comment()); + if(!doc.empty()) + { + docs[(*e)->name()] = doc; + } + } + // + // Only emit enumerators if there's a docstring for at least one enumerator. + // + if(!docs.empty()) + { + _out << nl << "Enumerators:"; + for(EnumeratorList::const_iterator e = enums.begin(); e != enums.end(); ++e) + { + _out << nl << fixIdent((*e)->name()) << " -- "; + map<string, StringVec>::iterator p = docs.find((*e)->name()); + if(p != docs.end()) + { + for(StringVec::const_iterator q = p->second.begin(); q != p->second.end(); ++q) + { + if(q != p->second.begin()) + { + _out << nl; + } + _out << *q; + } + } + } } - result.insert(bol, "Returns:\n"); } - static const string throwsTag = "@throws"; - pos = 0; - first = true; - do + _out << "\"\"\""; +} + +bool +Slice::Python::CodeVisitor::parseOpComment(const string& comment, OpComment& c) +{ + // + // Remove most javadoc & HTML markup. + // + StringVec lines = stripMarkup(comment); + if(lines.empty()) { - pos = result.find(throwsTag, pos); - if(pos != string::npos) - { - result.replace(pos, throwsTag.size() + 1, " "); + return false; + } + + // + // Extract the descriptions of parameters, exceptions and return values. + // + string name; + bool inParam = false, inException = false, inReturn = false; + vector<string>::size_type i = 0; + while(i < lines.size()) + { + string l = lines[i]; + string::size_type paramTag = l.find("@param"); + string::size_type throwTag = l.find("@throw"); + string::size_type returnTag = l.find("@return"); - if(first) + if(paramTag != string::npos) + { + string::size_type pos = l.find_first_of(" \t", paramTag); + if(pos != string::npos) + { + pos = l.find_first_not_of(" \t", pos); + } + if(pos != string::npos) { - string::size_type bol = result.rfind('\n', pos); - if(bol == string::npos) + string::size_type namePos = pos; + pos = l.find_first_of(" \t", pos); + inParam = true; + inException = false; + inReturn = false; + if(pos == string::npos) { - bol = 0; + // + // Doc assumed to have the format + // + // @param foo + // Description of foo... + // + name = l.substr(namePos); + c.params[name] = ""; } else { - bol++; + name = l.substr(namePos, pos - namePos); + pos = l.find_first_not_of(" \t", pos); + if(pos != string::npos) + { + c.params[name] = l.substr(pos); + } + else + { + c.params[name] = ""; + } + } + } + lines.erase(lines.begin() + i); + continue; + } + else if(throwTag != string::npos) + { + string::size_type pos = l.find_first_of(" \t", throwTag); + if(pos != string::npos) + { + pos = l.find_first_not_of(" \t", pos); + } + if(pos != string::npos) + { + string::size_type namePos = pos; + pos = l.find_first_of(" \t", pos); + inException = true; + inParam = false; + inReturn = false; + if(pos == string::npos) + { + // + // Doc assumed to have the format + // + // @throw foo + // Description of foo... + // + name = l.substr(namePos); + c.exceptions[name] = ""; + } + else + { + name = l.substr(namePos, pos - namePos); + pos = l.find_first_not_of(" \t", pos); + if(pos != string::npos) + { + c.exceptions[name] = l.substr(pos); + } + else + { + c.exceptions[name] = ""; + } + } + } + lines.erase(lines.begin() + i); + continue; + } + else if(returnTag != string::npos) + { + string::size_type pos = l.find_first_of(" \t", returnTag); + if(pos != string::npos) + { + pos = l.find_first_not_of(" \t", pos); + } + if(pos != string::npos) + { + inReturn = true; + inException = false; + inParam = false; + c.returns = l.substr(pos); + } + lines.erase(lines.begin() + i); + continue; + } + else + { + // + // We didn't find a tag so we assume this line is a continuation of a + // previous description. + // + string::size_type pos = l.find_first_not_of(" \t"); + if(pos != string::npos && l[pos] != '@') + { + if(inParam) + { + assert(!name.empty()); + if(!c.params[name].empty()) + { + c.params[name] += " "; + } + c.params[name] += l.substr(pos); + lines.erase(lines.begin() + i); + continue; + } + else if(inException) + { + assert(!name.empty()); + if(!c.exceptions[name].empty()) + { + c.exceptions[name] += " "; + } + c.exceptions[name] += l.substr(pos); + lines.erase(lines.begin() + i); + continue; + } + else if(inReturn) + { + if(!c.returns.empty()) + { + c.returns += " "; + } + c.returns += l.substr(pos); + lines.erase(lines.begin() + i); + continue; } - result.insert(bol, "Exceptions:\n"); - first = false; } } - } while(pos != string::npos); + + i++; + } // - // Escape triple quotes. + // All remaining lines become the general description. // - static const string quotes = "'''"; - pos = 0; - do + for(vector<string>::iterator p = lines.begin(); p != lines.end(); ++p) { - pos = result.find(quotes, pos); - if(pos != string::npos) + if(p->find_first_not_of(" \t\n\r") != string::npos) { - result.insert(pos, "\\"); - pos += quotes.size() + 1; + c.description.push_back(*p); } - } while(pos != string::npos); + } + + return true; +} + +void +Slice::Python::CodeVisitor::writeDocstring(const OperationPtr& op, DocstringMode mode, bool local) +{ + OpComment comment; + if(!parseOpComment(op->comment(), comment)) + { + return; + } + + TypePtr ret = op->returnType(); + ParamDeclList params = op->parameters(); + vector<string> inParams, outParams; + for(ParamDeclList::iterator p = params.begin(); p != params.end(); ++p) + { + if((*p)->isOutParam()) + { + outParams.push_back((*p)->name()); + } + else + { + inParams.push_back((*p)->name()); + } + } + + if(comment.description.empty()) + { + if((mode == DocSync || mode == DocDispatch) && comment.params.empty() && comment.exceptions.empty() && + comment.returns.empty()) + { + return; + } + else if(mode == DocAsyncBegin && inParams.empty()) + { + return; + } + else if(mode == DocAsyncEnd && outParams.empty() && comment.returns.empty()) + { + return; + } + else if(mode == DocAsyncDispatch && inParams.empty() && comment.exceptions.empty()) + { + return; + } + } // - // Fold multiple empty lines. + // Emit the general description. // - pos = 0; - while(true) + _out << nl << "\"\"\""; + if(!comment.description.empty()) { - pos = result.find('\n', pos); - if(pos == string::npos) + for(StringVec::const_iterator q = comment.description.begin(); q != comment.description.end(); ++q) { - break; + if(q != comment.description.begin()) + { + _out << nl; + } + _out << *q; } + } - // - // Skip the next LF or CR/LF, if present. - // - if(pos < result.size() - 1 && result[pos + 1] == '\n') + // + // Emit arguments. + // + bool needArgs = false; + switch(mode) + { + case DocSync: + case DocAsyncBegin: + case DocDispatch: + needArgs = !local || !inParams.empty(); + break; + case DocAsyncEnd: + case DocAsyncDispatch: + needArgs = true; + break; + } + + if(needArgs) + { + _out << nl << "Arguments:"; + if(mode == DocAsyncDispatch) { - pos += 2; + _out << nl << "_cb -- The asynchronous callback object."; } - else if(pos < result.size() - 2 && result[pos + 1] == '\r' && result[pos + 2] == '\n') + for(vector<string>::iterator q = inParams.begin(); q != inParams.end(); ++q) { - pos += 3; + string fixed = fixIdent(*q); + _out << nl << fixed << " -- "; + StringMap::const_iterator r = comment.params.find(*q); + if(r == comment.params.end()) + { + r = comment.params.find(fixed); // Just in case. + } + if(r != comment.params.end()) + { + _out << r->second; + } } - else + if(mode == DocAsyncBegin) { - ++pos; - continue; + _out << nl << "_response -- The asynchronous response callback." + << nl << "_ex -- The asynchronous exception callback." + << nl << "_sent -- The asynchronous sent callback."; } - - // - // Erase any more CR/LF characters. - // - string::size_type next = result.find_first_not_of("\r\n", pos); - if(next != string::npos) + if(!local && (mode == DocSync || mode == DocAsyncBegin)) + { + _out << nl << "_ctx -- The request context for the invocation."; + } + if(!local && (mode == DocDispatch || mode == DocAsyncDispatch)) { - result.erase(pos, next - pos); + _out << nl << "current -- The Current object for the invocation."; } } + else if(mode == DocAsyncEnd) + { + _out << nl << "Arguments:" + << nl << "_r - The asynchronous result object for the invocation."; + } // - // Remove trailing whitespace. + // Emit return value(s). // - pos = result.find_last_not_of(" \t\r\n"); - if(pos != string::npos) + if(mode == DocAsyncBegin) { - result.erase(pos + 1, result.size() - pos - 1); + _out << nl << "Returns: An asynchronous result object for the invocation."; } - return result; + if((mode == DocSync || mode == DocAsyncEnd || mode == DocDispatch) && (ret || !outParams.empty())) + { + if((outParams.size() + (ret ? 1 : 0)) > 1) + { + _out << nl << "Returns a tuple containing the following:"; + if(ret) + { + _out << nl << "_retval -- " << comment.returns; + } + for(vector<string>::iterator q = outParams.begin(); q != outParams.end(); ++q) + { + string fixed = fixIdent(*q); + _out << nl << fixed << " -- "; + StringMap::const_iterator r = comment.params.find(*q); + if(r == comment.params.end()) + { + r = comment.params.find(fixed); // Just in case. + } + if(r != comment.params.end()) + { + _out << r->second; + } + } + } + else if(ret && !comment.returns.empty()) + { + _out << nl << "Returns: " << comment.returns; + } + else if(!outParams.empty()) + { + assert(outParams.size() == 1); + _out << nl << "Returns:"; + string fixed = fixIdent(outParams[0]); + _out << nl << fixed << " -- "; + StringMap::const_iterator r = comment.params.find(outParams[0]); + if(r == comment.params.end()) + { + r = comment.params.find(fixed); // Just in case. + } + if(r != comment.params.end()) + { + _out << r->second; + } + } + } + + // + // Emit exceptions. + // + if((mode == DocSync || mode == DocAsyncEnd || mode == DocDispatch || mode == DocAsyncDispatch) && + !comment.exceptions.empty()) + { + _out << nl << "Throws:"; + for(StringMap::const_iterator r = comment.exceptions.begin(); r != comment.exceptions.end(); ++r) + { + _out << nl << r->first << " -- " << r->second; + } + } + _out << "\"\"\""; } void diff --git a/cpp/src/slice2confluence/.gitignore b/cpp/src/slice2confluence/.gitignore new file mode 100644 index 00000000000..3a412ca89c7 --- /dev/null +++ b/cpp/src/slice2confluence/.gitignore @@ -0,0 +1,4 @@ +// Generated by makegitignore.py + +// IMPORTANT: Do not edit this file -- any edits made here will be lost! +.depend diff --git a/cpp/src/slice2cpp/.gitignore b/cpp/src/slice2cpp/.gitignore new file mode 100644 index 00000000000..720f44c7047 --- /dev/null +++ b/cpp/src/slice2cpp/.gitignore @@ -0,0 +1,5 @@ +// Generated by makegitignore.py + +// IMPORTANT: Do not edit this file -- any edits made here will be lost! +.depend +.depend diff --git a/cpp/src/slice2cs/.gitignore b/cpp/src/slice2cs/.gitignore new file mode 100644 index 00000000000..720f44c7047 --- /dev/null +++ b/cpp/src/slice2cs/.gitignore @@ -0,0 +1,5 @@ +// Generated by makegitignore.py + +// IMPORTANT: Do not edit this file -- any edits made here will be lost! +.depend +.depend diff --git a/cpp/src/slice2freeze/.gitignore b/cpp/src/slice2freeze/.gitignore new file mode 100644 index 00000000000..720f44c7047 --- /dev/null +++ b/cpp/src/slice2freeze/.gitignore @@ -0,0 +1,5 @@ +// Generated by makegitignore.py + +// IMPORTANT: Do not edit this file -- any edits made here will be lost! +.depend +.depend diff --git a/cpp/src/slice2freezej/.gitignore b/cpp/src/slice2freezej/.gitignore new file mode 100644 index 00000000000..720f44c7047 --- /dev/null +++ b/cpp/src/slice2freezej/.gitignore @@ -0,0 +1,5 @@ +// Generated by makegitignore.py + +// IMPORTANT: Do not edit this file -- any edits made here will be lost! +.depend +.depend diff --git a/cpp/src/slice2html/.gitignore b/cpp/src/slice2html/.gitignore new file mode 100644 index 00000000000..720f44c7047 --- /dev/null +++ b/cpp/src/slice2html/.gitignore @@ -0,0 +1,5 @@ +// Generated by makegitignore.py + +// IMPORTANT: Do not edit this file -- any edits made here will be lost! +.depend +.depend diff --git a/cpp/src/slice2java/.gitignore b/cpp/src/slice2java/.gitignore new file mode 100644 index 00000000000..720f44c7047 --- /dev/null +++ b/cpp/src/slice2java/.gitignore @@ -0,0 +1,5 @@ +// Generated by makegitignore.py + +// IMPORTANT: Do not edit this file -- any edits made here will be lost! +.depend +.depend diff --git a/cpp/src/slice2js/.gitignore b/cpp/src/slice2js/.gitignore new file mode 100644 index 00000000000..720f44c7047 --- /dev/null +++ b/cpp/src/slice2js/.gitignore @@ -0,0 +1,5 @@ +// Generated by makegitignore.py + +// IMPORTANT: Do not edit this file -- any edits made here will be lost! +.depend +.depend diff --git a/cpp/src/slice2objc/.gitignore b/cpp/src/slice2objc/.gitignore new file mode 100644 index 00000000000..3a412ca89c7 --- /dev/null +++ b/cpp/src/slice2objc/.gitignore @@ -0,0 +1,4 @@ +// Generated by makegitignore.py + +// IMPORTANT: Do not edit this file -- any edits made here will be lost! +.depend diff --git a/cpp/src/slice2php/.gitignore b/cpp/src/slice2php/.gitignore new file mode 100644 index 00000000000..720f44c7047 --- /dev/null +++ b/cpp/src/slice2php/.gitignore @@ -0,0 +1,5 @@ +// Generated by makegitignore.py + +// IMPORTANT: Do not edit this file -- any edits made here will be lost! +.depend +.depend diff --git a/cpp/src/slice2py/.gitignore b/cpp/src/slice2py/.gitignore new file mode 100644 index 00000000000..3a412ca89c7 --- /dev/null +++ b/cpp/src/slice2py/.gitignore @@ -0,0 +1,4 @@ +// Generated by makegitignore.py + +// IMPORTANT: Do not edit this file -- any edits made here will be lost! +.depend |