From af125cd25151eaca3f96098c418326edf7a957c6 Mon Sep 17 00:00:00 2001 From: Cheryl Foil Date: Mon, 7 Jul 2008 02:59:22 +0000 Subject: [PATCH] Major overhaul to the basic structure of this parser, currently still sensitive and buggy. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/gsoc2008-cherylfoil@10654 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/DoxygenTranslator/DoxygenEntity.cpp | 17 +- Source/DoxygenTranslator/DoxygenEntity.h | 10 +- .../DoxygenTranslator/DoxygenTranslator.cpp | 665 +++++++++++++++--- 3 files changed, 573 insertions(+), 119 deletions(-) diff --git a/Source/DoxygenTranslator/DoxygenEntity.cpp b/Source/DoxygenTranslator/DoxygenEntity.cpp index 9b02ade12..cd192601e 100644 --- a/Source/DoxygenTranslator/DoxygenEntity.cpp +++ b/Source/DoxygenTranslator/DoxygenEntity.cpp @@ -30,13 +30,13 @@ string findCommand(int commandNum){ int arraySize = sizeof(commandArray2)/sizeof(*commandArray2); if (commandNum - 101 >= 0 && commandNum - 101 < arraySize){ - return commandArray2[commandNum]; + return commandArray2[commandNum - 101]; } return "" ; } -DoxygenEntity::DoxygenEntity(int typeEnt){ +DoxygenEntity::DoxygenEntity(string typeEnt){ typeOfEntity = typeEnt; data = ""; isLeaf = 1; @@ -47,7 +47,7 @@ DoxygenEntity::DoxygenEntity(int typeEnt){ * example: \b word * OR holding a string */ -DoxygenEntity::DoxygenEntity(int typeEnt, string param1){ +DoxygenEntity::DoxygenEntity(string typeEnt, string param1){ typeOfEntity = typeEnt; data = param1; isLeaf = 1; @@ -56,7 +56,7 @@ DoxygenEntity::DoxygenEntity(int typeEnt, string param1){ /* Nonterminal node * contains */ -DoxygenEntity::DoxygenEntity(int typeEnt, list entList){ +DoxygenEntity::DoxygenEntity(string typeEnt, list entList){ typeOfEntity = typeEnt; data = ""; isLeaf = 0; @@ -64,16 +64,19 @@ DoxygenEntity::DoxygenEntity(int typeEnt, list entList){ } -void DoxygenEntity::printEntity(){ +void DoxygenEntity::printEntity(int level){ if (isLeaf) { - cout << "Node Command: " << findCommand(typeOfEntity); + for (int i = 0; i < level; i++) {cout << "\t";} + cout << "Node Command: " << typeOfEntity << " "; if (data.compare("") != 0) cout << "Node Data: " << data; cout << endl; } else{ + cout << "Node Command : " << typeOfEntity << endl; list::iterator p = entityList.begin(); + level++; while (p != entityList.end()){ - (*p).printEntity(); + (*p).printEntity(level); p++; } } diff --git a/Source/DoxygenTranslator/DoxygenEntity.h b/Source/DoxygenTranslator/DoxygenEntity.h index 8330e4507..a0a99ed70 100644 --- a/Source/DoxygenTranslator/DoxygenEntity.h +++ b/Source/DoxygenTranslator/DoxygenEntity.h @@ -9,12 +9,12 @@ using namespace std; class DoxygenEntity{ public: - DoxygenEntity(int typeEnt); - DoxygenEntity(int typeEnt, string param1); - DoxygenEntity(int typeEnt, list entList); + DoxygenEntity(string typeEnt); + DoxygenEntity(string typeEnt, string param1); + DoxygenEntity(string typeEnt, list entList); virtual ~DoxygenEntity(); - void printEntity(); - int typeOfEntity; + void printEntity(int level); + string typeOfEntity; list entityList; string data; int isLeaf; diff --git a/Source/DoxygenTranslator/DoxygenTranslator.cpp b/Source/DoxygenTranslator/DoxygenTranslator.cpp index dadea41b5..e2fdaef8a 100644 --- a/Source/DoxygenTranslator/DoxygenTranslator.cpp +++ b/Source/DoxygenTranslator/DoxygenTranslator.cpp @@ -22,9 +22,10 @@ to test. */ //int testCommandParsingFunctions = 1;// not implemented -int testCodeCrawlingFunctions = 1; -int demonstrateParsing = 0; - +int testCodeCrawlingFunctions = 0; +int demonstrateParsing = 1; +int noisy = 1; // set this to 1 for extra chatter from the parsing stage. +int addCommand(string commandName, int &startInd, list &doxyList, string doxygenString); ////////////////////////////////////////// @@ -50,7 +51,7 @@ string commandArray[] = {"a", "addindex", "addtogroup", "anchor", "arg", "attent "sa", "section", "see", "showinitializer", "since", "skip", "skipline", "struct", "subpage", "subsection", "subsubsection", "test", "throw", "todo", "tparam", "typedef", "union", "until", "var", "verbatim", "verbinclude", "version", "warning", "weakgroup", "xmlonly", "xrefitem", - "$", "@", string(1, 92), string(1, '&'), "~", "<", ">", string(1, '#'), "%", "plaindescription"}; + "$", "@", string(1, 92), string(1, '&'), "~", "<", ">", string(1, '#'), "%"}; string sectionIndicators[] = { "attention", "author", "brief", "bug", "cond", "date", "deprecated", "details", @@ -58,12 +59,35 @@ string sectionIndicators[] = { "attention", "author", "brief", "bug", "cond", "d "tparam", "post" , "pre", "remarks", "return", "retval", "sa", "see", "since", "test", "throw", "todo", "version", "warning", "xrefitem" }; +/* All of the doxygen commands divided up by how they are parsed */ +string simpleCommands[] = {"n", "$", "@", string(1, 92), string(1, '&'), "~", "<", ">", string(1, '#'), "%"}; +string ignoredSimpleCommands[] = {"nothing at the moment"}; +string commandWords[] = {"a", "b", "c", "e", "em", "p", "def", "enum", "example", "package", + "relates", "namespace", "relatesalso","anchor", "dontinclude", "include", "includelineno"}; +string ignoredCommandWords[] = {"copydoc", "copybrief", "copydetails", "verbinclude", "htmlinclude"}; +string commandLines[] = {"addindex", "fn", "name", "line", "var", "skipline", "typedef", "skip", "until", "property"}; +string ignoreCommandLines[] = {"nothing at the moment"}; +string commandParagraph[] = {"return", "remarks", "since", "test", "sa", "see", "pre", "post", "details", "invariant", + "deprecated", "date", "note", "warning", "version", "todo", "bug", "attention", "brief", "arg", "author"}; +string ignoreCommandParagraphs[] = {"nothing at the moment"}; +string commandEndCommands[] = {"code", "dot", "msc", "f$", "f[", "f{environment}{", "htmlonly", "latexonly", "manonly", + "verbatim", "xmlonly", "cond", "if", "ifnot", "link"}; +string commandWordParagraphs[] = {"param", "tparam", "throw", "retval", "exception"}; +string commandWordLines[] = {"page", "subsection", "subsubsection", "section", "paragraph", "defgroup"}; +string commandWordOWordOWords [] = {"category", "class", "protocol", "interface", "struct", "union"}; +string commandOWords[] = {"dir", "file", "cond"}; +string commandErrorThrowings[] = {"annotatedclasslist", "classhierarchy", "define", "functionindex", "header", + "headerfilelist", "inherit", "l", "postheader", "private", "privatesection", "protected", + "protectedsection", "public", "publicsection", "endcode", "enddot", "endmsc", "endhtmlonly", + "endlatexonly", "endmanonly", "endlink", "endverbatim", "endxmlonly", "f]", "f}", "endcond", + "endif"}; +string commandUniques[] = {"xrefitem", "ingroup", "par", "headerfile", "overload", "weakgroup", "ref", + "subpage", "dotfile", "image", "addtogroup", "li"}; int startIndex = 0; int endIndex = 0; int isNewLine = 0; - - string doxygenString = ""; + //string doxygenString = ""; int briefDescExists = 0; /* Entity list is the root list. @@ -99,6 +123,61 @@ string sectionIndicators[] = { "attention", "author", "brief", "bug", "cond", "d } return -1; } + + int commandBelongs(string theCommand){ + string smallString = StringToLower(theCommand ); + //cout << " Looking for command " << theCommand << endl; + int i = 0; + for ( i = 0; i < sizeof(simpleCommands)/sizeof(*simpleCommands); i++){ + if(smallString.compare(simpleCommands[i]) == 0){return 1;} + } + for ( i = 0; i < sizeof(ignoredSimpleCommands)/sizeof(*ignoredSimpleCommands); i++){ + if(smallString.compare(ignoredSimpleCommands[i]) == 0){return 2;} + } + for ( i = 0; i < sizeof(commandWords)/sizeof(*commandWords); i++){ + if(smallString.compare( commandWords[i]) == 0){return 3;} + } + for ( i = 0; i < sizeof(ignoredCommandWords)/sizeof(*ignoredCommandWords); i++){ + if(smallString.compare( ignoredCommandWords[i]) == 0){return 4;} + } + for ( i = 0; i < sizeof(commandLines)/sizeof(*commandLines); i++){ + if(smallString.compare( commandLines[i]) == 0){return 5;} + } + for ( i = 0; i < sizeof(ignoreCommandLines)/sizeof(*ignoreCommandLines); i++){ + if(smallString.compare( ignoreCommandLines[i]) == 0){return 6;} + } + for ( i = 0; i < sizeof(commandParagraph)/sizeof(*commandParagraph); i++){ + if(smallString.compare( commandParagraph[i]) == 0){return 7;} + } + /* IgnoreCommandParagraph */ + for ( i = 0; i < sizeof(ignoreCommandParagraphs)/sizeof(*ignoreCommandParagraphs); i++){ + if(smallString.compare( ignoreCommandParagraphs[i]) == 0){return 8;} + } + for ( i = 0; i < sizeof(commandEndCommands)/sizeof(*commandEndCommands); i++){ + if(smallString.compare( commandEndCommands[i]) == 0){return 9;} + } + for ( i = 0; i < sizeof(commandWordParagraphs)/sizeof(*commandWordParagraphs); i++){ + if(smallString.compare( commandWordParagraphs[i]) == 0){return 10;} + } + for ( i = 0; i < sizeof(commandWordLines)/sizeof(*commandWordLines); i++){ + if(smallString.compare( commandWordLines[i]) == 0){return 11;} + } + for ( i = 0; i < sizeof(commandWordOWordOWords)/sizeof(*commandWordOWordOWords); i++){ + if(smallString.compare( commandWordOWordOWords[i]) == 0){return 12;} + } + for ( i = 0; i < sizeof(commandOWords)/sizeof(*commandOWords); i++){ + if(smallString.compare( commandOWords[i]) == 0){return 13;} + } + for ( i = 0; i < sizeof(commandErrorThrowings)/sizeof(*commandErrorThrowings); i++){ + if(smallString.compare( commandErrorThrowings[i]) == 0){return 14;} + } + for ( i = 0; i < sizeof(commandUniques)/sizeof(*commandUniques); i++){ + if(smallString.compare( commandUniques[i]) == 0){return 15;} + } + + return 0; + + } /* isSectionIndicator returns a boolean if the command is a section indicator * This is a helper method for finding the end of a paragraph @@ -123,7 +202,7 @@ string sectionIndicators[] = { "attention", "author", "brief", "bug", "cond", "d /* Tiny method to compartmentalise the removal of all optional comment fluff such as /// * or **** that often occurs before commment blobs. */ - int clearFluff(int startInd){ + int clearFluff(int &startInd, string doxygenString){ int startIndex = startInd; int amountRemoved = 0; @@ -132,7 +211,7 @@ string sectionIndicators[] = { "attention", "author", "brief", "bug", "cond", "d startIndex++; amountRemoved++; } - + startInd = startIndex; return startIndex; } @@ -141,13 +220,13 @@ string sectionIndicators[] = { "attention", "author", "brief", "bug", "cond", "d * Updates the index it is given after completion. */ - string getNextWord(int &startInd){ + string getNextWord(int &startInd, string doxygenString){ int startIndex = startInd; string nextWord = ""; - while (doxygenString[startIndex] == '/'|| doxygenString[startIndex] == ' ' + while (startIndex < doxygenString.length() && (doxygenString[startIndex] == '/'|| doxygenString[startIndex] == ' ' || doxygenString[startIndex] == '*' || doxygenString[startIndex]== '\n' - || doxygenString[startIndex] == '!'){ - if(doxygenString[startIndex]== '\n') return nextWord; + || doxygenString[startIndex] == '!')){ + if(doxygenString[startIndex]== '\n'){ startInd = startIndex; return nextWord;} startIndex++; //cout << "Start Index" << startIndex << endl; } @@ -168,7 +247,7 @@ string sectionIndicators[] = { "attention", "author", "brief", "bug", "cond", "d * and moved the index to the NEXT line * returns "" if nothing on the current line. */ - string getOneLine(int &startInd){ + string getOneLine(int &startInd, string doxygenString){ int startIndex = startInd; while (doxygenString[startIndex] == '/'|| doxygenString[startIndex] == ' ' || doxygenString[startIndex] == '*' || doxygenString[startIndex]== '\n' @@ -187,13 +266,11 @@ string sectionIndicators[] = { "attention", "author", "brief", "bug", "cond", "d startInd = endIndex; return returnedLine; } - -/* Returns a Paragraph- defined in Doxygen to be a paragraph of text - * seperate by either a structural command or a blank line - * This method is VERY messy currently +/* Returns a properly formatted (all doxygen *, //! etc removed) + * up til ANY command or end of paragraph is encountered. Has all the same issues as + * getStringTilEndOfParagraph formatting wise. */ - //TODO fix getStringTilEndOfParagraph to be more forgiving, work on ' ' characters - string getStringTilEndOfParagraph(int &startInd){ +string getStringTilCommand(int &startInd, string doxygenString){ if (startInd >= doxygenString.length()) return ""; int startIndex = startInd; int endIndex = startInd; @@ -203,8 +280,89 @@ string sectionIndicators[] = { "attention", "author", "brief", "bug", "cond", "d int spareIndex = 0; int counter; int finalIndex; - while(keepLooping && endIndex < doxygenString.length()){ - if (doxygenString[endIndex] == '\n'){ + while(keepLooping){ + if(endIndex >= doxygenString.length()){ + finalIndex = endIndex; + keepLooping = 0; + } + else if (doxygenString[endIndex] == '\n'){ + //cout << "1 "; + counter = endIndex; + if ( keepLooping && endIndex < doxygenString.length()-1) { + counter++; + //cout << "Counter :" << counter << endl; + while(keepLooping && endIndex < doxygenString.length() && (doxygenString[counter] == ' ' || + doxygenString[counter] == '*'|| doxygenString[counter] == '\n'|| doxygenString[counter] == '/' + || doxygenString[counter] == '!') ){ + if(doxygenString[counter] == '\n') { + //cout << "Blank line found" << endl; + keepLooping = 0; + finalIndex = counter;} + else{ counter++;} + } + + } + //endIndex = counter; + } + else if (doxygenString[endIndex] == 92 || doxygenString[endIndex] == '@'){ + finalIndex = endIndex; + keepLooping = 0; + } + else if(endIndex < doxygenString.length() -2 + && string("**/").compare(doxygenString.substr(endIndex , endIndex + 2)) == 0){ + finalIndex = endIndex; + //cout << "3 "; + keepLooping = 0; + } + if(keepLooping){ + //cout << "4 "; + endIndex++; + } + } + //cout << "Done with EndIndex" << endl; + while(doxygenString[startIndex] == '!' || doxygenString[startIndex] == ' ' + || doxygenString[startIndex] == '/' || doxygenString[startIndex] == '*') startIndex++; + + for (int i = startIndex; i < endIndex; i++){ + + if (doxygenString[i] == '\n') { + + while ((doxygenString[i] == '\n' || doxygenString[i] == ' ' + || doxygenString[i] == '*' || doxygenString[i] == '/')&& endIndex < doxygenString.length() - 1){ + i++; + } + description.append(" "); + } + description.push_back(doxygenString[i]); + //cout << doxygenString[i]; + } + //if(noisy) cout << "Final Index is: " << finalIndex << endl; + startInd = finalIndex; + return description; + } + + +/* Returns a Paragraph- defined in Doxygen to be a paragraph of text + * seperate by either a structural command or a blank line + * This method is VERY messy currently + */ + //TODO fix getStringTilEndOfParagraph to be more forgiving, work on ' ' characters + string getStringTilEndOfParagraph(int &startInd, string doxygenString){ + if (startInd >= doxygenString.length()) return ""; + int startIndex = startInd; + int endIndex = startInd; + string description = ""; + /* Find the End of the description */ + int keepLooping = 1; + int spareIndex = 0; + int counter; + int finalIndex; + while(keepLooping){ + if(endIndex >= doxygenString.length()){ + finalIndex = endIndex; + keepLooping = 0; + } + else if (doxygenString[endIndex] == '\n'){ //cout << "1 "; counter = endIndex; if ( keepLooping && endIndex < doxygenString.length()-1) { @@ -226,7 +384,7 @@ string sectionIndicators[] = { "attention", "author", "brief", "bug", "cond", "d else if (doxygenString[endIndex] == 92 || doxygenString[endIndex] == '@'){ //cout << "2 "; spareIndex = endIndex; - if (isSectionIndicator(getNextWord(spareIndex))) keepLooping = 0; + if (isSectionIndicator(getNextWord(spareIndex, doxygenString))) keepLooping = 0; } else if(endIndex < doxygenString.length() - 1 && string("*/").compare(doxygenString.substr(endIndex , endIndex + 1)) == 0){ @@ -266,7 +424,7 @@ string sectionIndicators[] = { "attention", "author", "brief", "bug", "cond", "d * currently this method does NOT process what is in between the two commands */ //TODO Make progressTilCommand return a formatted string - int progressTilEndCommand(string theCommand, int &startInd){ + int progressTilEndCommand(string theCommand, int &startInd, string doxygenString){ endIndex = startInd; while (endIndex < doxygenString.length()){ if (doxygenString[endIndex] == 92 || doxygenString[endIndex] == '@'){ @@ -282,7 +440,7 @@ string sectionIndicators[] = { "attention", "author", "brief", "bug", "cond", "d return 0; } - string getStringTilAnyCommand(string theCommand, int &startInd){ + string getStringTilAnyCommand(string theCommand, int &startInd, string doxygenString){ endIndex = startInd; startIndex = startInd; int keepLooping = 1; @@ -319,15 +477,17 @@ string sectionIndicators[] = { "attention", "author", "brief", "bug", "cond", "d * differs wildly */ int testClearFluff(){ - + string doxygenString = ""; string cases[] = {"/** WORD", "/*! WORD", "/******* WORD", "///// WORD", "//! WORD", "//! WORD", "///WORD", "/**\nWORD", "/**\n*WORD", "/** \n WORD"}; int testPassed = 1; + int placement = 0; int casesSize = sizeof(cases)/sizeof(*cases); for (int i = 0; i < casesSize; i++){ + placement = 0; doxygenString = cases[i]; - if(cases[i][clearFluff(0)] != 'W'){ - cout << "ClearFluff failed for string :" << doxygenString << "\t Displayed :" << cases[i][clearFluff(0)] << ": Instead." << endl; + if(cases[i][clearFluff(placement, doxygenString)] != 'W'){ + cout << "ClearFluff failed for string :" << doxygenString << "\t Displayed :" << cases[i][clearFluff(placement = 0, doxygenString)] << ": Instead." << endl; testPassed = 0; } } @@ -338,6 +498,7 @@ string sectionIndicators[] = { "attention", "author", "brief", "bug", "cond", "d }; int testGetNextWord(){ + string doxygenString = ""; string cases[] = {"/** WORD ", " * WORD ", "///!WORD ", " WORD ", "//! WORD ", " * WORD ", "*WORD "}; int testPassed = 1; string testWord = ""; @@ -346,7 +507,7 @@ string sectionIndicators[] = { "attention", "author", "brief", "bug", "cond", "d for (int i = 0; i < casesSize; i++){ doxygenString = cases[i]; placement = 0; - testWord = getNextWord(placement); + testWord = getNextWord(placement, doxygenString); if(testWord.compare("WORD") != 0){ cout << "GetNextWord failed for string :" << doxygenString << "\t Displayed :" << testWord << ": Instead." << endl; testPassed = 0; @@ -355,7 +516,7 @@ string sectionIndicators[] = { "attention", "author", "brief", "bug", "cond", "d } placement = 0; doxygenString = " * @WORD "; - testWord = getNextWord(placement); + testWord = getNextWord(placement, doxygenString); if(testWord.compare("@WORD") != 0){ cout << "GetNextWord failed for string :" << doxygenString << "\t Displayed :" << testWord << ": Instead." << endl; @@ -369,7 +530,7 @@ string sectionIndicators[] = { "attention", "author", "brief", "bug", "cond", "d commandWord = commandWord + "WORD"; doxygenString = testWord; placement = 0; - testWord = getNextWord(placement); + testWord = getNextWord(placement, doxygenString); if(testWord.compare(commandWord) != 0){ cout << "GetNextWord failed for string :" << doxygenString << "\t Displayed :" << testWord << ": Instead." << endl; @@ -377,38 +538,38 @@ string sectionIndicators[] = { "attention", "author", "brief", "bug", "cond", "d //else cout << "GetNextWord passed for string :" << doxygenString << endl; doxygenString = "WORD ANOTHER WORD1 WORD2 \n"; placement = 0; - testWord = getNextWord(placement); + testWord = getNextWord(placement, doxygenString); if(testWord.compare("WORD") != 0){ cout << "GetNextWord failed for string :" << doxygenString << "\t Displayed :" << testWord << ": Instead." << endl; testPassed = 0;} //else cout << "GetNextWord passed for string :" << doxygenString << endl; - testWord = getNextWord(placement); + testWord = getNextWord(placement, doxygenString); if(testWord.compare("ANOTHER") != 0){ cout << "GetNextWord failed for string :" << doxygenString << "\t Displayed :" << testWord << ": Instead." << endl; testPassed = 0;} //else cout << "GetNextWord passed for string :" << doxygenString << endl; - testWord = getNextWord(placement); + testWord = getNextWord(placement, doxygenString); if(testWord.compare("WORD1") != 0){ cout << "GetNextWord failed for string :" << doxygenString << "\t Displayed :" << testWord << ": Instead." << endl; testPassed = 0;} //else cout << "GetNextWord passed for string :" << doxygenString << endl; - testWord = getNextWord(placement); + testWord = getNextWord(placement, doxygenString); if(testWord.compare("WORD2") != 0){ cout << "GetNextWord failed for string :" << doxygenString << "\t Displayed :" << testWord << ": Instead." << endl; testPassed = 0;} //else cout << "GetNextWord passed for string :" << doxygenString << endl; - testWord = getNextWord(placement); + testWord = getNextWord(placement, doxygenString); if(testWord.compare("") != 0){ cout << "GetNextWord failed for string :" << doxygenString << "\t Displayed :" << testWord << ": Instead." << endl; testPassed = 0;} //else cout << "GetNextWord passed for string :" << doxygenString << endl; - testWord = getNextWord(placement); + testWord = getNextWord(placement, doxygenString); if(testWord.compare("") != 0){ cout << "GetNextWord failed for string :" << doxygenString << "\t Displayed :" << testWord << ": Instead." << endl; @@ -420,6 +581,7 @@ string sectionIndicators[] = { "attention", "author", "brief", "bug", "cond", "d } int testGetOneLine(){ + string doxygenString = ""; string cases[] = {" * Crop this sentence after this period.\n", " * Crop this sentence after this period.\n", "Crop this sentence after this period.\n", @@ -433,7 +595,7 @@ string sectionIndicators[] = { "attention", "author", "brief", "bug", "cond", "d for (int i = 0; i < casesSize; i++){ doxygenString = cases[i]; placement = 0; - testWord = getOneLine(placement); + testWord = getOneLine(placement, doxygenString); if(testWord.compare("Crop this sentence after this period.") != 0){ cout << "GetOneLine failed for string :" << doxygenString << "\t Displayed :" << testWord << ": Instead." << endl; testPassed = 0; @@ -441,17 +603,17 @@ string sectionIndicators[] = { "attention", "author", "brief", "bug", "cond", "d } doxygenString = ("Get this line.\n * Now get this line."); placement = 0; - testWord = getOneLine(placement); + testWord = getOneLine(placement, doxygenString); if(testWord.compare("Get this line.") != 0){ cout << "GetOneLine failed for string :" << doxygenString << "\t Displayed :" << testWord << ": Instead." << endl; testPassed = 0; } - testWord = getOneLine(placement); + testWord = getOneLine(placement, doxygenString); if(testWord.compare("Now get this line.") != 0){ cout << "GetOneLine failed for string :" << doxygenString << "\t Displayed :" << testWord << ": Instead." << endl; testPassed = 0; } - testWord = getOneLine(placement); + testWord = getOneLine(placement, doxygenString); if(testWord.compare("") != 0){ cout << "GetOneLine failed for string :" << doxygenString << "\t Displayed :" << testWord << ": Instead." << endl; testPassed = 0; @@ -463,17 +625,18 @@ string sectionIndicators[] = { "attention", "author", "brief", "bug", "cond", "d } //TODO Flesh testGetStringTilEndOfParagraph out, fix weird spacing problems int testGetStringTilEndOfParagraph(){ + string doxygenString = ""; int placement = 0; int testPassed = 1; string testParagraph; doxygenString = ("/* This is a description,\n * thus it continues on\n * for several lines.\n\n This Shouldn't be included.\n\n **/"); - testParagraph = getStringTilEndOfParagraph(placement); + testParagraph = getStringTilEndOfParagraph(placement, doxygenString); if( testParagraph.compare("This is a description, thus it continues on for several lines.") != 0){ cout << "GetOneLine failed for string :" << doxygenString << "\t Displayed :" << testParagraph << ": Instead." << endl; testPassed = 0; } //cout << "Curr Placement: " << placement<< endl; - testParagraph = getStringTilEndOfParagraph(placement); + testParagraph = getStringTilEndOfParagraph(placement, doxygenString); //cout << "Curr Placement: " << placement<< endl; if( testParagraph.compare(" This Shouldn't be included.") != 0){ cout << "GetOneLine failed for string :" << doxygenString << "\t Displayed :" << testParagraph << ": Instead." << endl; @@ -487,25 +650,42 @@ string sectionIndicators[] = { "attention", "author", "brief", "bug", "cond", "d doxygenString.push_back(92); doxygenString += "author cheryl foil \n\n **/"; placement = 0; - testParagraph = getStringTilEndOfParagraph(placement); + testParagraph = getStringTilEndOfParagraph(placement, doxygenString); if( testParagraph.compare("This is a description, thus it continues on for several lines.") != 0){ cout << "GetOneLine failed for string :" << doxygenString << "\t Displayed :" << testParagraph << ": Instead." << endl; testPassed = 0; } - if(testPassed) cout << "+++GetDescription passed for all tests+++\n" << endl; - else cout << "+++GetDescription FAILED+++\n" << endl; + if(testPassed) cout << "+++GetGetStringTilEndOfParagraph passed for all tests+++\n" << endl; + else cout << "+++GetGetStringTilEndOfParagraphFAILED+++\n" << endl; return testPassed; } + int testGetStringTilCommand(){ + string doxygenString = ""; + int placement = 0; + int testPassed = 1; + string testParagraph; + doxygenString = ("/* This is a description,\n * thus it continues on\n * for several @b lines.\n\n This Shouldn't be included.\n\n **/"); + testParagraph = getStringTilCommand(placement, doxygenString); + if( testParagraph.compare("This is a description, thus it continues on for several ") != 0){ + cout << "GetOneLine failed for string :" << doxygenString << "\t Displayed :" << testParagraph << ": Instead." << endl; + testPassed = 0; + } + if(testPassed) cout << "+++GetStringTilCommand passed for all tests+++\n" << endl; + else cout << "+++GetStringTilCommand FAILED+++\n" << endl; + return testPassed; + + } int testProgressTilEndCommand(){ + string doxygenString = ""; int placement = 0; int testPassed = 1; string testParagraph; doxygenString = "Let's pretend this \n * is a bunch of code to be ended in "; doxygenString.push_back(92); doxygenString += "endcodeSTOP"; - progressTilEndCommand("endcode", placement); + progressTilEndCommand("endcode", placement, doxygenString); //cout << "Placement : " << placement << endl; if( doxygenString[placement] != 'S'){ cout << "GetOneLine failed for string :" << doxygenString << "\n\t Displayed :" << testParagraph << ": Instead." << endl; @@ -532,6 +712,8 @@ string sectionIndicators[] = { "attention", "author", "brief", "bug", "cond", "d cout << "Testing progressTilEndCommand" << endl; testProgressTilEndCommand(); + cout << "Testing GetStringTilCommand" << endl; + testGetStringTilCommand(); return 1; } @@ -542,88 +724,357 @@ string sectionIndicators[] = { "attention", "author", "brief", "bug", "cond", "d list::iterator p = rootList.begin(); while (p != rootList.end()){ - (*p).printEntity(); + (*p).printEntity(0); p++; } } + + + + list parse(int startInd, string doxygenString){ + string currWord = ""; + int startIndex = startInd; + int savedIndex; + list aNewList; + endIndex = doxygenString.length(); + int currCommand; + while (startIndex < endIndex){ + savedIndex = startIndex; + currWord = getNextWord(startIndex, doxygenString); + if(noisy) cout << "Parsing for phrase starting in:" << currWord << endl; + if(currWord == ""){ + if (startIndex < endIndex) startIndex++; + } + else if(currWord[0] == 92 || currWord[0] == '@'){ + currWord = currWord.substr(1, currWord.length() - 1); + currCommand = findCommand(currWord); + if (currCommand < 0 ){ cout << "BAD COMMAND: " << currWord << endl; exit(1);} + //cout << "Command: " << currWord << " " << currCommand << endl; + addCommand(currWord, startIndex, aNewList, doxygenString); + } + else{ + startIndex = savedIndex; + addCommand(string("plainstring"), startIndex, aNewList, doxygenString); + + } + } + + return aNewList; + } + + /* Method for Adding a Simple Command + * Format: @command + * Plain commands, such as newline etc, they contain no other data + * \n \\ \@ \& \$ \# \< \> \% + */ + int addSimpleCommand(string theCommand, int &startInd, list &doxyList, string doxygenString){ + + if (noisy) cout << "Parsing " << theCommand << endl; + doxyList.push_back(DoxygenEntity(theCommand)); + return 1; + } + + /* NOT INCLUDED Simple Commands + * Format: @command + * Plain commands, such as newline etc, they contain no other data + */ + int ignoreSimpleCommand(string theCommand, int &startInd, list &doxyList, string doxygenString){ + + if (noisy) cout << "Not Adding " << theCommand << endl; + return 1; + //doxyList.push_back(DoxygenEntity(108)); + } + + /* CommandWord + * Format: @command + * Commands with a single WORD after then such as @b + * "a", "b", "c", "e", "em", "p", "def", "enum", "example", "package", + * "relates", "namespace", "relatesalso","anchor", "dontinclude", "include", "includelineno" + */ + int addCommandWord(string theCommand, int &startInd, list &doxyList, string doxygenString){ + if (noisy) cout << "Parsing " << theCommand << endl; + string name = getNextWord(startInd, doxygenString); + if (!name.empty()){ + doxyList.push_back(DoxygenEntity(theCommand, name)); + return 1; + } + else cout << "No word followed " << theCommand << " command. Not added" << endl; + return 0; + } + /* NOT INCLUDED CommandWord + * Format: @command + * Commands with a single WORD after then such as @b + * "copydoc", "copybrief", "copydetails", "verbinclude", "htmlinclude" + */ + int ignoreCommandWord(string theCommand, int &startInd, list &doxyList, string doxygenString){ + if (noisy) cout << "Not Adding " << theCommand << endl; + string name = getNextWord(startInd, doxygenString); + if (!name.empty()){ + return 1; + } + else cout << "WARNING: No word followed " << theCommand << " command." << endl; + return 0; + } + + /* CommandLine + * Format: @command (line) + * Commands with a single LINE after then such as @var + * "addindex", "fn", "name", "line", "var", "skipline", "typedef", "skip", "until", "property" + */ + int addCommandLine(string theCommand, int &startInd, list &doxyList, string doxygenString){ + if (noisy) cout << "Parsing " << theCommand << endl; + string line = getOneLine(startInd, doxygenString); + if(!line.empty()){ + int placement = 0; + list aNewList; + aNewList = parse(placement, line); + doxyList.push_back( DoxygenEntity(theCommand, aNewList)); + return 1; + } + else cout << "No line followed " << theCommand << " command. Not added" << endl; + return 0; + } + + /* NOT INCLUDED CommandLine + * Format: @command (line) + * Commands with a single LINE after then such as @var + * + */ + int ignoreCommandLine(string theCommand, int &startInd, list &doxyList, string doxygenString){ + if (noisy) cout << "Not Adding " << theCommand << endl; + string line = getOneLine(startInd, doxygenString); + if(!line.empty()){ + return 1; + } + else cout << "WARNING: No line followed " << theCommand << " command." << endl; + return 0; + } + + /* CommandParagraph + * Format: @command {paragraph} + * Commands with a single paragraph after then such as @return + * "return", "remarks", "since", "test", "sa", "see", "pre", "post", "details", "invariant", + * "deprecated", "date", "note", "warning", "version", "todo", "bug", "attention", "brief", "arg", "author" + */ + int addCommandParagraph(string theCommand, int &startInd, list &doxyList, string doxygenString){ + if (noisy) cout << "Parsing " << theCommand << endl; + string restOfParagraph = getStringTilEndOfParagraph(startInd, doxygenString); + if(!restOfParagraph.empty()){ + int placement = 0; + list aNewList; + aNewList = parse(placement, restOfParagraph); + doxyList.push_back( DoxygenEntity(theCommand, aNewList)); + return 1; + } + else cout << "No line followed " << theCommand << " command. Not added" << endl; + return 0; + } + /* CommandParagraph + * Format: @command {paragraph} + * Commands with a single LINE after then such as @var + * + */ + int ignoreCommandParagraph(string theCommand, int &startInd, list &doxyList, string doxygenString){ + if (noisy) cout << "Not Adding " << theCommand << endl; + string restOfParagraph = getStringTilEndOfParagraph(startInd, doxygenString); + if(!restOfParagraph.empty()){ + return 1; + } + else cout << "WARNING: No line followed " << theCommand << " command." << endl; + return 0; + } + /* Command EndCommand + * Format: @command and ends at @endcommand + * Commands that take in a block of text such as @code + * "code", "dot", "msc", "f$", "f[", "f{environment}{", "htmlonly", "latexonly", "manonly", + * "verbatim", "xmlonly", "cond", "if", "ifnot", "link" + * Returns 1 if success, 0 if the endcommand is never encountered. + */ + + int ignoreCommandEndCommand(string theCommand, int &startInd, list &doxyList, string doxygenString){ + if (noisy) cout << "Not Adding " << theCommand << endl; + return progressTilEndCommand( "end" + theCommand, startInd, doxygenString); + + } + + /* CommandWordParagraph + * Format: @command {paragraph} + * Commands such as param + * "param", "tparam", "throw", "retval", "exception" + */ + int addCommandWordParagraph(string theCommand, int &startInd, list &doxyList, string doxygenString){ + if (noisy) cout << "Parsing " << theCommand << endl; + string name = getNextWord(startInd, doxygenString); + if (name.empty()){ + cout << "No word followed " << theCommand << " command. Not added" << endl; + return 0; + } + string restOfParagraph = getStringTilEndOfParagraph(startInd, doxygenString); + int placement = 0; + if(!restOfParagraph.empty()){ + list aNewList; + aNewList = parse(placement, restOfParagraph); + aNewList.push_front(DoxygenEntity("plainstring", name)); + doxyList.push_back(DoxygenEntity(theCommand, aNewList)); + return 1; + } + else cout << "No paragraph followed " << theCommand << " command. Not added" << endl; + return 0; + } + /* CommandWordLine + * Format: @command (line) + * Commands such as param + * "page", "subsection", "subsubsection", "section", "paragraph", "defgroup" + */ + int addCommandWordLine(string theCommand, int &startInd, list &doxyList, string doxygenString){ + if (noisy) cout << "Parsing " << theCommand << endl; + string name = getNextWord(startInd, doxygenString); + if (name.empty()){ + cout << "No word followed " << theCommand << " command. Not added" << endl; + return 0; + } + string restOfLine = getStringTilEndOfParagraph(startInd, doxygenString); + int placement = 0; + if(!restOfLine.empty()){ + list aNewList; + aNewList = parse(placement, restOfLine); + aNewList.push_front(DoxygenEntity("plainstring", name)); + doxyList.push_back(DoxygenEntity(theCommand, aNewList)); + return 1; + } + else cout << "No line followed " << theCommand << " command. Not added" << endl; + return 0; + } + + /* Command Word Optional Word Optional Word + * Format: @command [] [] + * Commands such as class + * "category", "class", "protocol", "interface", "struct", "union" + */ + int addCommandWordOWordOWord(string theCommand, int &startInd, list &doxyList, string doxygenString){ + if (noisy) cout << "Parsing " << theCommand << endl; + string name = getNextWord(startInd, doxygenString); + if (name.empty()){ + cout << "No word followed " << theCommand << " command. Not added" << endl; + return 0; + } + string headerfile = getNextWord(startInd, doxygenString); + string headername = getNextWord(startInd, doxygenString); + list aNewList; + aNewList.push_back(DoxygenEntity("plainstring", name)); + if (!headerfile.empty()) aNewList.push_back(DoxygenEntity("plainstring", headerfile)); + if (!headername.empty()) aNewList.push_back(DoxygenEntity("plainstring", headername)); + doxyList.push_back(DoxygenEntity(theCommand, aNewList)); + return 1; + } + + /* Command Optional Word + * Format: @command [] + * Commands such as dir + * "dir", "file", "cond" + */ + int addCommandOWord(string theCommand, int &startInd, list &doxyList, string doxygenString){ + if (noisy) cout << "Parsing " << theCommand << endl; + string name = getNextWord(startInd, doxygenString); + doxyList.push_back(DoxygenEntity(theCommand, name)); + return 1; + } + /* The actual "meat" of the doxygen parser. This is not yet fully implemented * with my current design- however the skeletal outline is contained in * the file Skeleton */ - int addCommand(int commentNum, int &startInd, list &doxyList){ - startIndex = startInd; - string name; - string nextWordInLine = ""; - string restOfLine = ""; - string restOfParagraph = ""; - string headerfile =""; - string headername = ""; - switch(commentNum){ + int addCommand(string commandString, int &startInd, list &doxyList, string doxygenString){ + string theCommand = StringToLower(commandString); + string voidArray[] = {""}; + /* @command */ - /* \b */ - case 108: - name = getNextWord(startIndex); - if (!name.empty()) doxyList.push_back( DoxygenEntity(108, name)); - else cout << "No word followed b command. Not added" << endl; - break; - /* \brief */ - case 109: - restOfParagraph = getStringTilEndOfParagraph(startIndex); - if(!restOfParagraph.empty()) doxyList.push_back( DoxygenEntity(109, restOfLine)); - else cout << "Nothing followed brief command. Not added" < entityList() ))); - - break; - - default: - cout << "Command " << commentNum << " not supported yet" << endl; - break; + + if (theCommand.compare("plainstring") == 0){ + string nextPhrase = getStringTilCommand(startInd, doxygenString); + if (noisy) cout << "Parsing plain string :" << nextPhrase << endl; + doxyList.push_back(DoxygenEntity("plainstring", nextPhrase )); + return 1; + } + int commandNumber = commandBelongs(theCommand); + if (commandNumber == 1){ + return addSimpleCommand(theCommand, startInd,doxyList, doxygenString); } - startInd = startIndex; + if (commandNumber == 2){ + return ignoreSimpleCommand(theCommand, startInd,doxyList, doxygenString); + } + if (commandNumber == 3){ + return addCommandWord(theCommand, startInd,doxyList, doxygenString); + } + if (commandNumber == 4){ + return ignoreCommandWord(theCommand, startInd,doxyList, doxygenString); + } + if (commandNumber == 5){ + return addCommandLine(theCommand, startInd,doxyList, doxygenString); + } + if (commandNumber == 6){ + return ignoreCommandLine(theCommand, startInd,doxyList, doxygenString); + } + if (commandNumber == 7){ + return addCommandParagraph(theCommand, startInd,doxyList, doxygenString); + } + if (commandNumber == 8){ + return ignoreCommandParagraph(theCommand, startInd,doxyList, doxygenString); + } + if (commandNumber == 9){ + return ignoreCommandEndCommand(theCommand, startInd,doxyList, doxygenString); + } + if (commandNumber == 10){ + return addCommandWordParagraph(theCommand, startInd,doxyList, doxygenString); + } + if (commandNumber == 11){ + return addCommandWordLine(theCommand, startInd,doxyList, doxygenString); + } + if (commandNumber == 12){ + return addCommandWordOWordOWord(theCommand, startInd,doxyList, doxygenString); + } + if (commandNumber == 13){ + return addCommandOWord(theCommand, startInd,doxyList, doxygenString); + } + if (commandNumber == 14){ + return 0; + } + if (commandNumber == 15){ + return 0; + } + + return 0; + } + + int weirdTest(){ + string doxygenString = "this is a test."; + string restOfParagraph = ""; + int startIndex = 0; + restOfParagraph = getStringTilEndOfParagraph(startIndex , doxygenString); + cout << restOfParagraph<< " " << startIndex << endl; + + startIndex = 0; + restOfParagraph = getStringTilCommand(startIndex, doxygenString); + cout << restOfParagraph<< " " << startIndex << endl; } - /* Returns the parse tree */ + /* Returns a parse tree for a string */ -list parse(int startInd, int endInd, list &doxyList){ - string currWord = ""; - int startIndex = startInd; - int savedIndex; - int currCommand; - while (startIndex < endIndex){ - savedIndex = startIndex; - currWord = getNextWord(startIndex); - - if(currWord[0] == 92 || currWord[0] == '@'){ - currWord = doxygenString.substr(startIndex+1, currWord.length() - 1); - currCommand = findCommand(currWord); - if (currCommand < 0 ){ cout << "BAD COMMAND: " << currWord << endl; exit(1);} - //cout << "Command: " << currWord << " " << currCommand << endl; - addCommand(currCommand, startIndex, doxyList); - } - else{ - startIndex = savedIndex; - addCommand(238, startIndex, doxyList); - - } - } - - -} int main(int argc, char *argv[]){ + //weirdTest(); if(testCodeCrawlingFunctions) testCCF(); if (demonstrateParsing){ + string doxygenString = " This is a small sentence.\n *\n This is a line with a @b bold letter \n * \n @brief small @b description. **/"; + //string doxygenString = "This is a description.\n\n * @param x this is a parameter."; int placement = 0; - clearFluff(0); - parse(0, doxygenString.length(), rootList); + clearFluff(placement, doxygenString); + rootList = parse(placement, doxygenString); + cout << "---THE TREE---" << endl; printTree(); } return 1;