From a927f7ef634579129ce71882f9e707cf80669d8d Mon Sep 17 00:00:00 2001 From: "rickg%netscape.com" Date: Fri, 24 Jul 1998 21:57:43 +0000 Subject: [PATCH] tons-o-fixes in the parser git-svn-id: svn://10.0.0.236/trunk@6422 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/htmlparser/src/CNavDTD.cpp | 67 ++++++++++++------- mozilla/htmlparser/src/CNavDTD.h | 13 +++- mozilla/htmlparser/src/COtherDTD.cpp | 19 ++++-- mozilla/htmlparser/src/COtherDTD.h | 34 +++++++--- mozilla/htmlparser/src/CParserContext.cpp | 14 +++- mozilla/htmlparser/src/CRtfDTD.cpp | 15 ++++- mozilla/htmlparser/src/CRtfDTD.h | 34 +++++++--- mozilla/htmlparser/src/nsIDTD.h | 14 +++- mozilla/htmlparser/src/nsParser.cpp | 50 ++++++++------ mozilla/htmlparser/src/nsParser.h | 3 +- mozilla/htmlparser/src/nsParserTypes.h | 14 ++-- mozilla/htmlparser/src/nsScanner.cpp | 44 +++++++----- mozilla/htmlparser/src/nsScanner.h | 14 +++- mozilla/htmlparser/src/nsValidDTD.cpp | 15 ++++- mozilla/htmlparser/src/nsValidDTD.h | 34 +++++++--- mozilla/htmlparser/src/nsWellFormedDTD.cpp | 15 ++++- mozilla/htmlparser/src/nsWellFormedDTD.h | 35 +++++++--- mozilla/htmlparser/src/nsXIFDTD.cpp | 18 +++-- mozilla/htmlparser/src/nsXIFDTD.h | 17 +++-- mozilla/parser/htmlparser/src/CNavDTD.cpp | 67 ++++++++++++------- mozilla/parser/htmlparser/src/CNavDTD.h | 13 +++- mozilla/parser/htmlparser/src/COtherDTD.cpp | 19 ++++-- mozilla/parser/htmlparser/src/COtherDTD.h | 34 +++++++--- .../parser/htmlparser/src/CParserContext.cpp | 14 +++- mozilla/parser/htmlparser/src/CRtfDTD.cpp | 15 ++++- mozilla/parser/htmlparser/src/CRtfDTD.h | 34 +++++++--- mozilla/parser/htmlparser/src/nsIDTD.h | 14 +++- mozilla/parser/htmlparser/src/nsParser.cpp | 50 ++++++++------ mozilla/parser/htmlparser/src/nsParser.h | 3 +- mozilla/parser/htmlparser/src/nsParserTypes.h | 14 ++-- mozilla/parser/htmlparser/src/nsScanner.cpp | 44 +++++++----- mozilla/parser/htmlparser/src/nsScanner.h | 14 +++- mozilla/parser/htmlparser/src/nsValidDTD.cpp | 15 ++++- mozilla/parser/htmlparser/src/nsValidDTD.h | 34 +++++++--- .../parser/htmlparser/src/nsWellFormedDTD.cpp | 15 ++++- .../parser/htmlparser/src/nsWellFormedDTD.h | 35 +++++++--- mozilla/parser/htmlparser/src/nsXIFDTD.cpp | 18 +++-- mozilla/parser/htmlparser/src/nsXIFDTD.h | 17 +++-- 38 files changed, 656 insertions(+), 282 deletions(-) diff --git a/mozilla/htmlparser/src/CNavDTD.cpp b/mozilla/htmlparser/src/CNavDTD.cpp index ad7e07880f3..90fffca3394 100644 --- a/mozilla/htmlparser/src/CNavDTD.cpp +++ b/mozilla/htmlparser/src/CNavDTD.cpp @@ -357,9 +357,19 @@ CNavDTD::CNavDTD() : nsIDTD(), mTokenDeque(gTokenKiller), CNavDTD::~CNavDTD(){ DeleteTokenHandlers(); - if (mDTDDebug) - NS_RELEASE(mDTDDebug); -// NS_RELEASE(mSink); + NS_IF_RELEASE(mDTDDebug); + +} + +/** + * Call this method if you want the DTD to construct a fresh + * instance of itself. + * @update gess7/23/98 + * @param + * @return + */ +nsresult CNavDTD::CreateNewInstance(nsIDTD** aInstancePtrResult){ + return NS_NewNavHTMLDTD(aInstancePtrResult); } /** @@ -412,12 +422,12 @@ eAutoDetectResult CNavDTD::AutoDetectContentType(nsString& aBuffer,nsString& aTy * @param * @return */ -nsresult CNavDTD::WillBuildModel(nsString& aFilename){ +nsresult CNavDTD::WillBuildModel(nsString& aFilename,PRInt32 aLevel){ nsresult result=NS_OK; mFilename=aFilename; - if(mSink) { + if((1==aLevel) && (mSink)) { result = mSink->WillBuildModel(); } @@ -430,13 +440,14 @@ nsresult CNavDTD::WillBuildModel(nsString& aFilename){ * @param * @return */ -nsresult CNavDTD::DidBuildModel(PRInt32 anErrorCode){ +nsresult CNavDTD::DidBuildModel(PRInt32 anErrorCode,PRInt32 aLevel){ nsresult result= NS_OK; if((kNoError==anErrorCode) && (mContextStack.mCount>0)) { result = CloseContainersTo(0,eHTMLTag_unknown,PR_FALSE); } - if(mSink) { + + if((1==aLevel) && (mSink)) { result = mSink->DidBuildModel(1); } @@ -2843,8 +2854,7 @@ CNavDTD::ConsumeWhitespace(PRUnichar aChar, * @param anErrorCode: arg that will hold error condition * @return new token or null */ -nsresult -CNavDTD::ConsumeComment(PRUnichar aChar,CScanner& aScanner,CToken*& aToken){ +nsresult CNavDTD::ConsumeComment(PRUnichar aChar,CScanner& aScanner,CToken*& aToken){ aToken = new CCommentToken(); nsresult result=NS_OK; if(aToken) { @@ -2863,14 +2873,18 @@ CNavDTD::ConsumeComment(PRUnichar aChar,CScanner& aScanner,CToken*& aToken){ * @param anErrorCode: arg that will hold error condition * @return new token or null */ -nsresult -CNavDTD::ConsumeText(const nsString& aString, - CScanner& aScanner, - CToken*& aToken){ +nsresult CNavDTD::ConsumeText(const nsString& aString,CScanner& aScanner,CToken*& aToken){ nsresult result=NS_OK; if(aToken=new CTextToken(aString)) { PRUnichar ch=0; result=aToken->Consume(ch,aScanner); + if(result) { + nsString& temp=aToken->GetStringValueXXX(); + if(0==temp.Length()){ + delete aToken; + } + else result=kNoError; + } } return result; } @@ -2884,10 +2898,7 @@ CNavDTD::ConsumeText(const nsString& aString, * @param anErrorCode: arg that will hold error condition * @return new token or null */ -nsresult -CNavDTD::ConsumeNewline(PRUnichar aChar, - CScanner& aScanner, - CToken*& aToken){ +nsresult CNavDTD::ConsumeNewline(PRUnichar aChar,CScanner& aScanner,CToken*& aToken){ aToken=new CNewlineToken(); nsresult result=NS_OK; if(aToken) { @@ -2918,7 +2929,6 @@ nsresult CNavDTD::ConsumeToken(CToken*& aToken){ nsresult result=NS_OK; CScanner* theScanner=mParser->GetScanner(); if(NS_OK==result){ - PRUnichar theChar; result=theScanner->GetChar(theChar); switch(result) { @@ -2933,13 +2943,16 @@ nsresult CNavDTD::ConsumeToken(CToken*& aToken){ default: switch(theChar) { case kLessThan: - return ConsumeTag(theChar,*theScanner,aToken); + result=ConsumeTag(theChar,*theScanner,aToken); + break; case kAmpersand: - return ConsumeEntity(theChar,*theScanner,aToken); + result=ConsumeEntity(theChar,*theScanner,aToken); + break; case kCR: case kLF: - return ConsumeNewline(theChar,*theScanner,aToken); + result=ConsumeNewline(theChar,*theScanner,aToken); + break; case kNotFound: break; @@ -2947,15 +2960,17 @@ nsresult CNavDTD::ConsumeToken(CToken*& aToken){ default: if(!nsString::IsSpace(theChar)) { nsAutoString temp(theChar); - return ConsumeText(temp,*theScanner,aToken); + result=ConsumeText(temp,*theScanner,aToken); + break; } - return ConsumeWhitespace(theChar,*theScanner,aToken); + result=ConsumeWhitespace(theChar,*theScanner,aToken); + break; } //switch break; } //switch - if(NS_OK==result) - result=theScanner->Eof(); - } //while +// if(NS_OK==result) +// result=theScanner->Eof(); + } //if return result; } diff --git a/mozilla/htmlparser/src/CNavDTD.h b/mozilla/htmlparser/src/CNavDTD.h index 5bb10e4713c..93a8635942a 100644 --- a/mozilla/htmlparser/src/CNavDTD.h +++ b/mozilla/htmlparser/src/CNavDTD.h @@ -170,6 +170,15 @@ CLASS_EXPORT_HTMLPARS CNavDTD : public nsIDTD { */ virtual ~CNavDTD(); + /** + * Call this method if you want the DTD to construct a clone of itself. + * @update gess7/23/98 + * @param + * @return + */ + virtual nsresult CreateNewInstance(nsIDTD** aInstancePtrResult); + + NS_DECL_ISUPPORTS /** @@ -212,7 +221,7 @@ CLASS_EXPORT_HTMLPARS CNavDTD : public nsIDTD { * @param aFilename is the name of the file being parsed. * @return error code (almost always 0) */ - NS_IMETHOD WillBuildModel(nsString& aFilename); + NS_IMETHOD WillBuildModel(nsString& aFilename,PRInt32 aLevel); /** * The parser uses a code sandwich to wrap the parsing process. Before @@ -222,7 +231,7 @@ CLASS_EXPORT_HTMLPARS CNavDTD : public nsIDTD { * @param anErrorCode contans the last error that occured * @return error code */ - NS_IMETHOD DidBuildModel(PRInt32 anErrorCode); + NS_IMETHOD DidBuildModel(PRInt32 anErrorCode,PRInt32 aLevel); /** * This method is called by the parser, once for each token diff --git a/mozilla/htmlparser/src/COtherDTD.cpp b/mozilla/htmlparser/src/COtherDTD.cpp index 862933dd973..7389cb3d5b2 100644 --- a/mozilla/htmlparser/src/COtherDTD.cpp +++ b/mozilla/htmlparser/src/COtherDTD.cpp @@ -148,6 +148,17 @@ COtherDTD::~COtherDTD(){ //parent does all the real work of destruction. } +/** + * Call this method if you want the DTD to construct a fresh instance + * of itself + * @update gess7/23/98 + * @param + * @return + */ +nsresult COtherDTD::CreateNewInstance(nsIDTD** aInstancePtrResult){ + return NS_NewOtherHTMLDTD(aInstancePtrResult); +} + /** * This method is called to determine if the given DTD can parse * a document in a given source-type. @@ -178,8 +189,8 @@ eAutoDetectResult COtherDTD::AutoDetectContentType(nsString& aBuffer,nsString& a * @param * @return */ -NS_IMETHODIMP COtherDTD::WillBuildModel(nsString& aFilename) { - return CNavDTD::WillBuildModel(aFilename); +NS_IMETHODIMP COtherDTD::WillBuildModel(nsString& aFilename,PRInt32 aLevel) { + return CNavDTD::WillBuildModel(aFilename, aLevel); } /** @@ -188,8 +199,8 @@ NS_IMETHODIMP COtherDTD::WillBuildModel(nsString& aFilename) { * @param * @return */ -NS_IMETHODIMP COtherDTD::DidBuildModel(PRInt32 anErrorCode){ - return CNavDTD::DidBuildModel(anErrorCode); +NS_IMETHODIMP COtherDTD::DidBuildModel(PRInt32 anErrorCode,PRInt32 aLevel){ + return CNavDTD::DidBuildModel(anErrorCode, aLevel); } /** diff --git a/mozilla/htmlparser/src/COtherDTD.h b/mozilla/htmlparser/src/COtherDTD.h index 10be7a27ab1..77c88a8f8c5 100644 --- a/mozilla/htmlparser/src/COtherDTD.h +++ b/mozilla/htmlparser/src/COtherDTD.h @@ -62,6 +62,14 @@ class COtherDTD : public CNavDTD { */ virtual ~COtherDTD(); + /** + * Call this method if you want the DTD to construct a clone of itself. + * @update gess7/23/98 + * @param + * @return + */ + virtual nsresult CreateNewInstance(nsIDTD** aInstancePtrResult); + /** * This method is called to determine if the given DTD can parse * a document in a given source-type. @@ -82,20 +90,24 @@ class COtherDTD : public CNavDTD { virtual eAutoDetectResult AutoDetectContentType(nsString& aBuffer,nsString& aType); /** - * - * @update gess5/18/98 - * @param - * @return - */ - NS_IMETHOD WillBuildModel(nsString& aString); + * The parser uses a code sandwich to wrap the parsing process. Before + * the process begins, WillBuildModel() is called. Afterwards the parser + * calls DidBuildModel(). + * @update gess5/18/98 + * @param aFilename is the name of the file being parsed. + * @return error code (almost always 0) + */ + NS_IMETHOD WillBuildModel(nsString& aFilename,PRInt32 aLevel); - /** - * + /** + * The parser uses a code sandwich to wrap the parsing process. Before + * the process begins, WillBuildModel() is called. Afterwards the parser + * calls DidBuildModel(). * @update gess5/18/98 - * @param - * @return + * @param anErrorCode contans the last error that occured + * @return error code */ - NS_IMETHOD DidBuildModel(PRInt32 anErrorCode); + NS_IMETHOD DidBuildModel(PRInt32 anErrorCode,PRInt32 aLevel); /** * diff --git a/mozilla/htmlparser/src/CParserContext.cpp b/mozilla/htmlparser/src/CParserContext.cpp index e089510777d..35eeff728d0 100644 --- a/mozilla/htmlparser/src/CParserContext.cpp +++ b/mozilla/htmlparser/src/CParserContext.cpp @@ -33,6 +33,15 @@ public: CTokenDeallocator gTokenDeallocator; + +/** + * Your friendly little constructor. Ok, it's not the friendly, but the only guy + * using it is the parser. + * @update gess7/23/98 + * @param aScanner + * @param aKey + * @param aListener + */ CParserContext::CParserContext(CScanner* aScanner,void* aKey,nsIStreamObserver* aListener) : mSourceType(), mTokenDeque(gTokenDeallocator) @@ -69,8 +78,9 @@ CParserContext::~CParserContext(){ if(mTransferBuffer) delete [] mTransferBuffer; - //Remember that it's ok to simply - //ignore the DTD and the prevcontext. + NS_RELEASE(mDTD); + + //Remember that it's ok to simply ingore the PrevContext. } diff --git a/mozilla/htmlparser/src/CRtfDTD.cpp b/mozilla/htmlparser/src/CRtfDTD.cpp index 5c06e0ae06d..94a5784c9ad 100644 --- a/mozilla/htmlparser/src/CRtfDTD.cpp +++ b/mozilla/htmlparser/src/CRtfDTD.cpp @@ -216,6 +216,17 @@ CRtfDTD::CRtfDTD() : nsIDTD() { CRtfDTD::~CRtfDTD(){ } +/** + * Call this method if you want the DTD to construct fresh instance + * of itself. + * @update gess7/23/98 + * @param + * @return + */ +nsresult CRtfDTD::CreateNewInstance(nsIDTD** aInstancePtrResult){ + return NS_NewRTF_DTD(aInstancePtrResult); +} + /** * This method is called to determine if the given DTD can parse * a document in a given source-type. @@ -251,7 +262,7 @@ eAutoDetectResult CRtfDTD::AutoDetectContentType(nsString& aBuffer,nsString& aTy * @param * @return */ -NS_IMETHODIMP CRtfDTD::WillBuildModel(nsString& aFilename){ +NS_IMETHODIMP CRtfDTD::WillBuildModel(nsString& aFilename,PRInt32 aLevel){ nsresult result=NS_OK; return result; } @@ -262,7 +273,7 @@ NS_IMETHODIMP CRtfDTD::WillBuildModel(nsString& aFilename){ * @param * @return */ -NS_IMETHODIMP CRtfDTD::DidBuildModel(PRInt32 anErrorCode){ +NS_IMETHODIMP CRtfDTD::DidBuildModel(PRInt32 anErrorCode,PRInt32 aLevel){ nsresult result=NS_OK; return result; diff --git a/mozilla/htmlparser/src/CRtfDTD.h b/mozilla/htmlparser/src/CRtfDTD.h index d2a0df8d694..020b9a7c60c 100644 --- a/mozilla/htmlparser/src/CRtfDTD.h +++ b/mozilla/htmlparser/src/CRtfDTD.h @@ -165,6 +165,14 @@ class CRtfDTD : public nsIDTD { */ virtual ~CRtfDTD(); + /** + * Call this method if you want the DTD to construct a clone of itself. + * @update gess7/23/98 + * @param + * @return + */ + virtual nsresult CreateNewInstance(nsIDTD** aInstancePtrResult); + /** * This method is called to determine if the given DTD can parse * a document in a given source-type. @@ -185,20 +193,24 @@ class CRtfDTD : public nsIDTD { virtual eAutoDetectResult AutoDetectContentType(nsString& aBuffer,nsString& aType); /** - * - * @update gess5/18/98 - * @param - * @return - */ - NS_IMETHOD WillBuildModel(nsString& aFilename); + * The parser uses a code sandwich to wrap the parsing process. Before + * the process begins, WillBuildModel() is called. Afterwards the parser + * calls DidBuildModel(). + * @update gess5/18/98 + * @param aFilename is the name of the file being parsed. + * @return error code (almost always 0) + */ + NS_IMETHOD WillBuildModel(nsString& aFilename,PRInt32 aLevel); - /** - * + /** + * The parser uses a code sandwich to wrap the parsing process. Before + * the process begins, WillBuildModel() is called. Afterwards the parser + * calls DidBuildModel(). * @update gess5/18/98 - * @param - * @return + * @param anErrorCode contans the last error that occured + * @return error code */ - NS_IMETHOD DidBuildModel(PRInt32 anErrorCode); + NS_IMETHOD DidBuildModel(PRInt32 anErrorCode,PRInt32 aLevel); /** * diff --git a/mozilla/htmlparser/src/nsIDTD.h b/mozilla/htmlparser/src/nsIDTD.h index 4d48349be3c..833432bea6f 100644 --- a/mozilla/htmlparser/src/nsIDTD.h +++ b/mozilla/htmlparser/src/nsIDTD.h @@ -49,12 +49,22 @@ enum eAutoDetectResult {eUnknownDetect, eValidDetect, eInvalidDetect}; class nsIDTD : public nsISupports { public: + /** * Default constructor * @update gess6/24/98 */ virtual ~nsIDTD() {}; + + /** + * Call this method if you want the DTD to construct a clone of itself. + * @update gess7/23/98 + * @param + * @return + */ + virtual nsresult CreateNewInstance(nsIDTD** aInstancePtrResult)=0; + /** * This method informs the DTD about the parser being used to drive the parse process * @@ -100,7 +110,7 @@ class nsIDTD : public nsISupports { * @param aFilename--string that contains name of file being parsed (if applicable) * @return */ - NS_IMETHOD WillBuildModel(nsString& aFilename)=0; + NS_IMETHOD WillBuildModel(nsString& aFilename,PRInt32 aLevel)=0; /** * Called by the parser after the parsing process has concluded @@ -108,7 +118,7 @@ class nsIDTD : public nsISupports { * @param anErrorCode - contains error code resulting from parse process * @return */ - NS_IMETHOD DidBuildModel(PRInt32 anErrorCode)=0; + NS_IMETHOD DidBuildModel(PRInt32 anErrorCode,PRInt32 aLevel)=0; /** * Called during model building phase of parse process. Each token created during diff --git a/mozilla/htmlparser/src/nsParser.cpp b/mozilla/htmlparser/src/nsParser.cpp index 9e4b34516b5..b86b40e1c89 100644 --- a/mozilla/htmlparser/src/nsParser.cpp +++ b/mozilla/htmlparser/src/nsParser.cpp @@ -142,6 +142,7 @@ nsParser::nsParser() { mObserver = 0; mSink=0; mParserContext=0; + mParseLevel=0; } @@ -319,7 +320,7 @@ PRBool FindSuitableDTD( CParserContext& aParserContext) { if(theDTD) { result=theDTD->CanParse(aParserContext.mSourceType,0); if(result){ - aParserContext.mDTD=theDTD; + nsresult status=theDTD->CreateNewInstance(&aParserContext.mDTD); break; } } @@ -385,7 +386,7 @@ PRInt32 nsParser::WillBuildModel(nsString& aFilename){ if(PR_TRUE==FindSuitableDTD(*mParserContext)) { mParserContext->mDTD->SetParser(this); mParserContext->mDTD->SetContentSink(mSink); - mParserContext->mDTD->WillBuildModel(aFilename); + mParserContext->mDTD->WillBuildModel(aFilename,mParseLevel); } return kNoError; @@ -401,7 +402,7 @@ PRInt32 nsParser::DidBuildModel(PRInt32 anErrorCode) { //One last thing...close any open containers. PRInt32 result=anErrorCode; if(mParserContext->mDTD) { - result=mParserContext->mDTD->DidBuildModel(anErrorCode); + result=mParserContext->mDTD->DidBuildModel(anErrorCode,mParseLevel); } return result; @@ -454,6 +455,7 @@ PRInt32 nsParser::Parse(nsIURL* aURL,nsIStreamObserver* aListener, nsIDTDDebug * NS_PRECONDITION(0!=aURL,kNullURL); PRInt32 status=kBadURL; + mParseLevel++; /* Disable DTD Debug for now... mDTDDebug = aDTDDebug; @@ -479,6 +481,7 @@ PRInt32 nsParser::Parse(nsIURL* aURL,nsIStreamObserver* aListener, nsIDTDDebug * PRInt32 nsParser::Parse(fstream& aStream){ PRInt32 status=kNoError; + mParseLevel++; //ok, time to create our tokenizer and begin the process CParserContext* pc=new CParserContext(new CScanner(kUnknownFilename,aStream,PR_FALSE),&aStream,0); @@ -511,12 +514,13 @@ PRInt32 nsParser::Parse(fstream& aStream){ */ PRInt32 nsParser::Parse(nsString& aSourceBuffer,PRBool anHTMLString){ PRInt32 result=kNoError; + mParseLevel++; CParserContext* pc=new CParserContext(new CScanner(kUnknownFilename,PR_FALSE),&aSourceBuffer,0); + PushContext(*pc); if(PR_TRUE==anHTMLString) pc->mSourceType="text/html"; - mParserContext->mScanner->Append(aSourceBuffer); if(eValidDetect==AutoDetectContentType(aSourceBuffer,mParserContext->mSourceType)) { WillBuildModel(mParserContext->mScanner->GetFilename()); result=ResumeParse(); @@ -543,9 +547,9 @@ PRInt32 nsParser::ResumeParse() { mParserContext->mDTD->WillResumeParse(); if(kNoError==result) { result=Tokenize(); + BuildModel(); if(kInterrupted==result) mParserContext->mDTD->WillInterruptParse(); - BuildModel(); } return result; } @@ -566,27 +570,38 @@ PRInt32 nsParser::BuildModel() { if(!mParserContext->mCurrentPos) mParserContext->mCurrentPos=new nsDequeIterator(mParserContext->mTokenDeque.Begin()); + //Get the root DTD for use in model building... + CParserContext* theRootContext=mParserContext; + while(theRootContext->mPrevContext) + theRootContext=theRootContext->mPrevContext; + + nsIDTD* theRootDTD=theRootContext->mDTD; + PRInt32 result=kNoError; while((kNoError==result) && ((*mParserContext->mCurrentPosmCurrentPos->GetCurrent(); - + /************************************************************************** The point of this code to serve as a testbed for parser reentrancy. If you set recurse=1, we go reentrant, passing a text string of HTML onto the parser for inline processing, just like javascript/DOM would do it. And guess what? It worked the first time! - Uncomment the following code to enable the test: + Uncomment the following code to enable the test: int recurse=0; if(recurse){ - nsString theString("
cell
"); + nsString theString(" this is just a great big empty string "); +// nsString theString("

