зеркало из https://github.com/mozilla/pjs.git
Bug 15089, make XML parser error messages localizable. r=harishd,ftang, sr=jst.
This commit is contained in:
Родитель
233517873e
Коммит
9577ec2d01
|
@ -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
Двоичные данные
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>.
|
Двоичные данные
parser/htmlparser/macbuild/htmlparser.mcp
Двоичные данные
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>.
|
Загрузка…
Ссылка в новой задаче