diff --git a/mozilla/htmlparser/src/nsExpatTokenizer.cpp b/mozilla/htmlparser/src/nsExpatTokenizer.cpp
index 973c98d87f4..bf303f40da8 100644
--- a/mozilla/htmlparser/src/nsExpatTokenizer.cpp
+++ b/mozilla/htmlparser/src/nsExpatTokenizer.cpp
@@ -30,6 +30,7 @@
// #include "nsParser.h"
#include "nsIParser.h"
#include "prlog.h"
+#include
/************************************************************************
@@ -154,22 +155,69 @@ nsExpatTokenizer::~nsExpatTokenizer(){
Here begins the real working methods for the tokenizer.
*******************************************************************/
-/* Called immediately after an error has occurred in expat. Creates
- an error token and pushes it onto the token queue.
-*/
-void nsExpatTokenizer::PushXMLErrorToken(void)
+
+static void SetErrorContextInfo(nsParserError* aError, PRUint32 aByteIndex,
+ const char* aSourceBuffer, PRUint32 aLength)
+{
+ /* Figure out the substring inside aSourceBuffer that contains the line on which the error
+ occurred. Copy the line into error->sourceLine */
+ PR_ASSERT(aByteIndex > 0 && aByteIndex < aLength);
+ char* start = (char* ) &aSourceBuffer[aByteIndex]; /* Will try to find the start of the line */
+ char* end = (char* ) &aSourceBuffer[aByteIndex]; /* Will try to find the end of the line */
+ PRUint32 startIndex = aByteIndex; /* Track the position of the 'start' pointer into the buffer */
+ PRUint32 endIndex = aByteIndex; /* Track the position of the 'end' pointer into the buffer */
+ PRBool reachedStart;
+ PRBool reachedEnd;
+
+ /* Use start to find the first new line before the error position and
+ end to find the first new line after the error position */
+ reachedStart = ('\n' == *start || '\r' == *start || startIndex <= 0);
+ reachedEnd = ('\n' == *end || '\r' == *end || endIndex >= aLength);
+ while (!reachedStart || !reachedEnd) {
+ if (!reachedStart) {
+ start--;
+ startIndex--;
+ }
+ if (!reachedEnd) {
+ end++;
+ endIndex++;
+ }
+ reachedStart = ('\n' == *start || '\r' == *start || startIndex <= 0);
+ reachedEnd = ('\n' == *end || '\r' == *end || endIndex >= aLength);
+ }
+
+ if (startIndex == endIndex) {
+ /* Special case if the error is on a line where the only character is a newline */
+ aError->sourceLine.Append("");
+ }
+ else {
+ PR_ASSERT(endIndex - startIndex >= 2);
+
+ /* At this point, the substring starting at (startIndex + 1) and ending at (endIndex - 1),
+ is the line on which the error occurred. Copy that substring into the error structure. */
+ char* tempLine = new char[endIndex - startIndex];
+ strncpy(tempLine, &aSourceBuffer[startIndex + 1], (endIndex - 1) - startIndex);
+ tempLine[endIndex - startIndex - 1] = '\0';
+ aError->sourceLine.Append(tempLine);
+ delete [] tempLine;
+ }
+}
+
+/*
+ * Called immediately after an error has occurred in expat. Creates
+ * an error token and pushes it onto the token queue.
+ *
+ */
+void nsExpatTokenizer::PushXMLErrorToken(const char *aBuffer, PRUint32 aLength)
{
CErrorToken* token= (CErrorToken *) gTokenRecycler->CreateTokenOfType(eToken_error, eHTMLTag_unknown);
nsParserError *error = new nsParserError;
error->code = XML_GetErrorCode(mExpatParser);
error->lineNumber = XML_GetCurrentLineNumber(mExpatParser);
- error->colNumber = XML_GetCurrentColumnNumber(mExpatParser);
- // XXX Does the copy constructor of nsString free the passed in char *?
- error->description = XML_ErrorString(error->code);
- // XXX Not setting a source buffer and error offset for now
- error->offset = 0;
- error->sourceBuffer = "";
+ error->colNumber = XML_GetCurrentColumnNumber(mExpatParser);
+ error->description = XML_ErrorString(error->code);
+ SetErrorContextInfo(error, (PRUint32) XML_GetCurrentByteIndex(mExpatParser), aBuffer, aLength);
token->SetError(error);
@@ -182,7 +230,7 @@ nsresult nsExpatTokenizer::ParseXMLBuffer(const char *aBuffer, PRUint32 aLength)
if (mExpatParser) {
PR_ASSERT(aLength == strlen(aBuffer));
if (!XML_Parse(mExpatParser, aBuffer, aLength, PR_FALSE)) {
- PushXMLErrorToken();
+ PushXMLErrorToken(aBuffer, aLength);
}
}
else {
diff --git a/mozilla/htmlparser/src/nsExpatTokenizer.h b/mozilla/htmlparser/src/nsExpatTokenizer.h
index 428b6026468..e9d8d67b8a3 100644
--- a/mozilla/htmlparser/src/nsExpatTokenizer.h
+++ b/mozilla/htmlparser/src/nsExpatTokenizer.h
@@ -70,7 +70,7 @@ protected:
*/
void SetupExpatCallbacks(void);
- void PushXMLErrorToken(void);
+ void PushXMLErrorToken(const char *aBuffer, PRUint32 aLength);
/* The callback handlers that get called from the expat parser */
static void HandleStartElement(void *userData, const XML_Char *name, const XML_Char **atts);
diff --git a/mozilla/htmlparser/src/nsHTMLTags.cpp b/mozilla/htmlparser/src/nsHTMLTags.cpp
index bfb9ab3b219..504bbe0ca53 100644
--- a/mozilla/htmlparser/src/nsHTMLTags.cpp
+++ b/mozilla/htmlparser/src/nsHTMLTags.cpp
@@ -31,10 +31,10 @@ static char* tagTable[] = {
"kbd", "keygen", "label", "layer", "legend", "li", "link", "listing",
"map", "menu", "meta", "multicol", "nobr", "noembed", "noframes",
"nolayer", "noscript", "object", "ol", "optgroup", "option", "p", "param",
- "plaintext", "pre", "q", "s", "samp", "script", "select", "server",
- "small", "sound", "spacer", "span", "strike", "strong", "style", "sub",
- "sup", "table", "tbody", "td", "textarea", "tfoot", "th", "thead", "title",
- "tr", "tt", "u", "ul", "var", "wbr", "xmp"
+ "parsererror", "plaintext", "pre", "q", "s", "samp", "script", "select",
+ "server", "small", "sound", "sourcetext", "spacer", "span", "strike",
+ "strong", "style", "sub", "sup", "table", "tbody", "td", "textarea",
+ "tfoot", "th", "thead", "title", "tr", "tt", "u", "ul", "var", "wbr", "xmp"
};
nsHTMLTag NS_TagToEnum(const char* aTagName) {
diff --git a/mozilla/htmlparser/src/nsHTMLTags.h b/mozilla/htmlparser/src/nsHTMLTags.h
index a2209558c97..6e5e4195b44 100644
--- a/mozilla/htmlparser/src/nsHTMLTags.h
+++ b/mozilla/htmlparser/src/nsHTMLTags.h
@@ -46,24 +46,25 @@ enum nsHTMLTag {
eHTMLTag_nobr=66, eHTMLTag_noembed=67, eHTMLTag_noframes=68,
eHTMLTag_nolayer=69, eHTMLTag_noscript=70, eHTMLTag_object=71,
eHTMLTag_ol=72, eHTMLTag_optgroup=73, eHTMLTag_option=74, eHTMLTag_p=75,
- eHTMLTag_param=76, eHTMLTag_plaintext=77, eHTMLTag_pre=78, eHTMLTag_q=79,
- eHTMLTag_s=80, eHTMLTag_samp=81, eHTMLTag_script=82, eHTMLTag_select=83,
- eHTMLTag_server=84, eHTMLTag_small=85, eHTMLTag_sound=86,
- eHTMLTag_spacer=87, eHTMLTag_span=88, eHTMLTag_strike=89,
- eHTMLTag_strong=90, eHTMLTag_style=91, eHTMLTag_sub=92, eHTMLTag_sup=93,
- eHTMLTag_table=94, eHTMLTag_tbody=95, eHTMLTag_td=96, eHTMLTag_textarea=97,
- eHTMLTag_tfoot=98, eHTMLTag_th=99, eHTMLTag_thead=100, eHTMLTag_title=101,
- eHTMLTag_tr=102, eHTMLTag_tt=103, eHTMLTag_u=104, eHTMLTag_ul=105,
- eHTMLTag_var=106, eHTMLTag_wbr=107, eHTMLTag_xmp=108,
+ eHTMLTag_param=76, eHTMLTag_parsererror=77, eHTMLTag_plaintext=78,
+ eHTMLTag_pre=79, eHTMLTag_q=80, eHTMLTag_s=81, eHTMLTag_samp=82,
+ eHTMLTag_script=83, eHTMLTag_select=84, eHTMLTag_server=85,
+ eHTMLTag_small=86, eHTMLTag_sound=87, eHTMLTag_sourcetext=88,
+ eHTMLTag_spacer=89, eHTMLTag_span=90, eHTMLTag_strike=91,
+ eHTMLTag_strong=92, eHTMLTag_style=93, eHTMLTag_sub=94, eHTMLTag_sup=95,
+ eHTMLTag_table=96, eHTMLTag_tbody=97, eHTMLTag_td=98, eHTMLTag_textarea=99,
+ eHTMLTag_tfoot=100, eHTMLTag_th=101, eHTMLTag_thead=102,
+ eHTMLTag_title=103, eHTMLTag_tr=104, eHTMLTag_tt=105, eHTMLTag_u=106,
+ eHTMLTag_ul=107, eHTMLTag_var=108, eHTMLTag_wbr=109, eHTMLTag_xmp=110,
/* The remaining enums are not for tags */
- eHTMLTag_text=109, eHTMLTag_whitespace=110, eHTMLTag_newline=111,
- eHTMLTag_comment=112, eHTMLTag_entity=113, eHTMLTag_userdefined=114,
- eHTMLTag_secret_h1style=115, eHTMLTag_secret_h2style=116,
- eHTMLTag_secret_h3style=117, eHTMLTag_secret_h4style=118,
- eHTMLTag_secret_h5style=119, eHTMLTag_secret_h6style=120
+ eHTMLTag_text=111, eHTMLTag_whitespace=112, eHTMLTag_newline=113,
+ eHTMLTag_comment=114, eHTMLTag_entity=115, eHTMLTag_userdefined=116,
+ eHTMLTag_secret_h1style=117, eHTMLTag_secret_h2style=118,
+ eHTMLTag_secret_h3style=119, eHTMLTag_secret_h4style=120,
+ eHTMLTag_secret_h5style=121, eHTMLTag_secret_h6style=122
};
-#define NS_HTML_TAG_MAX 108
+#define NS_HTML_TAG_MAX 110
extern NS_HTMLPARS nsHTMLTag NS_TagToEnum(const char* aTag);
extern NS_HTMLPARS const char* NS_EnumToTag(nsHTMLTag aEnum);
diff --git a/mozilla/htmlparser/src/nsParserError.h b/mozilla/htmlparser/src/nsParserError.h
index f2cab09e790..7925f0dd623 100644
--- a/mozilla/htmlparser/src/nsParserError.h
+++ b/mozilla/htmlparser/src/nsParserError.h
@@ -35,9 +35,8 @@ typedef struct _nsParserError {
PRInt32 code;
PRInt32 lineNumber;
PRInt32 colNumber;
- nsString description;
- PRInt32 offset;
- nsString sourceBuffer;
+ nsString description;
+ nsString sourceLine;
} nsParserError;
#endif
diff --git a/mozilla/parser/htmlparser/src/nsExpatTokenizer.cpp b/mozilla/parser/htmlparser/src/nsExpatTokenizer.cpp
index 973c98d87f4..bf303f40da8 100644
--- a/mozilla/parser/htmlparser/src/nsExpatTokenizer.cpp
+++ b/mozilla/parser/htmlparser/src/nsExpatTokenizer.cpp
@@ -30,6 +30,7 @@
// #include "nsParser.h"
#include "nsIParser.h"
#include "prlog.h"
+#include
/************************************************************************
@@ -154,22 +155,69 @@ nsExpatTokenizer::~nsExpatTokenizer(){
Here begins the real working methods for the tokenizer.
*******************************************************************/
-/* Called immediately after an error has occurred in expat. Creates
- an error token and pushes it onto the token queue.
-*/
-void nsExpatTokenizer::PushXMLErrorToken(void)
+
+static void SetErrorContextInfo(nsParserError* aError, PRUint32 aByteIndex,
+ const char* aSourceBuffer, PRUint32 aLength)
+{
+ /* Figure out the substring inside aSourceBuffer that contains the line on which the error
+ occurred. Copy the line into error->sourceLine */
+ PR_ASSERT(aByteIndex > 0 && aByteIndex < aLength);
+ char* start = (char* ) &aSourceBuffer[aByteIndex]; /* Will try to find the start of the line */
+ char* end = (char* ) &aSourceBuffer[aByteIndex]; /* Will try to find the end of the line */
+ PRUint32 startIndex = aByteIndex; /* Track the position of the 'start' pointer into the buffer */
+ PRUint32 endIndex = aByteIndex; /* Track the position of the 'end' pointer into the buffer */
+ PRBool reachedStart;
+ PRBool reachedEnd;
+
+ /* Use start to find the first new line before the error position and
+ end to find the first new line after the error position */
+ reachedStart = ('\n' == *start || '\r' == *start || startIndex <= 0);
+ reachedEnd = ('\n' == *end || '\r' == *end || endIndex >= aLength);
+ while (!reachedStart || !reachedEnd) {
+ if (!reachedStart) {
+ start--;
+ startIndex--;
+ }
+ if (!reachedEnd) {
+ end++;
+ endIndex++;
+ }
+ reachedStart = ('\n' == *start || '\r' == *start || startIndex <= 0);
+ reachedEnd = ('\n' == *end || '\r' == *end || endIndex >= aLength);
+ }
+
+ if (startIndex == endIndex) {
+ /* Special case if the error is on a line where the only character is a newline */
+ aError->sourceLine.Append("");
+ }
+ else {
+ PR_ASSERT(endIndex - startIndex >= 2);
+
+ /* At this point, the substring starting at (startIndex + 1) and ending at (endIndex - 1),
+ is the line on which the error occurred. Copy that substring into the error structure. */
+ char* tempLine = new char[endIndex - startIndex];
+ strncpy(tempLine, &aSourceBuffer[startIndex + 1], (endIndex - 1) - startIndex);
+ tempLine[endIndex - startIndex - 1] = '\0';
+ aError->sourceLine.Append(tempLine);
+ delete [] tempLine;
+ }
+}
+
+/*
+ * Called immediately after an error has occurred in expat. Creates
+ * an error token and pushes it onto the token queue.
+ *
+ */
+void nsExpatTokenizer::PushXMLErrorToken(const char *aBuffer, PRUint32 aLength)
{
CErrorToken* token= (CErrorToken *) gTokenRecycler->CreateTokenOfType(eToken_error, eHTMLTag_unknown);
nsParserError *error = new nsParserError;
error->code = XML_GetErrorCode(mExpatParser);
error->lineNumber = XML_GetCurrentLineNumber(mExpatParser);
- error->colNumber = XML_GetCurrentColumnNumber(mExpatParser);
- // XXX Does the copy constructor of nsString free the passed in char *?
- error->description = XML_ErrorString(error->code);
- // XXX Not setting a source buffer and error offset for now
- error->offset = 0;
- error->sourceBuffer = "";
+ error->colNumber = XML_GetCurrentColumnNumber(mExpatParser);
+ error->description = XML_ErrorString(error->code);
+ SetErrorContextInfo(error, (PRUint32) XML_GetCurrentByteIndex(mExpatParser), aBuffer, aLength);
token->SetError(error);
@@ -182,7 +230,7 @@ nsresult nsExpatTokenizer::ParseXMLBuffer(const char *aBuffer, PRUint32 aLength)
if (mExpatParser) {
PR_ASSERT(aLength == strlen(aBuffer));
if (!XML_Parse(mExpatParser, aBuffer, aLength, PR_FALSE)) {
- PushXMLErrorToken();
+ PushXMLErrorToken(aBuffer, aLength);
}
}
else {
diff --git a/mozilla/parser/htmlparser/src/nsExpatTokenizer.h b/mozilla/parser/htmlparser/src/nsExpatTokenizer.h
index 428b6026468..e9d8d67b8a3 100644
--- a/mozilla/parser/htmlparser/src/nsExpatTokenizer.h
+++ b/mozilla/parser/htmlparser/src/nsExpatTokenizer.h
@@ -70,7 +70,7 @@ protected:
*/
void SetupExpatCallbacks(void);
- void PushXMLErrorToken(void);
+ void PushXMLErrorToken(const char *aBuffer, PRUint32 aLength);
/* The callback handlers that get called from the expat parser */
static void HandleStartElement(void *userData, const XML_Char *name, const XML_Char **atts);
diff --git a/mozilla/parser/htmlparser/src/nsHTMLTags.cpp b/mozilla/parser/htmlparser/src/nsHTMLTags.cpp
index bfb9ab3b219..504bbe0ca53 100644
--- a/mozilla/parser/htmlparser/src/nsHTMLTags.cpp
+++ b/mozilla/parser/htmlparser/src/nsHTMLTags.cpp
@@ -31,10 +31,10 @@ static char* tagTable[] = {
"kbd", "keygen", "label", "layer", "legend", "li", "link", "listing",
"map", "menu", "meta", "multicol", "nobr", "noembed", "noframes",
"nolayer", "noscript", "object", "ol", "optgroup", "option", "p", "param",
- "plaintext", "pre", "q", "s", "samp", "script", "select", "server",
- "small", "sound", "spacer", "span", "strike", "strong", "style", "sub",
- "sup", "table", "tbody", "td", "textarea", "tfoot", "th", "thead", "title",
- "tr", "tt", "u", "ul", "var", "wbr", "xmp"
+ "parsererror", "plaintext", "pre", "q", "s", "samp", "script", "select",
+ "server", "small", "sound", "sourcetext", "spacer", "span", "strike",
+ "strong", "style", "sub", "sup", "table", "tbody", "td", "textarea",
+ "tfoot", "th", "thead", "title", "tr", "tt", "u", "ul", "var", "wbr", "xmp"
};
nsHTMLTag NS_TagToEnum(const char* aTagName) {
diff --git a/mozilla/parser/htmlparser/src/nsHTMLTags.h b/mozilla/parser/htmlparser/src/nsHTMLTags.h
index a2209558c97..6e5e4195b44 100644
--- a/mozilla/parser/htmlparser/src/nsHTMLTags.h
+++ b/mozilla/parser/htmlparser/src/nsHTMLTags.h
@@ -46,24 +46,25 @@ enum nsHTMLTag {
eHTMLTag_nobr=66, eHTMLTag_noembed=67, eHTMLTag_noframes=68,
eHTMLTag_nolayer=69, eHTMLTag_noscript=70, eHTMLTag_object=71,
eHTMLTag_ol=72, eHTMLTag_optgroup=73, eHTMLTag_option=74, eHTMLTag_p=75,
- eHTMLTag_param=76, eHTMLTag_plaintext=77, eHTMLTag_pre=78, eHTMLTag_q=79,
- eHTMLTag_s=80, eHTMLTag_samp=81, eHTMLTag_script=82, eHTMLTag_select=83,
- eHTMLTag_server=84, eHTMLTag_small=85, eHTMLTag_sound=86,
- eHTMLTag_spacer=87, eHTMLTag_span=88, eHTMLTag_strike=89,
- eHTMLTag_strong=90, eHTMLTag_style=91, eHTMLTag_sub=92, eHTMLTag_sup=93,
- eHTMLTag_table=94, eHTMLTag_tbody=95, eHTMLTag_td=96, eHTMLTag_textarea=97,
- eHTMLTag_tfoot=98, eHTMLTag_th=99, eHTMLTag_thead=100, eHTMLTag_title=101,
- eHTMLTag_tr=102, eHTMLTag_tt=103, eHTMLTag_u=104, eHTMLTag_ul=105,
- eHTMLTag_var=106, eHTMLTag_wbr=107, eHTMLTag_xmp=108,
+ eHTMLTag_param=76, eHTMLTag_parsererror=77, eHTMLTag_plaintext=78,
+ eHTMLTag_pre=79, eHTMLTag_q=80, eHTMLTag_s=81, eHTMLTag_samp=82,
+ eHTMLTag_script=83, eHTMLTag_select=84, eHTMLTag_server=85,
+ eHTMLTag_small=86, eHTMLTag_sound=87, eHTMLTag_sourcetext=88,
+ eHTMLTag_spacer=89, eHTMLTag_span=90, eHTMLTag_strike=91,
+ eHTMLTag_strong=92, eHTMLTag_style=93, eHTMLTag_sub=94, eHTMLTag_sup=95,
+ eHTMLTag_table=96, eHTMLTag_tbody=97, eHTMLTag_td=98, eHTMLTag_textarea=99,
+ eHTMLTag_tfoot=100, eHTMLTag_th=101, eHTMLTag_thead=102,
+ eHTMLTag_title=103, eHTMLTag_tr=104, eHTMLTag_tt=105, eHTMLTag_u=106,
+ eHTMLTag_ul=107, eHTMLTag_var=108, eHTMLTag_wbr=109, eHTMLTag_xmp=110,
/* The remaining enums are not for tags */
- eHTMLTag_text=109, eHTMLTag_whitespace=110, eHTMLTag_newline=111,
- eHTMLTag_comment=112, eHTMLTag_entity=113, eHTMLTag_userdefined=114,
- eHTMLTag_secret_h1style=115, eHTMLTag_secret_h2style=116,
- eHTMLTag_secret_h3style=117, eHTMLTag_secret_h4style=118,
- eHTMLTag_secret_h5style=119, eHTMLTag_secret_h6style=120
+ eHTMLTag_text=111, eHTMLTag_whitespace=112, eHTMLTag_newline=113,
+ eHTMLTag_comment=114, eHTMLTag_entity=115, eHTMLTag_userdefined=116,
+ eHTMLTag_secret_h1style=117, eHTMLTag_secret_h2style=118,
+ eHTMLTag_secret_h3style=119, eHTMLTag_secret_h4style=120,
+ eHTMLTag_secret_h5style=121, eHTMLTag_secret_h6style=122
};
-#define NS_HTML_TAG_MAX 108
+#define NS_HTML_TAG_MAX 110
extern NS_HTMLPARS nsHTMLTag NS_TagToEnum(const char* aTag);
extern NS_HTMLPARS const char* NS_EnumToTag(nsHTMLTag aEnum);
diff --git a/mozilla/parser/htmlparser/src/nsParserError.h b/mozilla/parser/htmlparser/src/nsParserError.h
index f2cab09e790..7925f0dd623 100644
--- a/mozilla/parser/htmlparser/src/nsParserError.h
+++ b/mozilla/parser/htmlparser/src/nsParserError.h
@@ -35,9 +35,8 @@ typedef struct _nsParserError {
PRInt32 code;
PRInt32 lineNumber;
PRInt32 colNumber;
- nsString description;
- PRInt32 offset;
- nsString sourceBuffer;
+ nsString description;
+ nsString sourceLine;
} nsParserError;
#endif