doc.write"); +// nsString theString("
cell
"); Parse(theString,PR_TRUE); } - **************************************************************************/ + */ theMarkPos=*mParserContext->mCurrentPos; - result=mParserContext->mDTD->HandleToken(theToken); + + result=theRootDTD->HandleToken(theToken); +// result=mParserContext->mDTD->HandleToken(theToken); ++(*mParserContext->mCurrentPos); } @@ -813,10 +828,11 @@ PRBool nsParser::WillTokenize(){ PRInt32 nsParser::Tokenize(){ CToken* theToken=0; PRInt32 result=kNoError; - PRBool done=(0==++mMajorIteration) ? (!WillTokenize()) : PR_FALSE; - - while((PR_FALSE==done) && (kNoError==result)) { + ++mMajorIteration; + + WillTokenize(); + while(kNoError==result) { mParserContext->mScanner->Mark(); result=mParserContext->mDTD->ConsumeToken(theToken); if(kNoError==result) { @@ -835,8 +851,7 @@ PRInt32 nsParser::Tokenize(){ mParserContext->mScanner->RewindToMark(); } } - if((PR_TRUE==done) && (kInterrupted!=result)) - DidTokenize(); + DidTokenize(); return result; } @@ -851,11 +866,6 @@ PRInt32 nsParser::Tokenize(){ */ PRBool nsParser::DidTokenize(){ PRBool result=PR_TRUE; - -#ifdef VERBOSE_DEBUG - DebugDumpTokens(cout); -#endif - return result; } diff --git a/mozilla/htmlparser/src/nsParser.h b/mozilla/htmlparser/src/nsParser.h index 4c2056a6d3a..ce06eb452ff 100644 --- a/mozilla/htmlparser/src/nsParser.h +++ b/mozilla/htmlparser/src/nsParser.h @@ -294,14 +294,13 @@ protected: CParserContext* mParserContext; PRInt32 mMajorIteration; PRInt32 mMinorIteration; + PRInt32 mParseLevel; nsIStreamObserver* mObserver; nsIContentSink* mSink; nsIParserFilter* mParserFilter; nsIDTDDebug* mDTDDebug; - - }; diff --git a/mozilla/htmlparser/src/nsParserTypes.h b/mozilla/htmlparser/src/nsParserTypes.h index 83a1e91b308..9bad92f2a14 100644 --- a/mozilla/htmlparser/src/nsParserTypes.h +++ b/mozilla/htmlparser/src/nsParserTypes.h @@ -43,13 +43,13 @@ enum eParseMode { }; -const PRInt32 kEOF = 1000000L; -const PRInt32 kUnknownError = -1000; -const PRInt32 kCantPropagate = -6; -const PRInt32 kContextMismatch = -5; -const PRInt32 kBadFilename = -4; -const PRInt32 kBadURL = -3; -const PRInt32 kInterrupted = -2; +const PRInt32 kEOF = 10000; +const PRInt32 kUnknownError = 10001; +const PRInt32 kCantPropagate = 10002; +const PRInt32 kContextMismatch = 10003; +const PRInt32 kBadFilename = 10004; +const PRInt32 kBadURL = 10005; +const PRInt32 kInterrupted = 10006; const PRInt32 kNotFound = -1; const PRInt32 kNoError = NS_OK; diff --git a/mozilla/htmlparser/src/nsScanner.cpp b/mozilla/htmlparser/src/nsScanner.cpp index 93ce54eea57..938202153a5 100644 --- a/mozilla/htmlparser/src/nsScanner.cpp +++ b/mozilla/htmlparser/src/nsScanner.cpp @@ -31,8 +31,27 @@ const int kBufsize=64; /** - * Use this constructor if you want i/o to be based on an - * incremental netstream. If you pass a null filename, you + * Use this constructor if you want i/o to be based on + * a single string you hand in during construction. + * This short cut was added for Javascript. + * + * @update gess 5/12/98 + * @param aMode represents the parser mode (nav, other) + * @return + */ +CScanner::CScanner(nsString& anHTMLString) : + mBuffer(anHTMLString), mFilename("") +{ + mTotalRead=mBuffer.Length(); + mIncremental=PR_FALSE; + mOwnsStream=PR_FALSE; + mOffset=0; + mFileStream=0; +} + +/** + * Use this constructor if you want i/o to be based on strings + * the scanner receives. If you pass a null filename, you * can still provide data to the scanner via append. * * @update gess 5/12/98 @@ -42,6 +61,7 @@ const int kBufsize=64; CScanner::CScanner(nsString& aFilename,PRBool aCreateStream) : mBuffer(""), mFilename(aFilename) { + mIncremental=PR_TRUE; mOffset=0; mMarkPos=-1; mTotalRead=0; @@ -71,6 +91,7 @@ CScanner::CScanner(nsString& aFilename,PRBool aCreateStream) : CScanner::CScanner(nsString& aFilename,fstream& aStream,PRBool assumeOwnership) : mBuffer(""), mFilename(aFilename) { + mIncremental=PR_TRUE; mOffset=0; mMarkPos=-1; mTotalRead=0; @@ -135,26 +156,17 @@ void _PreCompressBuffer(nsString& aBuffer,PRInt32& anOffset,PRInt32& aMarkPos){ //we've guaranteed the client we can back up to, so make sure //you don't lose any of the data beyond that point. -/* - if((anOffset!=aMarkPos) && (0<=aMarkPos)) { - if(aMarkPos>0) { - aBuffer.Cut(0,aMarkPos); - if(anOffset>aMarkPos) - anOffset-=aMarkPos; - } - } - else aBuffer.Truncate(); -*/ PRInt32 len=aBuffer.Length(); - if((aMarkPos=0)) { + if((aMarkPos0)) { aBuffer.Cut(0,aMarkPos); anOffset-=aMarkPos; + aMarkPos=0; } - else { + else if((anOffset==aMarkPos) && (0WillBuildModel(); } @@ -430,13 +440,14 @@ nsresult CNavDTD::WillBuildModel(nsString& aFilename){ * @param * @return */ -nsresult CNavDTD::DidBuildModel(PRInt32 anErrorCode){ +nsresult CNavDTD::DidBuildModel(PRInt32 anErrorCode,PRInt32 aLevel){ nsresult result= NS_OK; if((kNoError==anErrorCode) && (mContextStack.mCount>0)) { result = CloseContainersTo(0,eHTMLTag_unknown,PR_FALSE); } - if(mSink) { + + if((1==aLevel) && (mSink)) { result = mSink->DidBuildModel(1); } @@ -2843,8 +2854,7 @@ CNavDTD::ConsumeWhitespace(PRUnichar aChar, * @param anErrorCode: arg that will hold error condition * @return new token or null */ -nsresult -CNavDTD::ConsumeComment(PRUnichar aChar,CScanner& aScanner,CToken*& aToken){ +nsresult CNavDTD::ConsumeComment(PRUnichar aChar,CScanner& aScanner,CToken*& aToken){ aToken = new CCommentToken(); nsresult result=NS_OK; if(aToken) { @@ -2863,14 +2873,18 @@ CNavDTD::ConsumeComment(PRUnichar aChar,CScanner& aScanner,CToken*& aToken){ * @param anErrorCode: arg that will hold error condition * @return new token or null */ -nsresult -CNavDTD::ConsumeText(const nsString& aString, - CScanner& aScanner, - CToken*& aToken){ +nsresult CNavDTD::ConsumeText(const nsString& aString,CScanner& aScanner,CToken*& aToken){ nsresult result=NS_OK; if(aToken=new CTextToken(aString)) { PRUnichar ch=0; result=aToken->Consume(ch,aScanner); + if(result) { + nsString& temp=aToken->GetStringValueXXX(); + if(0==temp.Length()){ + delete aToken; + } + else result=kNoError; + } } return result; } @@ -2884,10 +2898,7 @@ CNavDTD::ConsumeText(const nsString& aString, * @param anErrorCode: arg that will hold error condition * @return new token or null */ -nsresult -CNavDTD::ConsumeNewline(PRUnichar aChar, - CScanner& aScanner, - CToken*& aToken){ +nsresult CNavDTD::ConsumeNewline(PRUnichar aChar,CScanner& aScanner,CToken*& aToken){ aToken=new CNewlineToken(); nsresult result=NS_OK; if(aToken) { @@ -2918,7 +2929,6 @@ nsresult CNavDTD::ConsumeToken(CToken*& aToken){ nsresult result=NS_OK; CScanner* theScanner=mParser->GetScanner(); if(NS_OK==result){ - PRUnichar theChar; result=theScanner->GetChar(theChar); switch(result) { @@ -2933,13 +2943,16 @@ nsresult CNavDTD::ConsumeToken(CToken*& aToken){ default: switch(theChar) { case kLessThan: - return ConsumeTag(theChar,*theScanner,aToken); + result=ConsumeTag(theChar,*theScanner,aToken); + break; case kAmpersand: - return ConsumeEntity(theChar,*theScanner,aToken); + result=ConsumeEntity(theChar,*theScanner,aToken); + break; case kCR: case kLF: - return ConsumeNewline(theChar,*theScanner,aToken); + result=ConsumeNewline(theChar,*theScanner,aToken); + break; case kNotFound: break; @@ -2947,15 +2960,17 @@ nsresult CNavDTD::ConsumeToken(CToken*& aToken){ default: if(!nsString::IsSpace(theChar)) { nsAutoString temp(theChar); - return ConsumeText(temp,*theScanner,aToken); + result=ConsumeText(temp,*theScanner,aToken); + break; } - return ConsumeWhitespace(theChar,*theScanner,aToken); + result=ConsumeWhitespace(theChar,*theScanner,aToken); + break; } //switch break; } //switch - if(NS_OK==result) - result=theScanner->Eof(); - } //while +// if(NS_OK==result) +// result=theScanner->Eof(); + } //if return result; } diff --git a/mozilla/parser/htmlparser/src/CNavDTD.h b/mozilla/parser/htmlparser/src/CNavDTD.h index 5bb10e4713c..93a8635942a 100644 --- a/mozilla/parser/htmlparser/src/CNavDTD.h +++ b/mozilla/parser/htmlparser/src/CNavDTD.h @@ -170,6 +170,15 @@ CLASS_EXPORT_HTMLPARS CNavDTD : public nsIDTD { */ virtual ~CNavDTD(); + /** + * Call this method if you want the DTD to construct a clone of itself. + * @update gess7/23/98 + * @param + * @return + */ + virtual nsresult CreateNewInstance(nsIDTD** aInstancePtrResult); + + NS_DECL_ISUPPORTS /** @@ -212,7 +221,7 @@ CLASS_EXPORT_HTMLPARS CNavDTD : public nsIDTD { * @param aFilename is the name of the file being parsed. * @return error code (almost always 0) */ - NS_IMETHOD WillBuildModel(nsString& aFilename); + NS_IMETHOD WillBuildModel(nsString& aFilename,PRInt32 aLevel); /** * The parser uses a code sandwich to wrap the parsing process. Before @@ -222,7 +231,7 @@ CLASS_EXPORT_HTMLPARS CNavDTD : public nsIDTD { * @param anErrorCode contans the last error that occured * @return error code */ - NS_IMETHOD DidBuildModel(PRInt32 anErrorCode); + NS_IMETHOD DidBuildModel(PRInt32 anErrorCode,PRInt32 aLevel); /** * This method is called by the parser, once for each token diff --git a/mozilla/parser/htmlparser/src/COtherDTD.cpp b/mozilla/parser/htmlparser/src/COtherDTD.cpp index 862933dd973..7389cb3d5b2 100644 --- a/mozilla/parser/htmlparser/src/COtherDTD.cpp +++ b/mozilla/parser/htmlparser/src/COtherDTD.cpp @@ -148,6 +148,17 @@ COtherDTD::~COtherDTD(){ //parent does all the real work of destruction. } +/** + * Call this method if you want the DTD to construct a fresh instance + * of itself + * @update gess7/23/98 + * @param + * @return + */ +nsresult COtherDTD::CreateNewInstance(nsIDTD** aInstancePtrResult){ + return NS_NewOtherHTMLDTD(aInstancePtrResult); +} + /** * This method is called to determine if the given DTD can parse * a document in a given source-type. @@ -178,8 +189,8 @@ eAutoDetectResult COtherDTD::AutoDetectContentType(nsString& aBuffer,nsString& a * @param * @return */ -NS_IMETHODIMP COtherDTD::WillBuildModel(nsString& aFilename) { - return CNavDTD::WillBuildModel(aFilename); +NS_IMETHODIMP COtherDTD::WillBuildModel(nsString& aFilename,PRInt32 aLevel) { + return CNavDTD::WillBuildModel(aFilename, aLevel); } /** @@ -188,8 +199,8 @@ NS_IMETHODIMP COtherDTD::WillBuildModel(nsString& aFilename) { * @param * @return */ -NS_IMETHODIMP COtherDTD::DidBuildModel(PRInt32 anErrorCode){ - return CNavDTD::DidBuildModel(anErrorCode); +NS_IMETHODIMP COtherDTD::DidBuildModel(PRInt32 anErrorCode,PRInt32 aLevel){ + return CNavDTD::DidBuildModel(anErrorCode, aLevel); } /** diff --git a/mozilla/parser/htmlparser/src/COtherDTD.h b/mozilla/parser/htmlparser/src/COtherDTD.h index 10be7a27ab1..77c88a8f8c5 100644 --- a/mozilla/parser/htmlparser/src/COtherDTD.h +++ b/mozilla/parser/htmlparser/src/COtherDTD.h @@ -62,6 +62,14 @@ class COtherDTD : public CNavDTD { */ virtual ~COtherDTD(); + /** + * Call this method if you want the DTD to construct a clone of itself. + * @update gess7/23/98 + * @param + * @return + */ + virtual nsresult CreateNewInstance(nsIDTD** aInstancePtrResult); + /** * This method is called to determine if the given DTD can parse * a document in a given source-type. @@ -82,20 +90,24 @@ class COtherDTD : public CNavDTD { virtual eAutoDetectResult AutoDetectContentType(nsString& aBuffer,nsString& aType); /** - * - * @update gess5/18/98 - * @param - * @return - */ - NS_IMETHOD WillBuildModel(nsString& aString); + * The parser uses a code sandwich to wrap the parsing process. Before + * the process begins, WillBuildModel() is called. Afterwards the parser + * calls DidBuildModel(). + * @update gess5/18/98 + * @param aFilename is the name of the file being parsed. + * @return error code (almost always 0) + */ + NS_IMETHOD WillBuildModel(nsString& aFilename,PRInt32 aLevel); - /** - * + /** + * The parser uses a code sandwich to wrap the parsing process. Before + * the process begins, WillBuildModel() is called. Afterwards the parser + * calls DidBuildModel(). * @update gess5/18/98 - * @param - * @return + * @param anErrorCode contans the last error that occured + * @return error code */ - NS_IMETHOD DidBuildModel(PRInt32 anErrorCode); + NS_IMETHOD DidBuildModel(PRInt32 anErrorCode,PRInt32 aLevel); /** * diff --git a/mozilla/parser/htmlparser/src/CParserContext.cpp b/mozilla/parser/htmlparser/src/CParserContext.cpp index e089510777d..35eeff728d0 100644 --- a/mozilla/parser/htmlparser/src/CParserContext.cpp +++ b/mozilla/parser/htmlparser/src/CParserContext.cpp @@ -33,6 +33,15 @@ public: CTokenDeallocator gTokenDeallocator; + +/** + * Your friendly little constructor. Ok, it's not the friendly, but the only guy + * using it is the parser. + * @update gess7/23/98 + * @param aScanner + * @param aKey + * @param aListener + */ CParserContext::CParserContext(CScanner* aScanner,void* aKey,nsIStreamObserver* aListener) : mSourceType(), mTokenDeque(gTokenDeallocator) @@ -69,8 +78,9 @@ CParserContext::~CParserContext(){ if(mTransferBuffer) delete [] mTransferBuffer; - //Remember that it's ok to simply - //ignore the DTD and the prevcontext. + NS_RELEASE(mDTD); + + //Remember that it's ok to simply ingore the PrevContext. } diff --git a/mozilla/parser/htmlparser/src/CRtfDTD.cpp b/mozilla/parser/htmlparser/src/CRtfDTD.cpp index 5c06e0ae06d..94a5784c9ad 100644 --- a/mozilla/parser/htmlparser/src/CRtfDTD.cpp +++ b/mozilla/parser/htmlparser/src/CRtfDTD.cpp @@ -216,6 +216,17 @@ CRtfDTD::CRtfDTD() : nsIDTD() { CRtfDTD::~CRtfDTD(){ } +/** + * Call this method if you want the DTD to construct fresh instance + * of itself. + * @update gess7/23/98 + * @param + * @return + */ +nsresult CRtfDTD::CreateNewInstance(nsIDTD** aInstancePtrResult){ + return NS_NewRTF_DTD(aInstancePtrResult); +} + /** * This method is called to determine if the given DTD can parse * a document in a given source-type. @@ -251,7 +262,7 @@ eAutoDetectResult CRtfDTD::AutoDetectContentType(nsString& aBuffer,nsString& aTy * @param * @return */ -NS_IMETHODIMP CRtfDTD::WillBuildModel(nsString& aFilename){ +NS_IMETHODIMP CRtfDTD::WillBuildModel(nsString& aFilename,PRInt32 aLevel){ nsresult result=NS_OK; return result; } @@ -262,7 +273,7 @@ NS_IMETHODIMP CRtfDTD::WillBuildModel(nsString& aFilename){ * @param * @return */ -NS_IMETHODIMP CRtfDTD::DidBuildModel(PRInt32 anErrorCode){ +NS_IMETHODIMP CRtfDTD::DidBuildModel(PRInt32 anErrorCode,PRInt32 aLevel){ nsresult result=NS_OK; return result; diff --git a/mozilla/parser/htmlparser/src/CRtfDTD.h b/mozilla/parser/htmlparser/src/CRtfDTD.h index d2a0df8d694..020b9a7c60c 100644 --- a/mozilla/parser/htmlparser/src/CRtfDTD.h +++ b/mozilla/parser/htmlparser/src/CRtfDTD.h @@ -165,6 +165,14 @@ class CRtfDTD : public nsIDTD { */ virtual ~CRtfDTD(); + /** + * Call this method if you want the DTD to construct a clone of itself. + * @update gess7/23/98 + * @param + * @return + */ + virtual nsresult CreateNewInstance(nsIDTD** aInstancePtrResult); + /** * This method is called to determine if the given DTD can parse * a document in a given source-type. @@ -185,20 +193,24 @@ class CRtfDTD : public nsIDTD { virtual eAutoDetectResult AutoDetectContentType(nsString& aBuffer,nsString& aType); /** - * - * @update gess5/18/98 - * @param - * @return - */ - NS_IMETHOD WillBuildModel(nsString& aFilename); + * The parser uses a code sandwich to wrap the parsing process. Before + * the process begins, WillBuildModel() is called. Afterwards the parser + * calls DidBuildModel(). + * @update gess5/18/98 + * @param aFilename is the name of the file being parsed. + * @return error code (almost always 0) + */ + NS_IMETHOD WillBuildModel(nsString& aFilename,PRInt32 aLevel); - /** - * + /** + * The parser uses a code sandwich to wrap the parsing process. Before + * the process begins, WillBuildModel() is called. Afterwards the parser + * calls DidBuildModel(). * @update gess5/18/98 - * @param - * @return + * @param anErrorCode contans the last error that occured + * @return error code */ - NS_IMETHOD DidBuildModel(PRInt32 anErrorCode); + NS_IMETHOD DidBuildModel(PRInt32 anErrorCode,PRInt32 aLevel); /** * diff --git a/mozilla/parser/htmlparser/src/nsIDTD.h b/mozilla/parser/htmlparser/src/nsIDTD.h index 4d48349be3c..833432bea6f 100644 --- a/mozilla/parser/htmlparser/src/nsIDTD.h +++ b/mozilla/parser/htmlparser/src/nsIDTD.h @@ -49,12 +49,22 @@ enum eAutoDetectResult {eUnknownDetect, eValidDetect, eInvalidDetect}; class nsIDTD : public nsISupports { public: + /** * Default constructor * @update gess6/24/98 */ virtual ~nsIDTD() {}; + + /** + * Call this method if you want the DTD to construct a clone of itself. + * @update gess7/23/98 + * @param + * @return + */ + virtual nsresult CreateNewInstance(nsIDTD** aInstancePtrResult)=0; + /** * This method informs the DTD about the parser being used to drive the parse process * @@ -100,7 +110,7 @@ class nsIDTD : public nsISupports { * @param aFilename--string that contains name of file being parsed (if applicable) * @return */ - NS_IMETHOD WillBuildModel(nsString& aFilename)=0; + NS_IMETHOD WillBuildModel(nsString& aFilename,PRInt32 aLevel)=0; /** * Called by the parser after the parsing process has concluded @@ -108,7 +118,7 @@ class nsIDTD : public nsISupports { * @param anErrorCode - contains error code resulting from parse process * @return */ - NS_IMETHOD DidBuildModel(PRInt32 anErrorCode)=0; + NS_IMETHOD DidBuildModel(PRInt32 anErrorCode,PRInt32 aLevel)=0; /** * Called during model building phase of parse process. Each token created during diff --git a/mozilla/parser/htmlparser/src/nsParser.cpp b/mozilla/parser/htmlparser/src/nsParser.cpp index 9e4b34516b5..b86b40e1c89 100644 --- a/mozilla/parser/htmlparser/src/nsParser.cpp +++ b/mozilla/parser/htmlparser/src/nsParser.cpp @@ -142,6 +142,7 @@ nsParser::nsParser() { mObserver = 0; mSink=0; mParserContext=0; + mParseLevel=0; } @@ -319,7 +320,7 @@ PRBool FindSuitableDTD( CParserContext& aParserContext) { if(theDTD) { result=theDTD->CanParse(aParserContext.mSourceType,0); if(result){ - aParserContext.mDTD=theDTD; + nsresult status=theDTD->CreateNewInstance(&aParserContext.mDTD); break; } } @@ -385,7 +386,7 @@ PRInt32 nsParser::WillBuildModel(nsString& aFilename){ if(PR_TRUE==FindSuitableDTD(*mParserContext)) { mParserContext->mDTD->SetParser(this); mParserContext->mDTD->SetContentSink(mSink); - mParserContext->mDTD->WillBuildModel(aFilename); + mParserContext->mDTD->WillBuildModel(aFilename,mParseLevel); } return kNoError; @@ -401,7 +402,7 @@ PRInt32 nsParser::DidBuildModel(PRInt32 anErrorCode) { //One last thing...close any open containers. PRInt32 result=anErrorCode; if(mParserContext->mDTD) { - result=mParserContext->mDTD->DidBuildModel(anErrorCode); + result=mParserContext->mDTD->DidBuildModel(anErrorCode,mParseLevel); } return result; @@ -454,6 +455,7 @@ PRInt32 nsParser::Parse(nsIURL* aURL,nsIStreamObserver* aListener, nsIDTDDebug * NS_PRECONDITION(0!=aURL,kNullURL); PRInt32 status=kBadURL; + mParseLevel++; /* Disable DTD Debug for now... mDTDDebug = aDTDDebug; @@ -479,6 +481,7 @@ PRInt32 nsParser::Parse(nsIURL* aURL,nsIStreamObserver* aListener, nsIDTDDebug * PRInt32 nsParser::Parse(fstream& aStream){ PRInt32 status=kNoError; + mParseLevel++; //ok, time to create our tokenizer and begin the process CParserContext* pc=new CParserContext(new CScanner(kUnknownFilename,aStream,PR_FALSE),&aStream,0); @@ -511,12 +514,13 @@ PRInt32 nsParser::Parse(fstream& aStream){ */ PRInt32 nsParser::Parse(nsString& aSourceBuffer,PRBool anHTMLString){ PRInt32 result=kNoError; + mParseLevel++; CParserContext* pc=new CParserContext(new CScanner(kUnknownFilename,PR_FALSE),&aSourceBuffer,0); + PushContext(*pc); if(PR_TRUE==anHTMLString) pc->mSourceType="text/html"; - mParserContext->mScanner->Append(aSourceBuffer); if(eValidDetect==AutoDetectContentType(aSourceBuffer,mParserContext->mSourceType)) { WillBuildModel(mParserContext->mScanner->GetFilename()); result=ResumeParse(); @@ -543,9 +547,9 @@ PRInt32 nsParser::ResumeParse() { mParserContext->mDTD->WillResumeParse(); if(kNoError==result) { result=Tokenize(); + BuildModel(); if(kInterrupted==result) mParserContext->mDTD->WillInterruptParse(); - BuildModel(); } return result; } @@ -566,27 +570,38 @@ PRInt32 nsParser::BuildModel() { if(!mParserContext->mCurrentPos) mParserContext->mCurrentPos=new nsDequeIterator(mParserContext->mTokenDeque.Begin()); + //Get the root DTD for use in model building... + CParserContext* theRootContext=mParserContext; + while(theRootContext->mPrevContext) + theRootContext=theRootContext->mPrevContext; + + nsIDTD* theRootDTD=theRootContext->mDTD; + PRInt32 result=kNoError; while((kNoError==result) && ((*mParserContext->mCurrentPosmCurrentPos->GetCurrent(); - + /************************************************************************** The point of this code to serve as a testbed for parser reentrancy. If you set recurse=1, we go reentrant, passing a text string of HTML onto the parser for inline processing, just like javascript/DOM would do it. And guess what? It worked the first time! - Uncomment the following code to enable the test: + Uncomment the following code to enable the test: int recurse=0; if(recurse){ - nsString theString("
cell
"); + nsString theString(" this is just a great big empty string "); +// nsString theString("

