r=pollmann. Fix for bug 29395. XML error messages now show up in the content area for XML, RDF, and XUL files. Earlier, they would only show up for XML files.

- Generate tokens in the expat tokenizer to display an XML error message.
- Process those tokens in the XML DTD
- Add a SetStringValue() method to CToken that accepts an nsString parameter.
- Removed code in the XML content sink's NotifyError() method to create error message content.
This commit is contained in:
nisheeth%netscape.com 2000-03-30 01:41:48 +00:00
parent 8d8fffcdaa
commit bc23c89148
14 changed files with 338 additions and 286 deletions

View File

@ -868,125 +868,10 @@ nsXMLContentSink::AddLeaf(const nsIParserNode& aNode)
return NS_OK;
}
nsresult nsXMLContentSink::CreateErrorText(const nsParserError* aError, nsString& aErrorString)
{
nsString errorText("XML Parsing Error: ");
if (aError) {
errorText.Append(aError->description);
errorText.Append("\nLine Number ");
errorText.Append(aError->lineNumber, 10);
errorText.Append(", Column ");
errorText.Append(aError->colNumber, 10);
errorText.Append(":");
}
aErrorString = errorText;
return NS_OK;
}
nsresult nsXMLContentSink::CreateSourceText(const nsParserError* aError, nsString& aSourceString)
{
nsString sourceText;
PRInt32 errorPosition = aError->colNumber;
sourceText.Append(aError->sourceLine);
sourceText.Append("\n");
for (int i = 0; i < errorPosition; i++)
sourceText.Append("-");
sourceText.Append("^");
aSourceString = sourceText;
return NS_OK;
}
static void SetTextStringOnTextNode(const nsString& aTextString, nsIContent* aTextNode)
{
nsITextContent* text = nsnull;
PRUnichar *tempUnicode = aTextString.ToNewUnicode();
static NS_DEFINE_IID(kITextContentIID, NS_ITEXT_CONTENT_IID);
aTextNode->QueryInterface(kITextContentIID, (void**) &text);
text->SetText(tempUnicode, aTextString.Length(), PR_FALSE);
delete [] tempUnicode;
NS_RELEASE(text);
}
/*
* We create the following XML snippet programmatically and
* insert it into the content model:
*
* <ParserError>
* XML Error: "contents of aError->description"
* Line Number: "contents of aError->lineNumber"
* <SourceText>
* "Contents of aError->sourceLine"
* "^ pointing at the error location"
* </SourceText>
* </ParserError>
*
*/
NS_IMETHODIMP
nsXMLContentSink::NotifyError(const nsParserError* aError)
{
nsresult result = NS_OK;
nsAutoString parserErrorTag = "parsererror";
nsAutoString sourceTextTag = "sourcetext";
nsString errorText;
nsString sourceText;
nsIHTMLContent* errorContainerNode = nsnull;
nsIHTMLContent* sourceContainerNode = nsnull;
nsIContent* errorTextNode = nsnull;
nsIContent* sourceTextNode = nsnull;
/* Create container and text content nodes */
result = NS_CreateHTMLElement(&errorContainerNode, parserErrorTag); // XXX these should NOT be in the HTML namespace
if (NS_OK == result) {
result = NS_NewTextNode(&errorTextNode);
if (NS_OK == result) {
result = NS_CreateHTMLElement(&sourceContainerNode, sourceTextTag);
if (NS_OK == result) {
result = NS_NewTextNode(&sourceTextNode);
}
}
}
/* Create the error text string and source text string
and set the text strings into the text nodes. */
result = CreateErrorText(aError, errorText);
if (NS_OK == result) {
SetTextStringOnTextNode(errorText, errorTextNode);
}
result = CreateSourceText(aError, sourceText);
if (NS_OK == result) {
SetTextStringOnTextNode(sourceText, sourceTextNode);
}
/* Hook the content nodes up to the document and to each other */
if (NS_OK == result) {
errorContainerNode->SetDocument(mDocument, PR_FALSE);
errorTextNode->SetDocument(mDocument, PR_FALSE);
sourceContainerNode->SetDocument(mDocument, PR_FALSE);
sourceTextNode->SetDocument(mDocument, PR_FALSE);
if (nsnull == mDocElement) {
mDocElement = errorContainerNode;
NS_ADDREF(mDocElement);
mDocument->SetRootContent(mDocElement);
}
else {
mDocElement->AppendChildTo(errorContainerNode, PR_FALSE);
}
errorContainerNode->AppendChildTo(errorTextNode, PR_FALSE);
errorContainerNode->AppendChildTo(sourceContainerNode, PR_FALSE);
sourceContainerNode->AppendChildTo(sourceTextNode, PR_FALSE);
}
return result;
return NS_OK;
}
// nsIXMLContentSink

