aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/tools/swig/Source/Doxygen/javadoc.cxx
diff options
context:
space:
mode:
authorvitalyisaev <vitalyisaev@ydb.tech>2023-11-30 13:26:22 +0300
committervitalyisaev <vitalyisaev@ydb.tech>2023-11-30 15:44:45 +0300
commit0a98fece5a9b54f16afeb3a94b3eb3105e9c3962 (patch)
tree291d72dbd7e9865399f668c84d11ed86fb190bbf /contrib/tools/swig/Source/Doxygen/javadoc.cxx
parentcb2c8d75065e5b3c47094067cb4aa407d4813298 (diff)
downloadydb-0a98fece5a9b54f16afeb3a94b3eb3105e9c3962.tar.gz
YQ Connector:Use docker-compose in integrational tests
Diffstat (limited to 'contrib/tools/swig/Source/Doxygen/javadoc.cxx')
-rw-r--r--contrib/tools/swig/Source/Doxygen/javadoc.cxx849
1 files changed, 849 insertions, 0 deletions
diff --git a/contrib/tools/swig/Source/Doxygen/javadoc.cxx b/contrib/tools/swig/Source/Doxygen/javadoc.cxx
new file mode 100644
index 0000000000..a1406b2303
--- /dev/null
+++ b/contrib/tools/swig/Source/Doxygen/javadoc.cxx
@@ -0,0 +1,849 @@
+/* -----------------------------------------------------------------------------
+ * This file is part of SWIG, which is licensed as a whole under version 3
+ * (or any later version) of the GNU General Public License. Some additional
+ * terms also apply to certain portions of SWIG. The full details of the SWIG
+ * license and copyrights can be found in the LICENSE and COPYRIGHT files
+ * included with the SWIG source code as distributed by the SWIG developers
+ * and at https://www.swig.org/legal.html.
+ *
+ * javadoc.cxx
+ * ----------------------------------------------------------------------------- */
+
+#include "javadoc.h"
+#include "doxyparser.h"
+#include <iostream>
+#include <vector>
+#include <list>
+#include "swigmod.h"
+#define APPROX_LINE_LENGTH 64 // characters per line allowed
+#define TAB_SIZE 8 // current tab size in spaces
+//TODO {@link} {@linkplain} {@docRoot}, and other useful doxy commands that are not a javadoc tag
+
+// define static tables, they are filled in JavaDocConverter's constructor
+std::map<std::string, std::pair<JavaDocConverter::tagHandler, std::string> > JavaDocConverter::tagHandlers;
+
+using std::string;
+using std::list;
+using std::vector;
+
+void JavaDocConverter::fillStaticTables() {
+ if (tagHandlers.size()) // fill only once
+ return;
+
+ /*
+ * Some translation rules:
+ *
+ * @ and \ must be escaped for both Java and Python to appear on output: \@, \\,
+ * while Doxygen produces output in both cases.
+ * Rule: @ and \ with space on the right should get to output.
+ *
+ * :: remains intact, even in class::method(). But you can use class#method also
+ * in C++ comment and it is properly translated to C++ output (changed by doxygen to ::)
+ * and Java output (remains #).
+ * Rule: SWIG type system can't be used to convert C::m to C#m, because in Java it is C.m
+ * Use string replacement :: --> # in tag see and links.
+ *
+ * HTML tags must be translated - remain in Java, to markdown in Python
+ *
+ * Unknown HTML tags, for example <x> is translated to &lt;x&gt; by doxygen, while
+ * Java src is <x> and therefore invisible on output - browser ignores unknown command.
+ * This is handy in syntax descriptions, for example: more <fileName>.
+ *
+ * Standalone < and > need not be translated, they are rendered properly in
+ * all three outputs.
+ *
+ * ., %, and " need not to be translated
+ *
+ * entities must be translated - remain in Java, something meaningful in Python (&lt, ...)
+ *
+ * - Python
+ * - add comments also to auto-generated methods like equals(), delete() in Java,
+ * and methods for std::vector(), ...
+ * Commenting methods of std types is simple - add comment to std_*.i file.
+ */
+
+ // these commands insert HTML tags
+ tagHandlers["a"] = make_pair(&JavaDocConverter::handleTagHtml, "i");
+ tagHandlers["arg"] = make_pair(&JavaDocConverter::handleTagHtml, "li");
+ tagHandlers["b"] = make_pair(&JavaDocConverter::handleTagHtml, "b");
+ tagHandlers["c"] = make_pair(&JavaDocConverter::handleTagHtml, "code");
+ tagHandlers["cite"] = make_pair(&JavaDocConverter::handleTagHtml, "i");
+ tagHandlers["e"] = make_pair(&JavaDocConverter::handleTagHtml, "i");
+ tagHandlers["em"] = make_pair(&JavaDocConverter::handleTagHtml, "i");
+ tagHandlers["li"] = make_pair(&JavaDocConverter::handleTagHtml, "li");
+ tagHandlers["p"] = make_pair(&JavaDocConverter::handleTagHtml, "code");
+ // these commands insert just a single char, some of them need to be escaped
+ tagHandlers["$"] = make_pair(&JavaDocConverter::handleTagChar, "");
+ tagHandlers["@"] = make_pair(&JavaDocConverter::handleTagChar, "");
+ tagHandlers["\\"] = make_pair(&JavaDocConverter::handleTagChar, "");
+ tagHandlers["<"] = make_pair(&JavaDocConverter::handleTagChar, "&lt;");
+ tagHandlers[">"] = make_pair(&JavaDocConverter::handleTagChar, "&gt;");
+ tagHandlers["&"] = make_pair(&JavaDocConverter::handleTagChar, "&amp;");
+ tagHandlers["#"] = make_pair(&JavaDocConverter::handleTagChar, "");
+ tagHandlers["%"] = make_pair(&JavaDocConverter::handleTagChar, "");
+ tagHandlers["~"] = make_pair(&JavaDocConverter::handleTagChar, "");
+ tagHandlers["\""] = make_pair(&JavaDocConverter::handleTagChar, "&quot;");
+ tagHandlers["."] = make_pair(&JavaDocConverter::handleTagChar, "");
+ tagHandlers["::"] = make_pair(&JavaDocConverter::handleTagChar, "");
+ // these commands are stripped out
+ tagHandlers["attention"] = make_pair(&JavaDocConverter::handleParagraph, "");
+ tagHandlers["anchor"] = make_pair(&JavaDocConverter::handleTagAnchor, "");
+ tagHandlers["brief"] = make_pair(&JavaDocConverter::handleParagraph, "");
+ tagHandlers["bug"] = make_pair(&JavaDocConverter::handleParagraph, "");
+ tagHandlers["date"] = make_pair(&JavaDocConverter::handleParagraph, "");
+ tagHandlers["details"] = make_pair(&JavaDocConverter::handleParagraph, "");
+ // this command is inserts text accumulated after cmd htmlonly -
+ // see DoxygenParser - CMD_HTML_ONLY.
+ tagHandlers["htmlonly"] = make_pair(&JavaDocConverter::handleParagraph, "");
+ tagHandlers["invariant"] = make_pair(&JavaDocConverter::handleParagraph, "");
+ tagHandlers["latexonly"] = make_pair(&JavaDocConverter::handleParagraph, "");
+ tagHandlers["manonly"] = make_pair(&JavaDocConverter::handleParagraph, "");
+ tagHandlers["partofdescription"] = make_pair(&JavaDocConverter::handleParagraph, "");
+ tagHandlers["rtfonly"] = make_pair(&JavaDocConverter::handleParagraph, "");
+ tagHandlers["short"] = make_pair(&JavaDocConverter::handleParagraph, "");
+ tagHandlers["xmlonly"] = make_pair(&JavaDocConverter::handleParagraph, "");
+ // these commands are kept as-is, they are supported by JavaDoc
+ tagHandlers["author"] = make_pair(&JavaDocConverter::handleTagSame, "");
+ tagHandlers["authors"] = make_pair(&JavaDocConverter::handleTagSame, "author");
+ tagHandlers["deprecated"] = make_pair(&JavaDocConverter::handleTagSame, "");
+ tagHandlers["exception"] = make_pair(&JavaDocConverter::handleTagSame, "");
+ tagHandlers["package"] = make_pair(&JavaDocConverter::handleTagSame, "");
+ tagHandlers["param"] = make_pair(&JavaDocConverter::handleTagParam, "");
+ tagHandlers["tparam"] = make_pair(&JavaDocConverter::handleTagParam, "");
+ tagHandlers["ref"] = make_pair(&JavaDocConverter::handleTagRef, "");
+ tagHandlers["result"] = make_pair(&JavaDocConverter::handleTagSame, "return");
+ tagHandlers["return"] = make_pair(&JavaDocConverter::handleTagSame, "");
+ tagHandlers["returns"] = make_pair(&JavaDocConverter::handleTagSame, "return");
+ //tagHandlers["see"] = make_pair(&JavaDocConverter::handleTagSame, "");
+ //tagHandlers["sa"] = make_pair(&JavaDocConverter::handleTagSame, "see");
+ tagHandlers["since"] = make_pair(&JavaDocConverter::handleTagSame, "");
+ tagHandlers["throws"] = make_pair(&JavaDocConverter::handleTagSame, "");
+ tagHandlers["throw"] = make_pair(&JavaDocConverter::handleTagSame, "throws");
+ tagHandlers["version"] = make_pair(&JavaDocConverter::handleTagSame, "");
+ // these commands have special handlers
+ tagHandlers["code"] = make_pair(&JavaDocConverter::handleTagExtended, "code");
+ tagHandlers["cond"] = make_pair(&JavaDocConverter::handleTagMessage, "Conditional comment: ");
+ tagHandlers["copyright"] = make_pair(&JavaDocConverter::handleTagMessage, "Copyright: ");
+ tagHandlers["else"] = make_pair(&JavaDocConverter::handleTagIf, "Else: ");
+ tagHandlers["elseif"] = make_pair(&JavaDocConverter::handleTagIf, "Else if: ");
+ tagHandlers["endcond"] = make_pair(&JavaDocConverter::handleTagMessage, "End of conditional comment.");
+ // space in second arg prevents Javadoc to treat '@ example' as command. File name of
+ // example is still informative to user.
+ tagHandlers["example"] = make_pair(&JavaDocConverter::handleTagSame, " example");
+ tagHandlers["if"] = make_pair(&JavaDocConverter::handleTagIf, "If: ");
+ tagHandlers["ifnot"] = make_pair(&JavaDocConverter::handleTagIf, "If not: ");
+ tagHandlers["image"] = make_pair(&JavaDocConverter::handleTagImage, "");
+ tagHandlers["link"] = make_pair(&JavaDocConverter::handleTagLink, "");
+ tagHandlers["see"] = make_pair(&JavaDocConverter::handleTagSee, "");
+ tagHandlers["sa"] = make_pair(&JavaDocConverter::handleTagSee, "");
+ tagHandlers["note"] = make_pair(&JavaDocConverter::handleTagMessage, "Note: ");
+ tagHandlers["overload"] = make_pair(&JavaDocConverter::handleTagMessage,
+ "This is an overloaded member function, provided for"
+ " convenience. It differs from the above function only in what" " argument(s) it accepts.");
+ tagHandlers["par"] = make_pair(&JavaDocConverter::handleTagPar, "");
+ tagHandlers["remark"] = make_pair(&JavaDocConverter::handleTagMessage, "Remarks: ");
+ tagHandlers["remarks"] = make_pair(&JavaDocConverter::handleTagMessage, "Remarks: ");
+ tagHandlers["todo"] = make_pair(&JavaDocConverter::handleTagMessage, "TODO: ");
+ tagHandlers["verbatim"] = make_pair(&JavaDocConverter::handleTagExtended, "literal");
+
+ // \f commands output literal Latex formula, which is still better than nothing.
+ tagHandlers["f$"] = make_pair(&JavaDocConverter::handleTagVerbatim, "");
+ tagHandlers["f["] = make_pair(&JavaDocConverter::handleTagVerbatim, "");
+ tagHandlers["f{"] = make_pair(&JavaDocConverter::handleTagVerbatim, "");
+
+ tagHandlers["warning"] = make_pair(&JavaDocConverter::handleTagMessage, "Warning: ");
+ // this command just prints its contents
+ // (it is internal command of swig's parser, contains plain text)
+ tagHandlers["plainstd::string"] = make_pair(&JavaDocConverter::handlePlainString, "");
+ tagHandlers["plainstd::endl"] = make_pair(&JavaDocConverter::handleNewLine, "");
+ tagHandlers["n"] = make_pair(&JavaDocConverter::handleNewLine, "");
+
+ // HTML tags
+ tagHandlers["<a"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<a");
+ tagHandlers["<b"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<b");
+ tagHandlers["<blockquote"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<blockquote");
+ tagHandlers["<body"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<body");
+ tagHandlers["<br"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<br");
+ tagHandlers["<center"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<center");
+ tagHandlers["<caption"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<caption");
+ tagHandlers["<code"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<code");
+ tagHandlers["<dd"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<dd");
+ tagHandlers["<dfn"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<dfn");
+ tagHandlers["<div"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<div");
+ tagHandlers["<dl"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<dl");
+ tagHandlers["<dt"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<dt");
+ tagHandlers["<em"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<em");
+ tagHandlers["<form"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<form");
+ tagHandlers["<hr"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<hr");
+ tagHandlers["<h1"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<h1");
+ tagHandlers["<h2"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<h2");
+ tagHandlers["<h3"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<h3");
+ tagHandlers["<i"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<i");
+ tagHandlers["<input"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<input");
+ tagHandlers["<img"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<img");
+ tagHandlers["<li"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<li");
+ tagHandlers["<meta"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<meta");
+ tagHandlers["<multicol"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<multicol");
+ tagHandlers["<ol"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<ol");
+ tagHandlers["<p"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<p");
+ tagHandlers["<pre"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<pre");
+ tagHandlers["<small"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<small");
+ tagHandlers["<span"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<span");
+ tagHandlers["<strong"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<strong");
+ tagHandlers["<sub"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<sub");
+ tagHandlers["<sup"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<sup");
+ tagHandlers["<table"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<table");
+ tagHandlers["<td"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<td");
+ tagHandlers["<th"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<th");
+ tagHandlers["<tr"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<tr");
+ tagHandlers["<tt"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<tt");
+ tagHandlers["<kbd"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<kbd");
+ tagHandlers["<ul"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<ul");
+ tagHandlers["<var"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<var");
+
+ // HTML entities
+ tagHandlers["&copy"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&copy");
+ tagHandlers["&trade"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&trade");
+ tagHandlers["&reg"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&reg");
+ tagHandlers["&lt"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&lt");
+ tagHandlers["&gt"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&gt");
+ tagHandlers["&amp"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&amp");
+ tagHandlers["&apos"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&apos");
+ tagHandlers["&quot"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&quot");
+ tagHandlers["&lsquo"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&lsquo");
+ tagHandlers["&rsquo"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&rsquo");
+ tagHandlers["&ldquo"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&ldquo");
+ tagHandlers["&rdquo"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&rdquo");
+ tagHandlers["&ndash"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&ndash");
+ tagHandlers["&mdash"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&mdash");
+ tagHandlers["&nbsp"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&nbsp");
+ tagHandlers["&times"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&times");
+ tagHandlers["&minus"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&minus");
+ tagHandlers["&sdot"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&sdot");
+ tagHandlers["&sim"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&sim");
+ tagHandlers["&le"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&le");
+ tagHandlers["&ge"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&ge");
+ tagHandlers["&larr"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&larr");
+ tagHandlers["&rarr"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&rarr");
+}
+
+JavaDocConverter::JavaDocConverter(int flags) :
+ DoxygenTranslator(flags) {
+ fillStaticTables();
+}
+
+/**
+ * Formats comment lines by inserting '\n *' at to long lines and tabs for
+ * indent. Currently it is disabled, which means original comment format is
+ * preserved. Experience shows, that this is usually better than breaking
+ * lines automatically, especially because original line endings are not removed,
+ * which results in short lines. To be useful, this function should have much
+ * better algorithm.
+ */
+std::string JavaDocConverter::formatCommand(std::string unformattedLine, int indent) {
+ std::string formattedLines;
+ return unformattedLine; // currently disabled
+ std::string::size_type lastPosition = 0;
+ std::string::size_type i = 0;
+ int isFirstLine = 1;
+ while (i != std::string::npos && i < unformattedLine.length()) {
+ lastPosition = i;
+ if (isFirstLine) {
+ i += APPROX_LINE_LENGTH;
+ } else {
+ i += APPROX_LINE_LENGTH - indent * TAB_SIZE;
+ }
+
+ i = unformattedLine.find(" ", i);
+
+ if (i > 0 && i + 1 < unformattedLine.length()) {
+ if (!isFirstLine)
+ for (int j = 0; j < indent; j++) {
+ formattedLines.append("\t");
+ } else {
+ isFirstLine = 0;
+ }
+ formattedLines.append(unformattedLine.substr(lastPosition, i - lastPosition + 1));
+ formattedLines.append("\n *");
+
+ }
+ }
+ if (lastPosition < unformattedLine.length()) {
+ if (!isFirstLine) {
+ for (int j = 0; j < indent; j++) {
+ formattedLines.append("\t");
+ }
+ }
+ formattedLines.append(unformattedLine.substr(lastPosition, unformattedLine.length() - lastPosition));
+ }
+
+ return formattedLines;
+}
+
+/**
+ * Returns true, if the given parameter exists in the current node
+ * (for example param is a name of function parameter). If feature
+ * 'doxygen:nostripparams' is set, then this method always returns
+ * true - parameters are copied to output regardless of presence in
+ * function params list.
+ */
+bool JavaDocConverter::paramExists(std::string param) {
+
+ if (GetFlag(currentNode, "feature:doxygen:nostripparams")) {
+ return true;
+ }
+
+ ParmList *plist = CopyParmList(Getattr(currentNode, "parms"));
+
+ for (Parm *p = plist; p;) {
+
+ if (Getattr(p, "name") && Char(Getattr(p, "name")) == param) {
+ return true;
+ }
+ /* doesn't seem to work always: in some cases (especially for 'self' parameters)
+ * tmap:in is present, but tmap:in:next is not and so this code skips all the parameters
+ */
+ //p = Getattr(p, "tmap:in") ? Getattr(p, "tmap:in:next") : nextSibling(p);
+ p = nextSibling(p);
+ }
+
+ Delete(plist);
+
+ return false;
+}
+
+std::string JavaDocConverter::translateSubtree(DoxygenEntity &doxygenEntity) {
+ std::string translatedComment;
+
+ if (doxygenEntity.isLeaf) {
+ return translatedComment;
+ }
+
+ for (DoxygenEntityListIt p = doxygenEntity.entityList.begin(); p != doxygenEntity.entityList.end(); p++) {
+
+ translateEntity(*p, translatedComment);
+ translateSubtree(*p);
+ }
+
+ return translatedComment;
+}
+
+/**
+ * Checks if a handler for the given tag exists, and calls it.
+ */
+void JavaDocConverter::translateEntity(DoxygenEntity &tag, std::string &translatedComment) {
+
+ std::map<std::string, std::pair<tagHandler, std::string> >::iterator it;
+ it = tagHandlers.find(getBaseCommand(tag.typeOfEntity));
+
+ if (it != tagHandlers.end()) {
+ (this->*(it->second.first))(tag, translatedComment, it->second.second);
+ } else {
+ // do NOT print warning, since there are many tags, which are not
+ // translatable - many warnings hide important ones
+ // addError(WARN_DOXYGEN_COMMAND_ERROR, "Unknown doxygen or HTML tag: " + tag.typeOfEntity);
+ }
+}
+
+
+void JavaDocConverter::handleTagAnchor(DoxygenEntity &tag, std::string &translatedComment, std::string &) {
+ translatedComment += "<a id=\"" + translateSubtree(tag) + "\"></a>";
+}
+
+
+void JavaDocConverter::handleTagHtml(DoxygenEntity &tag, std::string &translatedComment, std::string &arg) {
+ if (tag.entityList.size()) { // do not include empty tags
+ std::string tagData = translateSubtree(tag);
+ // wrap the thing, ignoring whitespace
+ size_t wsPos = tagData.find_last_not_of("\n\t ");
+ if (wsPos != std::string::npos)
+ translatedComment += "<" + arg + ">" + tagData.substr(0, wsPos + 1) + "</" + arg + ">" + tagData.substr(wsPos + 1);
+ else
+ translatedComment += "<" + arg + ">" + translateSubtree(tag) + "</" + arg + "> ";
+ }
+}
+
+void JavaDocConverter::handleDoxyHtmlTag(DoxygenEntity &tag, std::string &translatedComment, std::string &arg) {
+ std::string htmlTagArgs = tag.data;
+ if (htmlTagArgs == "/") {
+ // end html tag, for example "</ul>
+ translatedComment += "</" + arg.substr(1) + ">";
+ } else {
+ translatedComment += arg + htmlTagArgs + ">";
+ }
+}
+
+void JavaDocConverter::handleHtmlEntity(DoxygenEntity &, std::string &translatedComment, std::string &arg) {
+ // html entities can be preserved for Java
+ translatedComment += arg + ';';
+}
+
+void JavaDocConverter::handleNewLine(DoxygenEntity &, std::string &translatedComment, std::string &) {
+ // <br> tag is added, because otherwise to much text is joined
+ // into same paragraph by javadoc. For example, doxy list:
+ // - item one
+ // - item two
+ // becomes one paragraph with surrounding text without newlines.
+ // This way we get to many empty lines in javadoc output, but this
+ // is still better than joined lines. Possibility for improvements
+ // exists.
+ translatedComment += "<br>\n * ";
+}
+
+void JavaDocConverter::handleTagChar(DoxygenEntity &tag, std::string &translatedComment, std::string &arg) {
+ // escape it if we need to, else just print
+ if (arg.size())
+ translatedComment += arg;
+ else
+ translatedComment += tag.typeOfEntity;
+}
+
+// handles tags which are the same in Doxygen and Javadoc.
+void JavaDocConverter::handleTagSame(DoxygenEntity &tag, std::string &translatedComment, std::string &arg) {
+ if (arg.size())
+ tag.typeOfEntity = arg;
+ translatedComment += formatCommand(std::string("@" + tag.typeOfEntity + " " + translateSubtree(tag)), 2);
+}
+
+void JavaDocConverter::handleParagraph(DoxygenEntity &tag, std::string &translatedComment, std::string &) {
+ translatedComment += formatCommand(translateSubtree(tag), 0);
+}
+
+void JavaDocConverter::handlePlainString(DoxygenEntity &tag, std::string &translatedComment, std::string &) {
+ translatedComment += tag.data;
+ // if (tag.data.size() && tag.data[tag.data.size()-1] != ' ')
+ // translatedComment += " ";
+}
+
+void JavaDocConverter::handleTagVerbatim(DoxygenEntity &tag, std::string &translatedComment, std::string &arg) {
+ translatedComment += arg + " ";
+ for (DoxygenEntityListCIt it = tag.entityList.begin(); it != tag.entityList.end(); it++) {
+ translatedComment += it->data;
+ }
+}
+
+void JavaDocConverter::handleTagExtended(DoxygenEntity &tag, std::string &translatedComment, std::string &arg) {
+ std::string dummy;
+ translatedComment += "{@" + arg + " ";
+ handleParagraph(tag, translatedComment, dummy);
+ translatedComment += "}";
+}
+
+void JavaDocConverter::handleTagIf(DoxygenEntity &tag, std::string &translatedComment, std::string &arg) {
+ std::string dummy;
+ translatedComment += arg;
+ if (tag.entityList.size()) {
+ translatedComment += tag.entityList.begin()->data;
+ tag.entityList.pop_front();
+ translatedComment += " {" + translateSubtree(tag) + "}";
+ }
+}
+
+void JavaDocConverter::handleTagMessage(DoxygenEntity &tag, std::string &translatedComment, std::string &arg) {
+ std::string dummy;
+ translatedComment += formatCommand(arg, 0);
+ handleParagraph(tag, translatedComment, dummy);
+}
+
+void JavaDocConverter::handleTagImage(DoxygenEntity &tag, std::string &translatedComment, std::string &) {
+ if (tag.entityList.size() < 2)
+ return;
+
+ std::string file;
+ std::string title;
+
+ std::list<DoxygenEntity>::iterator it = tag.entityList.begin();
+ if (it->data != "html")
+ return;
+
+ it++;
+ file = it->data;
+
+ it++;
+ if (it != tag.entityList.end())
+ title = it->data;
+
+ translatedComment += "<img src=";
+ if (file.size() >= 2 && file[0] == '"' && file[file.size() - 1] == '"')
+ translatedComment += file;
+ else
+ translatedComment += "\"" + file + "\"";
+ if (title.size())
+ translatedComment += " alt=" + title;
+
+ // the size indication is supported for Latex only in Doxygen, see manual
+
+ translatedComment += "/>";
+}
+
+void JavaDocConverter::handleTagPar(DoxygenEntity &tag, std::string &translatedComment, std::string &) {
+ std::string dummy;
+ translatedComment += "<p";
+ if (tag.entityList.size()) {
+ translatedComment += " alt=\"" + tag.entityList.begin()->data + "\"";
+ translatedComment += ">";
+ tag.entityList.pop_front();
+ handleParagraph(tag, translatedComment, dummy);
+ }
+ translatedComment += "</p>";
+}
+
+
+void JavaDocConverter::handleTagParam(DoxygenEntity &tag, std::string &translatedComment, std::string &) {
+ std::string dummy;
+
+ if (!tag.entityList.size())
+ return;
+ if (!paramExists(tag.entityList.begin()->data))
+ return;
+
+ translatedComment += "@param ";
+ translatedComment += tag.entityList.begin()->data;
+ tag.entityList.pop_front();
+ handleParagraph(tag, translatedComment, dummy);
+}
+
+
+void JavaDocConverter::handleTagRef(DoxygenEntity &tag, std::string &translatedComment, std::string &) {
+ std::string dummy;
+ if (!tag.entityList.size())
+ return;
+
+ // we translate to link, although \page is not supported in Java, but
+ // reader at least knows what to look at. Also for \anchor tag on the same
+ // page this link works.
+ string anchor = tag.entityList.begin()->data;
+ tag.entityList.pop_front();
+ string anchorText = anchor;
+ if (!tag.entityList.empty()) {
+ anchorText = tag.entityList.begin()->data;
+ }
+ translatedComment += "<a href=\"#" + anchor + "\">" + anchorText + "</a>";
+}
+
+
+string JavaDocConverter::convertLink(string linkObject) {
+ if (GetFlag(currentNode, "feature:doxygen:nolinktranslate"))
+ return linkObject;
+ // find the params in function in linkObject (if any)
+ size_t lbracePos = linkObject.find('(', 0);
+ size_t rbracePos = linkObject.find(')', 0);
+ if (lbracePos == string::npos || rbracePos == string::npos || lbracePos >= rbracePos)
+ return "";
+
+ string paramsStr = linkObject.substr(lbracePos + 1,
+ rbracePos - lbracePos - 1);
+ // strip the params, to fill them later
+ string additionalObject = linkObject.substr(rbracePos + 1, string::npos);
+ linkObject = linkObject.substr(0, lbracePos);
+
+ // find all the params
+ vector<string> params;
+ size_t lastPos = 0, commaPos = 0;
+ while (true) {
+ commaPos = paramsStr.find(',', lastPos);
+ if (commaPos == string::npos)
+ commaPos = paramsStr.size();
+ string param = paramsStr.substr(lastPos, commaPos - lastPos);
+ // if any param type is empty, we are failed
+ if (!param.size())
+ return "";
+ params.push_back(param);
+ lastPos = commaPos + 1;
+ if (lastPos >= paramsStr.size())
+ break;
+ }
+
+ linkObject += "(";
+ for (size_t i = 0; i < params.size(); i++) {
+ // translate c/c++ type string to swig's type
+ // i e 'int **arr[100][10]' -> 'a(100).a(10).p.p.int'
+ // also converting arrays to pointers
+ string paramStr = params[i];
+ String *swigType = NewString("");
+
+ // handle const qualifier
+ if (paramStr.find("const") != string::npos)
+ SwigType_add_qualifier(swigType, "const");
+
+ // handle pointers, references and arrays
+ for (int j = (int)params[i].size() - 1; j >= 0; j--) {
+ // skip all the [...] blocks, write 'p.' for every of it
+ if (paramStr[j] == ']') {
+ while (j >= 0 && paramStr[j] != '[')
+ j--;
+ // no closing brace
+ if (j < 0)
+ return "";
+ SwigType_add_pointer(swigType);
+ continue;
+ } else if (paramStr[j] == '*')
+ SwigType_add_pointer(swigType);
+ else if (paramStr[j] == '&')
+ SwigType_add_reference(swigType);
+ else if (isalnum(paramStr[j])) {
+ size_t typeNameStart = paramStr.find_last_of(' ', j + 1);
+ if (typeNameStart == string::npos)
+ typeNameStart = 0;
+ else
+ typeNameStart++;
+ Append(swigType, paramStr.substr(typeNameStart, j - typeNameStart + 1).c_str());
+ break;
+ }
+ }
+
+ // make dummy param list, to lookup typemaps for it
+ Parm *dummyParam = NewParm(swigType, "", 0);
+ Swig_typemap_attach_parms("jstype", dummyParam, NULL);
+ Language::instance()->replaceSpecialVariables(0, Getattr(dummyParam, "tmap:jstype"), dummyParam);
+
+ //Swig_print(dummyParam, 1);
+ linkObject += Char(Getattr(dummyParam, "tmap:jstype"));
+ if (i != params.size() - 1)
+ linkObject += ",";
+
+ Delete(dummyParam);
+ Delete(swigType);
+ }
+ linkObject += ")";
+
+ return linkObject + additionalObject;
+}
+
+void JavaDocConverter::handleTagLink(DoxygenEntity &tag, std::string &translatedComment, std::string &) {
+ std::string dummy;
+ if (!tag.entityList.size())
+ return;
+
+ string linkObject = convertLink(tag.entityList.begin()->data);
+ if (!linkObject.size())
+ linkObject = tag.entityList.begin()->data;
+ tag.entityList.pop_front();
+
+ translatedComment += "{@link ";
+ translatedComment += linkObject + " ";
+ handleParagraph(tag, translatedComment, dummy);
+ translatedComment += "}";
+}
+
+void JavaDocConverter::handleTagSee(DoxygenEntity &tag, std::string &translatedComment, std::string &) {
+ std::string dummy;
+ if (!tag.entityList.size())
+ return;
+
+ // tag.entity list contains contents of the @see paragraph. It should contain
+ // one link (references) to method with or without parameters. Doxygen supports
+ // arbitrary text and types mixed, but this feature is not supported here.
+ // :: or # may be used as a separator between class name and method name.
+ list<DoxygenEntity>::iterator it;
+ string methodRef;
+ for (it = tag.entityList.begin(); it != tag.entityList.end(); it++) {
+ if (it->typeOfEntity == "plainstd::endl") {
+ // handleNewLine(*it, translatedComment, dummy);
+ continue;
+ }
+ // restore entities which may be used in C++ type declaration
+ if (it->typeOfEntity == "&amp") {
+ methodRef += '&';
+ } else if (it->typeOfEntity == "&lt") {
+ methodRef += '<';
+ } else if (it->typeOfEntity == "&gt") {
+ methodRef += '>';
+ } else {
+ methodRef += it->data;
+ }
+ }
+
+ // replace :: with #, but only if it appears before left brace
+ size_t lbrace = methodRef.find('(');
+ size_t dblColon = methodRef.find("::");
+ if (dblColon < lbrace) {
+ methodRef = methodRef.substr(0, dblColon) + '#' + methodRef.substr(dblColon + 2);
+ }
+
+ translatedComment += "@see ";
+ string linkObject = convertLink(methodRef);
+ if (!linkObject.size()) {
+ linkObject = methodRef;
+ }
+ translatedComment += linkObject;
+}
+
+/* This function moves all line endings at the end of child entities
+ * out of the child entities to the parent.
+ * For example, entity tree:
+
+ -root
+ |-param
+ |-paramText
+ |-endline
+
+ should be turned to
+
+ -root
+ |-param
+ |-paramText
+ |-endline
+ *
+ */
+int JavaDocConverter::shiftEndlinesUpTree(DoxygenEntity &root, int level) {
+ DoxygenEntityListIt it = root.entityList.begin();
+ while (it != root.entityList.end()) {
+ // remove line endings
+ int ret = shiftEndlinesUpTree(*it, level + 1);
+ // insert them after this element
+ it++;
+ for (int i = 0; i < ret; i++) {
+ root.entityList.insert(it, DoxygenEntity("plainstd::endl"));
+ }
+ }
+
+ // continue only if we are not root
+ if (!level) {
+ return 0;
+ }
+
+ int removedCount = 0;
+ while (!root.entityList.empty()
+ && root.entityList.rbegin()->typeOfEntity == "plainstd::endl") {
+ root.entityList.pop_back();
+ removedCount++;
+ }
+ return removedCount;
+}
+
+/**
+ * This makes sure that all comment lines contain '*'. It is not mandatory in doxygen,
+ * but highly recommended for Javadoc. '*' in empty lines are indented according
+ * to indentation of the first line. Indentation of non-empty lines is not
+ * changed - garbage in garbage out.
+ */
+std::string JavaDocConverter::indentAndInsertAsterisks(const string &doc) {
+
+ size_t idx = doc.find('\n');
+ size_t indent = 0;
+ bool singleLineComment = idx == string::npos;
+ // Detect indentation.
+ // The first line in comment is the one after '/**', which may be
+ // spaces and '\n' or the text. In any case it is not suitable to detect
+ // indentation, so we have to skip the first '\n'.
+ // However, if there is just one line, then use that line to detect indentation.
+ if (idx != string::npos) {
+ size_t nonspaceIdx = doc.find_first_not_of(" \t", idx + 1);
+ if (nonspaceIdx != string::npos) {
+ indent = nonspaceIdx - idx;
+ }
+ }
+
+ if (indent == 0) {
+ // we can't indent the first line less than 0
+ indent = 1;
+ }
+ // Create the first line of Javadoc comment.
+ string indentStr(indent - 1, ' ');
+ string translatedStr = indentStr + "/**";
+ if (indent > 1) {
+ // remove the first space, so that '*' will be aligned
+ translatedStr = translatedStr.substr(1);
+ }
+
+ translatedStr += doc;
+
+ // insert '*' before each comment line, if it does not have it
+ idx = translatedStr.find('\n');
+
+ while (idx != string::npos) {
+
+ size_t nonspaceIdx = translatedStr.find_first_not_of(" \t", idx + 1);
+ if (nonspaceIdx != string::npos && translatedStr[nonspaceIdx] != '*') {
+ // line without '*' found - is it empty?
+ if (translatedStr[nonspaceIdx] != '\n') {
+ // add '* ' to each line without it
+ translatedStr = translatedStr.substr(0, nonspaceIdx) + "* " + translatedStr.substr(nonspaceIdx);
+ //printf(translatedStr.c_str());
+ } else {
+ // we found empty line, replace it with indented '*'
+ translatedStr = translatedStr.substr(0, idx + 1) + indentStr + "* " + translatedStr.substr(nonspaceIdx);
+ }
+ }
+ idx = translatedStr.find('\n', nonspaceIdx);
+ }
+
+ // Add the last comment line properly indented
+ size_t nonspaceEndIdx = translatedStr.find_last_not_of(" \t");
+ if (nonspaceEndIdx != string::npos) {
+ if (translatedStr[nonspaceEndIdx] != '\n') {
+ if (!singleLineComment)
+ translatedStr += '\n';
+ } else {
+ // remove trailing spaces
+ translatedStr = translatedStr.substr(0, nonspaceEndIdx + 1);
+ }
+ }
+ translatedStr += indentStr + "*/\n";
+
+ return translatedStr;
+}
+
+String *JavaDocConverter::makeDocumentation(Node *node) {
+
+ String *documentation = getDoxygenComment(node);
+
+ if (documentation == NULL) {
+ return NewString("");
+ }
+
+ if (GetFlag(node, "feature:doxygen:notranslate")) {
+
+ string doc = Char(documentation);
+
+ string translatedStr = indentAndInsertAsterisks(doc);
+
+ return NewString(translatedStr.c_str());
+ }
+
+ DoxygenEntityList entityList = parser.createTree(node, documentation);
+
+ // entityList.sort(CompareDoxygenEntities()); sorting currently not used,
+
+ if (m_flags & debug_translator) {
+ std::cout << "---RESORTED LIST---" << std::endl;
+ printTree(entityList);
+ }
+ // store the current node
+ // (currently just to handle params)
+ currentNode = node;
+
+ std::string javaDocString = "/**\n * ";
+
+ DoxygenEntity root("root", entityList);
+
+ shiftEndlinesUpTree(root);
+
+ // strip line endings at the beginning
+ while (!root.entityList.empty()
+ && root.entityList.begin()->typeOfEntity == "plainstd::endl") {
+ root.entityList.pop_front();
+ }
+
+ // and at the end
+ while (!root.entityList.empty()
+ && root.entityList.rbegin()->typeOfEntity == "plainstd::endl") {
+ root.entityList.pop_back();
+ }
+
+ javaDocString += translateSubtree(root);
+
+ javaDocString += "\n */\n";
+
+ if (m_flags & debug_translator) {
+ std::cout << "\n---RESULT IN JAVADOC---" << std::endl;
+ std::cout << javaDocString;
+ }
+
+ return NewString(javaDocString.c_str());
+}
+
+void JavaDocConverter::addError(int warningType, const std::string &message) {
+ Swig_warning(warningType, "", 0, "Doxygen parser warning: %s. \n", message.c_str());
+}