Bug 15089, make XML parser error messages localizable. r=harishd,ftang, sr=jst.

This commit is contained in:
heikki%netscape.com 2001-08-17 23:27:20 +00:00
Родитель 233517873e
Коммит 9577ec2d01
19 изменённых файлов: 633 добавлений и 182 удалений

Просмотреть файл

@ -353,6 +353,7 @@ sub ProcessJarManifests()
CreateJarFromManifest(":mozilla:extensions:irc:jar.mn", $chrome_dir, \%jars);
CreateJarFromManifest(":mozilla:extensions:wallet:jar.mn", $chrome_dir, \%jars);
CreateJarFromManifest(":mozilla:intl:uconv:src:jar.mn", $chrome_dir, \%jars);
CreateJarFromManifest(":mozilla:htmlparser:src:jar.mn", $chrome_dir, \%jars);
CreateJarFromManifest(":mozilla:layout:html:forms:src:jar.mn", $chrome_dir, \%jars);
CreateJarFromManifest(":mozilla:layout:html:base:src:jar.mn", $chrome_dir, \%jars);
CreateJarFromManifest(":mozilla:mailnews:jar.mn", $chrome_dir, \%jars);

Двоичные данные
htmlparser/macbuild/htmlparser.mcp

Двоичный файл не отображается.

Просмотреть файл

@ -0,0 +1 @@
xmlparse.properties

Просмотреть файл

@ -61,6 +61,7 @@ CPPSRCS = \
nsToken.cpp \
nsWellFormedDTD.cpp \
nsViewSourceHTML.cpp\
nsParserMsgUtils.cpp\
$(NULL)
ifndef MOZ_DISABLE_DTD_DEBUG

0
htmlparser/src/jar.mn Normal file
Просмотреть файл

Просмотреть файл

@ -48,6 +48,7 @@ CPPSRCS = \
nsWellFormedDTD.cpp \
nsViewSourceHTML.cpp\
nsParserModule.cpp \
nsParserMsgUtils.cpp \
!if !defined(MOZ_DISABLE_DTD_DEBUG)
nsLoggingSink.cpp \
nsHTMLNullSink.cpp \
@ -72,6 +73,7 @@ CPP_OBJS = \
.\$(OBJDIR)\nsWellFormedDTD.obj \
.\$(OBJDIR)\nsViewSourceHTML.obj\
.\$(OBJDIR)\nsParserModule.obj \
.\$(OBJDIR)\nsParserMsgUtils.obj \
!if !defined(MOZ_DISABLE_DTD_DEBUG)
.\$(OBJDIR)\nsLoggingSink.obj \
.\$(OBJDIR)\nsHTMLNullSink.obj \

Просмотреть файл

