Removed parser's knowledge of the Parser Debugger.
The Parser debugger has been moved out and renamed to DTDDebugger since this actually what it is doing. I cant totally remove the DTDDebugger parameter passed to the parser under the DTD creation is somehow moved from the parser. git-svn-id: svn://10.0.0.236/trunk@4456 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -23,7 +23,7 @@
|
||||
#include "nsString.h"
|
||||
#include "nsIURL.h"
|
||||
#include "nsIStreamListener.h"
|
||||
#include "nsIParserDebug.h"
|
||||
#include "nsIDTDDebug.h"
|
||||
|
||||
static NS_DEFINE_IID(kIRobotSinkObserverIID, NS_IROBOTSINKOBSERVER_IID);
|
||||
|
||||
@@ -168,14 +168,14 @@ extern "C" NS_EXPORT int DebugRobot(
|
||||
NS_ADDREF(myObserver);
|
||||
g_workList = workList;
|
||||
|
||||
nsIParserDebug * pIParserDebug;
|
||||
nsresult rval = NS_NewParserDebug(&pIParserDebug);
|
||||
nsIDTDDebug * pIDTDDebug;
|
||||
nsresult rval = NS_NewDTDDebug(&pIDTDDebug);
|
||||
if (NS_OK != rval) {
|
||||
fputs("Cannot create parser debugger.\n", stdout);
|
||||
NS_RELEASE(myObserver);
|
||||
return -1;
|
||||
}
|
||||
pIParserDebug->SetVerificationDirectory(verify_dir);
|
||||
pIDTDDebug->SetVerificationDirectory(verify_dir);
|
||||
|
||||
for (;;) {
|
||||
PRInt32 n = g_workList->Count();
|
||||
@@ -192,7 +192,7 @@ extern "C" NS_EXPORT int DebugRobot(
|
||||
printf("invalid URL: '");
|
||||
fputs(*urlName, stdout);
|
||||
printf("'\n");
|
||||
NS_RELEASE(pIParserDebug);
|
||||
NS_RELEASE(pIDTDDebug);
|
||||
NS_RELEASE(myObserver);
|
||||
return -1;
|
||||
}
|
||||
@@ -211,7 +211,7 @@ extern "C" NS_EXPORT int DebugRobot(
|
||||
rv = NS_NewParser(&parser);
|
||||
if (NS_OK != rv) {
|
||||
printf("can't make parser\n");
|
||||
NS_RELEASE(pIParserDebug);
|
||||
NS_RELEASE(pIDTDDebug);
|
||||
NS_RELEASE(myObserver);
|
||||
return -1;
|
||||
}
|
||||
@@ -220,7 +220,7 @@ extern "C" NS_EXPORT int DebugRobot(
|
||||
rv = NS_NewRobotSink(&sink);
|
||||
if (NS_OK != rv) {
|
||||
printf("can't make parser\n");
|
||||
NS_RELEASE(pIParserDebug);
|
||||
NS_RELEASE(pIDTDDebug);
|
||||
NS_RELEASE(myObserver);
|
||||
return -1;
|
||||
}
|
||||
@@ -229,7 +229,8 @@ extern "C" NS_EXPORT int DebugRobot(
|
||||
|
||||
parser->SetContentSink(sink);
|
||||
g_bReadyForNextUrl = PR_FALSE;
|
||||
parser->Parse(url, pl, pIParserDebug);/* XXX hook up stream listener here! */
|
||||
|
||||
parser->Parse(url, pl, pIDTDDebug);/* XXX hook up stream listener here! */
|
||||
while (!g_bReadyForNextUrl) {
|
||||
if (yieldProc != NULL)
|
||||
(*yieldProc)(url->GetSpec());
|
||||
@@ -253,8 +254,8 @@ extern "C" NS_EXPORT int DebugRobot(
|
||||
NS_RELEASE(pl);
|
||||
NS_RELEASE(myObserver);
|
||||
|
||||
pIParserDebug->DumpVectorRecord();
|
||||
NS_RELEASE(pIParserDebug);
|
||||
pIDTDDebug->DumpVectorRecord();
|
||||
NS_RELEASE(pIDTDDebug);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nsIParserDebug.h"
|
||||
#include "nsIDTDDebug.h"
|
||||
#include "CNavDTD.h"
|
||||
#include "nsHTMLTokens.h"
|
||||
#include "nsCRT.h"
|
||||
@@ -233,7 +233,7 @@ CNavDTD::CNavDTD() : nsIDTD(), mTokenDeque(gTokenKiller) {
|
||||
NS_INIT_REFCNT();
|
||||
mParser=0;
|
||||
mFilename=0;
|
||||
mParserDebug=0;
|
||||
mDTDDebug=0;
|
||||
nsCRT::zero(mLeafBits,sizeof(mLeafBits));
|
||||
nsCRT::zero(mContextStack,sizeof(mContextStack));
|
||||
nsCRT::zero(mStyleStack,sizeof(mStyleStack));
|
||||
@@ -257,18 +257,34 @@ CNavDTD::~CNavDTD(){
|
||||
if (mFilename)
|
||||
PL_strfree(mFilename);
|
||||
|
||||
if (mParserDebug)
|
||||
NS_RELEASE(mParserDebug);
|
||||
if (mDTDDebug)
|
||||
NS_RELEASE(mDTDDebug);
|
||||
// NS_RELEASE(mSink);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @update jevering6/23/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
|
||||
void CNavDTD::SetDTDDebug(nsIDTDDebug * aDTDDebug)
|
||||
{
|
||||
if (mDTDDebug)
|
||||
NS_RELEASE(mDTDDebug);
|
||||
mDTDDebug = aDTDDebug;
|
||||
if (mDTDDebug)
|
||||
NS_ADDREF(mDTDDebug);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess5/18/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
PRInt32 CNavDTD::WillBuildModel(const char* aFilename, nsIParserDebug* aParserDebug){
|
||||
PRInt32 CNavDTD::WillBuildModel(const char* aFilename){
|
||||
PRInt32 result=0;
|
||||
|
||||
if (mFilename) {
|
||||
@@ -279,9 +295,6 @@ PRInt32 CNavDTD::WillBuildModel(const char* aFilename, nsIParserDebug* aParserDe
|
||||
mFilename = PL_strdup(aFilename);
|
||||
}
|
||||
|
||||
mParserDebug = aParserDebug;
|
||||
NS_IF_ADDREF(mParserDebug);
|
||||
|
||||
if(mSink)
|
||||
mSink->WillBuildModel();
|
||||
|
||||
@@ -329,8 +342,8 @@ PRInt32 CNavDTD::HandleToken(CToken* aToken){
|
||||
|
||||
if(aHandler) {
|
||||
result=(*aHandler)(theToken,this);
|
||||
if (mParserDebug)
|
||||
mParserDebug->Verify(this, mParser, mContextStackPos, mContextStack, mFilename);
|
||||
if (mDTDDebug)
|
||||
mDTDDebug->Verify(this, mParser, mContextStackPos, mContextStack, mFilename);
|
||||
}
|
||||
|
||||
}//if
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
|
||||
class nsParser;
|
||||
class nsIHTMLContentSink;
|
||||
class nsIParserDebug;
|
||||
class nsIDTDDebug;
|
||||
|
||||
class CNavDTD : public nsIDTD {
|
||||
|
||||
@@ -69,13 +69,21 @@ class CNavDTD : public nsIDTD {
|
||||
*/
|
||||
virtual ~CNavDTD();
|
||||
|
||||
/**
|
||||
*
|
||||
* @update jevering6/23/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
virtual void SetDTDDebug(nsIDTDDebug * aDTDDebug);
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess5/18/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
virtual PRInt32 WillBuildModel(const char* aFilename=0, nsIParserDebug* aParserDebug=0);
|
||||
virtual PRInt32 WillBuildModel(const char* aFilename=0);
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -348,6 +356,8 @@ class CNavDTD : public nsIDTD {
|
||||
*/
|
||||
PRInt32 HandleStyleToken(CToken* aToken);
|
||||
|
||||
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
@@ -680,7 +690,7 @@ protected:
|
||||
PRBool mHasOpenMap;
|
||||
nsDeque mTokenDeque;
|
||||
char* mFilename;
|
||||
nsIParserDebug* mParserDebug;
|
||||
nsIDTDDebug* mDTDDebug;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nsIParserDebug.h"
|
||||
#include "nsIDTDDebug.h"
|
||||
#include "COtherDTD.h"
|
||||
#include "nsHTMLTokens.h"
|
||||
#include "nsCRT.h"
|
||||
@@ -236,7 +236,7 @@ COtherDTD::COtherDTD() : nsIDTD(), mTokenDeque(gTokenKiller) {
|
||||
NS_INIT_REFCNT();
|
||||
mParser=0;
|
||||
mFilename=0;
|
||||
mParserDebug=0;
|
||||
mDTDDebug=0;
|
||||
nsCRT::zero(mLeafBits,sizeof(mLeafBits));
|
||||
nsCRT::zero(mContextStack,sizeof(mContextStack));
|
||||
nsCRT::zero(mStyleStack,sizeof(mStyleStack));
|
||||
@@ -259,18 +259,34 @@ COtherDTD::~COtherDTD(){
|
||||
DeleteTokenHandlers();
|
||||
if (mFilename)
|
||||
PL_strfree(mFilename);
|
||||
if (mParserDebug)
|
||||
NS_RELEASE(mParserDebug);
|
||||
if (mDTDDebug)
|
||||
NS_RELEASE(mDTDDebug);
|
||||
// NS_RELEASE(mSink);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @update jevering6/23/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
|
||||
void COtherDTD::SetDTDDebug(nsIDTDDebug * aDTDDebug)
|
||||
{
|
||||
if (mDTDDebug)
|
||||
NS_RELEASE(mDTDDebug);
|
||||
mDTDDebug = aDTDDebug;
|
||||
if (mDTDDebug)
|
||||
NS_ADDREF(mDTDDebug);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess5/18/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
PRInt32 COtherDTD::WillBuildModel(const char* aFilename, nsIParserDebug* aParserDebug){
|
||||
PRInt32 COtherDTD::WillBuildModel(const char* aFilename){
|
||||
PRInt32 result=0;
|
||||
|
||||
if (mFilename) {
|
||||
@@ -281,9 +297,6 @@ PRInt32 COtherDTD::WillBuildModel(const char* aFilename, nsIParserDebug* aParser
|
||||
mFilename = PL_strdup(aFilename);
|
||||
}
|
||||
|
||||
mParserDebug = aParserDebug;
|
||||
NS_IF_ADDREF(mParserDebug);
|
||||
|
||||
if(mSink)
|
||||
mSink->WillBuildModel();
|
||||
|
||||
@@ -330,8 +343,8 @@ PRInt32 COtherDTD::HandleToken(CToken* aToken){
|
||||
|
||||
if(aHandler) {
|
||||
result=(*aHandler)(theToken,this);
|
||||
if (mParserDebug)
|
||||
mParserDebug->Verify(this, mParser, mContextStackPos, mContextStack, mFilename);
|
||||
if (mDTDDebug)
|
||||
mDTDDebug->Verify(this, mParser, mContextStackPos, mContextStack, mFilename);
|
||||
}
|
||||
|
||||
}//if
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
|
||||
class nsParser;
|
||||
class nsIHTMLContentSink;
|
||||
class nsIParserDebug;
|
||||
class nsIDTDDebug;
|
||||
|
||||
class COtherDTD : public nsIDTD {
|
||||
|
||||
@@ -68,15 +68,21 @@ class COtherDTD : public nsIDTD {
|
||||
*/
|
||||
virtual ~COtherDTD();
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @update jevering6/23/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
virtual void SetDTDDebug(nsIDTDDebug * aDTDDebug);
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess5/18/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
virtual PRInt32 WillBuildModel(const char* aFilename=0, nsIParserDebug* aIParserDebug=0);
|
||||
virtual PRInt32 WillBuildModel(const char* aFilename=0);
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -681,7 +687,7 @@ protected:
|
||||
PRBool mHasOpenMap;
|
||||
nsDeque mTokenDeque;
|
||||
char* mFilename;
|
||||
nsIParserDebug* mParserDebug;
|
||||
nsIDTDDebug* mDTDDebug;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ DEFINES = -D_IMPL_NS_HTMLPARS
|
||||
CPPSRCS = \
|
||||
nsHTMLContentSink.cpp \
|
||||
nsParserNode.cpp \
|
||||
nsParserDebug.cpp \
|
||||
nsDTDDebug.cpp \
|
||||
nsScanner.cpp \
|
||||
nsToken.cpp \
|
||||
nsTokenHandler.cpp \
|
||||
|
||||
@@ -32,7 +32,7 @@ CPPSRCS=nsHTMLContentSink.cpp \
|
||||
|
||||
EXPORTS=nshtmlpars.h nsIContentSink.h nsIHTMLContentSink.h \
|
||||
nsHTMLTokens.h nsIParserNode.h nsIParser.h nsToken.h \
|
||||
nsIParserDebug.h nsIParserFilter.h
|
||||
nsIDTDDebug.h nsIParserFilter.h
|
||||
|
||||
CPP_OBJS=.\$(OBJDIR)\nsHTMLContentSink.obj \
|
||||
.\$(OBJDIR)\CNavDTD.obj \
|
||||
@@ -40,7 +40,7 @@ CPP_OBJS=.\$(OBJDIR)\nsHTMLContentSink.obj \
|
||||
.\$(OBJDIR)\nsParser.obj \
|
||||
.\$(OBJDIR)\nsHTMLTokens.obj .\$(OBJDIR)\nsParserNode.obj \
|
||||
.\$(OBJDIR)\nsScanner.obj .\$(OBJDIR)\nsToken.obj \
|
||||
.\$(OBJDIR)\nsTokenHandler.obj .\$(OBJDIR)\nsParserDebug.obj \
|
||||
.\$(OBJDIR)\nsTokenHandler.obj .\$(OBJDIR)\nsDTDDebug.obj \
|
||||
.\$(OBJDIR)\prstrm.obj
|
||||
|
||||
LINCS=-I$(PUBLIC)\xpcom -I$(PUBLIC)\raptor -I$(PUBLIC)\netlib
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
class nsIParser;
|
||||
class CToken;
|
||||
class nsIContentSink;
|
||||
class nsIParserDebug;
|
||||
class nsIDTDDebug;
|
||||
class nsIURL;
|
||||
|
||||
class nsIDTD : public nsISupports {
|
||||
@@ -69,7 +69,7 @@ class nsIDTD : public nsISupports {
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
virtual PRInt32 WillBuildModel(const char* aFilename=0, nsIParserDebug* aParserDebug=0)=0;
|
||||
virtual PRInt32 WillBuildModel(const char* aFilename=0)=0;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -124,6 +124,13 @@ class nsIDTD : public nsISupports {
|
||||
*/
|
||||
virtual PRBool CanContain(PRInt32 aParent, PRInt32 aChild) = 0;
|
||||
|
||||
/**
|
||||
*
|
||||
* @update jevering6/23/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
virtual void SetDTDDebug(nsIDTDDebug * aDTDDebug) = 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -23,14 +23,14 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NS_IPARSERDEBUG__
|
||||
#define NS_IPARSERDEBUG__
|
||||
#ifndef NS_IDTDDEBUG__
|
||||
#define NS_IDTDDEBUG__
|
||||
|
||||
#include "nsISupports.h"
|
||||
#include "nsHTMLTokens.h"
|
||||
#include "prtypes.h"
|
||||
|
||||
#define NS_IPARSERDEBUG_IID \
|
||||
#define NS_IDTDDEBUG_IID \
|
||||
{0x7b68c220, 0x0685, 0x11d2, \
|
||||
{0xa4, 0xb5, 0x00, 0x80, 0x5f, 0x2a, 0x0e, 0xd2}}
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
class nsIDTD;
|
||||
class nsParser;
|
||||
|
||||
class nsIParserDebug : public nsISupports {
|
||||
class nsIDTDDebug : public nsISupports {
|
||||
|
||||
public:
|
||||
|
||||
@@ -52,6 +52,6 @@ public:
|
||||
|
||||
};
|
||||
|
||||
extern NS_EXPORT nsresult NS_NewParserDebug(nsIParserDebug** aInstancePtrResult);
|
||||
extern NS_EXPORT nsresult NS_NewDTDDebug(nsIDTDDebug** aInstancePtrResult);
|
||||
|
||||
#endif /* NS_IPARSERDEBUG__ */
|
||||
#endif /* NS_IDTDDEBUG__ */
|
||||
@@ -34,7 +34,7 @@ class nsString;
|
||||
class CToken;
|
||||
class nsIURL;
|
||||
class nsIDTD;
|
||||
class nsIParserDebug;
|
||||
class nsIDTDDebug;
|
||||
|
||||
/**
|
||||
* This class defines the iparser interface. This XPCOM
|
||||
@@ -48,6 +48,7 @@ class nsIParser : public nsISupports {
|
||||
virtual nsIContentSink* SetContentSink(nsIContentSink* aContentSink)=0;
|
||||
|
||||
virtual void SetDTD(nsIDTD* aDTD)=0;
|
||||
|
||||
virtual nsIDTD* GetDTD(void)=0;
|
||||
|
||||
/**
|
||||
@@ -62,9 +63,9 @@ class nsIParser : public nsISupports {
|
||||
|
||||
virtual PRInt32 Parse(nsIURL* aURL,
|
||||
nsIStreamListener* aListener,
|
||||
nsIParserDebug * aDebug = 0) = 0;
|
||||
nsIDTDDebug * aDTDDebug = 0) = 0;
|
||||
|
||||
virtual PRInt32 Parse(const char* aFilename,nsIParserDebug * aDebug = 0)=0;
|
||||
virtual PRInt32 Parse(const char* aFilename)=0;
|
||||
|
||||
virtual PRInt32 Parse(nsString& anHTMLString,PRBool appendTokens)=0;
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
#include <fstream.h>
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsIParserFilter.h"
|
||||
#include "nsIParserDebug.h"
|
||||
#include "nsIDTDDebug.h"
|
||||
|
||||
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
||||
static NS_DEFINE_IID(kClassIID, NS_PARSER_IID);
|
||||
@@ -86,8 +86,8 @@ CTokenDeallocator gTokenKiller;
|
||||
*/
|
||||
nsParser::nsParser() : mTokenDeque(gTokenKiller) {
|
||||
NS_INIT_REFCNT();
|
||||
mDTDDebug = 0;
|
||||
mParserFilter = 0;
|
||||
mParserDebug = 0;
|
||||
mListener = 0;
|
||||
mTransferBuffer=0;
|
||||
mSink=0;
|
||||
@@ -108,6 +108,7 @@ nsParser::nsParser() : mTokenDeque(gTokenKiller) {
|
||||
*/
|
||||
nsParser::~nsParser() {
|
||||
NS_IF_RELEASE(mListener);
|
||||
NS_IF_RELEASE(mDTDDebug);
|
||||
if(mTransferBuffer)
|
||||
delete [] mTransferBuffer;
|
||||
mTransferBuffer=0;
|
||||
@@ -120,7 +121,6 @@ nsParser::~nsParser() {
|
||||
mScanner=0;
|
||||
|
||||
NS_IF_RELEASE(mDTD);
|
||||
NS_IF_RELEASE(mParserDebug);
|
||||
NS_IF_RELEASE(mURL);
|
||||
|
||||
}
|
||||
@@ -334,16 +334,17 @@ PRBool nsParser::DetermineContentType(const char* aContentType) {
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
PRInt32 nsParser::WillBuildModel(const char* aFilename, const char* aContentType, nsIParserDebug * aDebug){
|
||||
PRInt32 nsParser::WillBuildModel(const char* aFilename, const char* aContentType){
|
||||
mMajorIteration=-1;
|
||||
mMinorIteration=-1;
|
||||
|
||||
mParseMode=DetermineParseMode();
|
||||
mDTD=(0==mDTD) ? CreateDTD(mParseMode,aContentType) : mDTD;
|
||||
if(mDTD) {
|
||||
mDTD->SetDTDDebug(mDTDDebug);
|
||||
mDTD->SetParser(this);
|
||||
mDTD->SetContentSink(mSink);
|
||||
mDTD->WillBuildModel(aFilename,mParserDebug);
|
||||
mDTD->WillBuildModel(aFilename);
|
||||
}
|
||||
|
||||
#ifdef DEBUG_SAVE_SOURCE_DOC
|
||||
@@ -394,20 +395,17 @@ PRInt32 nsParser::DidBuildModel(PRInt32 anErrorCode) {
|
||||
* @param aFilename -- const char* containing file to be parsed.
|
||||
* @return PR_TRUE if parse succeeded, PR_FALSE otherwise.
|
||||
*/
|
||||
PRBool nsParser::Parse(const char* aFilename,nsIParserDebug* aParserDebug){
|
||||
PRBool nsParser::Parse(const char* aFilename){
|
||||
NS_PRECONDITION(0!=aFilename,kNullFilename);
|
||||
PRInt32 status=kBadFilename;
|
||||
|
||||
if(aFilename) {
|
||||
|
||||
mParserDebug = aParserDebug;
|
||||
NS_IF_ADDREF(mParserDebug);
|
||||
|
||||
//ok, time to create our tokenizer and begin the process
|
||||
mScanner=new CScanner(aFilename,mParseMode);
|
||||
char theContentType[600];
|
||||
DetermineContentType(theContentType);
|
||||
WillBuildModel(aFilename,theContentType,aParserDebug);
|
||||
WillBuildModel(aFilename,theContentType);
|
||||
status=ResumeParse();
|
||||
DidBuildModel(status);
|
||||
|
||||
@@ -429,14 +427,13 @@ PRBool nsParser::Parse(const char* aFilename,nsIParserDebug* aParserDebug){
|
||||
* @param aFilename -- const char* containing file to be parsed.
|
||||
* @return PR_TRUE if parse succeeded, PR_FALSE otherwise.
|
||||
*/
|
||||
PRInt32 nsParser::Parse(nsIURL* aURL,nsIStreamListener* aListener,nsIParserDebug* aParserDebug) {
|
||||
PRInt32 nsParser::Parse(nsIURL* aURL,nsIStreamListener* aListener, nsIDTDDebug * aDTDDebug) {
|
||||
NS_PRECONDITION(0!=aURL,kNullURL);
|
||||
|
||||
PRInt32 status=kBadURL;
|
||||
|
||||
NS_IF_RELEASE(mParserDebug);
|
||||
mParserDebug = aParserDebug;
|
||||
NS_IF_ADDREF(mParserDebug);
|
||||
mDTDDebug = aDTDDebug;
|
||||
NS_IF_ADDREF(mDTDDebug);
|
||||
|
||||
NS_IF_RELEASE(mURL);
|
||||
mURL = aURL;
|
||||
@@ -594,7 +591,7 @@ nsresult nsParser::OnStartBinding(const char* aContentType){
|
||||
if (nsnull != mListener) {
|
||||
mListener->OnStartBinding(aContentType);
|
||||
}
|
||||
nsresult result=WillBuildModel(mURL->GetSpec(),aContentType,mParserDebug);
|
||||
nsresult result=WillBuildModel(mURL->GetSpec(),aContentType);
|
||||
if(!mTransferBuffer) {
|
||||
mTransferBuffer=new char[gTransferBufferSize+1];
|
||||
}
|
||||
|
||||
@@ -72,9 +72,9 @@ class IContentSink;
|
||||
class nsIHTMLContentSink;
|
||||
class nsIURL;
|
||||
class nsIDTD;
|
||||
class nsIDTDDebug;
|
||||
class CScanner;
|
||||
class nsIParserFilter;
|
||||
class nsIParserDebug;
|
||||
|
||||
|
||||
class nsParser : public nsIParser, public nsIStreamListener {
|
||||
@@ -129,8 +129,7 @@ friend class CTokenHandler;
|
||||
* @return TRUE if all went well -- FALSE otherwise
|
||||
*/
|
||||
virtual PRInt32 Parse(nsIURL* aURL,
|
||||
nsIStreamListener* aListener,
|
||||
nsIParserDebug * aDebug = 0);
|
||||
nsIStreamListener* aListener, nsIDTDDebug * aDTDDebug = 0);
|
||||
|
||||
/**
|
||||
* Cause parser to parse input from given file in given mode
|
||||
@@ -139,7 +138,7 @@ friend class CTokenHandler;
|
||||
* @param aMode is the desired parser mode (Nav, other, etc.)
|
||||
* @return TRUE if all went well -- FALSE otherwise
|
||||
*/
|
||||
virtual PRInt32 Parse(const char* aFilename,nsIParserDebug * aDebug = 0);
|
||||
virtual PRInt32 Parse(const char* aFilename);
|
||||
|
||||
/**
|
||||
* @update gess5/11/98
|
||||
@@ -205,7 +204,7 @@ protected:
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
PRInt32 WillBuildModel(const char* aFilename=0,const char* aContentType=0, nsIParserDebug* aDebug=0);
|
||||
PRInt32 WillBuildModel(const char* aFilename=0,const char* aContentType=0);
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -324,8 +323,8 @@ protected:
|
||||
|
||||
nsDeque mTokenDeque;
|
||||
CScanner* mScanner;
|
||||
nsIParserDebug* mParserDebug;
|
||||
nsIURL* mURL;
|
||||
nsIDTDDebug* mDTDDebug;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -1,535 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/**
|
||||
* MODULE NOTES:
|
||||
* @update jevering 06/18/98
|
||||
*
|
||||
* This file contains the parser debugger object which aids in
|
||||
* walking links and reporting statistic information, reporting
|
||||
* bad vectors.
|
||||
*/
|
||||
|
||||
#include "CNavDTD.h"
|
||||
#include "nsHTMLTokens.h"
|
||||
#include "nsParser.h"
|
||||
#include "nsIParserDebug.h"
|
||||
#include "nsCRT.h"
|
||||
#include "prenv.h" //this is here for debug reasons...
|
||||
#include "prtypes.h" //this is here for debug reasons...
|
||||
#include "prio.h"
|
||||
#include "plstr.h"
|
||||
#include "prstrm.h"
|
||||
#include <fstream.h>
|
||||
#include <time.h>
|
||||
#include "prmem.h"
|
||||
|
||||
#define CONTEXT_VECTOR_MAP "/vector.map"
|
||||
#define CONTEXT_VECTOR_STAT "/vector.stat"
|
||||
#define VECTOR_TABLE_HEADER "count vector\r\n====== =============================================\r\n"
|
||||
|
||||
// structure to store the vector statistic information
|
||||
|
||||
typedef struct vector_info {
|
||||
PRInt32 references; // number of occurances counted
|
||||
PRInt32 count; // number of tags in the vector
|
||||
PRBool good_vector; // is this a valid vector?
|
||||
eHTMLTags* vector; // and the vector
|
||||
} VectorInfo;
|
||||
|
||||
// the statistic vector table grows each time it exceeds this
|
||||
// stepping value
|
||||
#define TABLE_SIZE 128
|
||||
|
||||
class CParserDebug : public nsIParserDebug {
|
||||
public:
|
||||
|
||||
CParserDebug(char * aVerifyDir = 0);
|
||||
~CParserDebug();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
void SetVerificationDirectory(char * verify_dir);
|
||||
void SetRecordStatistics(PRBool bval);
|
||||
PRBool Verify(nsIDTD * aDTD, nsParser * aParser, int ContextStackPos, eHTMLTags aContextStack[], char * aURLRef);
|
||||
void DumpVectorRecord(void);
|
||||
|
||||
// global table for storing vector statistics and the size
|
||||
|
||||
private:
|
||||
VectorInfo ** mVectorInfoArray;
|
||||
PRInt32 mVectorCount;
|
||||
char * mVerificationDir;
|
||||
PRBool mRecordingStatistics;
|
||||
|
||||
PRBool DebugRecord(char * path, char * pURLRef, char * filename);
|
||||
void NoteVector(eHTMLTags aTags[],PRInt32 count, PRBool good_vector);
|
||||
void MakeVectorString(char * vector_string, VectorInfo * pInfo);
|
||||
};
|
||||
|
||||
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
||||
static NS_DEFINE_IID(kIDebugParserIID, NS_IPARSERDEBUG_IID);
|
||||
|
||||
/**
|
||||
* This method is defined in nsIParser. It is used to
|
||||
* cause the COM-like construction of an nsParser.
|
||||
*
|
||||
* @update jevering 3/25/98
|
||||
* @param nsIParser** ptr to newly instantiated parser
|
||||
* @return NS_xxx error result
|
||||
*/
|
||||
|
||||
NS_EXPORT nsresult NS_NewParserDebug(nsIParserDebug** aInstancePtrResult)
|
||||
{
|
||||
CParserDebug *it = new CParserDebug();
|
||||
|
||||
if (it == 0) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return it->QueryInterface(kIDebugParserIID, (void **)aInstancePtrResult);
|
||||
}
|
||||
|
||||
CParserDebug::CParserDebug(char * aVerifyDir)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
mVectorInfoArray = 0;
|
||||
mVectorCount = 0;
|
||||
if (aVerifyDir)
|
||||
mVerificationDir = PL_strdup(aVerifyDir);
|
||||
else {
|
||||
char * pString = PR_GetEnv("VERIFY_PARSER");
|
||||
if (pString)
|
||||
mVerificationDir = PL_strdup(pString);
|
||||
else
|
||||
mVerificationDir = 0;
|
||||
}
|
||||
mRecordingStatistics = PR_TRUE;
|
||||
}
|
||||
|
||||
CParserDebug::~CParserDebug()
|
||||
{
|
||||
if (mVerificationDir)
|
||||
PL_strfree(mVerificationDir);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method gets called as part of our COM-like interfaces.
|
||||
* Its purpose is to create an interface to parser object
|
||||
* of some type.
|
||||
*
|
||||
* @update gess 4/8/98
|
||||
* @param nsIID id of object to discover
|
||||
* @param aInstancePtr ptr to newly discovered interface
|
||||
* @return NS_xxx result code
|
||||
*/
|
||||
nsresult CParserDebug::QueryInterface(const nsIID& aIID, void** aInstancePtr)
|
||||
{
|
||||
if (NULL == aInstancePtr) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
if(aIID.Equals(kISupportsIID)) { //do IUnknown...
|
||||
*aInstancePtr = (nsIParserDebug*)(this);
|
||||
}
|
||||
else if(aIID.Equals(kIDebugParserIID)) { //do IParserDebug base class...
|
||||
*aInstancePtr = (nsIParserDebug*)(this);
|
||||
}
|
||||
else {
|
||||
*aInstancePtr=0;
|
||||
return NS_NOINTERFACE;
|
||||
}
|
||||
((nsISupports*) *aInstancePtr)->AddRef();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMPL_ADDREF(CParserDebug)
|
||||
NS_IMPL_RELEASE(CParserDebug)
|
||||
|
||||
void CParserDebug::SetVerificationDirectory(char * verify_dir)
|
||||
{
|
||||
if (mVerificationDir) {
|
||||
PL_strfree(mVerificationDir);
|
||||
mVerificationDir = 0;
|
||||
}
|
||||
mVerificationDir = PL_strdup(verify_dir);
|
||||
}
|
||||
|
||||
void CParserDebug::SetRecordStatistics(PRBool bval)
|
||||
{
|
||||
mRecordingStatistics = bval;
|
||||
}
|
||||
|
||||
/**
|
||||
* This debug method records an invalid context vector and it's
|
||||
* associated context vector and URL in a simple flat file mapping which
|
||||
* resides in the verification directory and is named context.map
|
||||
*
|
||||
* @update jevering 6/06/98
|
||||
* @param path is the directory structure indicating the bad context vector
|
||||
* @param pURLRef is the associated URL
|
||||
* @param filename to record mapping to if not already recorded
|
||||
* @return TRUE if it is already record (dont rerecord)
|
||||
*/
|
||||
|
||||
PRBool CParserDebug::DebugRecord(char * path, char * pURLRef, char * filename)
|
||||
{
|
||||
char recordPath[2048];
|
||||
PRIntn oflags = 0;
|
||||
|
||||
// create the record file name from the verification director
|
||||
// and the default name.
|
||||
strcpy(recordPath,mVerificationDir);
|
||||
strcat(recordPath,CONTEXT_VECTOR_MAP);
|
||||
|
||||
// create the file exists, only open for read/write
|
||||
// otherwise, create it
|
||||
if(PR_Access(recordPath,PR_ACCESS_EXISTS) != PR_SUCCESS)
|
||||
oflags = PR_CREATE_FILE;
|
||||
oflags |= PR_RDWR;
|
||||
|
||||
// open the record file
|
||||
PRFileDesc * recordFile = PR_Open(recordPath,oflags,0);
|
||||
|
||||
if (recordFile) {
|
||||
|
||||
char * string = (char *)PR_Malloc(2048);
|
||||
PRBool found = PR_FALSE;
|
||||
|
||||
// vectors are stored on the format iof "URL vector filename"
|
||||
// where the vector contains the verification path and
|
||||
// the filename contains the debug source dump
|
||||
sprintf(string,"%s %s %s\r\n", pURLRef, path, filename);
|
||||
|
||||
// get the file size, read in the file and parse it line at
|
||||
// a time to check to see if we have already recorded this
|
||||
// occurance
|
||||
|
||||
PRInt32 iSize = PR_Seek(recordFile,0,PR_SEEK_END);
|
||||
if (iSize) {
|
||||
|
||||
char * buffer = (char*)PR_Malloc(iSize);
|
||||
char * stringbuf = (char*)PR_Calloc(sizeof(char*),2048);
|
||||
if (buffer!=NULL && string!=NULL) {
|
||||
PRInt32 ibufferpos, istringpos;
|
||||
|
||||
// beginning of file for read
|
||||
PR_Seek(recordFile,0,PR_SEEK_SET);
|
||||
PR_Read(recordFile,buffer,iSize);
|
||||
|
||||
// run through the file looking for a matching vector
|
||||
for (ibufferpos = istringpos = 0; ibufferpos < iSize; ibufferpos++)
|
||||
{
|
||||
// compare string once we have hit the end of the line
|
||||
if (buffer[ibufferpos] == '\r') {
|
||||
stringbuf[istringpos] = '\0';
|
||||
istringpos = 0;
|
||||
// skip newline and space
|
||||
ibufferpos++;
|
||||
|
||||
if (PL_strlen(stringbuf)) {
|
||||
char * space;
|
||||
// chop of the filename for compare
|
||||
if ((space = PL_strrchr(stringbuf, ' '))!=NULL)
|
||||
*space = '\0';
|
||||
|
||||
// we have already recorded this one, free up, and return
|
||||
if (!PL_strncmp(string,stringbuf,PL_strlen(stringbuf))) {
|
||||
PR_Free(buffer);
|
||||
PR_Free(stringbuf);
|
||||
PR_Free(string);
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// build up the compare string
|
||||
else
|
||||
stringbuf[istringpos++] = buffer[ibufferpos];
|
||||
}
|
||||
|
||||
// throw away the record file data
|
||||
PR_Free(buffer);
|
||||
PR_Free(stringbuf);
|
||||
}
|
||||
}
|
||||
|
||||
// if this bad vector was not recorded, add it to record file
|
||||
|
||||
if (!found) {
|
||||
PR_Seek(recordFile,0,PR_SEEK_END);
|
||||
PR_Write(recordFile,string,PL_strlen(string));
|
||||
}
|
||||
|
||||
PR_Close(recordFile);
|
||||
PR_Free(string);
|
||||
}
|
||||
|
||||
// vector was not recorded
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* compare function for quick sort. Compares references and
|
||||
* sorts in decending order
|
||||
*/
|
||||
|
||||
static int compare( const void *arg1, const void *arg2 )
|
||||
{
|
||||
VectorInfo ** p1 = (VectorInfo**)arg1;
|
||||
VectorInfo ** p2 = (VectorInfo**)arg2;
|
||||
return (*p2)->references - (*p1)->references;
|
||||
}
|
||||
|
||||
/**
|
||||
* This debug routines stores statistical information about a
|
||||
* context vector. The context vector statistics are stored in
|
||||
* a global array. The table is resorted each time it grows to
|
||||
* aid in lookup speed. If a vector has already been noted, its
|
||||
* reference count is bumped, otherwise it is added to the table
|
||||
*
|
||||
* @update jevering 6/11/98
|
||||
* @param aTags is the tag list (vector)
|
||||
* @param count is the size of the vector
|
||||
* @return
|
||||
*/
|
||||
|
||||
void CParserDebug::NoteVector(eHTMLTags aTags[],PRInt32 count, PRBool good_vector)
|
||||
{
|
||||
// if the table doesn't exist, create it
|
||||
if (!mVectorInfoArray) {
|
||||
mVectorInfoArray = (VectorInfo**)PR_Calloc(TABLE_SIZE,sizeof(VectorInfo*));
|
||||
}
|
||||
else {
|
||||
// attempt to look up the vector
|
||||
for (PRInt32 i = 0; i < mVectorCount; i++)
|
||||
|
||||
// check the vector only if they are the same size, if they
|
||||
// match then just return without doing further work
|
||||
if (mVectorInfoArray[i]->count == count)
|
||||
if (!memcmp(mVectorInfoArray[i]->vector, aTags, sizeof(eHTMLTags)*count)) {
|
||||
|
||||
// bzzzt. and we have a winner.. bump the ref count
|
||||
mVectorInfoArray[i]->references++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// the context vector hasn't been noted, so allocate it and
|
||||
// initialize it one.. add it to the table
|
||||
VectorInfo * pVectorInfo = (VectorInfo*)PR_Malloc(sizeof(VectorInfo));
|
||||
pVectorInfo->references = 1;
|
||||
pVectorInfo->count = count;
|
||||
pVectorInfo->good_vector = good_vector;
|
||||
pVectorInfo->vector = (eHTMLTags*)PR_Malloc(count*sizeof(eHTMLTags));
|
||||
memcpy(pVectorInfo->vector,aTags,sizeof(eHTMLTags)*count);
|
||||
mVectorInfoArray[mVectorCount++] = pVectorInfo;
|
||||
|
||||
// have we maxed out the table? grow it.. sort it.. love it.
|
||||
if ((mVectorCount % TABLE_SIZE) == 0) {
|
||||
mVectorInfoArray = (VectorInfo**)realloc(
|
||||
mVectorInfoArray,
|
||||
(sizeof(VectorInfo*)*((mVectorCount/TABLE_SIZE)+1)*TABLE_SIZE));
|
||||
if (mVectorCount) {
|
||||
qsort((void*)mVectorInfoArray,(size_t)mVectorCount,sizeof(VectorInfo*),compare);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CParserDebug::MakeVectorString(char * vector_string, VectorInfo * pInfo)
|
||||
{
|
||||
sprintf (vector_string, "%6d ", pInfo->references);
|
||||
for (PRInt32 j = 0; j < pInfo->count; j++) {
|
||||
PL_strcat(vector_string, "<");
|
||||
PL_strcat(vector_string, (const char *)GetTagName(pInfo->vector[j]));
|
||||
PL_strcat(vector_string, ">");
|
||||
}
|
||||
PL_strcat(vector_string,"\r\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* This debug routine dumps out the vector statistics to a text
|
||||
* file in the verification directory and defaults to the name
|
||||
* "vector.stat". It contains all parsed context vectors and there
|
||||
* occurance count sorted in decending order.
|
||||
*
|
||||
* @update jevering 6/11/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
|
||||
void CParserDebug::DumpVectorRecord(void)
|
||||
{
|
||||
// do we have a table?
|
||||
if (mVectorCount) {
|
||||
|
||||
// hopefully, they wont exceed 1K.
|
||||
char vector_string[1024];
|
||||
char path[1024];
|
||||
|
||||
path[0] = '\0';
|
||||
|
||||
// put in the verification directory.. else the root
|
||||
if (mVerificationDir)
|
||||
strcpy(path,mVerificationDir);
|
||||
|
||||
strcat(path,CONTEXT_VECTOR_STAT);
|
||||
|
||||
// open the stat file creaming any existing stat file
|
||||
PRFileDesc * statisticFile = PR_Open(path,PR_CREATE_FILE|PR_RDWR,0);
|
||||
if (statisticFile) {
|
||||
|
||||
PRInt32 i;
|
||||
PRofstream ps;
|
||||
ps.attach(statisticFile);
|
||||
|
||||
// oh what the heck, sort it again
|
||||
if (mVectorCount) {
|
||||
qsort((void*)mVectorInfoArray,(size_t)mVectorCount,sizeof(VectorInfo*),compare);
|
||||
}
|
||||
|
||||
// cute little header
|
||||
sprintf(vector_string,"Context vector occurance results. Processed %d unique vectors.\r\n\r\n", mVectorCount);
|
||||
ps << vector_string;
|
||||
|
||||
ps << "Invalid context vector summary (see " CONTEXT_VECTOR_STAT ") for mapping.\r\n";
|
||||
ps << VECTOR_TABLE_HEADER;
|
||||
|
||||
// dump out the bad vectors encountered
|
||||
for (i = 0; i < mVectorCount; i++) {
|
||||
if (!mVectorInfoArray[i]->good_vector) {
|
||||
MakeVectorString(vector_string, mVectorInfoArray[i]);
|
||||
ps << vector_string;
|
||||
}
|
||||
}
|
||||
|
||||
ps << "\r\n\r\nValid context vector summary\r\n";
|
||||
ps << VECTOR_TABLE_HEADER;
|
||||
|
||||
// take a big vector table dump (good vectors)
|
||||
for (i = 0; i < mVectorCount; i++) {
|
||||
if (mVectorInfoArray[i]->good_vector) {
|
||||
MakeVectorString(vector_string, mVectorInfoArray[i]);
|
||||
ps << vector_string;
|
||||
}
|
||||
// free em up. they mean nothing to me now (I'm such a user)
|
||||
|
||||
if (mVectorInfoArray[i]->vector)
|
||||
PR_Free(mVectorInfoArray[i]->vector);
|
||||
PR_Free(mVectorInfoArray[i]);
|
||||
} //for
|
||||
PR_Close(statisticFile);
|
||||
}//if
|
||||
|
||||
// ok, we are done with the table, free it up as well
|
||||
PR_Free(mVectorInfoArray);
|
||||
mVectorInfoArray = 0;
|
||||
mVectorCount = 0;
|
||||
|
||||
} //if
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This debug method allows us to determine whether or not
|
||||
* we've seen (and can handle) the given context vector.
|
||||
*
|
||||
* @update gess4/22/98
|
||||
* @param tags is an array of eHTMLTags
|
||||
* @param count represents the number of items in the tags array
|
||||
* @param aDTD is the DTD we plan to ask for verification
|
||||
* @return TRUE if we know how to handle it, else false
|
||||
*/
|
||||
|
||||
PRBool CParserDebug::Verify(nsIDTD * aDTD, nsParser * aParser, int aContextStackPos, eHTMLTags aContextStack[], char * aURLRef)
|
||||
{
|
||||
PRBool result=PR_TRUE;
|
||||
|
||||
//ok, now see if we understand this vector
|
||||
|
||||
if(0!=mVerificationDir || mRecordingStatistics) {
|
||||
|
||||
if(aDTD && aContextStackPos>1) {
|
||||
for (int i = 0; i < aContextStackPos-1; i++)
|
||||
if (!aDTD->CanContain(aContextStack[i],aContextStack[i+1])) {
|
||||
result = PR_FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mRecordingStatistics) {
|
||||
NoteVector(aContextStack,aContextStackPos,result);
|
||||
}
|
||||
|
||||
if(0!=mVerificationDir) {
|
||||
char path[2048];
|
||||
strcpy(path,mVerificationDir);
|
||||
|
||||
int i=0;
|
||||
for(i=0;i<aContextStackPos;i++){
|
||||
strcat(path,"/");
|
||||
const char* name=GetTagName(aContextStack[i]);
|
||||
strcat(path,name);
|
||||
PR_MkDir(path,0);
|
||||
}
|
||||
if(PR_FALSE==result){
|
||||
static PRBool rnd_initialized = PR_FALSE;
|
||||
|
||||
if (!rnd_initialized) {
|
||||
// seed randomn number generator to aid in temp file
|
||||
// creation.
|
||||
rnd_initialized = PR_TRUE;
|
||||
srand((unsigned)time(NULL));
|
||||
}
|
||||
|
||||
// generate a filename to dump the html source into
|
||||
char filename[1024];
|
||||
do {
|
||||
// use system time to generate a temporary file name
|
||||
time_t ltime;
|
||||
time (<ime);
|
||||
// add in random number so that we can create uniques names
|
||||
// faster than simply every second.
|
||||
ltime += (time_t)rand();
|
||||
sprintf(filename,"%s/%lX.html", path, ltime);
|
||||
// try until we find one we can create
|
||||
} while (PR_Access(filename,PR_ACCESS_EXISTS) == PR_SUCCESS);
|
||||
|
||||
// check to see if we already recorded an instance of this particular
|
||||
// bad vector.
|
||||
if (!DebugRecord(path, aURLRef, filename))
|
||||
{
|
||||
// save file to directory indicated by bad context vector
|
||||
PRFileDesc * debugFile = PR_Open(filename,PR_CREATE_FILE|PR_RDWR,0);
|
||||
// if we were able to open the debug file, then
|
||||
// write the true URL at the top of the file.
|
||||
if (debugFile) {
|
||||
// dump the html source into the newly created file.
|
||||
PRofstream ps;
|
||||
ps.attach(debugFile);
|
||||
if (aParser)
|
||||
aParser->DebugDumpSource(ps);
|
||||
PR_Close(debugFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -23,7 +23,7 @@
|
||||
#include "nsString.h"
|
||||
#include "nsIURL.h"
|
||||
#include "nsIStreamListener.h"
|
||||
#include "nsIParserDebug.h"
|
||||
#include "nsIDTDDebug.h"
|
||||
|
||||
static NS_DEFINE_IID(kIRobotSinkObserverIID, NS_IROBOTSINKOBSERVER_IID);
|
||||
|
||||
@@ -168,14 +168,14 @@ extern "C" NS_EXPORT int DebugRobot(
|
||||
NS_ADDREF(myObserver);
|
||||
g_workList = workList;
|
||||
|
||||
nsIParserDebug * pIParserDebug;
|
||||
nsresult rval = NS_NewParserDebug(&pIParserDebug);
|
||||
nsIDTDDebug * pIDTDDebug;
|
||||
nsresult rval = NS_NewDTDDebug(&pIDTDDebug);
|
||||
if (NS_OK != rval) {
|
||||
fputs("Cannot create parser debugger.\n", stdout);
|
||||
NS_RELEASE(myObserver);
|
||||
return -1;
|
||||
}
|
||||
pIParserDebug->SetVerificationDirectory(verify_dir);
|
||||
pIDTDDebug->SetVerificationDirectory(verify_dir);
|
||||
|
||||
for (;;) {
|
||||
PRInt32 n = g_workList->Count();
|
||||
@@ -192,7 +192,7 @@ extern "C" NS_EXPORT int DebugRobot(
|
||||
printf("invalid URL: '");
|
||||
fputs(*urlName, stdout);
|
||||
printf("'\n");
|
||||
NS_RELEASE(pIParserDebug);
|
||||
NS_RELEASE(pIDTDDebug);
|
||||
NS_RELEASE(myObserver);
|
||||
return -1;
|
||||
}
|
||||
@@ -211,7 +211,7 @@ extern "C" NS_EXPORT int DebugRobot(
|
||||
rv = NS_NewParser(&parser);
|
||||
if (NS_OK != rv) {
|
||||
printf("can't make parser\n");
|
||||
NS_RELEASE(pIParserDebug);
|
||||
NS_RELEASE(pIDTDDebug);
|
||||
NS_RELEASE(myObserver);
|
||||
return -1;
|
||||
}
|
||||
@@ -220,7 +220,7 @@ extern "C" NS_EXPORT int DebugRobot(
|
||||
rv = NS_NewRobotSink(&sink);
|
||||
if (NS_OK != rv) {
|
||||
printf("can't make parser\n");
|
||||
NS_RELEASE(pIParserDebug);
|
||||
NS_RELEASE(pIDTDDebug);
|
||||
NS_RELEASE(myObserver);
|
||||
return -1;
|
||||
}
|
||||
@@ -229,7 +229,8 @@ extern "C" NS_EXPORT int DebugRobot(
|
||||
|
||||
parser->SetContentSink(sink);
|
||||
g_bReadyForNextUrl = PR_FALSE;
|
||||
parser->Parse(url, pl, pIParserDebug);/* XXX hook up stream listener here! */
|
||||
|
||||
parser->Parse(url, pl, pIDTDDebug);/* XXX hook up stream listener here! */
|
||||
while (!g_bReadyForNextUrl) {
|
||||
if (yieldProc != NULL)
|
||||
(*yieldProc)(url->GetSpec());
|
||||
@@ -253,8 +254,8 @@ extern "C" NS_EXPORT int DebugRobot(
|
||||
NS_RELEASE(pl);
|
||||
NS_RELEASE(myObserver);
|
||||
|
||||
pIParserDebug->DumpVectorRecord();
|
||||
NS_RELEASE(pIParserDebug);
|
||||
pIDTDDebug->DumpVectorRecord();
|
||||
NS_RELEASE(pIDTDDebug);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nsIParserDebug.h"
|
||||
#include "nsIDTDDebug.h"
|
||||
#include "CNavDTD.h"
|
||||
#include "nsHTMLTokens.h"
|
||||
#include "nsCRT.h"
|
||||
@@ -233,7 +233,7 @@ CNavDTD::CNavDTD() : nsIDTD(), mTokenDeque(gTokenKiller) {
|
||||
NS_INIT_REFCNT();
|
||||
mParser=0;
|
||||
mFilename=0;
|
||||
mParserDebug=0;
|
||||
mDTDDebug=0;
|
||||
nsCRT::zero(mLeafBits,sizeof(mLeafBits));
|
||||
nsCRT::zero(mContextStack,sizeof(mContextStack));
|
||||
nsCRT::zero(mStyleStack,sizeof(mStyleStack));
|
||||
@@ -257,18 +257,34 @@ CNavDTD::~CNavDTD(){
|
||||
if (mFilename)
|
||||
PL_strfree(mFilename);
|
||||
|
||||
if (mParserDebug)
|
||||
NS_RELEASE(mParserDebug);
|
||||
if (mDTDDebug)
|
||||
NS_RELEASE(mDTDDebug);
|
||||
// NS_RELEASE(mSink);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @update jevering6/23/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
|
||||
void CNavDTD::SetDTDDebug(nsIDTDDebug * aDTDDebug)
|
||||
{
|
||||
if (mDTDDebug)
|
||||
NS_RELEASE(mDTDDebug);
|
||||
mDTDDebug = aDTDDebug;
|
||||
if (mDTDDebug)
|
||||
NS_ADDREF(mDTDDebug);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess5/18/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
PRInt32 CNavDTD::WillBuildModel(const char* aFilename, nsIParserDebug* aParserDebug){
|
||||
PRInt32 CNavDTD::WillBuildModel(const char* aFilename){
|
||||
PRInt32 result=0;
|
||||
|
||||
if (mFilename) {
|
||||
@@ -279,9 +295,6 @@ PRInt32 CNavDTD::WillBuildModel(const char* aFilename, nsIParserDebug* aParserDe
|
||||
mFilename = PL_strdup(aFilename);
|
||||
}
|
||||
|
||||
mParserDebug = aParserDebug;
|
||||
NS_IF_ADDREF(mParserDebug);
|
||||
|
||||
if(mSink)
|
||||
mSink->WillBuildModel();
|
||||
|
||||
@@ -329,8 +342,8 @@ PRInt32 CNavDTD::HandleToken(CToken* aToken){
|
||||
|
||||
if(aHandler) {
|
||||
result=(*aHandler)(theToken,this);
|
||||
if (mParserDebug)
|
||||
mParserDebug->Verify(this, mParser, mContextStackPos, mContextStack, mFilename);
|
||||
if (mDTDDebug)
|
||||
mDTDDebug->Verify(this, mParser, mContextStackPos, mContextStack, mFilename);
|
||||
}
|
||||
|
||||
}//if
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
|
||||
class nsParser;
|
||||
class nsIHTMLContentSink;
|
||||
class nsIParserDebug;
|
||||
class nsIDTDDebug;
|
||||
|
||||
class CNavDTD : public nsIDTD {
|
||||
|
||||
@@ -69,13 +69,21 @@ class CNavDTD : public nsIDTD {
|
||||
*/
|
||||
virtual ~CNavDTD();
|
||||
|
||||
/**
|
||||
*
|
||||
* @update jevering6/23/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
virtual void SetDTDDebug(nsIDTDDebug * aDTDDebug);
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess5/18/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
virtual PRInt32 WillBuildModel(const char* aFilename=0, nsIParserDebug* aParserDebug=0);
|
||||
virtual PRInt32 WillBuildModel(const char* aFilename=0);
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -348,6 +356,8 @@ class CNavDTD : public nsIDTD {
|
||||
*/
|
||||
PRInt32 HandleStyleToken(CToken* aToken);
|
||||
|
||||
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
@@ -680,7 +690,7 @@ protected:
|
||||
PRBool mHasOpenMap;
|
||||
nsDeque mTokenDeque;
|
||||
char* mFilename;
|
||||
nsIParserDebug* mParserDebug;
|
||||
nsIDTDDebug* mDTDDebug;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nsIParserDebug.h"
|
||||
#include "nsIDTDDebug.h"
|
||||
#include "COtherDTD.h"
|
||||
#include "nsHTMLTokens.h"
|
||||
#include "nsCRT.h"
|
||||
@@ -236,7 +236,7 @@ COtherDTD::COtherDTD() : nsIDTD(), mTokenDeque(gTokenKiller) {
|
||||
NS_INIT_REFCNT();
|
||||
mParser=0;
|
||||
mFilename=0;
|
||||
mParserDebug=0;
|
||||
mDTDDebug=0;
|
||||
nsCRT::zero(mLeafBits,sizeof(mLeafBits));
|
||||
nsCRT::zero(mContextStack,sizeof(mContextStack));
|
||||
nsCRT::zero(mStyleStack,sizeof(mStyleStack));
|
||||
@@ -259,18 +259,34 @@ COtherDTD::~COtherDTD(){
|
||||
DeleteTokenHandlers();
|
||||
if (mFilename)
|
||||
PL_strfree(mFilename);
|
||||
if (mParserDebug)
|
||||
NS_RELEASE(mParserDebug);
|
||||
if (mDTDDebug)
|
||||
NS_RELEASE(mDTDDebug);
|
||||
// NS_RELEASE(mSink);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @update jevering6/23/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
|
||||
void COtherDTD::SetDTDDebug(nsIDTDDebug * aDTDDebug)
|
||||
{
|
||||
if (mDTDDebug)
|
||||
NS_RELEASE(mDTDDebug);
|
||||
mDTDDebug = aDTDDebug;
|
||||
if (mDTDDebug)
|
||||
NS_ADDREF(mDTDDebug);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess5/18/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
PRInt32 COtherDTD::WillBuildModel(const char* aFilename, nsIParserDebug* aParserDebug){
|
||||
PRInt32 COtherDTD::WillBuildModel(const char* aFilename){
|
||||
PRInt32 result=0;
|
||||
|
||||
if (mFilename) {
|
||||
@@ -281,9 +297,6 @@ PRInt32 COtherDTD::WillBuildModel(const char* aFilename, nsIParserDebug* aParser
|
||||
mFilename = PL_strdup(aFilename);
|
||||
}
|
||||
|
||||
mParserDebug = aParserDebug;
|
||||
NS_IF_ADDREF(mParserDebug);
|
||||
|
||||
if(mSink)
|
||||
mSink->WillBuildModel();
|
||||
|
||||
@@ -330,8 +343,8 @@ PRInt32 COtherDTD::HandleToken(CToken* aToken){
|
||||
|
||||
if(aHandler) {
|
||||
result=(*aHandler)(theToken,this);
|
||||
if (mParserDebug)
|
||||
mParserDebug->Verify(this, mParser, mContextStackPos, mContextStack, mFilename);
|
||||
if (mDTDDebug)
|
||||
mDTDDebug->Verify(this, mParser, mContextStackPos, mContextStack, mFilename);
|
||||
}
|
||||
|
||||
}//if
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
|
||||
class nsParser;
|
||||
class nsIHTMLContentSink;
|
||||
class nsIParserDebug;
|
||||
class nsIDTDDebug;
|
||||
|
||||
class COtherDTD : public nsIDTD {
|
||||
|
||||
@@ -68,15 +68,21 @@ class COtherDTD : public nsIDTD {
|
||||
*/
|
||||
virtual ~COtherDTD();
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @update jevering6/23/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
virtual void SetDTDDebug(nsIDTDDebug * aDTDDebug);
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess5/18/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
virtual PRInt32 WillBuildModel(const char* aFilename=0, nsIParserDebug* aIParserDebug=0);
|
||||
virtual PRInt32 WillBuildModel(const char* aFilename=0);
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -681,7 +687,7 @@ protected:
|
||||
PRBool mHasOpenMap;
|
||||
nsDeque mTokenDeque;
|
||||
char* mFilename;
|
||||
nsIParserDebug* mParserDebug;
|
||||
nsIDTDDebug* mDTDDebug;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ DEFINES = -D_IMPL_NS_HTMLPARS
|
||||
CPPSRCS = \
|
||||
nsHTMLContentSink.cpp \
|
||||
nsParserNode.cpp \
|
||||
nsParserDebug.cpp \
|
||||
nsDTDDebug.cpp \
|
||||
nsScanner.cpp \
|
||||
nsToken.cpp \
|
||||
nsTokenHandler.cpp \
|
||||
|
||||
@@ -32,7 +32,7 @@ CPPSRCS=nsHTMLContentSink.cpp \
|
||||
|
||||
EXPORTS=nshtmlpars.h nsIContentSink.h nsIHTMLContentSink.h \
|
||||
nsHTMLTokens.h nsIParserNode.h nsIParser.h nsToken.h \
|
||||
nsIParserDebug.h nsIParserFilter.h
|
||||
nsIDTDDebug.h nsIParserFilter.h
|
||||
|
||||
CPP_OBJS=.\$(OBJDIR)\nsHTMLContentSink.obj \
|
||||
.\$(OBJDIR)\CNavDTD.obj \
|
||||
@@ -40,7 +40,7 @@ CPP_OBJS=.\$(OBJDIR)\nsHTMLContentSink.obj \
|
||||
.\$(OBJDIR)\nsParser.obj \
|
||||
.\$(OBJDIR)\nsHTMLTokens.obj .\$(OBJDIR)\nsParserNode.obj \
|
||||
.\$(OBJDIR)\nsScanner.obj .\$(OBJDIR)\nsToken.obj \
|
||||
.\$(OBJDIR)\nsTokenHandler.obj .\$(OBJDIR)\nsParserDebug.obj \
|
||||
.\$(OBJDIR)\nsTokenHandler.obj .\$(OBJDIR)\nsDTDDebug.obj \
|
||||
.\$(OBJDIR)\prstrm.obj
|
||||
|
||||
LINCS=-I$(PUBLIC)\xpcom -I$(PUBLIC)\raptor -I$(PUBLIC)\netlib
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
class nsIParser;
|
||||
class CToken;
|
||||
class nsIContentSink;
|
||||
class nsIParserDebug;
|
||||
class nsIDTDDebug;
|
||||
class nsIURL;
|
||||
|
||||
class nsIDTD : public nsISupports {
|
||||
@@ -69,7 +69,7 @@ class nsIDTD : public nsISupports {
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
virtual PRInt32 WillBuildModel(const char* aFilename=0, nsIParserDebug* aParserDebug=0)=0;
|
||||
virtual PRInt32 WillBuildModel(const char* aFilename=0)=0;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -124,6 +124,13 @@ class nsIDTD : public nsISupports {
|
||||
*/
|
||||
virtual PRBool CanContain(PRInt32 aParent, PRInt32 aChild) = 0;
|
||||
|
||||
/**
|
||||
*
|
||||
* @update jevering6/23/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
virtual void SetDTDDebug(nsIDTDDebug * aDTDDebug) = 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -23,14 +23,14 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NS_IPARSERDEBUG__
|
||||
#define NS_IPARSERDEBUG__
|
||||
#ifndef NS_IDTDDEBUG__
|
||||
#define NS_IDTDDEBUG__
|
||||
|
||||
#include "nsISupports.h"
|
||||
#include "nsHTMLTokens.h"
|
||||
#include "prtypes.h"
|
||||
|
||||
#define NS_IPARSERDEBUG_IID \
|
||||
#define NS_IDTDDEBUG_IID \
|
||||
{0x7b68c220, 0x0685, 0x11d2, \
|
||||
{0xa4, 0xb5, 0x00, 0x80, 0x5f, 0x2a, 0x0e, 0xd2}}
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
class nsIDTD;
|
||||
class nsParser;
|
||||
|
||||
class nsIParserDebug : public nsISupports {
|
||||
class nsIDTDDebug : public nsISupports {
|
||||
|
||||
public:
|
||||
|
||||
@@ -52,6 +52,6 @@ public:
|
||||
|
||||
};
|
||||
|
||||
extern NS_EXPORT nsresult NS_NewParserDebug(nsIParserDebug** aInstancePtrResult);
|
||||
extern NS_EXPORT nsresult NS_NewDTDDebug(nsIDTDDebug** aInstancePtrResult);
|
||||
|
||||
#endif /* NS_IPARSERDEBUG__ */
|
||||
#endif /* NS_IDTDDEBUG__ */
|
||||
@@ -34,7 +34,7 @@ class nsString;
|
||||
class CToken;
|
||||
class nsIURL;
|
||||
class nsIDTD;
|
||||
class nsIParserDebug;
|
||||
class nsIDTDDebug;
|
||||
|
||||
/**
|
||||
* This class defines the iparser interface. This XPCOM
|
||||
@@ -48,6 +48,7 @@ class nsIParser : public nsISupports {
|
||||
virtual nsIContentSink* SetContentSink(nsIContentSink* aContentSink)=0;
|
||||
|
||||
virtual void SetDTD(nsIDTD* aDTD)=0;
|
||||
|
||||
virtual nsIDTD* GetDTD(void)=0;
|
||||
|
||||
/**
|
||||
@@ -62,9 +63,9 @@ class nsIParser : public nsISupports {
|
||||
|
||||
virtual PRInt32 Parse(nsIURL* aURL,
|
||||
nsIStreamListener* aListener,
|
||||
nsIParserDebug * aDebug = 0) = 0;
|
||||
nsIDTDDebug * aDTDDebug = 0) = 0;
|
||||
|
||||
virtual PRInt32 Parse(const char* aFilename,nsIParserDebug * aDebug = 0)=0;
|
||||
virtual PRInt32 Parse(const char* aFilename)=0;
|
||||
|
||||
virtual PRInt32 Parse(nsString& anHTMLString,PRBool appendTokens)=0;
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
#include <fstream.h>
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsIParserFilter.h"
|
||||
#include "nsIParserDebug.h"
|
||||
#include "nsIDTDDebug.h"
|
||||
|
||||
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
||||
static NS_DEFINE_IID(kClassIID, NS_PARSER_IID);
|
||||
@@ -86,8 +86,8 @@ CTokenDeallocator gTokenKiller;
|
||||
*/
|
||||
nsParser::nsParser() : mTokenDeque(gTokenKiller) {
|
||||
NS_INIT_REFCNT();
|
||||
mDTDDebug = 0;
|
||||
mParserFilter = 0;
|
||||
mParserDebug = 0;
|
||||
mListener = 0;
|
||||
mTransferBuffer=0;
|
||||
mSink=0;
|
||||
@@ -108,6 +108,7 @@ nsParser::nsParser() : mTokenDeque(gTokenKiller) {
|
||||
*/
|
||||
nsParser::~nsParser() {
|
||||
NS_IF_RELEASE(mListener);
|
||||
NS_IF_RELEASE(mDTDDebug);
|
||||
if(mTransferBuffer)
|
||||
delete [] mTransferBuffer;
|
||||
mTransferBuffer=0;
|
||||
@@ -120,7 +121,6 @@ nsParser::~nsParser() {
|
||||
mScanner=0;
|
||||
|
||||
NS_IF_RELEASE(mDTD);
|
||||
NS_IF_RELEASE(mParserDebug);
|
||||
NS_IF_RELEASE(mURL);
|
||||
|
||||
}
|
||||
@@ -334,16 +334,17 @@ PRBool nsParser::DetermineContentType(const char* aContentType) {
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
PRInt32 nsParser::WillBuildModel(const char* aFilename, const char* aContentType, nsIParserDebug * aDebug){
|
||||
PRInt32 nsParser::WillBuildModel(const char* aFilename, const char* aContentType){
|
||||
mMajorIteration=-1;
|
||||
mMinorIteration=-1;
|
||||
|
||||
mParseMode=DetermineParseMode();
|
||||
mDTD=(0==mDTD) ? CreateDTD(mParseMode,aContentType) : mDTD;
|
||||
if(mDTD) {
|
||||
mDTD->SetDTDDebug(mDTDDebug);
|
||||
mDTD->SetParser(this);
|
||||
mDTD->SetContentSink(mSink);
|
||||
mDTD->WillBuildModel(aFilename,mParserDebug);
|
||||
mDTD->WillBuildModel(aFilename);
|
||||
}
|
||||
|
||||
#ifdef DEBUG_SAVE_SOURCE_DOC
|
||||
@@ -394,20 +395,17 @@ PRInt32 nsParser::DidBuildModel(PRInt32 anErrorCode) {
|
||||
* @param aFilename -- const char* containing file to be parsed.
|
||||
* @return PR_TRUE if parse succeeded, PR_FALSE otherwise.
|
||||
*/
|
||||
PRBool nsParser::Parse(const char* aFilename,nsIParserDebug* aParserDebug){
|
||||
PRBool nsParser::Parse(const char* aFilename){
|
||||
NS_PRECONDITION(0!=aFilename,kNullFilename);
|
||||
PRInt32 status=kBadFilename;
|
||||
|
||||
if(aFilename) {
|
||||
|
||||
mParserDebug = aParserDebug;
|
||||
NS_IF_ADDREF(mParserDebug);
|
||||
|
||||
//ok, time to create our tokenizer and begin the process
|
||||
mScanner=new CScanner(aFilename,mParseMode);
|
||||
char theContentType[600];
|
||||
DetermineContentType(theContentType);
|
||||
WillBuildModel(aFilename,theContentType,aParserDebug);
|
||||
WillBuildModel(aFilename,theContentType);
|
||||
status=ResumeParse();
|
||||
DidBuildModel(status);
|
||||
|
||||
@@ -429,14 +427,13 @@ PRBool nsParser::Parse(const char* aFilename,nsIParserDebug* aParserDebug){
|
||||
* @param aFilename -- const char* containing file to be parsed.
|
||||
* @return PR_TRUE if parse succeeded, PR_FALSE otherwise.
|
||||
*/
|
||||
PRInt32 nsParser::Parse(nsIURL* aURL,nsIStreamListener* aListener,nsIParserDebug* aParserDebug) {
|
||||
PRInt32 nsParser::Parse(nsIURL* aURL,nsIStreamListener* aListener, nsIDTDDebug * aDTDDebug) {
|
||||
NS_PRECONDITION(0!=aURL,kNullURL);
|
||||
|
||||
PRInt32 status=kBadURL;
|
||||
|
||||
NS_IF_RELEASE(mParserDebug);
|
||||
mParserDebug = aParserDebug;
|
||||
NS_IF_ADDREF(mParserDebug);
|
||||
mDTDDebug = aDTDDebug;
|
||||
NS_IF_ADDREF(mDTDDebug);
|
||||
|
||||
NS_IF_RELEASE(mURL);
|
||||
mURL = aURL;
|
||||
@@ -594,7 +591,7 @@ nsresult nsParser::OnStartBinding(const char* aContentType){
|
||||
if (nsnull != mListener) {
|
||||
mListener->OnStartBinding(aContentType);
|
||||
}
|
||||
nsresult result=WillBuildModel(mURL->GetSpec(),aContentType,mParserDebug);
|
||||
nsresult result=WillBuildModel(mURL->GetSpec(),aContentType);
|
||||
if(!mTransferBuffer) {
|
||||
mTransferBuffer=new char[gTransferBufferSize+1];
|
||||
}
|
||||
|
||||
@@ -72,9 +72,9 @@ class IContentSink;
|
||||
class nsIHTMLContentSink;
|
||||
class nsIURL;
|
||||
class nsIDTD;
|
||||
class nsIDTDDebug;
|
||||
class CScanner;
|
||||
class nsIParserFilter;
|
||||
class nsIParserDebug;
|
||||
|
||||
|
||||
class nsParser : public nsIParser, public nsIStreamListener {
|
||||
@@ -129,8 +129,7 @@ friend class CTokenHandler;
|
||||
* @return TRUE if all went well -- FALSE otherwise
|
||||
*/
|
||||
virtual PRInt32 Parse(nsIURL* aURL,
|
||||
nsIStreamListener* aListener,
|
||||
nsIParserDebug * aDebug = 0);
|
||||
nsIStreamListener* aListener, nsIDTDDebug * aDTDDebug = 0);
|
||||
|
||||
/**
|
||||
* Cause parser to parse input from given file in given mode
|
||||
@@ -139,7 +138,7 @@ friend class CTokenHandler;
|
||||
* @param aMode is the desired parser mode (Nav, other, etc.)
|
||||
* @return TRUE if all went well -- FALSE otherwise
|
||||
*/
|
||||
virtual PRInt32 Parse(const char* aFilename,nsIParserDebug * aDebug = 0);
|
||||
virtual PRInt32 Parse(const char* aFilename);
|
||||
|
||||
/**
|
||||
* @update gess5/11/98
|
||||
@@ -205,7 +204,7 @@ protected:
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
PRInt32 WillBuildModel(const char* aFilename=0,const char* aContentType=0, nsIParserDebug* aDebug=0);
|
||||
PRInt32 WillBuildModel(const char* aFilename=0,const char* aContentType=0);
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -324,8 +323,8 @@ protected:
|
||||
|
||||
nsDeque mTokenDeque;
|
||||
CScanner* mScanner;
|
||||
nsIParserDebug* mParserDebug;
|
||||
nsIURL* mURL;
|
||||
nsIDTDDebug* mDTDDebug;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -1,535 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/**
|
||||
* MODULE NOTES:
|
||||
* @update jevering 06/18/98
|
||||
*
|
||||
* This file contains the parser debugger object which aids in
|
||||
* walking links and reporting statistic information, reporting
|
||||
* bad vectors.
|
||||
*/
|
||||
|
||||
#include "CNavDTD.h"
|
||||
#include "nsHTMLTokens.h"
|
||||
#include "nsParser.h"
|
||||
#include "nsIParserDebug.h"
|
||||
#include "nsCRT.h"
|
||||
#include "prenv.h" //this is here for debug reasons...
|
||||
#include "prtypes.h" //this is here for debug reasons...
|
||||
#include "prio.h"
|
||||
#include "plstr.h"
|
||||
#include "prstrm.h"
|
||||
#include <fstream.h>
|
||||
#include <time.h>
|
||||
#include "prmem.h"
|
||||
|
||||
#define CONTEXT_VECTOR_MAP "/vector.map"
|
||||
#define CONTEXT_VECTOR_STAT "/vector.stat"
|
||||
#define VECTOR_TABLE_HEADER "count vector\r\n====== =============================================\r\n"
|
||||
|
||||
// structure to store the vector statistic information
|
||||
|
||||
typedef struct vector_info {
|
||||
PRInt32 references; // number of occurances counted
|
||||
PRInt32 count; // number of tags in the vector
|
||||
PRBool good_vector; // is this a valid vector?
|
||||
eHTMLTags* vector; // and the vector
|
||||
} VectorInfo;
|
||||
|
||||
// the statistic vector table grows each time it exceeds this
|
||||
// stepping value
|
||||
#define TABLE_SIZE 128
|
||||
|
||||
class CParserDebug : public nsIParserDebug {
|
||||
public:
|
||||
|
||||
CParserDebug(char * aVerifyDir = 0);
|
||||
~CParserDebug();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
void SetVerificationDirectory(char * verify_dir);
|
||||
void SetRecordStatistics(PRBool bval);
|
||||
PRBool Verify(nsIDTD * aDTD, nsParser * aParser, int ContextStackPos, eHTMLTags aContextStack[], char * aURLRef);
|
||||
void DumpVectorRecord(void);
|
||||
|
||||
// global table for storing vector statistics and the size
|
||||
|
||||
private:
|
||||
VectorInfo ** mVectorInfoArray;
|
||||
PRInt32 mVectorCount;
|
||||
char * mVerificationDir;
|
||||
PRBool mRecordingStatistics;
|
||||
|
||||
PRBool DebugRecord(char * path, char * pURLRef, char * filename);
|
||||
void NoteVector(eHTMLTags aTags[],PRInt32 count, PRBool good_vector);
|
||||
void MakeVectorString(char * vector_string, VectorInfo * pInfo);
|
||||
};
|
||||
|
||||
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
||||
static NS_DEFINE_IID(kIDebugParserIID, NS_IPARSERDEBUG_IID);
|
||||
|
||||
/**
|
||||
* This method is defined in nsIParser. It is used to
|
||||
* cause the COM-like construction of an nsParser.
|
||||
*
|
||||
* @update jevering 3/25/98
|
||||
* @param nsIParser** ptr to newly instantiated parser
|
||||
* @return NS_xxx error result
|
||||
*/
|
||||
|
||||
NS_EXPORT nsresult NS_NewParserDebug(nsIParserDebug** aInstancePtrResult)
|
||||
{
|
||||
CParserDebug *it = new CParserDebug();
|
||||
|
||||
if (it == 0) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return it->QueryInterface(kIDebugParserIID, (void **)aInstancePtrResult);
|
||||
}
|
||||
|
||||
CParserDebug::CParserDebug(char * aVerifyDir)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
mVectorInfoArray = 0;
|
||||
mVectorCount = 0;
|
||||
if (aVerifyDir)
|
||||
mVerificationDir = PL_strdup(aVerifyDir);
|
||||
else {
|
||||
char * pString = PR_GetEnv("VERIFY_PARSER");
|
||||
if (pString)
|
||||
mVerificationDir = PL_strdup(pString);
|
||||
else
|
||||
mVerificationDir = 0;
|
||||
}
|
||||
mRecordingStatistics = PR_TRUE;
|
||||
}
|
||||
|
||||
CParserDebug::~CParserDebug()
|
||||
{
|
||||
if (mVerificationDir)
|
||||
PL_strfree(mVerificationDir);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method gets called as part of our COM-like interfaces.
|
||||
* Its purpose is to create an interface to parser object
|
||||
* of some type.
|
||||
*
|
||||
* @update gess 4/8/98
|
||||
* @param nsIID id of object to discover
|
||||
* @param aInstancePtr ptr to newly discovered interface
|
||||
* @return NS_xxx result code
|
||||
*/
|
||||
nsresult CParserDebug::QueryInterface(const nsIID& aIID, void** aInstancePtr)
|
||||
{
|
||||
if (NULL == aInstancePtr) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
if(aIID.Equals(kISupportsIID)) { //do IUnknown...
|
||||
*aInstancePtr = (nsIParserDebug*)(this);
|
||||
}
|
||||
else if(aIID.Equals(kIDebugParserIID)) { //do IParserDebug base class...
|
||||
*aInstancePtr = (nsIParserDebug*)(this);
|
||||
}
|
||||
else {
|
||||
*aInstancePtr=0;
|
||||
return NS_NOINTERFACE;
|
||||
}
|
||||
((nsISupports*) *aInstancePtr)->AddRef();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMPL_ADDREF(CParserDebug)
|
||||
NS_IMPL_RELEASE(CParserDebug)
|
||||
|
||||
void CParserDebug::SetVerificationDirectory(char * verify_dir)
|
||||
{
|
||||
if (mVerificationDir) {
|
||||
PL_strfree(mVerificationDir);
|
||||
mVerificationDir = 0;
|
||||
}
|
||||
mVerificationDir = PL_strdup(verify_dir);
|
||||
}
|
||||
|
||||
void CParserDebug::SetRecordStatistics(PRBool bval)
|
||||
{
|
||||
mRecordingStatistics = bval;
|
||||
}
|
||||
|
||||
/**
|
||||
* This debug method records an invalid context vector and it's
|
||||
* associated context vector and URL in a simple flat file mapping which
|
||||
* resides in the verification directory and is named context.map
|
||||
*
|
||||
* @update jevering 6/06/98
|
||||
* @param path is the directory structure indicating the bad context vector
|
||||
* @param pURLRef is the associated URL
|
||||
* @param filename to record mapping to if not already recorded
|
||||
* @return TRUE if it is already record (dont rerecord)
|
||||
*/
|
||||
|
||||
PRBool CParserDebug::DebugRecord(char * path, char * pURLRef, char * filename)
|
||||
{
|
||||
char recordPath[2048];
|
||||
PRIntn oflags = 0;
|
||||
|
||||
// create the record file name from the verification director
|
||||
// and the default name.
|
||||
strcpy(recordPath,mVerificationDir);
|
||||
strcat(recordPath,CONTEXT_VECTOR_MAP);
|
||||
|
||||
// create the file exists, only open for read/write
|
||||
// otherwise, create it
|
||||
if(PR_Access(recordPath,PR_ACCESS_EXISTS) != PR_SUCCESS)
|
||||
oflags = PR_CREATE_FILE;
|
||||
oflags |= PR_RDWR;
|
||||
|
||||
// open the record file
|
||||
PRFileDesc * recordFile = PR_Open(recordPath,oflags,0);
|
||||
|
||||
if (recordFile) {
|
||||
|
||||
char * string = (char *)PR_Malloc(2048);
|
||||
PRBool found = PR_FALSE;
|
||||
|
||||
// vectors are stored on the format iof "URL vector filename"
|
||||
// where the vector contains the verification path and
|
||||
// the filename contains the debug source dump
|
||||
sprintf(string,"%s %s %s\r\n", pURLRef, path, filename);
|
||||
|
||||
// get the file size, read in the file and parse it line at
|
||||
// a time to check to see if we have already recorded this
|
||||
// occurance
|
||||
|
||||
PRInt32 iSize = PR_Seek(recordFile,0,PR_SEEK_END);
|
||||
if (iSize) {
|
||||
|
||||
char * buffer = (char*)PR_Malloc(iSize);
|
||||
char * stringbuf = (char*)PR_Calloc(sizeof(char*),2048);
|
||||
if (buffer!=NULL && string!=NULL) {
|
||||
PRInt32 ibufferpos, istringpos;
|
||||
|
||||
// beginning of file for read
|
||||
PR_Seek(recordFile,0,PR_SEEK_SET);
|
||||
PR_Read(recordFile,buffer,iSize);
|
||||
|
||||
// run through the file looking for a matching vector
|
||||
for (ibufferpos = istringpos = 0; ibufferpos < iSize; ibufferpos++)
|
||||
{
|
||||
// compare string once we have hit the end of the line
|
||||
if (buffer[ibufferpos] == '\r') {
|
||||
stringbuf[istringpos] = '\0';
|
||||
istringpos = 0;
|
||||
// skip newline and space
|
||||
ibufferpos++;
|
||||
|
||||
if (PL_strlen(stringbuf)) {
|
||||
char * space;
|
||||
// chop of the filename for compare
|
||||
if ((space = PL_strrchr(stringbuf, ' '))!=NULL)
|
||||
*space = '\0';
|
||||
|
||||
// we have already recorded this one, free up, and return
|
||||
if (!PL_strncmp(string,stringbuf,PL_strlen(stringbuf))) {
|
||||
PR_Free(buffer);
|
||||
PR_Free(stringbuf);
|
||||
PR_Free(string);
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// build up the compare string
|
||||
else
|
||||
stringbuf[istringpos++] = buffer[ibufferpos];
|
||||
}
|
||||
|
||||
// throw away the record file data
|
||||
PR_Free(buffer);
|
||||
PR_Free(stringbuf);
|
||||
}
|
||||
}
|
||||
|
||||
// if this bad vector was not recorded, add it to record file
|
||||
|
||||
if (!found) {
|
||||
PR_Seek(recordFile,0,PR_SEEK_END);
|
||||
PR_Write(recordFile,string,PL_strlen(string));
|
||||
}
|
||||
|
||||
PR_Close(recordFile);
|
||||
PR_Free(string);
|
||||
}
|
||||
|
||||
// vector was not recorded
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* compare function for quick sort. Compares references and
|
||||
* sorts in decending order
|
||||
*/
|
||||
|
||||
static int compare( const void *arg1, const void *arg2 )
|
||||
{
|
||||
VectorInfo ** p1 = (VectorInfo**)arg1;
|
||||
VectorInfo ** p2 = (VectorInfo**)arg2;
|
||||
return (*p2)->references - (*p1)->references;
|
||||
}
|
||||
|
||||
/**
|
||||
* This debug routines stores statistical information about a
|
||||
* context vector. The context vector statistics are stored in
|
||||
* a global array. The table is resorted each time it grows to
|
||||
* aid in lookup speed. If a vector has already been noted, its
|
||||
* reference count is bumped, otherwise it is added to the table
|
||||
*
|
||||
* @update jevering 6/11/98
|
||||
* @param aTags is the tag list (vector)
|
||||
* @param count is the size of the vector
|
||||
* @return
|
||||
*/
|
||||
|
||||
void CParserDebug::NoteVector(eHTMLTags aTags[],PRInt32 count, PRBool good_vector)
|
||||
{
|
||||
// if the table doesn't exist, create it
|
||||
if (!mVectorInfoArray) {
|
||||
mVectorInfoArray = (VectorInfo**)PR_Calloc(TABLE_SIZE,sizeof(VectorInfo*));
|
||||
}
|
||||
else {
|
||||
// attempt to look up the vector
|
||||
for (PRInt32 i = 0; i < mVectorCount; i++)
|
||||
|
||||
// check the vector only if they are the same size, if they
|
||||
// match then just return without doing further work
|
||||
if (mVectorInfoArray[i]->count == count)
|
||||
if (!memcmp(mVectorInfoArray[i]->vector, aTags, sizeof(eHTMLTags)*count)) {
|
||||
|
||||
// bzzzt. and we have a winner.. bump the ref count
|
||||
mVectorInfoArray[i]->references++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// the context vector hasn't been noted, so allocate it and
|
||||
// initialize it one.. add it to the table
|
||||
VectorInfo * pVectorInfo = (VectorInfo*)PR_Malloc(sizeof(VectorInfo));
|
||||
pVectorInfo->references = 1;
|
||||
pVectorInfo->count = count;
|
||||
pVectorInfo->good_vector = good_vector;
|
||||
pVectorInfo->vector = (eHTMLTags*)PR_Malloc(count*sizeof(eHTMLTags));
|
||||
memcpy(pVectorInfo->vector,aTags,sizeof(eHTMLTags)*count);
|
||||
mVectorInfoArray[mVectorCount++] = pVectorInfo;
|
||||
|
||||
// have we maxed out the table? grow it.. sort it.. love it.
|
||||
if ((mVectorCount % TABLE_SIZE) == 0) {
|
||||
mVectorInfoArray = (VectorInfo**)realloc(
|
||||
mVectorInfoArray,
|
||||
(sizeof(VectorInfo*)*((mVectorCount/TABLE_SIZE)+1)*TABLE_SIZE));
|
||||
if (mVectorCount) {
|
||||
qsort((void*)mVectorInfoArray,(size_t)mVectorCount,sizeof(VectorInfo*),compare);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CParserDebug::MakeVectorString(char * vector_string, VectorInfo * pInfo)
|
||||
{
|
||||
sprintf (vector_string, "%6d ", pInfo->references);
|
||||
for (PRInt32 j = 0; j < pInfo->count; j++) {
|
||||
PL_strcat(vector_string, "<");
|
||||
PL_strcat(vector_string, (const char *)GetTagName(pInfo->vector[j]));
|
||||
PL_strcat(vector_string, ">");
|
||||
}
|
||||
PL_strcat(vector_string,"\r\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* This debug routine dumps out the vector statistics to a text
|
||||
* file in the verification directory and defaults to the name
|
||||
* "vector.stat". It contains all parsed context vectors and there
|
||||
* occurance count sorted in decending order.
|
||||
*
|
||||
* @update jevering 6/11/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
|
||||
void CParserDebug::DumpVectorRecord(void)
|
||||
{
|
||||
// do we have a table?
|
||||
if (mVectorCount) {
|
||||
|
||||
// hopefully, they wont exceed 1K.
|
||||
char vector_string[1024];
|
||||
char path[1024];
|
||||
|
||||
path[0] = '\0';
|
||||
|
||||
// put in the verification directory.. else the root
|
||||
if (mVerificationDir)
|
||||
strcpy(path,mVerificationDir);
|
||||
|
||||
strcat(path,CONTEXT_VECTOR_STAT);
|
||||
|
||||
// open the stat file creaming any existing stat file
|
||||
PRFileDesc * statisticFile = PR_Open(path,PR_CREATE_FILE|PR_RDWR,0);
|
||||
if (statisticFile) {
|
||||
|
||||
PRInt32 i;
|
||||
PRofstream ps;
|
||||
ps.attach(statisticFile);
|
||||
|
||||
// oh what the heck, sort it again
|
||||
if (mVectorCount) {
|
||||
qsort((void*)mVectorInfoArray,(size_t)mVectorCount,sizeof(VectorInfo*),compare);
|
||||
}
|
||||
|
||||
// cute little header
|
||||
sprintf(vector_string,"Context vector occurance results. Processed %d unique vectors.\r\n\r\n", mVectorCount);
|
||||
ps << vector_string;
|
||||
|
||||
ps << "Invalid context vector summary (see " CONTEXT_VECTOR_STAT ") for mapping.\r\n";
|
||||
ps << VECTOR_TABLE_HEADER;
|
||||
|
||||
// dump out the bad vectors encountered
|
||||
for (i = 0; i < mVectorCount; i++) {
|
||||
if (!mVectorInfoArray[i]->good_vector) {
|
||||
MakeVectorString(vector_string, mVectorInfoArray[i]);
|
||||
ps << vector_string;
|
||||
}
|
||||
}
|
||||
|
||||
ps << "\r\n\r\nValid context vector summary\r\n";
|
||||
ps << VECTOR_TABLE_HEADER;
|
||||
|
||||
// take a big vector table dump (good vectors)
|
||||
for (i = 0; i < mVectorCount; i++) {
|
||||
if (mVectorInfoArray[i]->good_vector) {
|
||||
MakeVectorString(vector_string, mVectorInfoArray[i]);
|
||||
ps << vector_string;
|
||||
}
|
||||
// free em up. they mean nothing to me now (I'm such a user)
|
||||
|
||||
if (mVectorInfoArray[i]->vector)
|
||||
PR_Free(mVectorInfoArray[i]->vector);
|
||||
PR_Free(mVectorInfoArray[i]);
|
||||
} //for
|
||||
PR_Close(statisticFile);
|
||||
}//if
|
||||
|
||||
// ok, we are done with the table, free it up as well
|
||||
PR_Free(mVectorInfoArray);
|
||||
mVectorInfoArray = 0;
|
||||
mVectorCount = 0;
|
||||
|
||||
} //if
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This debug method allows us to determine whether or not
|
||||
* we've seen (and can handle) the given context vector.
|
||||
*
|
||||
* @update gess4/22/98
|
||||
* @param tags is an array of eHTMLTags
|
||||
* @param count represents the number of items in the tags array
|
||||
* @param aDTD is the DTD we plan to ask for verification
|
||||
* @return TRUE if we know how to handle it, else false
|
||||
*/
|
||||
|
||||
PRBool CParserDebug::Verify(nsIDTD * aDTD, nsParser * aParser, int aContextStackPos, eHTMLTags aContextStack[], char * aURLRef)
|
||||
{
|
||||
PRBool result=PR_TRUE;
|
||||
|
||||
//ok, now see if we understand this vector
|
||||
|
||||
if(0!=mVerificationDir || mRecordingStatistics) {
|
||||
|
||||
if(aDTD && aContextStackPos>1) {
|
||||
for (int i = 0; i < aContextStackPos-1; i++)
|
||||
if (!aDTD->CanContain(aContextStack[i],aContextStack[i+1])) {
|
||||
result = PR_FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mRecordingStatistics) {
|
||||
NoteVector(aContextStack,aContextStackPos,result);
|
||||
}
|
||||
|
||||
if(0!=mVerificationDir) {
|
||||
char path[2048];
|
||||
strcpy(path,mVerificationDir);
|
||||
|
||||
int i=0;
|
||||
for(i=0;i<aContextStackPos;i++){
|
||||
strcat(path,"/");
|
||||
const char* name=GetTagName(aContextStack[i]);
|
||||
strcat(path,name);
|
||||
PR_MkDir(path,0);
|
||||
}
|
||||
if(PR_FALSE==result){
|
||||
static PRBool rnd_initialized = PR_FALSE;
|
||||
|
||||
if (!rnd_initialized) {
|
||||
// seed randomn number generator to aid in temp file
|
||||
// creation.
|
||||
rnd_initialized = PR_TRUE;
|
||||
srand((unsigned)time(NULL));
|
||||
}
|
||||
|
||||
// generate a filename to dump the html source into
|
||||
char filename[1024];
|
||||
do {
|
||||
// use system time to generate a temporary file name
|
||||
time_t ltime;
|
||||
time (<ime);
|
||||
// add in random number so that we can create uniques names
|
||||
// faster than simply every second.
|
||||
ltime += (time_t)rand();
|
||||
sprintf(filename,"%s/%lX.html", path, ltime);
|
||||
// try until we find one we can create
|
||||
} while (PR_Access(filename,PR_ACCESS_EXISTS) == PR_SUCCESS);
|
||||
|
||||
// check to see if we already recorded an instance of this particular
|
||||
// bad vector.
|
||||
if (!DebugRecord(path, aURLRef, filename))
|
||||
{
|
||||
// save file to directory indicated by bad context vector
|
||||
PRFileDesc * debugFile = PR_Open(filename,PR_CREATE_FILE|PR_RDWR,0);
|
||||
// if we were able to open the debug file, then
|
||||
// write the true URL at the top of the file.
|
||||
if (debugFile) {
|
||||
// dump the html source into the newly created file.
|
||||
PRofstream ps;
|
||||
ps.attach(debugFile);
|
||||
if (aParser)
|
||||
aParser->DebugDumpSource(ps);
|
||||
PR_Close(debugFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
Reference in New Issue
Block a user