From 59734eb59735bc6d3ed6e1cfd110347b2aacfac1 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 15 Feb 1999 23:07:37 +0000 Subject: [PATCH] 1. Parser improvements a) const and virtual methods are parsed correctly (not static yet) b) "const" which is part of the return type is not swallowed 2. HelpGen improvements: -o outputdir parameter added to the cmd line, "//---------" kind comments discarded now. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@1700 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- utils/HelpGen/include/cjparser.h | 2 +- utils/HelpGen/src/HelpGen.cpp | 149 ++++++++++++++++++++-------- utils/HelpGen/src/cjparser.cpp | 25 +++-- utils/HelpGen/src/srcparser.cpp | 6 +- utils/HelpGen/src/wx_extra_imps.cpp | 6 +- 5 files changed, 133 insertions(+), 55 deletions(-) diff --git a/utils/HelpGen/include/cjparser.h b/utils/HelpGen/include/cjparser.h index 47c955e832..94107b9018 100644 --- a/utils/HelpGen/include/cjparser.h +++ b/utils/HelpGen/include/cjparser.h @@ -42,7 +42,7 @@ protected: char* cur; // about the current class - bool mIsVirtaul; + bool mIsVirtual; bool mIsTemplate; size_t mNestingLevel; diff --git a/utils/HelpGen/src/HelpGen.cpp b/utils/HelpGen/src/HelpGen.cpp index 28f36a2f01..0b01804d38 100644 --- a/utils/HelpGen/src/HelpGen.cpp +++ b/utils/HelpGen/src/HelpGen.cpp @@ -13,7 +13,7 @@ TODO (+ means fixed) (i) small fixes in the current version - + +1. Quote special TeX characters like '&' and '_' (=> derive from wxFile) 2. Document typedefs 3. Document global variables @@ -23,7 +23,7 @@ (ii) plans for version 2 1. Use wxTextFile for direct file access to avoid one scan method problems 2. Use command line parsrer class for the options - + */ // ============================================================================= @@ -84,7 +84,7 @@ static const char *GetCurrentTime(const char *timeFormat); class wxTeXFile : public wxFile { public: - wxTeXFile() : wxFile() { } + wxTeXFile() { } bool WriteTeX(const wxString& s) { @@ -93,19 +93,26 @@ public: return wxFile::Write(t); } + +private: + wxTeXFile(const wxTeXFile&); + wxTeXFile& operator=(const wxTeXFile&); }; class HelpGenVisitor : public spVisitor { public: // ctor - HelpGenVisitor(); + HelpGenVisitor(const wxString& directoryOut) : m_directoryOut(directoryOut) + { + Reset(); + } virtual void VisitFile( spFile& fl ); virtual void VisitClass( spClass& cl ); virtual void VisitEnumeration( spEnumeration& en ); virtual void VisitTypeDef( spTypeDef& td ); - virtual void VisitPreprocessorLine( spPreprocessorLine& pd ); + virtual void VisitPreprocessorLine( spPreprocessorLine& pd ); virtual void VisitAttribute( spAttribute& attr ); virtual void VisitOperation( spOperation& op ); virtual void VisitParameter( spParameter& param ); @@ -127,11 +134,12 @@ protected: // write the headers for corresponding sections (only once) void InsertDataStructuresHeader(); void InsertMethodsHeader(); - + // terminate the function documentation if it was started void CloseFunction(); - wxTeXFile m_file; // file we're writing to now + wxString m_directoryOut; // directory for the output + wxTeXFile m_file; // file we're writing to now // state variables bool m_inClass, // TRUE after file successfully opened @@ -145,8 +153,12 @@ protected: m_textStoredTypedefs, m_textStoredFunctionComment; - // headers included by this file + // headers included by this file wxArrayString m_headers; + +private: + HelpGenVisitor(const HelpGenVisitor&); + HelpGenVisitor& operator=(const HelpGenVisitor&); }; // ----------------------------------------------------------------------------- @@ -160,7 +172,7 @@ protected: // this function never returns static void usage() { - wxLogError("usage: HelpGen [-q|-v]
\n"); + wxLogError("usage: HelpGen [-q|-v] [-o outdir]
\n"); exit(1); } @@ -171,27 +183,63 @@ int main(int argc, char **argv) usage(); } + wxString directoryOut; + int first; for ( first = 1; (first < argc) && argv[first][0] == '-'; first++ ) { - switch ( argv[first][1] ) { - case 'v': - // be verbose - wxLog::GetActiveTarget()->SetVerbose(); - break; + // all options have one letter + if ( argv[first][2] == '\0' ) { + switch ( argv[first][1] ) { + case 'v': + // be verbose + wxLog::GetActiveTarget()->SetVerbose(); + continue; + + case 'q': + // be quiet + wxLog::GetActiveTarget()->SetVerbose(false); + continue; + + case 'o': + first++; + if ( first >= argc ) { + wxLogError("-o option requires an argument."); + + break; + } + + directoryOut = argv[first]; + if ( !!directoryOut ) { + // terminate with a '/' if it doesn't have it + switch ( directoryOut.Last() ) { + case '/': +#ifdef __WXMSW__ + case '\\': +#endif + break; - case 'q': - // be quiet - wxLog::GetActiveTarget()->SetVerbose(false); - break; + default: + directoryOut += '/'; + } + } + //else: it's empty, do nothing + + continue; - default: - usage(); + default: + break; + } } + + // only get here after a break from switch or from else branch of if + wxLogError("unknown option '%s'", argv[first]); + + usage(); } // create a parser object and a visitor derivation CJSourceParser parser; - HelpGenVisitor visitor; + HelpGenVisitor visitor(directoryOut); // parse all files for ( int i = first; i < argc; i++ ) { @@ -213,11 +261,6 @@ int main(int argc, char **argv) // HelpGenVisitor implementation // ----------------------------------------------------------------------------- -HelpGenVisitor::HelpGenVisitor() -{ - Reset(); -} - void HelpGenVisitor::Reset() { m_inClass = @@ -301,9 +344,12 @@ void HelpGenVisitor::VisitClass( spClass& cl ) // the file name is built from the class name by removing the leading "wx" // if any and converting it to the lower case - wxString filename = name; - if ( filename(0, 2) == "wx" ) { - filename.erase(0, 2); + wxString filename = m_directoryOut; + if ( name(0, 2) == "wx" ) { + filename << name.c_str() + 2; + } + else { + filename << name; } filename.MakeLower(); @@ -329,7 +375,12 @@ void HelpGenVisitor::VisitClass( spClass& cl ) // write out the header { wxString header; - header.Printf("% automatically generated by HelpGen from %s at %s\n" + header.Printf("%%\n" + "%% automatically generated by HelpGen from\n" + "%% %s at %s\n" + "%%\n" + "\n" + "\n" "\\section{\\class{%s}}\\label{%s}\n", filename.c_str(), GetCurrentTime("%d/%b/%y %H:%M:%S"), name.c_str(), wxString(name).MakeLower().c_str()); @@ -346,7 +397,7 @@ void HelpGenVisitor::VisitClass( spClass& cl ) "defs", "string", "dynarray", - "file", + "file", "time", }; @@ -430,7 +481,7 @@ void HelpGenVisitor::VisitClass( spClass& cl ) wxString baseclass = *i; derived << "\\helpref{" << baseclass << "}"; - derived << "{" << baseclass.MakeLower() << "}"; + derived << "{" << baseclass.MakeLower() << "}"; } } totalText << derived << "\n\n"; @@ -566,7 +617,7 @@ void HelpGenVisitor::VisitOperation( spOperation& op ) wxString totalText; const char *funcname = op.GetName().c_str(); const char *classname = op.GetClass().GetName().c_str(); - + // check for the special case of dtor wxString dtor; if ( (funcname[0] == '~') && (strcmp(funcname + 1, classname) == 0) ) { @@ -574,7 +625,9 @@ void HelpGenVisitor::VisitOperation( spOperation& op ) funcname = dtor; } - totalText.Printf("\\membersection{%s::%s}\\label{%s}\n\n" + totalText.Printf("\n" + "\\membersection{%s::%s}\\label{%s}\n" + "\n" "\\%sfunc{%s%s}{%s}{", classname, funcname, MakeLabel(classname, funcname).c_str(), @@ -598,13 +651,13 @@ void HelpGenVisitor::VisitParameter( spParameter& param ) else { totalText << ", "; } - + totalText << "\\param{" << param.mType << " }{" << param.GetName(); wxString defvalue = param.mInitVal; if ( !defvalue.IsEmpty() ) { totalText << " = " << defvalue; } - + totalText << '}'; m_file.WriteTeX(totalText); @@ -622,7 +675,7 @@ static wxString MakeLabel(const char *classname, const char *funcname) // but may be later others will be added static const char *macros[] = { "destruct" }; static const char *replacement[] = { "dtor" }; - + size_t n; for ( n = 0; n < WXSIZEOF(macros); n++ ) { if ( strncmp(funcname + 1, macros[n], strlen(macros[n])) == 0 ) { @@ -665,15 +718,23 @@ static void TeXFilter(wxString* str) static wxString GetAllComments(const spContext& ctx) { - wxString comment; - const MCommentListT& comments = ctx.GetCommentList(); - for ( MCommentListT::const_iterator i = comments.begin(); - i != comments.end(); - i++ ) { - comment << (*i)->GetText(); + wxString comments; + const MCommentListT& commentsList = ctx.GetCommentList(); + for ( MCommentListT::const_iterator i = commentsList.begin(); + i != commentsList.end(); + i++ ) { + wxString comment = (*i)->GetText(); + + // don't take comments like "// ----------" &c + comment.Trim(FALSE); + if ( !!comment && + comment == wxString(comment[0u], comment.length() - 1) + '\n' ) + comments << "\n"; + else + comments << comment; } - return comment; + return comments; } static const char *GetCurrentTime(const char *timeFormat) diff --git a/utils/HelpGen/src/cjparser.cpp b/utils/HelpGen/src/cjparser.cpp index 9c90e37862..b6d1dd7514 100644 --- a/utils/HelpGen/src/cjparser.cpp +++ b/utils/HelpGen/src/cjparser.cpp @@ -923,7 +923,7 @@ static bool is_keyword( char* cur ) // restore original character suppresed by terminating zero *(cur + len) = tmp; - return ( i != __gMultiLangMap.end() ); + return i == __gMultiLangMap.end() ? false : true; } static inline void get_string_between( char* start, char* end, @@ -979,7 +979,7 @@ spFile* CJSourceParser::Parse( char* start, char* end ) spFile* pTopCtx = new spFile(); mpCurCtx = pTopCtx; - mIsVirtaul = 0; + mIsVirtual = 0; mIsTemplate = 0; mNestingLevel = 0; @@ -1008,7 +1008,7 @@ spFile* CJSourceParser::Parse( char* start, char* end ) ) == 0 ) { - int o; + int o = 0; ++o; } @@ -1047,7 +1047,8 @@ spFile* CJSourceParser::Parse( char* start, char* end ) default: break; } - if ( is_keyword( cur ) ) + // 'const' is a part of the return type, not a keyword here + if ( strncmp(cur, "const", 5) != 0 && is_keyword( cur ) ) { // parses, token, if token identifies // the container context (e.g. class/namespace) @@ -1445,7 +1446,7 @@ void CJSourceParser::ParseKeyword( char*& cur ) if ( cmp_tokens_fast( cur, "virtual", len ) ) { // probably the virtual method is in front of us; - mIsVirtaul = 1; + mIsVirtual = 1; skip_token( cur ); return; } @@ -1480,8 +1481,12 @@ bool CJSourceParser::ParseNameAndRetVal( char*& cur, bool& isAMacro ) char* start = cur; + bool isVirtual = false; while( *cur != '(' ) { + if ( get_token_str( cur ) == "virtual" ) + isVirtual = true; + skip_token( cur ); if ( !get_next_token( cur ) ) return FALSE; } @@ -1524,6 +1529,7 @@ bool CJSourceParser::ParseNameAndRetVal( char*& cur, bool& isAMacro ) mpCurCtx->AddMember( pOp ); pOp->mVisibility = mCurVis; + pOp->mIsVirtual = isVirtual; // add comments about operation AttachComments( *pOp, cur ); @@ -1610,7 +1616,8 @@ bool CJSourceParser::ParseArguments( char*& cur ) if ( blocksSkipped == 0 ) { if ( *cur == 10 ) ++_gLineNo; - ++cur; + ++cur; // skip ')' + break; // function without paramters } @@ -1674,6 +1681,10 @@ bool CJSourceParser::ParseArguments( char*& cur ) } while(1); + // skip possible whitespace between ')' and following "const" + while ( isspace(*cur) ) + cur++; + // check if it was really a function not a macro, // if so, than it should be terminated with semicolon ';' // or opening implemenetaton bracket '{' @@ -1710,6 +1721,8 @@ bool CJSourceParser::ParseArguments( char*& cur ) if ( cmp_tokens_fast( tok, "const", 5 ) ) { + ((spOperation*)mpCurCtx)->mIsConstant = true; + skip_token(tok); if ( !get_next_token(tok) ) return FALSE; continue; diff --git a/utils/HelpGen/src/srcparser.cpp b/utils/HelpGen/src/srcparser.cpp index abe2cd9a9e..10a219f9e7 100644 --- a/utils/HelpGen/src/srcparser.cpp +++ b/utils/HelpGen/src/srcparser.cpp @@ -414,7 +414,11 @@ void spClass::SortMembers() spOperation::spOperation() : mHasDefinition( FALSE ) -{} +{ + mIsConstant = + mIsVirtual = + mHasDefinition = false; +} string spOperation::GetFullName(MarkupTagsT tags) { diff --git a/utils/HelpGen/src/wx_extra_imps.cpp b/utils/HelpGen/src/wx_extra_imps.cpp index 056a522371..e4af6ef024 100644 --- a/utils/HelpGen/src/wx_extra_imps.cpp +++ b/utils/HelpGen/src/wx_extra_imps.cpp @@ -34,9 +34,9 @@ void WXDLLEXPORT wxSplitPath(const char *pszFileName, { wxCHECK_RET( pszFileName, _("NULL file name in wxSplitPath") ); - const char *pDot = strrchr(pszFileName, FILE_SEP_EXT); - const char *pSepUnix = strrchr(pszFileName, FILE_SEP_PATH_UNIX); - const char *pSepDos = strrchr(pszFileName, FILE_SEP_PATH_DOS); + const char *pDot = strrchr(pszFileName, wxFILE_SEP_EXT); + const char *pSepUnix = strrchr(pszFileName, wxFILE_SEP_PATH_UNIX); + const char *pSepDos = strrchr(pszFileName, wxFILE_SEP_PATH_DOS); // take the last of the two size_t nPosUnix = pSepUnix ? pSepUnix - pszFileName : 0; -- 2.45.2