/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ #include #include // NOT FULLY DEFINED SERVICES #include #include #include #include #include #include #include <../parser/inc/x_docu.hxx> #include #include #include #include #include #ifdef UNX #define strnicmp strncasecmp #endif namespace csi { namespace dsapi { const char * AtTagTitle( const Tok_AtTag & i_rToken ); SapiDocu_PE::SapiDocu_PE(ParserInfo & io_rPositionInfo) : pDocu(0), eState(e_none), pPositionInfo(&io_rPositionInfo), fCurTokenAddFunction(&SapiDocu_PE::AddDocuToken2Void), pCurAtTag(0), sCurDimAttribute(), sCurAtSeeType_byXML(200) { } SapiDocu_PE::~SapiDocu_PE() { } void SapiDocu_PE::ProcessToken( DYN csi::dsapi::Token & let_drToken ) { if (IsComplete()) { pDocu = 0; eState = e_none; } if ( eState == e_none ) { pDocu = new ary::doc::OldIdlDocu; eState = st_short; fCurTokenAddFunction = &SapiDocu_PE::AddDocuToken2Short; } csv_assert(pDocu); let_drToken.Trigger(*this); delete &let_drToken; } void SapiDocu_PE::Process_AtTag( const Tok_AtTag & i_rToken ) { if (NOT pCurAtTag) { eState = st_attags; fCurTokenAddFunction = &SapiDocu_PE::AddDocuToken2CurAtTag; } else { csv_assert(eState == st_attags); pDocu->AddAtTag(*pCurAtTag.Release()); } if (i_rToken.Id() == Tok_AtTag::param) { pCurAtTag = new DT_ParameterAtTag; fCurTokenAddFunction = &SapiDocu_PE::SetCurParameterAtTagName; } else if (i_rToken.Id() == Tok_AtTag::see) { pCurAtTag = new DT_SeeAlsoAtTag; fCurTokenAddFunction = &SapiDocu_PE::SetCurSeeAlsoAtTagLinkText; } else if (i_rToken.Id() == Tok_AtTag::deprecated) { pDocu->SetDeprecated(); pCurAtTag = new DT_StdAtTag(""); // Dummy that will not be used. fCurTokenAddFunction = &SapiDocu_PE::AddDocuToken2Deprecated; } else if (i_rToken.Id() == Tok_AtTag::since) { pCurAtTag = new DT_SinceAtTag; fCurTokenAddFunction = &SapiDocu_PE::SetCurSinceAtTagVersion_OOo; } else { pCurAtTag = new DT_StdAtTag( AtTagTitle(i_rToken) ); fCurTokenAddFunction = &SapiDocu_PE::AddDocuToken2CurAtTag; } } void SapiDocu_PE::Process_HtmlTag( const Tok_HtmlTag & i_rToken ) { if (eState == st_short AND i_rToken.IsParagraphStarter()) { eState = st_description; fCurTokenAddFunction = &SapiDocu_PE::AddDocuToken2Description; } // Workaround special for some errors in API docu: if ( strnicmp("",i_rToken.Text()) != 0 ) TheMessages().Out_InvalidConstSymbol( i_rToken.Text(), pPositionInfo->CurFile(), pPositionInfo->CurLine() ); (this->*fCurTokenAddFunction)( *new DT_TextToken("true") ); return; } else if ( strnicmp("",i_rToken.Text()) != 0 ) TheMessages().Out_InvalidConstSymbol( i_rToken.Text(), pPositionInfo->CurFile(), pPositionInfo->CurLine() ); (this->*fCurTokenAddFunction)( *new DT_TextToken("false") ); return; } else if ( strnicmp("",i_rToken.Text()) != 0 ) TheMessages().Out_InvalidConstSymbol( i_rToken.Text(), pPositionInfo->CurFile(), pPositionInfo->CurLine() ); (this->*fCurTokenAddFunction)( *new DT_TextToken("null") ); return; } else if ( strnicmp("",i_rToken.Text()) != 0 ) TheMessages().Out_InvalidConstSymbol( i_rToken.Text(), pPositionInfo->CurFile(), pPositionInfo->CurLine() ); (this->*fCurTokenAddFunction)( *new DT_TextToken("void") ); return; } (this->*fCurTokenAddFunction)( *new DT_Style(i_rToken.Text(),false) ); } void SapiDocu_PE::Process_XmlConst( const Tok_XmlConst & i_rToken ) { (this->*fCurTokenAddFunction)(*new DT_MupConst(i_rToken.Text())); } void SapiDocu_PE::Process_XmlLink_BeginTag( const Tok_XmlLink_BeginTag & i_rToken ) { switch (i_rToken.Id()) { case Tok_XmlLink_Tag::e_const: (this->*fCurTokenAddFunction)(*new DT_Style("",false)); break; case Tok_XmlLink_Tag::member: (this->*fCurTokenAddFunction)(*new DT_MupMember(i_rToken.Scope())); break; case Tok_XmlLink_Tag::type: (this->*fCurTokenAddFunction)(*new DT_MupType(i_rToken.Scope())); break; default: // Do nothing. ; } if ( i_rToken.Dim().length() > 0 ) sCurDimAttribute = i_rToken.Dim(); else sCurDimAttribute.clear(); } void SapiDocu_PE::Process_XmlLink_EndTag( const Tok_XmlLink_EndTag & i_rToken ) { switch (i_rToken.Id()) { case Tok_XmlLink_Tag::e_const: (this->*fCurTokenAddFunction)(*new DT_Style("",false)); break; case Tok_XmlLink_Tag::member: (this->*fCurTokenAddFunction)(*new DT_MupMember(true)); break; case Tok_XmlLink_Tag::type: (this->*fCurTokenAddFunction)(*new DT_MupType(true)); break; default: // Do nothing. ; } if ( sCurDimAttribute.length() > 0 ) { (this->*fCurTokenAddFunction)( *new DT_TextToken(sCurDimAttribute.c_str()) ); sCurDimAttribute.clear(); } } void SapiDocu_PE::Process_XmlFormat_BeginTag( const Tok_XmlFormat_BeginTag & i_rToken ) { switch (i_rToken.Id()) { case Tok_XmlFormat_Tag::code: (this->*fCurTokenAddFunction)(*new DT_Style("",false)); break; case Tok_XmlFormat_Tag::listing: (this->*fCurTokenAddFunction)(*new DT_Style("
",true));
			break;
		case Tok_XmlFormat_Tag::atom:
			(this->*fCurTokenAddFunction)(*new DT_Style("",true));
			break;
		default:
		    //  Do nothing.
		    ;
	}
    if ( i_rToken.Dim().length() > 0 )
        sCurDimAttribute = i_rToken.Dim();
    else
        sCurDimAttribute.clear();
}

