diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y index d16a743e4..95bd8701d 100644 --- a/Source/CParse/parser.y +++ b/Source/CParse/parser.y @@ -13,7 +13,7 @@ #define yylex yylex -char cvsroot_parser_y[] = "$Id$"; +char cvsroot_parser_y[] = "$Id: parser.y 10767 2008-08-16 07:31:05Z cherylfoil $"; #include "swig.h" #include "cparse.h" @@ -3209,15 +3209,18 @@ c_constructor_decl : storage_class type LPAREN parms RPAREN ctor_end { doxygen_comment : DOXYGENSTRING { + while(Strchr($1,'/') == Char($1)) + Replace($1,"/","",DOH_REPLACE_FIRST); if(isStructuralDoxygen($1)){ $$ = new_node("doxycomm"); Setattr($$,"DoxygenComment",$1); } else { if(currentComment != 0){ - Append(currentComment, $1); + Append(currentComment,$1); } - else currentComment = $1; + else + currentComment = $1; $$ = 0; } } diff --git a/Source/DoxygenTranslator/src/DoxygenEntity.h b/Source/DoxygenTranslator/src/DoxygenEntity.h index 4313bfb2a..779065bdf 100644 --- a/Source/DoxygenTranslator/src/DoxygenEntity.h +++ b/Source/DoxygenTranslator/src/DoxygenEntity.h @@ -21,5 +21,17 @@ public: int isLeaf; }; +struct find_entity { + find_entity(string typeString) { + typeOfEntity = typeString; + } + + bool operator()(DoxygenEntity& entity) { + return entity.typeOfEntity == typeOfEntity; + } + + string typeOfEntity; +}; + #endif /*TOKENLIST_H_*/ diff --git a/Source/DoxygenTranslator/src/DoxygenTranslator.cpp b/Source/DoxygenTranslator/src/DoxygenTranslator.cpp index d6f0ae152..7fe2897c5 100644 --- a/Source/DoxygenTranslator/src/DoxygenTranslator.cpp +++ b/Source/DoxygenTranslator/src/DoxygenTranslator.cpp @@ -5,13 +5,16 @@ #include #include "DoxygenEntity.h" #include "JavaDocConverter.h" +#include "PyDocConverter.h" DoxygenParser doxyParse; JavaDocConverter jDC; +PyDocConverter pyDC; DoxygenTranslator::DoxygenTranslator(){ doxyParse = DoxygenParser(); JavaDocConverter jDC = JavaDocConverter(); + PyDocConverter pyDC = PyDocConverter(); } DoxygenTranslator::~DoxygenTranslator(){ @@ -19,13 +22,16 @@ DoxygenTranslator::~DoxygenTranslator(){ } -char *DoxygenTranslator::convert(char* doxygenBlob, char* option){ +char *DoxygenTranslator::convert(Node *n, char* doxygenBlob, char* option){ list rootList = doxyParse.createTree(string(doxygenBlob)); string returnedString; if(strcmp(option, "JAVADOC") == 0){ - returnedString = jDC.convertToJavaDoc(rootList); + returnedString = jDC.convertToJavaDoc(n, rootList); + } + else if(strcmp(option, "PYDOC") == 0){ + returnedString = pyDC.convertToPyDoc(n, rootList); } else cout << "Option not current supported.\n"; char *nonConstString; @@ -59,7 +65,7 @@ int testCommands(){ //cout << "---ORIGINAL DOXYGEN--- " << endl << exampleArray[i] << endl; char *nonConstString = (char *)malloc(exampleArray[i].length()+1); strcpy(nonConstString, exampleArray[i].c_str()); - char * result = dT.convert(nonConstString, "JAVADOC"); + char * result = dT.convert(NULL, nonConstString, "JAVADOC"); free(nonConstString); free(result); } diff --git a/Source/DoxygenTranslator/src/DoxygenTranslator.h b/Source/DoxygenTranslator/src/DoxygenTranslator.h index e5fe7bcbb..3c26e3a25 100644 --- a/Source/DoxygenTranslator/src/DoxygenTranslator.h +++ b/Source/DoxygenTranslator/src/DoxygenTranslator.h @@ -1,10 +1,13 @@ #ifndef DOXYGENTRANSLATOR_H_ #define DOXYGENTRANSLATOR_H_ + +#include "swig.h" + class DoxygenTranslator { public: DoxygenTranslator(); virtual ~DoxygenTranslator(); - char* convert(char* doxygenBlob, char* option); + char* convert(Node *n, char* doxygenBlob, char* option); }; #endif /*DOXYGENTRANSLATOR_H_*/ diff --git a/Source/DoxygenTranslator/src/JavaDocConverter.cpp b/Source/DoxygenTranslator/src/JavaDocConverter.cpp index 70c3bb731..b611cddf9 100644 --- a/Source/DoxygenTranslator/src/JavaDocConverter.cpp +++ b/Source/DoxygenTranslator/src/JavaDocConverter.cpp @@ -213,7 +213,7 @@ string translateEntity(DoxygenEntity &doxyEntity){ return ""; } -string JavaDocConverter:: convertToJavaDoc(list entityList){ +string JavaDocConverter:: convertToJavaDoc(Node *n, list entityList){ entityList.sort(compare_DoxygenEntities); diff --git a/Source/DoxygenTranslator/src/JavaDocConverter.h b/Source/DoxygenTranslator/src/JavaDocConverter.h index 53a270ce4..39de3dd15 100644 --- a/Source/DoxygenTranslator/src/JavaDocConverter.h +++ b/Source/DoxygenTranslator/src/JavaDocConverter.h @@ -1,15 +1,17 @@ - #include - #include - #include "DoxygenEntity.h" #ifndef JAVADOCCONVERTER_H_ #define JAVADOCCONVERTER_H_ +#include +#include +#include "swig.h" +#include "DoxygenEntity.h" + class JavaDocConverter { public: JavaDocConverter(); - string convertToJavaDoc(list entityList); + string convertToJavaDoc(Node *n, list entityList); ~JavaDocConverter(); void printSortedTree(list &entityList); }; diff --git a/Source/DoxygenTranslator/src/PyDocConverter.cpp b/Source/DoxygenTranslator/src/PyDocConverter.cpp new file mode 100644 index 000000000..ad675e273 --- /dev/null +++ b/Source/DoxygenTranslator/src/PyDocConverter.cpp @@ -0,0 +1,205 @@ +#include "PyDocConverter.h" +#include +#include + +#define APPROX_LINE_LENGTH 64//characters per line allowed +#define TAB_SIZE 8//characters per line allowed + +//TODO {@link} {@linkplain} {@docRoot}, and other useful doxy commands that are not a pydoc tag +PyDocConverter::PyDocConverter() +{ + debug = 1; +} + +PyDocConverter::~PyDocConverter() +{ +} + +/* Sorts entities by pyDoc standard order for commands + * NOTE: will not behave entirely properly until "First level" comments + * such as brief descriptions are TAGGED as such + */ +bool compare_DoxygenEntities(DoxygenEntity first, DoxygenEntity second); + +void PyDocConverter::printSortedTree(list &entityList){ + list::iterator p = entityList.begin(); + while (p != entityList.end()){ + (*p).printEntity(0); + p++; + } +} + +string PyDocConverter::formatParam(Node *n, DoxygenEntity &doxygenEntity) { + string result; + ParmList *plist = CopyParmList(Getattr(n, "parms")); + Parm *p = NULL; + + DoxygenEntity& paramNameEntity = *doxygenEntity.entityList.begin(); + DoxygenEntity& paramDescriptionEntity = *(++doxygenEntity.entityList.begin()); + + for (p = plist; p;) { + if(Char(Getattr(p, "name")) == paramNameEntity.data) { + std::string name = Char(Swig_name_make(n, 0, Getattr(p, "name"), 0, 0)); + std::string type = Char(Swig_name_make(n, 0, Getattr(p, "type"), 0, 0)); + + std::ostringstream parameterDocString; + + parameterDocString << std::endl << name << " (" << type << "): "; + parameterDocString << paramDescriptionEntity.data; + + result = parameterDocString.str(); + break; + } + p = Getattr(p, "tmap:in") ? Getattr(p, "tmap:in:next") : nextSibling(p); + } + + Delete(plist); + return result; +} + +string PyDocConverter::formatCommand(string unformattedLine, int indent){ + string formattedLines = "\n"; + int lastPosition = 0; + int i = 0; + int isFirstLine = 1; + while (i != -1 && 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; +} + +/* Contains the conversions for tags + * could probably be much more efficient... + */ +string PyDocConverter::pyDocFormat(DoxygenEntity &doxygenEntity){ + if(doxygenEntity.typeOfEntity.compare("partofdescription") == 0){ + return doxygenEntity.data; + } + if (doxygenEntity.typeOfEntity.compare("plainstring") == 0){ + return doxygenEntity.data; + } + else if (doxygenEntity.typeOfEntity.compare("b") == 0){ + return "" + doxygenEntity.data + ""; + } + else if (doxygenEntity.typeOfEntity.compare("c") == 0){ + return "" + doxygenEntity.data + ""; + } + else if (doxygenEntity.typeOfEntity.compare("@") == 0){ + return "@"; + } + else if (doxygenEntity.typeOfEntity.compare("\\") == 0){ + return "\\"; + } + else if (doxygenEntity.typeOfEntity.compare("<") == 0){ + return "<"; + } + else if (doxygenEntity.typeOfEntity.compare(">") == 0){ + return ">"; + } + else if (doxygenEntity.typeOfEntity.compare("&") == 0){ + return "&"; + } + else if (doxygenEntity.typeOfEntity.compare("#") == 0){ + return "#"; + } + else if (doxygenEntity.typeOfEntity.compare("%") == 0){ + return "%"; + } + else if (doxygenEntity.typeOfEntity.compare("~") == 0){ + return "~"; + } + return ""; +} + + +string PyDocConverter::translateSubtree( DoxygenEntity &doxygenEntity){ + string returnedString; + if (doxygenEntity.isLeaf){ return pyDocFormat(doxygenEntity) + " ";} + else { + returnedString += pyDocFormat(doxygenEntity); + list::iterator p = doxygenEntity.entityList.begin(); + while (p != doxygenEntity.entityList.end()){ + returnedString+= translateSubtree(*p); + p++; + } + } + return returnedString; +} + +string PyDocConverter::translateEntity(Node *n, DoxygenEntity &doxyEntity){ + if(doxyEntity.typeOfEntity.compare("partofdescription")== 0) return formatCommand(string(translateSubtree(doxyEntity)), 0); + if ((doxyEntity.typeOfEntity.compare("brief") == 0)||(doxyEntity.typeOfEntity.compare("details") == 0)){ + return formatCommand(string(translateSubtree(doxyEntity)), 0) + "\n * ";} + else if(doxyEntity.typeOfEntity.compare("plainstring")== 0 + || doxyEntity.typeOfEntity.compare("deprecated")== 0 + || doxyEntity.typeOfEntity.compare("brief")== 0) + return formatCommand(doxyEntity.data, 0) + "\n * "; + else if(doxyEntity.typeOfEntity.compare("see") == 0){ + return formatCommand(string("@" + doxyEntity.typeOfEntity + "\t\t" + translateSubtree(doxyEntity)), 2); + } + else if(doxyEntity.typeOfEntity.compare("param") == 0) { + return formatParam(n, doxyEntity); + } + else if(doxyEntity.typeOfEntity.compare("return")== 0 + || doxyEntity.typeOfEntity.compare("author")== 0 + || doxyEntity.typeOfEntity.compare("param")== 0 + || doxyEntity.typeOfEntity.compare("since")== 0 + || doxyEntity.typeOfEntity.compare("version")== 0 + || doxyEntity.typeOfEntity.compare("exception") == 0 + || doxyEntity.typeOfEntity.compare("deprecated") == 0){ + return formatCommand(string("@" + doxyEntity.typeOfEntity + "\t" + translateSubtree(doxyEntity)), 2); + } + else if(doxyEntity.typeOfEntity.compare("sa")== 0){ + return formatCommand(string("@see\t\t" + translateSubtree(doxyEntity)), 2); + } + else return formatCommand(pyDocFormat(doxyEntity), 0 ); + return ""; +} + +string PyDocConverter::convertToPyDoc(Node *n, list entityList){ + entityList.sort(compare_DoxygenEntities); + + if(debug){ + cout << "---RESORTED LIST---" << endl; + printSortedTree(entityList); + } + + string pyDocString = "\"\"\""; + + list::iterator entityIterator = entityList.begin(); + while (entityIterator != entityList.end()){ + pyDocString += translateEntity(n, *entityIterator); + entityIterator++; + } + + pyDocString += "\n\"\"\"\n"; + + if(debug){ + cout << "\n---RESULT IN PYDOC---" << endl; + cout << pyDocString; + } + + return pyDocString; +} \ No newline at end of file diff --git a/Source/DoxygenTranslator/src/PyDocConverter.h b/Source/DoxygenTranslator/src/PyDocConverter.h new file mode 100644 index 000000000..b9d813476 --- /dev/null +++ b/Source/DoxygenTranslator/src/PyDocConverter.h @@ -0,0 +1,29 @@ +#ifndef PYDOCCONVERTER_H_ +#define PYDOCCONVERTER_H_ + +#include +#include +#include "swig.h" +#include "DoxygenEntity.h" + +class PyDocConverter +{ +public: + + PyDocConverter(); + string convertToPyDoc(Node *n, list entityList); + ~PyDocConverter(); + void printSortedTree(list &entityList); + +protected: + std::string formatParam(Node *n, DoxygenEntity &doxygenEntity); + std::string formatCommand(string unformattedLine, int indent); + std::string pyDocFormat(DoxygenEntity &doxygenEntity); + std::string translateSubtree( DoxygenEntity &doxygenEntity); + std::string translateEntity(Node *n, DoxygenEntity &doxyEntity); + +private: + bool debug; +}; + +#endif /*PYDOCCONVERTER_H_*/ diff --git a/Source/Makefile.am b/Source/Makefile.am index 65b5c6f6f..bfa6b3413 100644 --- a/Source/Makefile.am +++ b/Source/Makefile.am @@ -97,6 +97,8 @@ eswig_SOURCES = CParse/cscanner.c \ DoxygenTranslator/src/DoxygenTranslator.cpp\ DoxygenTranslator/src/JavaDocConverter.h\ DoxygenTranslator/src/JavaDocConverter.cpp\ + DoxygenTranslator/src/PyDocConverter.h\ + DoxygenTranslator/src/PyDocConverter.cpp\ DoxygenTranslator/src/Token.h\ DoxygenTranslator/src/Token.cpp\ DoxygenTranslator/src/TokenList.h\ diff --git a/Source/Modules/java.cxx b/Source/Modules/java.cxx index 961f9098c..edb88ebbb 100644 --- a/Source/Modules/java.cxx +++ b/Source/Modules/java.cxx @@ -510,7 +510,7 @@ public: if (doxygen_javadoc_flag){ if (Getattr(n,"DoxygenComment")){ if(comment_creation_chatter) Printf(f_module, "/* This was generated from top() */"); - char *convertedString = doxyTranslator.convert(Char(Getattr(n,"DoxygenComment")),"JAVADOC"); + char *convertedString = doxyTranslator.convert(n, Char(Getattr(n,"DoxygenComment")),"JAVADOC"); Printf(f_module, convertedString); free(convertedString); } @@ -1238,7 +1238,7 @@ public: if (doxygen_javadoc_flag){ if (Getattr(n,"DoxygenComment")){ if(comment_creation_chatter) Printv(proxy_class_constants_code, "/* This was generated from enumvalueDeclaration */", NIL ); - char *convertedString = doxyTranslator.convert(Char(Getattr(n,"DoxygenComment")),"JAVADOC"); + char *convertedString = doxyTranslator.convert(n, Char(Getattr(n,"DoxygenComment")),"JAVADOC"); Printv(proxy_class_constants_code, convertedString, NIL); free(convertedString); } @@ -1310,7 +1310,7 @@ public: if (doxygen_javadoc_flag){ if (Getattr(n,"DoxygenComment")){ if(comment_creation_chatter) Printf(enum_code, "/* This was generated from enumvalueDeclaration() */" ); - char *convertedString = doxyTranslator.convert(Char(Getattr(n,"DoxygenComment")),"JAVADOC"); + char *convertedString = doxyTranslator.convert(n, Char(Getattr(n,"DoxygenComment")),"JAVADOC"); Printf(enum_code, convertedString); free(convertedString); } @@ -1382,7 +1382,7 @@ public: if (doxygen_javadoc_flag){ if (Getattr(n,"DoxygenComment")){ if(comment_creation_chatter) Printv(structuralComments, "/* This was generated from doxygenComment() */\n", NIL); - char *convertedString = doxyTranslator.convert(Char(Getattr(n,"DoxygenComment")),"JAVADOC"); + char *convertedString = doxyTranslator.convert(n, Char(Getattr(n,"DoxygenComment")),"JAVADOC"); Printv(structuralComments, convertedString, NIL); free(convertedString); } @@ -1412,7 +1412,7 @@ public: if (doxygen_javadoc_flag){ if (Getattr(n,"DoxygenComment")){ if(comment_creation_chatter) Printf(constants_code, "/* This was generated from enumvalueDeclaration */\n"); - char *convertedString = doxyTranslator.convert(Char(Getattr(n,"DoxygenComment")),"JAVADOC"); + char *convertedString = doxyTranslator.convert(n, Char(Getattr(n,"DoxygenComment")),"JAVADOC"); Printf(constants_code, convertedString); free(convertedString); } @@ -1683,7 +1683,7 @@ public: if (doxygen_javadoc_flag){ if (Getattr(n,"DoxygenComment")){ if(comment_creation_chatter) Printv(proxy_class_def, "/* This was generated from emitProxyClassDefAndCPPCasts() */\n", NIL ); - char *convertedString = doxyTranslator.convert(Char(Getattr(n,"DoxygenComment")),"JAVADOC"); + char *convertedString = doxyTranslator.convert(n, Char(Getattr(n,"DoxygenComment")),"JAVADOC"); Printv(proxy_class_def, convertedString, NIL); free(convertedString); } @@ -2026,7 +2026,7 @@ public: if (doxygen_javadoc_flag){ if (Getattr(n,"DoxygenComment")){ if(comment_creation_chatter) Printf(function_code, "/* This was generated from proxyclassfunctionhandler */"); - char *convertedString = doxyTranslator.convert(Char(Getattr(n,"DoxygenComment")),"JAVADOC"); + char *convertedString = doxyTranslator.convert(n, Char(Getattr(n,"DoxygenComment")),"JAVADOC"); Printf(function_code, convertedString); free(convertedString); } @@ -2258,7 +2258,7 @@ public: if (doxygen_javadoc_flag){ if (Getattr(n,"DoxygenComment")){ if(comment_creation_chatter) Printf(function_code, "/* This was generated from constructionhandler */\n" ); - char *convertedString = doxyTranslator.convert(Char(Getattr(n,"DoxygenComment")),"JAVADOC"); + char *convertedString = doxyTranslator.convert(n, Char(Getattr(n,"DoxygenComment")),"JAVADOC"); Printf(function_code, convertedString); free(convertedString); } @@ -2529,7 +2529,7 @@ public: if (doxygen_javadoc_flag){ if (Getattr(n,"DoxygenComment")){ if(comment_creation_chatter) Printf(function_code, "/* This was generated from moduleClassFunctionHandler() */\n" ); - char *convertedString = doxyTranslator.convert(Char(Getattr(n,"DoxygenComment")),"JAVADOC"); + char *convertedString = doxyTranslator.convert(n, Char(Getattr(n,"DoxygenComment")),"JAVADOC"); Printf(function_code, convertedString); free(convertedString); } diff --git a/Source/Modules/python.cxx b/Source/Modules/python.cxx index 7a878b4f8..ba02eae2e 100644 --- a/Source/Modules/python.cxx +++ b/Source/Modules/python.cxx @@ -7,7 +7,7 @@ * Python language module for SWIG. * ----------------------------------------------------------------------------- */ -char cvsroot_python_cxx[] = "$Id$"; +char cvsroot_python_cxx[] = "$Id: python.cxx 10453 2008-05-15 21:18:44Z wsfulton $"; #include "swigmod.h" #define ctab2 " " @@ -18,6 +18,7 @@ char cvsroot_python_cxx[] = "$Id$"; static int treduce = SWIG_cparse_template_reduce(0); #include +#include "../DoxygenTranslator/src/DoxygenTranslator.h" #define PYSHADOW_MEMBER 0x2 @@ -70,6 +71,7 @@ static int buildnone = 0; static int nobuildnone = 0; static int safecstrings = 0; static int dirvtable = 0; +static int doxygen = 1; static int proxydel = 1; static int fastunpack = 0; static int fastproxy = 0; @@ -83,6 +85,8 @@ static int extranative = 0; static int outputtuple = 0; static int nortti = 0; +static DoxygenTranslator doxyTranslator; + /* flags for the make_autodoc function */ enum autodoc_t { AUTODOC_CLASS, @@ -103,6 +107,7 @@ Python Options (available with -python)\n\ -classptr - Generate shadow 'ClassPtr' as in older swig versions\n\ -cppcast - Enable C++ casting operators (default) \n\ -dirvtable - Generate a pseudo virtual table for directors for faster dispatch \n\ + -doxygen - Convert C++ doxygen comments to pydoc comments in proxy classes \n\ -extranative - Return extra native C++ wraps for std containers when possible \n\ -fastinit - Use fast init mechanism for classes (default)\n\ -fastunpack - Use fast unpack mechanism to parse the argument functions \n\ @@ -324,6 +329,9 @@ public: } else if (strcmp(argv[i], "-dirvtable") == 0) { dirvtable = 1; Swig_mark_arg(i); + } else if (strcmp(argv[i], "-doxygen") == 0) { + doxygen = 1; + Swig_mark_arg(i); } else if (strcmp(argv[i], "-nodirvtable") == 0) { dirvtable = 0; Swig_mark_arg(i); @@ -2898,11 +2906,24 @@ public: } } Printf(f_shadow, ":\n"); - if (have_docstring(n)) { + + //translate and write pydoc comment if flagged + if (doxygen){ + if (Getattr(n,"DoxygenComment")){ + //if(comment_creation_chatter) Printf(function_code, "/* This was generated from classHandler */"); + char *convertedString = doxyTranslator.convert(n, Char(Getattr(n,"DoxygenComment")), "PYDOC"); + Printf(f_shadow, Char(pythoncode(convertedString, shadow_indent))); + free(convertedString); + } + } + + // otherwise use default docstrings if requested + else if (have_docstring(n)) { String *str = docstring(n, AUTODOC_CLASS, tab4); if (str != NULL && Len(str)) Printv(f_shadow, tab4, str, "\n", NIL); } + if (!modern) { Printv(f_shadow, tab4, "__swig_setmethods__ = {}\n", NIL); if (Len(base_class)) { @@ -3109,6 +3130,14 @@ public: } else { Printv(f_shadow, tab4, "def ", symname, "(",parms , ")", returnTypeAnnotation(n), ":", NIL); Printv(f_shadow, "\n", NIL); + if (doxygen) { + if (Getattr(n,"DoxygenComment")){ + //if(comment_creation_chatter) Printf(function_code, "/* This was generated from classHandler */"); + char *convertedString = doxyTranslator.convert(n, Char(Getattr(n,"DoxygenComment")), "PYDOC"); + Printf(f_shadow, Char(pythoncode(convertedString, tab8))); + free(convertedString); + } + } if (have_docstring(n)) Printv(f_shadow, tab8, docstring(n, AUTODOC_METHOD, tab8), "\n", NIL); if (have_pythonprepend(n)) {