View File

@ -158,8 +158,6 @@ protected:
void StartLayoutProcess();
nsresult AddText(const nsString& aString);
nsresult CreateErrorText(const nsParserError* aError, nsString& aErrorString);
nsresult CreateSourceText(const nsParserError* aError, nsString& aSourceString);
static void
GetElementFactory(PRInt32 aNameSpaceID, nsIElementFactory** aResult);

View File

@ -61,6 +61,7 @@ static NS_DEFINE_IID(kClassIID, NS_EXPATTOKENIZER_IID);
static const char* kDocTypeDeclPrefix = "<!DOCTYPE";
static const char* kChromeProtocol = "chrome";
static const char* kDTDDirectory = "dtd/";
static const char kHTMLNameSpaceURI[] = "http://www.w3.org/TR/REC-html40";
const nsIID&
nsExpatTokenizer::GetIID()
@ -286,17 +287,112 @@ void nsExpatTokenizer::GetLine(const char* aSourceBuffer, PRUint32 aLength,
}
}
static nsresult
CreateErrorText(const nsParserError* aError, nsString& aErrorString)
{
aErrorString = "XML Parsing Error: ";
if (aError) {
aErrorString.Append(aError->description);
aErrorString.Append("\nLine Number ");
aErrorString.Append(aError->lineNumber, 10);
aErrorString.Append(", Column ");
aErrorString.Append(aError->colNumber, 10);
aErrorString.Append(":");
}
return NS_OK;
}
static nsresult
CreateSourceText(const nsParserError* aError, nsString& aSourceString)
{
PRInt32 errorPosition = aError->colNumber;
aSourceString.Append(aError->sourceLine);
aSourceString.Append("\n");
for (int i = 0; i < errorPosition; i++)
aSourceString.Append("-");
aSourceString.Append("^");
return NS_OK;
}
/* Create and add the tokens in the following order to display the error:
ParserError start token
Text token containing error message
SourceText start token
Text token containing source text
SourceText end token
ParserError end token
*/
nsresult
nsExpatTokenizer::AddErrorMessageTokens(nsParserError* aError)
{
nsresult rv = NS_OK;
CToken* newToken = mState->tokenRecycler->CreateTokenOfType(eToken_start, eHTMLTag_parsererror);
AddToken(newToken, NS_OK, mState->tokenDeque, mState->tokenRecycler);
CAttributeToken* attrToken = (CAttributeToken*)
mState->tokenRecycler->CreateTokenOfType(eToken_attribute, eHTMLTag_unknown);
nsString& key = attrToken->GetKey();
key.Assign("xmlns");
attrToken->SetStringValue(kHTMLNameSpaceURI);
newToken->SetAttributeCount(1);
newToken = (CToken*) attrToken;
AddToken(newToken, NS_OK, mState->tokenDeque, mState->tokenRecycler);
nsAutoString textStr;
CreateErrorText(aError, textStr);
newToken = mState->tokenRecycler->CreateTokenOfType(eToken_text, eHTMLTag_unknown);
newToken->SetStringValue(textStr);
AddToken(newToken, NS_OK, mState->tokenDeque, mState->tokenRecycler);
newToken = mState->tokenRecycler->CreateTokenOfType(eToken_start, eHTMLTag_sourcetext);
AddToken(newToken, NS_OK, mState->tokenDeque, mState->tokenRecycler);
textStr.Truncate();
CreateSourceText(aError, textStr);
newToken = mState->tokenRecycler->CreateTokenOfType(eToken_text, eHTMLTag_unknown);
newToken->SetStringValue(textStr);
AddToken(newToken, NS_OK, mState->tokenDeque, mState->tokenRecycler);
newToken = mState->tokenRecycler->CreateTokenOfType(eToken_end, eHTMLTag_sourcetext);
AddToken(newToken, NS_OK, mState->tokenDeque, mState->tokenRecycler);
newToken = mState->tokenRecycler->CreateTokenOfType(eToken_end, eHTMLTag_parsererror);
AddToken(newToken, NS_OK, mState->tokenDeque, mState->tokenRecycler);
return rv;
}
/*
* Called immediately after an error has occurred in expat. Creates
* an error token and pushes it onto the token queue.
* tokens to display the error and an error token to the token stream.
*
* The error tokens will end up creating the following content model
* in the content sink:
*
* <ParserError>
* XML Error: "contents of aError->description"
* Line Number: "contents of aError->lineNumber"
* <SourceText>
* "Contents of aError->sourceLine"
* "^ pointing at the error location"
* </SourceText>
* </ParserError>
*
*/
void nsExpatTokenizer::PushXMLErrorToken(const char *aBuffer, PRUint32 aLength, PRBool aIsFinal)
nsresult
nsExpatTokenizer::PushXMLErrorTokens(const char *aBuffer, PRUint32 aLength, PRBool aIsFinal)
{
CErrorToken* token= (CErrorToken *) mState->tokenRecycler->CreateTokenOfType(eToken_error, eHTMLTag_unknown);
CErrorToken* errorToken= (CErrorToken *) mState->tokenRecycler->CreateTokenOfType(eToken_error, eHTMLTag_unknown);
nsParserError *error = new nsParserError;
nsresult rv = NS_OK;
if(error){
if (error && errorToken) {
/* Fill in the values of the error token */
error->code = XML_GetErrorCode(mExpatParser);
error->lineNumber = XML_GetCurrentLineNumber(mExpatParser);
error->colNumber = XML_GetCurrentColumnNumber(mExpatParser);
@ -310,11 +406,18 @@ void nsExpatTokenizer::PushXMLErrorToken(const char *aBuffer, PRUint32 aLength,
error->sourceLine.Append(mLastLine);
}
token->SetError(error);
errorToken->SetError(error);
CToken* theToken = (CToken* )token;
AddToken(theToken, NS_OK, mState->tokenDeque, mState->tokenRecycler);
/* Add the error token */
CToken* newToken = (CToken*) errorToken;
AddToken(newToken, NS_OK, mState->tokenDeque, mState->tokenRecycler);
/* Add the error message tokens */
AddErrorMessageTokens(error);
}
return rv;
}
nsresult nsExpatTokenizer::ParseXMLBuffer(const char* aBuffer, PRUint32 aLength, PRBool aIsFinal)
@ -326,7 +429,7 @@ nsresult nsExpatTokenizer::ParseXMLBuffer(const char* aBuffer, PRUint32 aLength,
nsCOMPtr<nsExpatTokenizer> me=this;
if (!XML_Parse(mExpatParser, aBuffer, aLength, aIsFinal)) {
PushXMLErrorToken(aBuffer, aLength, aIsFinal);
PushXMLErrorTokens(aBuffer, aLength, aIsFinal);
result=NS_ERROR_HTMLPARSER_STOPPARSING;
}
else if (aBuffer && aLength) {

View File

@ -94,7 +94,9 @@ protected:
void SetupExpatParser(void);
// Propagate XML errors to the content sink
void PushXMLErrorToken(const char *aBuffer, PRUint32 aLength, PRBool aIsFinal);
nsresult PushXMLErrorTokens(const char *aBuffer, PRUint32 aLength, PRBool aIsFinal);
nsresult AddErrorMessageTokens(nsParserError* aError);
void GetLine(const char* aSourceBuffer, PRUint32 aLength,
PRUint32 aByteIndex, nsString& aLine);

View File

@ -167,6 +167,14 @@ void CToken::SetStringValue(const char* name){
mTextValue=name;
}
/**
* Setter method for the string value of this token
*/
void CToken::SetStringValue(nsString& aStr)
{
mTextValue = aStr;
}
/**
* This method retrieves the value of this internal string.
*

View File

@ -126,6 +126,11 @@ class CToken {
*/
virtual void SetStringValue(const char* name);
/**
* Setter method for the string value of this token
*/
virtual void SetStringValue(nsString& aStr);
/**
* Retrieve string value of the token as a c-string
* @update gess5/11/98

View File

@ -474,8 +474,9 @@ NS_IMETHODIMP CWellFormedDTD::HandleToken(CToken* aToken,nsIParser* aParser) {
eHTMLTokenTypes theType= (eHTMLTokenTypes)theToken->GetTokenType();
if(mDTDState==NS_ERROR_HTMLPARSER_STOPPARSING) {
//Report only errors to the sink.
if(theType!=eToken_error) return result;
// Report only errors to the sink.
if(theType != eToken_error)
return result;
}
mParser=(nsParser*)aParser;
@ -658,31 +659,55 @@ nsresult CWellFormedDTD::HandleEndToken(CToken* aToken) {
nsresult CWellFormedDTD::HandleErrorToken(CToken* aToken) {
NS_PRECONDITION(0!=aToken,"null token");
nsresult result=NS_OK;
nsresult result=NS_OK;
// Cycle through the remaining tokens in the token stream and handle them
// These tokens were added so that content objects for the error message
// are generated by the content sink
while (PR_TRUE) {
CToken* token = mTokenizer->PopToken();
if(token) {
eHTMLTokenTypes type = (eHTMLTokenTypes) token->GetTokenType();
switch(type) {
case eToken_newline:
mLineNumber++; //now fall through
case eToken_whitespace:
case eToken_text:
HandleLeafToken(token);
break;
case eToken_start:
HandleStartToken(token);
break;
case eToken_end:
HandleEndToken(token);
break;
default:
// Do nothing
break;
}
}
else
break;
}
// Propagate the error onto the content sink.
CErrorToken *errTok = (CErrorToken *)aToken;
// XXX Dump error to error output stream just in case the content
// sink is RDF or XUL and does not implement error handling. We need to factor
// code better among HTMLContentSink, XMLContentSink, RDFContentSink,
// and XULContentSink. Until that happens, instead of cutting and
// pasting error handling code for each content sink, I output an
// error to cerr here.
const nsParserError* error = errTok->GetError();
result=(mSink)? mSink->NotifyError(error):NS_OK;
// Output the error to the console
if (error) {
char* temp;
cerr << "XML Error in file '" << (temp = mFilename.ToNewCString()) << "', ";
cout << "XML Error in file '" << (temp = mFilename.ToNewCString()) << "', ";
Recycle(temp);
cerr << "Line Number: " << error->lineNumber << ", ";
cerr << "Col Number: " << error->colNumber << ", ";
cerr << "Description: " << (temp = error->description.ToNewCString()) << "\n";
cout << "Line Number: " << error->lineNumber << ", ";
cout << "Col Number: " << error->colNumber << ", ";
cout << "Description: " << (temp = error->description.ToNewCString()) << "\n";
Recycle(temp);
cerr << "Source Line: " << (temp = error->sourceLine.ToNewCString()) << "\n";
cout << "Source Line: " << (temp = error->sourceLine.ToNewCString()) << "\n";
Recycle(temp);
}
result=(mSink)? mSink->NotifyError(errTok->GetError()):NS_OK;
return result;
}

View File

@ -868,125 +868,10 @@ nsXMLContentSink::AddLeaf(const nsIParserNode& aNode)
return NS_OK;
}
nsresult nsXMLContentSink::CreateErrorText(const nsParserError* aError, nsString& aErrorString)
{
nsString errorText("XML Parsing Error: ");
if (aError) {
errorText.Append(aError->description);
errorText.Append("\nLine Number ");
errorText.Append(aError->lineNumber, 10);
errorText.Append(", Column ");
errorText.Append(aError->colNumber, 10);
errorText.Append(":");
}
aErrorString = errorText;
return NS_OK;
}
nsresult nsXMLContentSink::CreateSourceText(const nsParserError* aError, nsString& aSourceString)
{
nsString sourceText;
PRInt32 errorPosition = aError->colNumber;
sourceText.Append(aError->sourceLine);
sourceText.Append("\n");
for (int i = 0; i < errorPosition; i++)
sourceText.Append("-");
sourceText.Append("^");
aSourceString = sourceText;
return NS_OK;
}
static void SetTextStringOnTextNode(const nsString& aTextString, nsIContent* aTextNode)
{
nsITextContent* text = nsnull;
PRUnichar *tempUnicode = aTextString.ToNewUnicode();
static NS_DEFINE_IID(kITextContentIID, NS_ITEXT_CONTENT_IID);
aTextNode->QueryInterface(kITextContentIID, (void**) &text);
text->SetText(tempUnicode, aTextString.Length(), PR_FALSE);
delete [] tempUnicode;
NS_RELEASE(text);
}
/*
* We create the following XML snippet programmatically and
* insert it into the content model:
*
* <ParserError>
* XML Error: "contents of aError->description"
* Line Number: "contents of aError->lineNumber"
* <SourceText>
* "Contents of aError->sourceLine"
* "^ pointing at the error location"
* </SourceText>
* </ParserError>
*
*/
NS_IMETHODIMP
nsXMLContentSink::NotifyError(const nsParserError* aError)
{
nsresult result = NS_OK;
nsAutoString parserErrorTag = "parsererror";
nsAutoString sourceTextTag = "sourcetext";
nsString errorText;
nsString sourceText;
nsIHTMLContent* errorContainerNode = nsnull;
nsIHTMLContent* sourceContainerNode = nsnull;
nsIContent* errorTextNode = nsnull;
nsIContent* sourceTextNode = nsnull;
/* Create container and text content nodes */
result = NS_CreateHTMLElement(&errorContainerNode, parserErrorTag); // XXX these should NOT be in the HTML namespace
if (NS_OK == result) {
result = NS_NewTextNode(&errorTextNode);
if (NS_OK == result) {
result = NS_CreateHTMLElement(&sourceContainerNode, sourceTextTag);
if (NS_OK == result) {
result = NS_NewTextNode(&sourceTextNode);
}
}
}
/* Create the error text string and source text string
and set the text strings into the text nodes. */
result = CreateErrorText(aError, errorText);
if (NS_OK == result) {
SetTextStringOnTextNode(errorText, errorTextNode);
}
result = CreateSourceText(aError, sourceText);
if (NS_OK == result) {
SetTextStringOnTextNode(sourceText, sourceTextNode);
}
/* Hook the content nodes up to the document and to each other */
if (NS_OK == result) {
errorContainerNode->SetDocument(mDocument, PR_FALSE);
errorTextNode->SetDocument(mDocument, PR_FALSE);
sourceContainerNode->SetDocument(mDocument, PR_FALSE);
sourceTextNode->SetDocument(mDocument, PR_FALSE);
if (nsnull == mDocElement) {
mDocElement = errorContainerNode;
NS_ADDREF(mDocElement);
mDocument->SetRootContent(mDocElement);
}
else {
mDocElement->AppendChildTo(errorContainerNode, PR_FALSE);
}
errorContainerNode->AppendChildTo(errorTextNode, PR_FALSE);
errorContainerNode->AppendChildTo(sourceContainerNode, PR_FALSE);
sourceContainerNode->AppendChildTo(sourceTextNode, PR_FALSE);
}
return result;
return NS_OK;
}
// nsIXMLContentSink

View File

@ -158,8 +158,6 @@ protected:
void StartLayoutProcess();
nsresult AddText(const nsString& aString);
nsresult CreateErrorText(const nsParserError* aError, nsString& aErrorString);
nsresult CreateSourceText(const nsParserError* aError, nsString& aSourceString);
static void
GetElementFactory(PRInt32 aNameSpaceID, nsIElementFactory** aResult);

View File

@ -61,6 +61,7 @@ static NS_DEFINE_IID(kClassIID, NS_EXPATTOKENIZER_IID);
static const char* kDocTypeDeclPrefix = "<!DOCTYPE";
static const char* kChromeProtocol = "chrome";
static const char* kDTDDirectory = "dtd/";
static const char kHTMLNameSpaceURI[] = "http://www.w3.org/TR/REC-html40";
const nsIID&
nsExpatTokenizer::GetIID()
@ -286,17 +287,112 @@ void nsExpatTokenizer::GetLine(const char* aSourceBuffer, PRUint32 aLength,
}
}
static nsresult
CreateErrorText(const nsParserError* aError, nsString& aErrorString)
{
aErrorString = "XML Parsing Error: ";
if (aError) {
aErrorString.Append(aError->description);
aErrorString.Append("\nLine Number ");
aErrorString.Append(aError->lineNumber, 10);
aErrorString.Append(", Column ");
aErrorString.Append(aError->colNumber, 10);
aErrorString.Append(":");
}
return NS_OK;
}
static nsresult
CreateSourceText(const nsParserError* aError, nsString& aSourceString)
{
PRInt32 errorPosition = aError->colNumber;
aSourceString.Append(aError->sourceLine);
aSourceString.Append("\n");
for (int i = 0; i < errorPosition; i++)
aSourceString.Append("-");
aSourceString.Append("^");
return NS_OK;
}
/* Create and add the tokens in the following order to display the error:
ParserError start token
Text token containing error message
SourceText start token
Text token containing source text
SourceText end token
ParserError end token
*/
nsresult
nsExpatTokenizer::AddErrorMessageTokens(nsParserError* aError)
{
nsresult rv = NS_OK;
CToken* newToken = mState->tokenRecycler->CreateTokenOfType(eToken_start, eHTMLTag_parsererror);
AddToken(newToken, NS_OK, mState->tokenDeque, mState->tokenRecycler);
CAttributeToken* attrToken = (CAttributeToken*)
mState->tokenRecycler->CreateTokenOfType(eToken_attribute, eHTMLTag_unknown);
nsString& key = attrToken->GetKey();
key.Assign("xmlns");
attrToken->SetStringValue(kHTMLNameSpaceURI);
newToken->SetAttributeCount(1);
newToken = (CToken*) attrToken;
AddToken(newToken, NS_OK, mState->tokenDeque, mState->tokenRecycler);
nsAutoString textStr;
CreateErrorText(aError, textStr);
newToken = mState->tokenRecycler->CreateTokenOfType(eToken_text, eHTMLTag_unknown);
newToken->SetStringValue(textStr);
AddToken(newToken, NS_OK, mState->tokenDeque, mState->tokenRecycler);
newToken = mState->tokenRecycler->CreateTokenOfType(eToken_start, eHTMLTag_sourcetext);
AddToken(newToken, NS_OK, mState->tokenDeque, mState->tokenRecycler);
textStr.Truncate();
CreateSourceText(aError, textStr);
newToken = mState->tokenRecycler->CreateTokenOfType(eToken_text, eHTMLTag_unknown);
newToken->SetStringValue(textStr);
AddToken(newToken, NS_OK, mState->tokenDeque, mState->tokenRecycler);
newToken = mState->tokenRecycler->CreateTokenOfType(eToken_end, eHTMLTag_sourcetext);
AddToken(newToken, NS_OK, mState->tokenDeque, mState->tokenRecycler);
newToken = mState->tokenRecycler->CreateTokenOfType(eToken_end, eHTMLTag_parsererror);
AddToken(newToken, NS_OK, mState->tokenDeque, mState->tokenRecycler);
return rv;
}
/*
* Called immediately after an error has occurred in expat. Creates
* an error token and pushes it onto the token queue.
* tokens to display the error and an error token to the token stream.
*
* The error tokens will end up creating the following content model
* in the content sink:
*
* <ParserError>
* XML Error: "contents of aError->description"
* Line Number: "contents of aError->lineNumber"
* <SourceText>
* "Contents of aError->sourceLine"
* "^ pointing at the error location"
* </SourceText>
* </ParserError>
*
*/
void nsExpatTokenizer::PushXMLErrorToken(const char *aBuffer, PRUint32 aLength, PRBool aIsFinal)
nsresult
nsExpatTokenizer::PushXMLErrorTokens(const char *aBuffer, PRUint32 aLength, PRBool aIsFinal)
{
CErrorToken* token= (CErrorToken *) mState->tokenRecycler->CreateTokenOfType(eToken_error, eHTMLTag_unknown);
CErrorToken* errorToken= (CErrorToken *) mState->tokenRecycler->CreateTokenOfType(eToken_error, eHTMLTag_unknown);
nsParserError *error = new nsParserError;
nsresult rv = NS_OK;
if(error){
if (error && errorToken) {
/* Fill in the values of the error token */
error->code = XML_GetErrorCode(mExpatParser);
error->lineNumber = XML_GetCurrentLineNumber(mExpatParser);
error->colNumber = XML_GetCurrentColumnNumber(mExpatParser);
@ -310,11 +406,18 @@ void nsExpatTokenizer::PushXMLErrorToken(const char *aBuffer, PRUint32 aLength,
error->sourceLine.Append(mLastLine);
}
token->SetError(error);
errorToken->SetError(error);
CToken* theToken = (CToken* )token;
AddToken(theToken, NS_OK, mState->tokenDeque, mState->tokenRecycler);
/* Add the error token */
CToken* newToken = (CToken*) errorToken;
AddToken(newToken, NS_OK, mState->tokenDeque, mState->tokenRecycler);
/* Add the error message tokens */
AddErrorMessageTokens(error);
}
return rv;
}
nsresult nsExpatTokenizer::ParseXMLBuffer(const char* aBuffer, PRUint32 aLength, PRBool aIsFinal)
@ -326,7 +429,7 @@ nsresult nsExpatTokenizer::ParseXMLBuffer(const char* aBuffer, PRUint32 aLength,
nsCOMPtr<nsExpatTokenizer> me=this;
if (!XML_Parse(mExpatParser, aBuffer, aLength, aIsFinal)) {
PushXMLErrorToken(aBuffer, aLength, aIsFinal);
PushXMLErrorTokens(aBuffer, aLength, aIsFinal);
result=NS_ERROR_HTMLPARSER_STOPPARSING;
}
else if (aBuffer && aLength) {

View File

@ -94,7 +94,9 @@ protected:
void SetupExpatParser(void);
// Propagate XML errors to the content sink
void PushXMLErrorToken(const char *aBuffer, PRUint32 aLength, PRBool aIsFinal);
nsresult PushXMLErrorTokens(const char *aBuffer, PRUint32 aLength, PRBool aIsFinal);
nsresult AddErrorMessageTokens(nsParserError* aError);
void GetLine(const char* aSourceBuffer, PRUint32 aLength,
PRUint32 aByteIndex, nsString& aLine);

View File

@ -167,6 +167,14 @@ void CToken::SetStringValue(const char* name){
mTextValue=name;
}
/**
* Setter method for the string value of this token
*/
void CToken::SetStringValue(nsString& aStr)
{
mTextValue = aStr;
}
/**
* This method retrieves the value of this internal string.
*

View File

@ -126,6 +126,11 @@ class CToken {
*/
virtual void SetStringValue(const char* name);
/**
* Setter method for the string value of this token
*/
virtual void SetStringValue(nsString& aStr);
/**
* Retrieve string value of the token as a c-string
* @update gess5/11/98

View File

@ -474,8 +474,9 @@ NS_IMETHODIMP CWellFormedDTD::HandleToken(CToken* aToken,nsIParser* aParser) {
eHTMLTokenTypes theType= (eHTMLTokenTypes)theToken->GetTokenType();
if(mDTDState==NS_ERROR_HTMLPARSER_STOPPARSING) {
//Report only errors to the sink.
if(theType!=eToken_error) return result;
// Report only errors to the sink.
if(theType != eToken_error)
return result;
}
mParser=(nsParser*)aParser;
@ -658,31 +659,55 @@ nsresult CWellFormedDTD::HandleEndToken(CToken* aToken) {
nsresult CWellFormedDTD::HandleErrorToken(CToken* aToken) {
NS_PRECONDITION(0!=aToken,"null token");
nsresult result=NS_OK;
nsresult result=NS_OK;
// Cycle through the remaining tokens in the token stream and handle them
// These tokens were added so that content objects for the error message
// are generated by the content sink
while (PR_TRUE) {
CToken* token = mTokenizer->PopToken();
if(token) {
eHTMLTokenTypes type = (eHTMLTokenTypes) token->GetTokenType();
switch(type) {
case eToken_newline:
mLineNumber++; //now fall through
case eToken_whitespace:
case eToken_text:
HandleLeafToken(token);
break;
case eToken_start:
HandleStartToken(token);
break;
case eToken_end:
HandleEndToken(token);
break;
default:
// Do nothing
break;
}
}
else
break;
}
// Propagate the error onto the content sink.
CErrorToken *errTok = (CErrorToken *)aToken;
// XXX Dump error to error output stream just in case the content
// sink is RDF or XUL and does not implement error handling. We need to factor
// code better among HTMLContentSink, XMLContentSink, RDFContentSink,
// and XULContentSink. Until that happens, instead of cutting and
// pasting error handling code for each content sink, I output an
// error to cerr here.
const nsParserError* error = errTok->GetError();
result=(mSink)? mSink->NotifyError(error):NS_OK;
// Output the error to the console
if (error) {
char* temp;
cerr << "XML Error in file '" << (temp = mFilename.ToNewCString()) << "', ";
cout << "XML Error in file '" << (temp = mFilename.ToNewCString()) << "', ";
Recycle(temp);
cerr << "Line Number: " << error->lineNumber << ", ";
cerr << "Col Number: " << error->colNumber << ", ";
cerr << "Description: " << (temp = error->description.ToNewCString()) << "\n";
cout << "Line Number: " << error->lineNumber << ", ";
cout << "Col Number: " << error->colNumber << ", ";
cout << "Description: " << (temp = error->description.ToNewCString()) << "\n";
Recycle(temp);
cerr << "Source Line: " << (temp = error->sourceLine.ToNewCString()) << "\n";
cout << "Source Line: " << (temp = error->sourceLine.ToNewCString()) << "\n";
Recycle(temp);
}
result=(mSink)? mSink->NotifyError(errTok->GetError()):NS_OK;
return result;
}