void
SapiDocu_PE::Process_XmlFormat_EndTag( const Tok_XmlFormat_EndTag & i_rToken )
{
	switch (i_rToken.Id())
	{
		case Tok_XmlFormat_Tag::code:
			(this->*fCurTokenAddFunction)(*new DT_Style("",false));
			break;
		case Tok_XmlFormat_Tag::listing:
			(this->*fCurTokenAddFunction)(*new DT_Style("
",true)); break; case Tok_XmlFormat_Tag::atom: (this->*fCurTokenAddFunction)(*new DT_Style("
",true)); break; default: // Do nothing. ; } if ( sCurDimAttribute.length() > 0 ) { (this->*fCurTokenAddFunction)( *new DT_TextToken(sCurDimAttribute.c_str()) ); sCurDimAttribute.clear(); } } void SapiDocu_PE::Process_Word( const Tok_Word & i_rToken ) { (this->*fCurTokenAddFunction)(*new DT_TextToken(i_rToken.Text())); } void SapiDocu_PE::Process_Comma() { csv_assert(1==7); // (this->*fCurTokenAddFunction)(*new DT_Comma(i_rToken.Text())); } void SapiDocu_PE::Process_DocuEnd() { eState = st_complete; if (pCurAtTag) pDocu->AddAtTag(*pCurAtTag.Release()); fCurTokenAddFunction = &SapiDocu_PE::AddDocuToken2Void; } void SapiDocu_PE::Process_EOL() { (this->*fCurTokenAddFunction)(*new DT_EOL); } void SapiDocu_PE::Process_White() { (this->*fCurTokenAddFunction)(*new DT_White); } DYN ary::doc::OldIdlDocu * SapiDocu_PE::ReleaseJustParsedDocu() { if (IsComplete()) { eState = e_none; return pDocu.Release(); } return 0; } bool SapiDocu_PE::IsComplete() const { return eState == st_complete; } void SapiDocu_PE::AddDocuToken2Void( DYN ary::inf::DocuToken & let_drNewToken ) { delete &let_drNewToken; } void SapiDocu_PE::AddDocuToken2Short( DYN ary::inf::DocuToken & let_drNewToken ) { csv_assert(pDocu); pDocu->AddToken2Short(let_drNewToken); } void SapiDocu_PE::AddDocuToken2Description( DYN ary::inf::DocuToken & let_drNewToken ) { csv_assert(pDocu); pDocu->AddToken2Description(let_drNewToken); } void SapiDocu_PE::AddDocuToken2Deprecated( DYN ary::inf::DocuToken & let_drNewToken ) { csv_assert(pDocu); pDocu->AddToken2DeprecatedText(let_drNewToken); } void SapiDocu_PE::AddDocuToken2CurAtTag( DYN ary::inf::DocuToken & let_drNewToken ) { csv_assert(pCurAtTag); pCurAtTag->AddToken(let_drNewToken); } void SapiDocu_PE::SetCurParameterAtTagName( DYN ary::inf::DocuToken & let_drNewToken ) { if (let_drNewToken.IsWhiteOnly()) { delete &let_drNewToken; return; } csv_assert(pCurAtTag); DT_TextToken * dpText = dynamic_cast< DT_TextToken* >(&let_drNewToken); if (dpText != 0) pCurAtTag->SetName(dpText->GetText()); else pCurAtTag->SetName("parameter ?"); delete &let_drNewToken; fCurTokenAddFunction = &SapiDocu_PE::AddDocuToken2CurAtTag; } void SapiDocu_PE::SetCurSeeAlsoAtTagLinkText( DYN ary::inf::DocuToken & let_drNewToken ) { csv_assert(pCurAtTag); if (let_drNewToken.IsWhiteOnly()) { delete &let_drNewToken; return; } DT_TextToken * pText = dynamic_cast< DT_TextToken* >(&let_drNewToken); if (pText != 0) pCurAtTag->SetName(pText->GetText()); else { DT_MupType * pTypeBegin = dynamic_cast< DT_MupType* >(&let_drNewToken); DT_MupMember * pMemberBegin = dynamic_cast< DT_MupMember* >(&let_drNewToken); if (pTypeBegin != 0 OR pMemberBegin != 0) { sCurAtSeeType_byXML.reset(); sCurAtSeeType_byXML << ( pTypeBegin != 0 ? pTypeBegin->Scope() : pMemberBegin->Scope() ); if (sCurAtSeeType_byXML.tellp() > 0) { sCurAtSeeType_byXML << "::"; } delete &let_drNewToken; fCurTokenAddFunction = &SapiDocu_PE::SetCurSeeAlsoAtTagLinkText_2; return; } else { pCurAtTag->SetName("? (no identifier found)"); } } delete &let_drNewToken; fCurTokenAddFunction = &SapiDocu_PE::AddDocuToken2CurAtTag; } void SapiDocu_PE::SetCurSeeAlsoAtTagLinkText_2( DYN ary::inf::DocuToken & let_drNewToken ) { csv_assert(pCurAtTag); if (let_drNewToken.IsWhiteOnly()) { delete &let_drNewToken; return; } DT_TextToken * pText = dynamic_cast< DT_TextToken* >(&let_drNewToken); if (pText != 0) { sCurAtSeeType_byXML << pText->GetText(); pCurAtTag->SetName(sCurAtSeeType_byXML.c_str()); } else { pCurAtTag->SetName("? (no identifier found)"); } sCurAtSeeType_byXML.reset(); delete &let_drNewToken; fCurTokenAddFunction = &SapiDocu_PE::SetCurSeeAlsoAtTagLinkText_3; } void SapiDocu_PE::SetCurSeeAlsoAtTagLinkText_3( DYN ary::inf::DocuToken & let_drNewToken ) { csv_assert(pCurAtTag); if (let_drNewToken.IsWhiteOnly()) { delete &let_drNewToken; return; } /// Could emit warning, but don't because this parser is obsolete. // Tok_XmlLink_BeginTag * // pLinkEnd = dynamic_cast< Tok_XmlLink_EndTag* >(&let_drNewToken); // if (pLinkEnd == 0) // { // warn_aboutMissingClosingTag(); // } delete &let_drNewToken; fCurTokenAddFunction = &SapiDocu_PE::AddDocuToken2CurAtTag; } const String C_sSinceFormat("Correct version format: \"OpenOffice .[. if micro is not 0]\"."); void SapiDocu_PE::SetCurSinceAtTagVersion_OOo( DYN ary::inf::DocuToken & let_drNewToken ) { csv_assert(pCurAtTag); DT_TextToken * pToken = dynamic_cast< DT_TextToken* >(&let_drNewToken); if (pToken == 0) { delete &let_drNewToken; return; } const String sVersion(pToken->GetText()); // if (NOT CheckVersionSyntax_OOo(sVersion)) if (sVersion != "OpenOffice") { Cerr() << "Version information in @since tag has incorrect format.\n" << "Found: \"" << sVersion << "\"\n" << C_sSinceFormat << Endl(); exit(1); } const autodoc::CommandLine & rCommandLine = autodoc::CommandLine::Get_(); if (NOT rCommandLine.DoesTransform_SinceTag()) pCurAtTag->AddToken(let_drNewToken); fCurTokenAddFunction = &SapiDocu_PE::SetCurSinceAtTagVersion_Number; } void SapiDocu_PE::SetCurSinceAtTagVersion_Number( DYN ary::inf::DocuToken & let_drNewToken ) { csv_assert(pCurAtTag); DT_TextToken * pToken = dynamic_cast< DT_TextToken* >(&let_drNewToken); if (pToken == 0) { if (dynamic_cast< DT_White* >(&let_drNewToken) != 0) { String & sValue = pCurAtTag->Access_Text().Access_TextOfFirstToken(); StreamLock sHelp(1000); sValue = sHelp() << sValue << " " << c_str; } delete &let_drNewToken; return; } const String sVersion(pToken->GetText()); if (NOT CheckVersionSyntax_Number(sVersion)) { Cerr() << "Version information in @since tag has incorrect format.\n" << "Found: \"" << sVersion << "\"\n" << C_sSinceFormat << Endl(); exit(1); } const autodoc::CommandLine & rCommandLine = autodoc::CommandLine::Get_(); if ( rCommandLine.DoesTransform_SinceTag()) { pCurAtTag->AddToken(let_drNewToken); if (rCommandLine.DisplayOf_SinceTagValue(sVersion).empty()) { // This is the numbered part, but we don't know it. delete &let_drNewToken; StreamLock sl(200); sl() << "Since-value '" << sVersion << "' not found in translation table."; throw X_Docu("since", sl().c_str()); } } else { AddDocuToken2SinceAtTag(let_drNewToken); } fCurTokenAddFunction = &SapiDocu_PE::AddDocuToken2SinceAtTag; } void SapiDocu_PE::AddDocuToken2SinceAtTag( DYN ary::inf::DocuToken & let_drNewToken ) { csv_assert(pCurAtTag); String & sValue = pCurAtTag->Access_Text().Access_TextOfFirstToken(); StreamLock sHelp(1000); DT_TextToken * pToken = dynamic_cast< DT_TextToken* >(&let_drNewToken); if (pToken != 0) { sValue = sHelp() << sValue << pToken->GetText() << c_str; } else if (dynamic_cast< DT_White* >(&let_drNewToken) != 0) { sValue = sHelp() << sValue << " " << c_str; } delete &let_drNewToken; } bool SapiDocu_PE::CheckVersionSyntax_Number(const String & i_versionPart2) { if (i_versionPart2.length () == 0) return false; const char pt = '.'; unsigned int countDigit = 0; unsigned int countPoint = 0; const char * pFirstPoint = 0; const char * pLastPoint = 0; for ( const char * p = i_versionPart2.begin(); *p != 0; ++p ) { if ( std::isdigit(*p) ) ++countDigit; else if (*p == pt) { if (countPoint == 0) pFirstPoint = p; pLastPoint = p; ++countPoint; } } if ( countDigit + countPoint == i_versionPart2.length() // only digits and points AND pFirstPoint != 0 AND countPoint < 3 // 1 or 2 points AND pFirstPoint + 1 != pLastPoint // there are digits between two points AND *i_versionPart2.begin() != pt AND *(pLastPoint + 1) != 0 // points are surrounded by digits AND (*(pLastPoint + 1) != '0' OR pLastPoint == pFirstPoint) ) // the first micro-digit is not 0 { return true; } return false; } const char * AtTagTitle( const Tok_AtTag & i_rToken ) { switch (i_rToken.Id()) { case Tok_AtTag::author: return ""; case Tok_AtTag::see: return "See also"; case Tok_AtTag::param: return "Parameters"; case Tok_AtTag::e_return: return "Returns"; case Tok_AtTag::e_throw: return "Throws"; case Tok_AtTag::example: return "Example"; case Tok_AtTag::deprecated: return "Deprecated"; case Tok_AtTag::suspicious: return ""; case Tok_AtTag::missing: return ""; case Tok_AtTag::incomplete: return ""; case Tok_AtTag::version: return ""; case Tok_AtTag::guarantees: return "Guarantees"; case Tok_AtTag::exception: return "Exception"; case Tok_AtTag::since: return "Since version"; default: // See below. ; } return i_rToken.Text(); } } // namespace dsapi } // namespace csi