@ -42,6 +42,9 @@
#include "nsSpecialSystemDirectory.h"
#include "nsIURL.h"
#include "nsParserMsgUtils.h"
#include "nsTextFormatter.h"
typedef struct _XMLParserState {
XML_Parser parser;
nsScanner* scanner;
@ -278,21 +281,24 @@ void nsExpatTokenizer::GetLine(const char* aSourceBuffer, PRUint32 aLength,
}
}
static nsresult
CreateErrorText(const nsParserError* aError, nsString& aErrorString)
{
aErrorString.AssignWithConversion("XML Parsing Error: ");
aErrorString.Truncate();
if (aError) {
aErrorString.Append(aError->description);
aErrorString.AppendWithConversion("\nLocation: ");
aErrorString.Append(aError->sourceURL);
aErrorString.AppendWithConversion("\nLine Number ");
aErrorString.AppendInt(aError->lineNumber, 10);
aErrorString.AppendWithConversion(", Column ");
aErrorString.AppendInt(aError->colNumber, 10);
aErrorString.AppendWithConversion(":");
nsAutoString msg;
nsresult rv = nsParserMsgUtils::GetLocalizedStringByName(XMLPARSER_PROPERTIES,"XMLParsingError",msg);
if (NS_FAILED(rv))
return rv;
// XML Parsing Error: %1$S\nLocation: %2$S\nLine Number %3$d, Column %4$d:
PRUnichar *message = nsTextFormatter::smprintf(msg.get(),aError->description.get(),aError->sourceURL.get(),aError->lineNumber,aError->colNumber);
if (!message) {
return NS_ERROR_OUT_OF_MEMORY;
}
aErrorString.Assign(message);
nsTextFormatter::smprintf_free(message);
}
return NS_OK;
@ -379,89 +385,109 @@ nsExpatTokenizer::PushXMLErrorTokens(const char *aBuffer, PRUint32 aLength, PRBo
{
CErrorToken* errorToken= (CErrorToken *) mState->tokenAllocator->CreateTokenOfType(eToken_error, eHTMLTag_unknown);
nsParserError *error = new nsParserError;
nsresult rv = NS_OK;
if (error && errorToken) {
/* Fill in the values of the error token */
error->code = XML_GetErrorCode(mExpatParser);
error->lineNumber = XML_GetCurrentLineNumber(mExpatParser);
// Adjust the column number so that it is one based rather than zero based.
error->colNumber = XML_GetCurrentColumnNumber(mExpatParser) + 1;
error->description.AssignWithConversion(XML_ErrorString(error->code));
if (error->code==XML_ERROR_TAG_MISMATCH){
/*
* Certain things can be assumed about the token stream because of
* the way expat behaves. eg:
*
* - data:text/xml,</foo> is NOT WELL-FORMED
* - data:text/xml,<foo></bar> is a TAG_MISMATCH.
*
* We can assume that there is at least one extra open tag (the one we
* want), so balance is initially set to one.
*
* Then loop through the tokens:
* - Each time we see eToken_end (</tag>) increment balance, because
* that means there is another pair of tags we don't care about.
* - Each time we see eToken_start (<tag>) decrement balance because it
* matches a close tag (perhaps the MISMATCHed tag in which case
* balance should hit 0).
* - If balance ever hits zero, exit the loop. Because of the way
* balance is adjusted, if balance is zero expected *must* be a start
* tag.
*
* We must check expected in the condition in case expat or nsDeque go
* crazy and give us 0 (null) before balance reaches 0.
*/
nsDequeIterator current = mState->tokenDeque->End();
CToken *expected = NS_STATIC_CAST(CToken*,--current);
PRUint32 balance = 1;
while (expected) {
switch (expected->GetTokenType()) {
case eToken_start:
--balance;
break;
case eToken_end:
++balance;
break;
default:
break; // we don't care about newlines or other tokens
}
if (!balance) {
// if balance is zero, this must be a start tag
CStartToken *startToken=NS_STATIC_CAST(CStartToken*,expected);
error->description.Append(NS_LITERAL_STRING(". Expected: </"));
error->description.Append(startToken->GetStringValue());
error->description.Append(NS_LITERAL_STRING(">"));
break;
}
expected = NS_STATIC_CAST(CToken*,--current);
}
}
error->sourceURL.Assign((PRUnichar*)XML_GetBase(mExpatParser));
if (!aIsFinal) {
PRInt32 byteIndexRelativeToFile = 0;
byteIndexRelativeToFile = XML_GetCurrentByteIndex(mExpatParser);
GetLine(aBuffer, aLength, (byteIndexRelativeToFile - mBytesParsed), error->sourceLine);
}
else {
error->sourceLine.Append(mLastLine);
}
errorToken->SetError(error);
/* Add the error token */
CToken* newToken = (CToken*) errorToken;
AddToken(newToken, NS_OK, mState->tokenDeque, mState->tokenAllocator);
/* Add the error message tokens */
AddErrorMessageTokens(error);
if (!error || !errorToken) {
delete error;
IF_FREE(errorToken,mState->tokenAllocator);
return NS_ERROR_OUT_OF_MEMORY;
}
return rv;
/* Fill in the values of the error token */
error->code = XML_GetErrorCode(mExpatParser);
error->lineNumber = XML_GetCurrentLineNumber(mExpatParser);
// Adjust the column number so that it is one based rather than zero based.
error->colNumber = XML_GetCurrentColumnNumber(mExpatParser) + 1;
NS_WARN_IF_FALSE(error->code >= 1, "unexpected XML error code");
// Map Expat error code to an error string
nsAutoString errorMsg;
// XXX Deal with error returns.
nsParserMsgUtils::GetLocalizedStringByID(XMLPARSER_PROPERTIES,error->code,errorMsg);
if (error->code==XML_ERROR_TAG_MISMATCH) {
/*
* Certain things can be assumed about the token stream because of
* the way expat behaves. eg:
*
* - data:text/xml,</foo> is NOT WELL-FORMED
* - data:text/xml,<foo></bar> is a TAG_MISMATCH.
*
* We can assume that there is at least one extra open tag (the one we
* want), so balance is initially set to one.
*
* Then loop through the tokens:
* - Each time we see eToken_end (</tag>) increment balance, because
* that means there is another pair of tags we don't care about.
* - Each time we see eToken_start (<tag>) decrement balance because it
* matches a close tag (perhaps the MISMATCHed tag in which case
* balance should hit 0).
* - If balance ever hits zero, exit the loop. Because of the way
* balance is adjusted, if balance is zero expected *must* be a start
* tag.
*
* We must check expected in the condition in case expat or nsDeque go
* crazy and give us 0 (null) before balance reaches 0.
*/
nsDequeIterator current = mState->tokenDeque->End();
CToken *expected = NS_STATIC_CAST(CToken*,--current);
PRUint32 balance = 1;
while (expected) {
switch (expected->GetTokenType()) {
case eToken_start:
--balance;
break;
case eToken_end:
++balance;
break;
default:
break; // we don't care about newlines or other tokens
}
if (!balance) {
// if balance is zero, this must be a start tag
CStartToken *startToken=NS_STATIC_CAST(CStartToken*,expected);
nsAutoString expectedMsg;
nsParserMsgUtils::GetLocalizedStringByName(XMLPARSER_PROPERTIES,"Expected",expectedMsg);
// . Expected: </%S>.
PRUnichar *message = nsTextFormatter::smprintf(expectedMsg.get(),nsAutoString(startToken->GetStringValue()).get());
if (!message) {
delete error;
IF_FREE(errorToken,mState->tokenAllocator);
return NS_ERROR_OUT_OF_MEMORY;
}
errorMsg.Append(message);
nsTextFormatter::smprintf_free(message);
break;
}
expected = NS_STATIC_CAST(CToken*,--current);
}
}
error->description.Assign(errorMsg);
error->sourceURL.Assign((PRUnichar*)XML_GetBase(mExpatParser));
if (!aIsFinal) {
PRInt32 byteIndexRelativeToFile = 0;
byteIndexRelativeToFile = XML_GetCurrentByteIndex(mExpatParser);
GetLine(aBuffer, aLength, (byteIndexRelativeToFile - mBytesParsed), error->sourceLine);
}
else {
error->sourceLine.Append(mLastLine);
}
errorToken->SetError(error);
/* Add the error token */
CToken* newToken = (CToken*) errorToken;
AddToken(newToken, NS_OK, mState->tokenDeque, mState->tokenAllocator);
/* Add the error message tokens */
AddErrorMessageTokens(error);
return NS_OK;
}
nsresult nsExpatTokenizer::ParseXMLBuffer(const char* aBuffer, PRUint32 aLength, PRBool aIsFinal)

Просмотреть файл

@ -0,0 +1,104 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsIServiceManager.h"
#include "nsIIOService.h"
#include "nsIURI.h"
#include "nsIStringBundle.h"
#include "nsITextContent.h"
#include "nsISupportsArray.h"
#include "nsXPIDLString.h"
#include "nsParserMsgUtils.h"
#include "nsNetCID.h"
static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
static NS_DEFINE_CID(kStringBundleServiceCID, NS_STRINGBUNDLESERVICE_CID);
// This code is derived from nsFormControlHelper::GetLocalizedString()
static nsresult GetBundle(const char * aPropFileName, nsIStringBundle **aBundle)
{
NS_ENSURE_ARG_POINTER(aPropFileName);
NS_ENSURE_ARG_POINTER(aBundle);
// Create a URL for the string resource file
// Create a bundle for the localization
nsresult rv;
nsCOMPtr<nsIIOService> pNetService(do_GetService(kIOServiceCID, &rv));
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsIURI> uri;
rv = pNetService->NewURI(aPropFileName, nsnull, getter_AddRefs(uri));
if (NS_SUCCEEDED(rv)) {
// Create bundle
nsCOMPtr<nsIStringBundleService> stringService =
do_GetService(kStringBundleServiceCID, &rv);
if (NS_SUCCEEDED(rv)) {
nsXPIDLCString spec;
rv = uri->GetSpec(getter_Copies(spec));
if (NS_SUCCEEDED(rv) && spec) {
rv = stringService->CreateBundle(spec, aBundle);
}
}
}
}
return rv;
}
nsresult
nsParserMsgUtils::GetLocalizedStringByName(const char * aPropFileName, const char* aKey, nsString& oVal)
{
oVal.Truncate();
NS_ENSURE_ARG_POINTER(aKey);
nsCOMPtr<nsIStringBundle> bundle;
nsresult rv = GetBundle(aPropFileName,getter_AddRefs(bundle));
if (NS_SUCCEEDED(rv) && bundle) {
nsXPIDLString valUni;
nsAutoString key; key.AssignWithConversion(aKey);
rv = bundle->GetStringFromName(key.get(), getter_Copies(valUni));
if (NS_SUCCEEDED(rv) && valUni) {
oVal.Assign(valUni);
}
}
return rv;
}
nsresult
nsParserMsgUtils::GetLocalizedStringByID(const char * aPropFileName, PRUint32 aID, nsString& oVal)
{
oVal.Truncate();
nsCOMPtr<nsIStringBundle> bundle;
nsresult rv = GetBundle(aPropFileName,getter_AddRefs(bundle));
if (NS_SUCCEEDED(rv) && bundle) {
nsXPIDLString valUni;
rv = bundle->GetStringFromID(aID, getter_Copies(valUni));
if (NS_SUCCEEDED(rv) && valUni) {
oVal.Assign(valUni);
}
}
return rv;
}

Просмотреть файл

@ -0,0 +1,38 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsParserMsgUtils_h
#define nsParserMsgUtils_h
#include "nsString.h"
#define XMLPARSER_PROPERTIES "chrome://communicator/locale/layout/xmlparser.properties"
class nsParserMsgUtils {
nsParserMsgUtils(); // Currently this is not meant to be created, use the static methods
~nsParserMsgUtils(); // If perf required, change this to cache values etc.
public:
static nsresult GetLocalizedStringByName(const char * aPropFileName, const char* aKey, nsString& aVal);
static nsresult GetLocalizedStringByID(const char * aPropFileName, PRUint32 aID, nsString& aVal);
};
#endif

Просмотреть файл

@ -0,0 +1,53 @@
# The contents of this file are subject to the Netscape Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/NPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 2001 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
#
# Map Expat error codes to error strings
1 = out of memory
2 = syntax error
3 = no element found
4 = not well-formed
5 = unclosed token
6 = unclosed token
7 = mismatched tag
8 = duplicate attribute
9 = junk after document element
10 = illegal parameter entity reference
11 = undefined entity
12 = recursive entity reference
13 = asynchronous entity
14 = reference to invalid character number
15 = reference to binary entity
16 = reference to external entity in attribute
17 = xml processing instruction not at start of external entity
18 = unknown encoding
19 = encoding specified in XML declaration is incorrect
20 = unclosed CDATA section
21 = error in processing external entity reference
22 = document is not standalone
# %1$S is replaced by the Expat error string, may be followed by Expected (see below)
# %2$S is replaced by URL
# %3$d is replaced by line number
# %4$d is replaced by column number
XMLParsingError = XML Parsing Error: %1$S\nLocation: %2$S\nLine Number %3$d, Column %4$d:
# %S is replaced by a tag name.
# This gets appended to the error string if the error is mismatched tag.
Expected = . Expected: </%S>.

Двоичные данные
parser/htmlparser/macbuild/htmlparser.mcp

Двоичный файл не отображается.

Просмотреть файл

@ -0,0 +1 @@
xmlparse.properties

Просмотреть файл

@ -61,6 +61,7 @@ CPPSRCS = \
nsToken.cpp \
nsWellFormedDTD.cpp \
nsViewSourceHTML.cpp\
nsParserMsgUtils.cpp\
$(NULL)
ifndef MOZ_DISABLE_DTD_DEBUG

Просмотреть файл

Просмотреть файл

@ -48,6 +48,7 @@ CPPSRCS = \
nsWellFormedDTD.cpp \
nsViewSourceHTML.cpp\
nsParserModule.cpp \
nsParserMsgUtils.cpp \
!if !defined(MOZ_DISABLE_DTD_DEBUG)
nsLoggingSink.cpp \
nsHTMLNullSink.cpp \
@ -72,6 +73,7 @@ CPP_OBJS = \
.\$(OBJDIR)\nsWellFormedDTD.obj \
.\$(OBJDIR)\nsViewSourceHTML.obj\
.\$(OBJDIR)\nsParserModule.obj \
.\$(OBJDIR)\nsParserMsgUtils.obj \
!if !defined(MOZ_DISABLE_DTD_DEBUG)
.\$(OBJDIR)\nsLoggingSink.obj \
.\$(OBJDIR)\nsHTMLNullSink.obj \

Просмотреть файл

@ -42,6 +42,9 @@
#include "nsSpecialSystemDirectory.h"
#include "nsIURL.h"
#include "nsParserMsgUtils.h"
#include "nsTextFormatter.h"
typedef struct _XMLParserState {
XML_Parser parser;
nsScanner* scanner;
@ -278,21 +281,24 @@ void nsExpatTokenizer::GetLine(const char* aSourceBuffer, PRUint32 aLength,
}
}
static nsresult
CreateErrorText(const nsParserError* aError, nsString& aErrorString)
{
aErrorString.AssignWithConversion("XML Parsing Error: ");
aErrorString.Truncate();
if (aError) {
aErrorString.Append(aError->description);
aErrorString.AppendWithConversion("\nLocation: ");
aErrorString.Append(aError->sourceURL);
aErrorString.AppendWithConversion("\nLine Number ");
aErrorString.AppendInt(aError->lineNumber, 10);
aErrorString.AppendWithConversion(", Column ");
aErrorString.AppendInt(aError->colNumber, 10);
aErrorString.AppendWithConversion(":");
nsAutoString msg;
nsresult rv = nsParserMsgUtils::GetLocalizedStringByName(XMLPARSER_PROPERTIES,"XMLParsingError",msg);
if (NS_FAILED(rv))
return rv;
// XML Parsing Error: %1$S\nLocation: %2$S\nLine Number %3$d, Column %4$d:
PRUnichar *message = nsTextFormatter::smprintf(msg.get(),aError->description.get(),aError->sourceURL.get(),aError->lineNumber,aError->colNumber);
if (!message) {
return NS_ERROR_OUT_OF_MEMORY;
}
aErrorString.Assign(message);
nsTextFormatter::smprintf_free(message);
}
return NS_OK;
@ -379,89 +385,109 @@ nsExpatTokenizer::PushXMLErrorTokens(const char *aBuffer, PRUint32 aLength, PRBo
{
CErrorToken* errorToken= (CErrorToken *) mState->tokenAllocator->CreateTokenOfType(eToken_error, eHTMLTag_unknown);
nsParserError *error = new nsParserError;
nsresult rv = NS_OK;
if (error && errorToken) {
/* Fill in the values of the error token */
error->code = XML_GetErrorCode(mExpatParser);
error->lineNumber = XML_GetCurrentLineNumber(mExpatParser);
// Adjust the column number so that it is one based rather than zero based.
error->colNumber = XML_GetCurrentColumnNumber(mExpatParser) + 1;
error->description.AssignWithConversion(XML_ErrorString(error->code));
if (error->code==XML_ERROR_TAG_MISMATCH){
/*
* Certain things can be assumed about the token stream because of
* the way expat behaves. eg:
*
* - data:text/xml,</foo> is NOT WELL-FORMED
* - data:text/xml,<foo></bar> is a TAG_MISMATCH.
*
* We can assume that there is at least one extra open tag (the one we
* want), so balance is initially set to one.
*
* Then loop through the tokens:
* - Each time we see eToken_end (</tag>) increment balance, because
* that means there is another pair of tags we don't care about.
* - Each time we see eToken_start (<tag>) decrement balance because it
* matches a close tag (perhaps the MISMATCHed tag in which case
* balance should hit 0).
* - If balance ever hits zero, exit the loop. Because of the way
* balance is adjusted, if balance is zero expected *must* be a start
* tag.
*
* We must check expected in the condition in case expat or nsDeque go
* crazy and give us 0 (null) before balance reaches 0.
*/
nsDequeIterator current = mState->tokenDeque->End();
CToken *expected = NS_STATIC_CAST(CToken*,--current);
PRUint32 balance = 1;
while (expected) {
switch (expected->GetTokenType()) {
case eToken_start:
--balance;
break;
case eToken_end:
++balance;
break;
default:
break; // we don't care about newlines or other tokens
}
if (!balance) {
// if balance is zero, this must be a start tag
CStartToken *startToken=NS_STATIC_CAST(CStartToken*,expected);
error->description.Append(NS_LITERAL_STRING(". Expected: </"));
error->description.Append(startToken->GetStringValue());
error->description.Append(NS_LITERAL_STRING(">"));
break;
}
expected = NS_STATIC_CAST(CToken*,--current);
}
}
error->sourceURL.Assign((PRUnichar*)XML_GetBase(mExpatParser));
if (!aIsFinal) {
PRInt32 byteIndexRelativeToFile = 0;
byteIndexRelativeToFile = XML_GetCurrentByteIndex(mExpatParser);
GetLine(aBuffer, aLength, (byteIndexRelativeToFile - mBytesParsed), error->sourceLine);
}
else {
error->sourceLine.Append(mLastLine);
}
errorToken->SetError(error);
/* Add the error token */
CToken* newToken = (CToken*) errorToken;
AddToken(newToken, NS_OK, mState->tokenDeque, mState->tokenAllocator);
/* Add the error message tokens */
AddErrorMessageTokens(error);
if (!error || !errorToken) {
delete error;
IF_FREE(errorToken,mState->tokenAllocator);
return NS_ERROR_OUT_OF_MEMORY;
}
return rv;
/* Fill in the values of the error token */
error->code = XML_GetErrorCode(mExpatParser);
error->lineNumber = XML_GetCurrentLineNumber(mExpatParser);
// Adjust the column number so that it is one based rather than zero based.
error->colNumber = XML_GetCurrentColumnNumber(mExpatParser) + 1;
NS_WARN_IF_FALSE(error->code >= 1, "unexpected XML error code");
// Map Expat error code to an error string
nsAutoString errorMsg;
// XXX Deal with error returns.
nsParserMsgUtils::GetLocalizedStringByID(XMLPARSER_PROPERTIES,error->code,errorMsg);
if (error->code==XML_ERROR_TAG_MISMATCH) {
/*
* Certain things can be assumed about the token stream because of
* the way expat behaves. eg:
*
* - data:text/xml,</foo> is NOT WELL-FORMED
* - data:text/xml,<foo></bar> is a TAG_MISMATCH.
*
* We can assume that there is at least one extra open tag (the one we
* want), so balance is initially set to one.
*
* Then loop through the tokens:
* - Each time we see eToken_end (</tag>) increment balance, because
* that means there is another pair of tags we don't care about.
* - Each time we see eToken_start (<tag>) decrement balance because it
* matches a close tag (perhaps the MISMATCHed tag in which case
* balance should hit 0).
* - If balance ever hits zero, exit the loop. Because of the way
* balance is adjusted, if balance is zero expected *must* be a start
* tag.
*
* We must check expected in the condition in case expat or nsDeque go
* crazy and give us 0 (null) before balance reaches 0.
*/
nsDequeIterator current = mState->tokenDeque->End();
CToken *expected = NS_STATIC_CAST(CToken*,--current);
PRUint32 balance = 1;
while (expected) {
switch (expected->GetTokenType()) {
case eToken_start:
--balance;
break;
case eToken_end:
++balance;
break;
default:
break; // we don't care about newlines or other tokens
}
if (!balance) {
// if balance is zero, this must be a start tag
CStartToken *startToken=NS_STATIC_CAST(CStartToken*,expected);
nsAutoString expectedMsg;
nsParserMsgUtils::GetLocalizedStringByName(XMLPARSER_PROPERTIES,"Expected",expectedMsg);
// . Expected: </%S>.
PRUnichar *message = nsTextFormatter::smprintf(expectedMsg.get(),nsAutoString(startToken->GetStringValue()).get());
if (!message) {
delete error;
IF_FREE(errorToken,mState->tokenAllocator);
return NS_ERROR_OUT_OF_MEMORY;
}
errorMsg.Append(message);
nsTextFormatter::smprintf_free(message);
break;
}
expected = NS_STATIC_CAST(CToken*,--current);
}
}
error->description.Assign(errorMsg);
error->sourceURL.Assign((PRUnichar*)XML_GetBase(mExpatParser));
if (!aIsFinal) {
PRInt32 byteIndexRelativeToFile = 0;
byteIndexRelativeToFile = XML_GetCurrentByteIndex(mExpatParser);
GetLine(aBuffer, aLength, (byteIndexRelativeToFile - mBytesParsed), error->sourceLine);
}
else {
error->sourceLine.Append(mLastLine);
}
errorToken->SetError(error);
/* Add the error token */
CToken* newToken = (CToken*) errorToken;
AddToken(newToken, NS_OK, mState->tokenDeque, mState->tokenAllocator);
/* Add the error message tokens */
AddErrorMessageTokens(error);
return NS_OK;
}
nsresult nsExpatTokenizer::ParseXMLBuffer(const char* aBuffer, PRUint32 aLength, PRBool aIsFinal)

Просмотреть файл

@ -0,0 +1,104 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsIServiceManager.h"
#include "nsIIOService.h"
#include "nsIURI.h"
#include "nsIStringBundle.h"
#include "nsITextContent.h"
#include "nsISupportsArray.h"
#include "nsXPIDLString.h"
#include "nsParserMsgUtils.h"
#include "nsNetCID.h"
static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
static NS_DEFINE_CID(kStringBundleServiceCID, NS_STRINGBUNDLESERVICE_CID);
// This code is derived from nsFormControlHelper::GetLocalizedString()
static nsresult GetBundle(const char * aPropFileName, nsIStringBundle **aBundle)
{
NS_ENSURE_ARG_POINTER(aPropFileName);
NS_ENSURE_ARG_POINTER(aBundle);
// Create a URL for the string resource file
// Create a bundle for the localization
nsresult rv;
nsCOMPtr<nsIIOService> pNetService(do_GetService(kIOServiceCID, &rv));
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsIURI> uri;
rv = pNetService->NewURI(aPropFileName, nsnull, getter_AddRefs(uri));
if (NS_SUCCEEDED(rv)) {
// Create bundle
nsCOMPtr<nsIStringBundleService> stringService =
do_GetService(kStringBundleServiceCID, &rv);
if (NS_SUCCEEDED(rv)) {
nsXPIDLCString spec;
rv = uri->GetSpec(getter_Copies(spec));
if (NS_SUCCEEDED(rv) && spec) {
rv = stringService->CreateBundle(spec, aBundle);
}
}
}
}
return rv;
}
nsresult
nsParserMsgUtils::GetLocalizedStringByName(const char * aPropFileName, const char* aKey, nsString& oVal)
{
oVal.Truncate();
NS_ENSURE_ARG_POINTER(aKey);
nsCOMPtr<nsIStringBundle> bundle;
nsresult rv = GetBundle(aPropFileName,getter_AddRefs(bundle));
if (NS_SUCCEEDED(rv) && bundle) {
nsXPIDLString valUni;
nsAutoString key; key.AssignWithConversion(aKey);
rv = bundle->GetStringFromName(key.get(), getter_Copies(valUni));
if (NS_SUCCEEDED(rv) && valUni) {
oVal.Assign(valUni);
}
}
return rv;
}
nsresult
nsParserMsgUtils::GetLocalizedStringByID(const char * aPropFileName, PRUint32 aID, nsString& oVal)
{
oVal.Truncate();
nsCOMPtr<nsIStringBundle> bundle;
nsresult rv = GetBundle(aPropFileName,getter_AddRefs(bundle));
if (NS_SUCCEEDED(rv) && bundle) {
nsXPIDLString valUni;
rv = bundle->GetStringFromID(aID, getter_Copies(valUni));
if (NS_SUCCEEDED(rv) && valUni) {
oVal.Assign(valUni);
}
}
return rv;
}

Просмотреть файл

@ -0,0 +1,38 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsParserMsgUtils_h
#define nsParserMsgUtils_h
#include "nsString.h"
#define XMLPARSER_PROPERTIES "chrome://communicator/locale/layout/xmlparser.properties"
class nsParserMsgUtils {
nsParserMsgUtils(); // Currently this is not meant to be created, use the static methods
~nsParserMsgUtils(); // If perf required, change this to cache values etc.
public:
static nsresult GetLocalizedStringByName(const char * aPropFileName, const char* aKey, nsString& aVal);
static nsresult GetLocalizedStringByID(const char * aPropFileName, PRUint32 aID, nsString& aVal);
};
#endif

Просмотреть файл

@ -0,0 +1,53 @@
# The contents of this file are subject to the Netscape Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/NPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 2001 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
#
# Map Expat error codes to error strings
1 = out of memory
2 = syntax error
3 = no element found
4 = not well-formed
5 = unclosed token
6 = unclosed token
7 = mismatched tag
8 = duplicate attribute
9 = junk after document element
10 = illegal parameter entity reference
11 = undefined entity
12 = recursive entity reference
13 = asynchronous entity
14 = reference to invalid character number
15 = reference to binary entity
16 = reference to external entity in attribute
17 = xml processing instruction not at start of external entity
18 = unknown encoding
19 = encoding specified in XML declaration is incorrect
20 = unclosed CDATA section
21 = error in processing external entity reference
22 = document is not standalone
# %1$S is replaced by the Expat error string, may be followed by Expected (see below)
# %2$S is replaced by URL
# %3$d is replaced by line number
# %4$d is replaced by column number
XMLParsingError = XML Parsing Error: %1$S\nLocation: %2$S\nLine Number %3$d, Column %4$d:
# %S is replaced by a tag name.
# This gets appended to the error string if the error is mismatched tag.
Expected = . Expected: </%S>.