doc.write"); +// nsString theString("
cell
"); Parse(theString,PR_TRUE); } - **************************************************************************/ + */ theMarkPos=*mParserContext->mCurrentPos; - result=mParserContext->mDTD->HandleToken(theToken); + + result=theRootDTD->HandleToken(theToken); +// result=mParserContext->mDTD->HandleToken(theToken); ++(*mParserContext->mCurrentPos); } @@ -813,10 +828,11 @@ PRBool nsParser::WillTokenize(){ PRInt32 nsParser::Tokenize(){ CToken* theToken=0; PRInt32 result=kNoError; - PRBool done=(0==++mMajorIteration) ? (!WillTokenize()) : PR_FALSE; - - while((PR_FALSE==done) && (kNoError==result)) { + ++mMajorIteration; + + WillTokenize(); + while(kNoError==result) { mParserContext->mScanner->Mark(); result=mParserContext->mDTD->ConsumeToken(theToken); if(kNoError==result) { @@ -835,8 +851,7 @@ PRInt32 nsParser::Tokenize(){ mParserContext->mScanner->RewindToMark(); } } - if((PR_TRUE==done) && (kInterrupted!=result)) - DidTokenize(); + DidTokenize(); return result; } @@ -851,11 +866,6 @@ PRInt32 nsParser::Tokenize(){ */ PRBool nsParser::DidTokenize(){ PRBool result=PR_TRUE; - -#ifdef VERBOSE_DEBUG - DebugDumpTokens(cout); -#endif - return result; } diff --git a/mozilla/parser/htmlparser/src/nsParser.h b/mozilla/parser/htmlparser/src/nsParser.h index 4c2056a6d3a..ce06eb452ff 100644 --- a/mozilla/parser/htmlparser/src/nsParser.h +++ b/mozilla/parser/htmlparser/src/nsParser.h @@ -294,14 +294,13 @@ protected: CParserContext* mParserContext; PRInt32 mMajorIteration; PRInt32 mMinorIteration; + PRInt32 mParseLevel; nsIStreamObserver* mObserver; nsIContentSink* mSink; nsIParserFilter* mParserFilter; nsIDTDDebug* mDTDDebug; - - }; diff --git a/mozilla/parser/htmlparser/src/nsParserTypes.h b/mozilla/parser/htmlparser/src/nsParserTypes.h index 83a1e91b308..9bad92f2a14 100644 --- a/mozilla/parser/htmlparser/src/nsParserTypes.h +++ b/mozilla/parser/htmlparser/src/nsParserTypes.h @@ -43,13 +43,13 @@ enum eParseMode { }; -const PRInt32 kEOF = 1000000L; -const PRInt32 kUnknownError = -1000; -const PRInt32 kCantPropagate = -6; -const PRInt32 kContextMismatch = -5; -const PRInt32 kBadFilename = -4; -const PRInt32 kBadURL = -3; -const PRInt32 kInterrupted = -2; +const PRInt32 kEOF = 10000; +const PRInt32 kUnknownError = 10001; +const PRInt32 kCantPropagate = 10002; +const PRInt32 kContextMismatch = 10003; +const PRInt32 kBadFilename = 10004; +const PRInt32 kBadURL = 10005; +const PRInt32 kInterrupted = 10006; const PRInt32 kNotFound = -1; const PRInt32 kNoError = NS_OK; diff --git a/mozilla/parser/htmlparser/src/nsScanner.cpp b/mozilla/parser/htmlparser/src/nsScanner.cpp index 93ce54eea57..938202153a5 100644 --- a/mozilla/parser/htmlparser/src/nsScanner.cpp +++ b/mozilla/parser/htmlparser/src/nsScanner.cpp @@ -31,8 +31,27 @@ const int kBufsize=64; /** - * Use this constructor if you want i/o to be based on an - * incremental netstream. If you pass a null filename, you + * Use this constructor if you want i/o to be based on + * a single string you hand in during construction. + * This short cut was added for Javascript. + * + * @update gess 5/12/98 + * @param aMode represents the parser mode (nav, other) + * @return + */ +CScanner::CScanner(nsString& anHTMLString) : + mBuffer(anHTMLString), mFilename("") +{ + mTotalRead=mBuffer.Length(); + mIncremental=PR_FALSE; + mOwnsStream=PR_FALSE; + mOffset=0; + mFileStream=0; +} + +/** + * Use this constructor if you want i/o to be based on strings + * the scanner receives. If you pass a null filename, you * can still provide data to the scanner via append. * * @update gess 5/12/98 @@ -42,6 +61,7 @@ const int kBufsize=64; CScanner::CScanner(nsString& aFilename,PRBool aCreateStream) : mBuffer(""), mFilename(aFilename) { + mIncremental=PR_TRUE; mOffset=0; mMarkPos=-1; mTotalRead=0; @@ -71,6 +91,7 @@ CScanner::CScanner(nsString& aFilename,PRBool aCreateStream) : CScanner::CScanner(nsString& aFilename,fstream& aStream,PRBool assumeOwnership) : mBuffer(""), mFilename(aFilename) { + mIncremental=PR_TRUE; mOffset=0; mMarkPos=-1; mTotalRead=0; @@ -135,26 +156,17 @@ void _PreCompressBuffer(nsString& aBuffer,PRInt32& anOffset,PRInt32& aMarkPos){ //we've guaranteed the client we can back up to, so make sure //you don't lose any of the data beyond that point. -/* - if((anOffset!=aMarkPos) && (0<=aMarkPos)) { - if(aMarkPos>0) { - aBuffer.Cut(0,aMarkPos); - if(anOffset>aMarkPos) - anOffset-=aMarkPos; - } - } - else aBuffer.Truncate(); -*/ PRInt32 len=aBuffer.Length(); - if((aMarkPos=0)) { + if((aMarkPos0)) { aBuffer.Cut(0,aMarkPos); anOffset-=aMarkPos; + aMarkPos=0; } - else { + else if((anOffset==aMarkPos) && (0