xref: /aosp_15_r20/external/cronet/third_party/libxml/src/HTMLparser.c (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker /*
2*6777b538SAndroid Build Coastguard Worker  * HTMLparser.c : an HTML 4.0 non-verifying parser
3*6777b538SAndroid Build Coastguard Worker  *
4*6777b538SAndroid Build Coastguard Worker  * See Copyright for the status of this software.
5*6777b538SAndroid Build Coastguard Worker  *
6*6777b538SAndroid Build Coastguard Worker  * [email protected]
7*6777b538SAndroid Build Coastguard Worker  */
8*6777b538SAndroid Build Coastguard Worker 
9*6777b538SAndroid Build Coastguard Worker #define IN_LIBXML
10*6777b538SAndroid Build Coastguard Worker #include "libxml.h"
11*6777b538SAndroid Build Coastguard Worker #ifdef LIBXML_HTML_ENABLED
12*6777b538SAndroid Build Coastguard Worker 
13*6777b538SAndroid Build Coastguard Worker #include <string.h>
14*6777b538SAndroid Build Coastguard Worker #include <ctype.h>
15*6777b538SAndroid Build Coastguard Worker #include <stdlib.h>
16*6777b538SAndroid Build Coastguard Worker 
17*6777b538SAndroid Build Coastguard Worker #include <libxml/HTMLparser.h>
18*6777b538SAndroid Build Coastguard Worker #include <libxml/xmlmemory.h>
19*6777b538SAndroid Build Coastguard Worker #include <libxml/tree.h>
20*6777b538SAndroid Build Coastguard Worker #include <libxml/parser.h>
21*6777b538SAndroid Build Coastguard Worker #include <libxml/parserInternals.h>
22*6777b538SAndroid Build Coastguard Worker #include <libxml/xmlerror.h>
23*6777b538SAndroid Build Coastguard Worker #include <libxml/HTMLtree.h>
24*6777b538SAndroid Build Coastguard Worker #include <libxml/entities.h>
25*6777b538SAndroid Build Coastguard Worker #include <libxml/encoding.h>
26*6777b538SAndroid Build Coastguard Worker #include <libxml/xmlIO.h>
27*6777b538SAndroid Build Coastguard Worker #include <libxml/uri.h>
28*6777b538SAndroid Build Coastguard Worker 
29*6777b538SAndroid Build Coastguard Worker #include "private/buf.h"
30*6777b538SAndroid Build Coastguard Worker #include "private/enc.h"
31*6777b538SAndroid Build Coastguard Worker #include "private/error.h"
32*6777b538SAndroid Build Coastguard Worker #include "private/html.h"
33*6777b538SAndroid Build Coastguard Worker #include "private/io.h"
34*6777b538SAndroid Build Coastguard Worker #include "private/parser.h"
35*6777b538SAndroid Build Coastguard Worker #include "private/tree.h"
36*6777b538SAndroid Build Coastguard Worker 
37*6777b538SAndroid Build Coastguard Worker #define HTML_MAX_NAMELEN 1000
38*6777b538SAndroid Build Coastguard Worker #define HTML_PARSER_BIG_BUFFER_SIZE 1000
39*6777b538SAndroid Build Coastguard Worker #define HTML_PARSER_BUFFER_SIZE 100
40*6777b538SAndroid Build Coastguard Worker 
41*6777b538SAndroid Build Coastguard Worker static int htmlOmittedDefaultValue = 1;
42*6777b538SAndroid Build Coastguard Worker 
43*6777b538SAndroid Build Coastguard Worker xmlChar * htmlDecodeEntities(htmlParserCtxtPtr ctxt, int len,
44*6777b538SAndroid Build Coastguard Worker 			     xmlChar end, xmlChar  end2, xmlChar end3);
45*6777b538SAndroid Build Coastguard Worker static void htmlParseComment(htmlParserCtxtPtr ctxt);
46*6777b538SAndroid Build Coastguard Worker 
47*6777b538SAndroid Build Coastguard Worker /************************************************************************
48*6777b538SAndroid Build Coastguard Worker  *									*
49*6777b538SAndroid Build Coastguard Worker  *		Some factorized error routines				*
50*6777b538SAndroid Build Coastguard Worker  *									*
51*6777b538SAndroid Build Coastguard Worker  ************************************************************************/
52*6777b538SAndroid Build Coastguard Worker 
53*6777b538SAndroid Build Coastguard Worker /**
54*6777b538SAndroid Build Coastguard Worker  * htmlErrMemory:
55*6777b538SAndroid Build Coastguard Worker  * @ctxt:  an HTML parser context
56*6777b538SAndroid Build Coastguard Worker  * @extra:  extra information
57*6777b538SAndroid Build Coastguard Worker  *
58*6777b538SAndroid Build Coastguard Worker  * Handle a redefinition of attribute error
59*6777b538SAndroid Build Coastguard Worker  */
60*6777b538SAndroid Build Coastguard Worker static void
htmlErrMemory(xmlParserCtxtPtr ctxt)61*6777b538SAndroid Build Coastguard Worker htmlErrMemory(xmlParserCtxtPtr ctxt)
62*6777b538SAndroid Build Coastguard Worker {
63*6777b538SAndroid Build Coastguard Worker     xmlCtxtErrMemory(ctxt);
64*6777b538SAndroid Build Coastguard Worker }
65*6777b538SAndroid Build Coastguard Worker 
66*6777b538SAndroid Build Coastguard Worker /**
67*6777b538SAndroid Build Coastguard Worker  * htmlParseErr:
68*6777b538SAndroid Build Coastguard Worker  * @ctxt:  an HTML parser context
69*6777b538SAndroid Build Coastguard Worker  * @error:  the error number
70*6777b538SAndroid Build Coastguard Worker  * @msg:  the error message
71*6777b538SAndroid Build Coastguard Worker  * @str1:  string infor
72*6777b538SAndroid Build Coastguard Worker  * @str2:  string infor
73*6777b538SAndroid Build Coastguard Worker  *
74*6777b538SAndroid Build Coastguard Worker  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
75*6777b538SAndroid Build Coastguard Worker  */
76*6777b538SAndroid Build Coastguard Worker static void LIBXML_ATTR_FORMAT(3,0)
htmlParseErr(xmlParserCtxtPtr ctxt,xmlParserErrors error,const char * msg,const xmlChar * str1,const xmlChar * str2)77*6777b538SAndroid Build Coastguard Worker htmlParseErr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
78*6777b538SAndroid Build Coastguard Worker              const char *msg, const xmlChar *str1, const xmlChar *str2)
79*6777b538SAndroid Build Coastguard Worker {
80*6777b538SAndroid Build Coastguard Worker     xmlCtxtErr(ctxt, NULL, XML_FROM_HTML, error, XML_ERR_ERROR,
81*6777b538SAndroid Build Coastguard Worker                str1, str2, NULL, 0, msg, str1, str2);
82*6777b538SAndroid Build Coastguard Worker }
83*6777b538SAndroid Build Coastguard Worker 
84*6777b538SAndroid Build Coastguard Worker /**
85*6777b538SAndroid Build Coastguard Worker  * htmlParseErrInt:
86*6777b538SAndroid Build Coastguard Worker  * @ctxt:  an HTML parser context
87*6777b538SAndroid Build Coastguard Worker  * @error:  the error number
88*6777b538SAndroid Build Coastguard Worker  * @msg:  the error message
89*6777b538SAndroid Build Coastguard Worker  * @val:  integer info
90*6777b538SAndroid Build Coastguard Worker  *
91*6777b538SAndroid Build Coastguard Worker  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
92*6777b538SAndroid Build Coastguard Worker  */
93*6777b538SAndroid Build Coastguard Worker static void LIBXML_ATTR_FORMAT(3,0)
htmlParseErrInt(xmlParserCtxtPtr ctxt,xmlParserErrors error,const char * msg,int val)94*6777b538SAndroid Build Coastguard Worker htmlParseErrInt(xmlParserCtxtPtr ctxt, xmlParserErrors error,
95*6777b538SAndroid Build Coastguard Worker              const char *msg, int val)
96*6777b538SAndroid Build Coastguard Worker {
97*6777b538SAndroid Build Coastguard Worker     xmlCtxtErr(ctxt, NULL, XML_FROM_HTML, error, XML_ERR_ERROR,
98*6777b538SAndroid Build Coastguard Worker                NULL, NULL, NULL, val, msg, val);
99*6777b538SAndroid Build Coastguard Worker }
100*6777b538SAndroid Build Coastguard Worker 
101*6777b538SAndroid Build Coastguard Worker /************************************************************************
102*6777b538SAndroid Build Coastguard Worker  *									*
103*6777b538SAndroid Build Coastguard Worker  *	Parser stacks related functions and macros		*
104*6777b538SAndroid Build Coastguard Worker  *									*
105*6777b538SAndroid Build Coastguard Worker  ************************************************************************/
106*6777b538SAndroid Build Coastguard Worker 
107*6777b538SAndroid Build Coastguard Worker /**
108*6777b538SAndroid Build Coastguard Worker  * htmlnamePush:
109*6777b538SAndroid Build Coastguard Worker  * @ctxt:  an HTML parser context
110*6777b538SAndroid Build Coastguard Worker  * @value:  the element name
111*6777b538SAndroid Build Coastguard Worker  *
112*6777b538SAndroid Build Coastguard Worker  * Pushes a new element name on top of the name stack
113*6777b538SAndroid Build Coastguard Worker  *
114*6777b538SAndroid Build Coastguard Worker  * Returns -1 in case of error, the index in the stack otherwise
115*6777b538SAndroid Build Coastguard Worker  */
116*6777b538SAndroid Build Coastguard Worker static int
htmlnamePush(htmlParserCtxtPtr ctxt,const xmlChar * value)117*6777b538SAndroid Build Coastguard Worker htmlnamePush(htmlParserCtxtPtr ctxt, const xmlChar * value)
118*6777b538SAndroid Build Coastguard Worker {
119*6777b538SAndroid Build Coastguard Worker     if ((ctxt->html < 3) && (xmlStrEqual(value, BAD_CAST "head")))
120*6777b538SAndroid Build Coastguard Worker         ctxt->html = 3;
121*6777b538SAndroid Build Coastguard Worker     if ((ctxt->html < 10) && (xmlStrEqual(value, BAD_CAST "body")))
122*6777b538SAndroid Build Coastguard Worker         ctxt->html = 10;
123*6777b538SAndroid Build Coastguard Worker     if (ctxt->nameNr >= ctxt->nameMax) {
124*6777b538SAndroid Build Coastguard Worker         size_t newSize = ctxt->nameMax * 2;
125*6777b538SAndroid Build Coastguard Worker         const xmlChar **tmp;
126*6777b538SAndroid Build Coastguard Worker 
127*6777b538SAndroid Build Coastguard Worker         tmp = xmlRealloc((xmlChar **) ctxt->nameTab,
128*6777b538SAndroid Build Coastguard Worker                          newSize * sizeof(ctxt->nameTab[0]));
129*6777b538SAndroid Build Coastguard Worker         if (tmp == NULL) {
130*6777b538SAndroid Build Coastguard Worker             htmlErrMemory(ctxt);
131*6777b538SAndroid Build Coastguard Worker             return (-1);
132*6777b538SAndroid Build Coastguard Worker         }
133*6777b538SAndroid Build Coastguard Worker         ctxt->nameTab = tmp;
134*6777b538SAndroid Build Coastguard Worker         ctxt->nameMax = newSize;
135*6777b538SAndroid Build Coastguard Worker     }
136*6777b538SAndroid Build Coastguard Worker     ctxt->nameTab[ctxt->nameNr] = value;
137*6777b538SAndroid Build Coastguard Worker     ctxt->name = value;
138*6777b538SAndroid Build Coastguard Worker     return (ctxt->nameNr++);
139*6777b538SAndroid Build Coastguard Worker }
140*6777b538SAndroid Build Coastguard Worker /**
141*6777b538SAndroid Build Coastguard Worker  * htmlnamePop:
142*6777b538SAndroid Build Coastguard Worker  * @ctxt: an HTML parser context
143*6777b538SAndroid Build Coastguard Worker  *
144*6777b538SAndroid Build Coastguard Worker  * Pops the top element name from the name stack
145*6777b538SAndroid Build Coastguard Worker  *
146*6777b538SAndroid Build Coastguard Worker  * Returns the name just removed
147*6777b538SAndroid Build Coastguard Worker  */
148*6777b538SAndroid Build Coastguard Worker static const xmlChar *
htmlnamePop(htmlParserCtxtPtr ctxt)149*6777b538SAndroid Build Coastguard Worker htmlnamePop(htmlParserCtxtPtr ctxt)
150*6777b538SAndroid Build Coastguard Worker {
151*6777b538SAndroid Build Coastguard Worker     const xmlChar *ret;
152*6777b538SAndroid Build Coastguard Worker 
153*6777b538SAndroid Build Coastguard Worker     if (ctxt->nameNr <= 0)
154*6777b538SAndroid Build Coastguard Worker         return (NULL);
155*6777b538SAndroid Build Coastguard Worker     ctxt->nameNr--;
156*6777b538SAndroid Build Coastguard Worker     if (ctxt->nameNr < 0)
157*6777b538SAndroid Build Coastguard Worker         return (NULL);
158*6777b538SAndroid Build Coastguard Worker     if (ctxt->nameNr > 0)
159*6777b538SAndroid Build Coastguard Worker         ctxt->name = ctxt->nameTab[ctxt->nameNr - 1];
160*6777b538SAndroid Build Coastguard Worker     else
161*6777b538SAndroid Build Coastguard Worker         ctxt->name = NULL;
162*6777b538SAndroid Build Coastguard Worker     ret = ctxt->nameTab[ctxt->nameNr];
163*6777b538SAndroid Build Coastguard Worker     ctxt->nameTab[ctxt->nameNr] = NULL;
164*6777b538SAndroid Build Coastguard Worker     return (ret);
165*6777b538SAndroid Build Coastguard Worker }
166*6777b538SAndroid Build Coastguard Worker 
167*6777b538SAndroid Build Coastguard Worker /**
168*6777b538SAndroid Build Coastguard Worker  * htmlNodeInfoPush:
169*6777b538SAndroid Build Coastguard Worker  * @ctxt:  an HTML parser context
170*6777b538SAndroid Build Coastguard Worker  * @value:  the node info
171*6777b538SAndroid Build Coastguard Worker  *
172*6777b538SAndroid Build Coastguard Worker  * Pushes a new element name on top of the node info stack
173*6777b538SAndroid Build Coastguard Worker  *
174*6777b538SAndroid Build Coastguard Worker  * Returns 0 in case of error, the index in the stack otherwise
175*6777b538SAndroid Build Coastguard Worker  */
176*6777b538SAndroid Build Coastguard Worker static int
htmlNodeInfoPush(htmlParserCtxtPtr ctxt,htmlParserNodeInfo * value)177*6777b538SAndroid Build Coastguard Worker htmlNodeInfoPush(htmlParserCtxtPtr ctxt, htmlParserNodeInfo *value)
178*6777b538SAndroid Build Coastguard Worker {
179*6777b538SAndroid Build Coastguard Worker     if (ctxt->nodeInfoNr >= ctxt->nodeInfoMax) {
180*6777b538SAndroid Build Coastguard Worker         if (ctxt->nodeInfoMax == 0)
181*6777b538SAndroid Build Coastguard Worker                 ctxt->nodeInfoMax = 5;
182*6777b538SAndroid Build Coastguard Worker         ctxt->nodeInfoMax *= 2;
183*6777b538SAndroid Build Coastguard Worker         ctxt->nodeInfoTab = (htmlParserNodeInfo *)
184*6777b538SAndroid Build Coastguard Worker                          xmlRealloc((htmlParserNodeInfo *)ctxt->nodeInfoTab,
185*6777b538SAndroid Build Coastguard Worker                                     ctxt->nodeInfoMax *
186*6777b538SAndroid Build Coastguard Worker                                     sizeof(ctxt->nodeInfoTab[0]));
187*6777b538SAndroid Build Coastguard Worker         if (ctxt->nodeInfoTab == NULL) {
188*6777b538SAndroid Build Coastguard Worker             htmlErrMemory(ctxt);
189*6777b538SAndroid Build Coastguard Worker             return (0);
190*6777b538SAndroid Build Coastguard Worker         }
191*6777b538SAndroid Build Coastguard Worker     }
192*6777b538SAndroid Build Coastguard Worker     ctxt->nodeInfoTab[ctxt->nodeInfoNr] = *value;
193*6777b538SAndroid Build Coastguard Worker     ctxt->nodeInfo = &ctxt->nodeInfoTab[ctxt->nodeInfoNr];
194*6777b538SAndroid Build Coastguard Worker     return (ctxt->nodeInfoNr++);
195*6777b538SAndroid Build Coastguard Worker }
196*6777b538SAndroid Build Coastguard Worker 
197*6777b538SAndroid Build Coastguard Worker /**
198*6777b538SAndroid Build Coastguard Worker  * htmlNodeInfoPop:
199*6777b538SAndroid Build Coastguard Worker  * @ctxt:  an HTML parser context
200*6777b538SAndroid Build Coastguard Worker  *
201*6777b538SAndroid Build Coastguard Worker  * Pops the top element name from the node info stack
202*6777b538SAndroid Build Coastguard Worker  *
203*6777b538SAndroid Build Coastguard Worker  * Returns 0 in case of error, the pointer to NodeInfo otherwise
204*6777b538SAndroid Build Coastguard Worker  */
205*6777b538SAndroid Build Coastguard Worker static htmlParserNodeInfo *
htmlNodeInfoPop(htmlParserCtxtPtr ctxt)206*6777b538SAndroid Build Coastguard Worker htmlNodeInfoPop(htmlParserCtxtPtr ctxt)
207*6777b538SAndroid Build Coastguard Worker {
208*6777b538SAndroid Build Coastguard Worker     if (ctxt->nodeInfoNr <= 0)
209*6777b538SAndroid Build Coastguard Worker         return (NULL);
210*6777b538SAndroid Build Coastguard Worker     ctxt->nodeInfoNr--;
211*6777b538SAndroid Build Coastguard Worker     if (ctxt->nodeInfoNr < 0)
212*6777b538SAndroid Build Coastguard Worker         return (NULL);
213*6777b538SAndroid Build Coastguard Worker     if (ctxt->nodeInfoNr > 0)
214*6777b538SAndroid Build Coastguard Worker         ctxt->nodeInfo = &ctxt->nodeInfoTab[ctxt->nodeInfoNr - 1];
215*6777b538SAndroid Build Coastguard Worker     else
216*6777b538SAndroid Build Coastguard Worker         ctxt->nodeInfo = NULL;
217*6777b538SAndroid Build Coastguard Worker     return &ctxt->nodeInfoTab[ctxt->nodeInfoNr];
218*6777b538SAndroid Build Coastguard Worker }
219*6777b538SAndroid Build Coastguard Worker 
220*6777b538SAndroid Build Coastguard Worker /*
221*6777b538SAndroid Build Coastguard Worker  * Macros for accessing the content. Those should be used only by the parser,
222*6777b538SAndroid Build Coastguard Worker  * and not exported.
223*6777b538SAndroid Build Coastguard Worker  *
224*6777b538SAndroid Build Coastguard Worker  * Dirty macros, i.e. one need to make assumption on the context to use them
225*6777b538SAndroid Build Coastguard Worker  *
226*6777b538SAndroid Build Coastguard Worker  *   CUR_PTR return the current pointer to the xmlChar to be parsed.
227*6777b538SAndroid Build Coastguard Worker  *   CUR     returns the current xmlChar value, i.e. a 8 bit value if compiled
228*6777b538SAndroid Build Coastguard Worker  *           in ISO-Latin or UTF-8, and the current 16 bit value if compiled
229*6777b538SAndroid Build Coastguard Worker  *           in UNICODE mode. This should be used internally by the parser
230*6777b538SAndroid Build Coastguard Worker  *           only to compare to ASCII values otherwise it would break when
231*6777b538SAndroid Build Coastguard Worker  *           running with UTF-8 encoding.
232*6777b538SAndroid Build Coastguard Worker  *   NXT(n)  returns the n'th next xmlChar. Same as CUR is should be used only
233*6777b538SAndroid Build Coastguard Worker  *           to compare on ASCII based substring.
234*6777b538SAndroid Build Coastguard Worker  *   UPP(n)  returns the n'th next xmlChar converted to uppercase. Same as CUR
235*6777b538SAndroid Build Coastguard Worker  *           it should be used only to compare on ASCII based substring.
236*6777b538SAndroid Build Coastguard Worker  *   SKIP(n) Skip n xmlChar, and must also be used only to skip ASCII defined
237*6777b538SAndroid Build Coastguard Worker  *           strings without newlines within the parser.
238*6777b538SAndroid Build Coastguard Worker  *
239*6777b538SAndroid Build Coastguard Worker  * Clean macros, not dependent of an ASCII context, expect UTF-8 encoding
240*6777b538SAndroid Build Coastguard Worker  *
241*6777b538SAndroid Build Coastguard Worker  *   NEXT    Skip to the next character, this does the proper decoding
242*6777b538SAndroid Build Coastguard Worker  *           in UTF-8 mode. It also pop-up unfinished entities on the fly.
243*6777b538SAndroid Build Coastguard Worker  *   NEXTL(l) Skip the current unicode character of l xmlChars long.
244*6777b538SAndroid Build Coastguard Worker  *   COPY(to) copy one char to *to, increment CUR_PTR and to accordingly
245*6777b538SAndroid Build Coastguard Worker  */
246*6777b538SAndroid Build Coastguard Worker 
247*6777b538SAndroid Build Coastguard Worker #define UPPER (toupper(*ctxt->input->cur))
248*6777b538SAndroid Build Coastguard Worker 
249*6777b538SAndroid Build Coastguard Worker #define SKIP(val) ctxt->input->cur += (val),ctxt->input->col+=(val)
250*6777b538SAndroid Build Coastguard Worker 
251*6777b538SAndroid Build Coastguard Worker #define NXT(val) ctxt->input->cur[(val)]
252*6777b538SAndroid Build Coastguard Worker 
253*6777b538SAndroid Build Coastguard Worker #define UPP(val) (toupper(ctxt->input->cur[(val)]))
254*6777b538SAndroid Build Coastguard Worker 
255*6777b538SAndroid Build Coastguard Worker #define CUR_PTR ctxt->input->cur
256*6777b538SAndroid Build Coastguard Worker #define BASE_PTR ctxt->input->base
257*6777b538SAndroid Build Coastguard Worker 
258*6777b538SAndroid Build Coastguard Worker #define SHRINK \
259*6777b538SAndroid Build Coastguard Worker     if ((!PARSER_PROGRESSIVE(ctxt)) && \
260*6777b538SAndroid Build Coastguard Worker         (ctxt->input->cur - ctxt->input->base > 2 * INPUT_CHUNK) && \
261*6777b538SAndroid Build Coastguard Worker 	(ctxt->input->end - ctxt->input->cur < 2 * INPUT_CHUNK)) \
262*6777b538SAndroid Build Coastguard Worker 	xmlParserShrink(ctxt);
263*6777b538SAndroid Build Coastguard Worker 
264*6777b538SAndroid Build Coastguard Worker #define GROW \
265*6777b538SAndroid Build Coastguard Worker     if ((!PARSER_PROGRESSIVE(ctxt)) && \
266*6777b538SAndroid Build Coastguard Worker         (ctxt->input->end - ctxt->input->cur < INPUT_CHUNK)) \
267*6777b538SAndroid Build Coastguard Worker 	xmlParserGrow(ctxt);
268*6777b538SAndroid Build Coastguard Worker 
269*6777b538SAndroid Build Coastguard Worker #define SKIP_BLANKS htmlSkipBlankChars(ctxt)
270*6777b538SAndroid Build Coastguard Worker 
271*6777b538SAndroid Build Coastguard Worker /* Imported from XML */
272*6777b538SAndroid Build Coastguard Worker 
273*6777b538SAndroid Build Coastguard Worker #define CUR (*ctxt->input->cur)
274*6777b538SAndroid Build Coastguard Worker #define NEXT xmlNextChar(ctxt)
275*6777b538SAndroid Build Coastguard Worker 
276*6777b538SAndroid Build Coastguard Worker #define RAW (*ctxt->input->cur)
277*6777b538SAndroid Build Coastguard Worker 
278*6777b538SAndroid Build Coastguard Worker 
279*6777b538SAndroid Build Coastguard Worker #define NEXTL(l) do {							\
280*6777b538SAndroid Build Coastguard Worker     if (*(ctxt->input->cur) == '\n') {					\
281*6777b538SAndroid Build Coastguard Worker 	ctxt->input->line++; ctxt->input->col = 1;			\
282*6777b538SAndroid Build Coastguard Worker     } else ctxt->input->col++;						\
283*6777b538SAndroid Build Coastguard Worker     ctxt->input->cur += l;						\
284*6777b538SAndroid Build Coastguard Worker   } while (0)
285*6777b538SAndroid Build Coastguard Worker 
286*6777b538SAndroid Build Coastguard Worker /************
287*6777b538SAndroid Build Coastguard Worker     \
288*6777b538SAndroid Build Coastguard Worker     if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt);	\
289*6777b538SAndroid Build Coastguard Worker     if (*ctxt->input->cur == '&') xmlParserHandleReference(ctxt);
290*6777b538SAndroid Build Coastguard Worker  ************/
291*6777b538SAndroid Build Coastguard Worker 
292*6777b538SAndroid Build Coastguard Worker #define CUR_CHAR(l) htmlCurrentChar(ctxt, &l)
293*6777b538SAndroid Build Coastguard Worker 
294*6777b538SAndroid Build Coastguard Worker #define COPY_BUF(l,b,i,v)						\
295*6777b538SAndroid Build Coastguard Worker     if (l == 1) b[i++] = v;						\
296*6777b538SAndroid Build Coastguard Worker     else i += xmlCopyChar(l,&b[i],v)
297*6777b538SAndroid Build Coastguard Worker 
298*6777b538SAndroid Build Coastguard Worker /**
299*6777b538SAndroid Build Coastguard Worker  * htmlFindEncoding:
300*6777b538SAndroid Build Coastguard Worker  * @the HTML parser context
301*6777b538SAndroid Build Coastguard Worker  *
302*6777b538SAndroid Build Coastguard Worker  * Ty to find and encoding in the current data available in the input
303*6777b538SAndroid Build Coastguard Worker  * buffer this is needed to try to switch to the proper encoding when
304*6777b538SAndroid Build Coastguard Worker  * one face a character error.
305*6777b538SAndroid Build Coastguard Worker  * That's an heuristic, since it's operating outside of parsing it could
306*6777b538SAndroid Build Coastguard Worker  * try to use a meta which had been commented out, that's the reason it
307*6777b538SAndroid Build Coastguard Worker  * should only be used in case of error, not as a default.
308*6777b538SAndroid Build Coastguard Worker  *
309*6777b538SAndroid Build Coastguard Worker  * Returns an encoding string or NULL if not found, the string need to
310*6777b538SAndroid Build Coastguard Worker  *   be freed
311*6777b538SAndroid Build Coastguard Worker  */
312*6777b538SAndroid Build Coastguard Worker static xmlChar *
htmlFindEncoding(xmlParserCtxtPtr ctxt)313*6777b538SAndroid Build Coastguard Worker htmlFindEncoding(xmlParserCtxtPtr ctxt) {
314*6777b538SAndroid Build Coastguard Worker     const xmlChar *start, *cur, *end;
315*6777b538SAndroid Build Coastguard Worker     xmlChar *ret;
316*6777b538SAndroid Build Coastguard Worker 
317*6777b538SAndroid Build Coastguard Worker     if ((ctxt == NULL) || (ctxt->input == NULL) ||
318*6777b538SAndroid Build Coastguard Worker         (ctxt->input->flags & XML_INPUT_HAS_ENCODING))
319*6777b538SAndroid Build Coastguard Worker         return(NULL);
320*6777b538SAndroid Build Coastguard Worker     if ((ctxt->input->cur == NULL) || (ctxt->input->end == NULL))
321*6777b538SAndroid Build Coastguard Worker         return(NULL);
322*6777b538SAndroid Build Coastguard Worker 
323*6777b538SAndroid Build Coastguard Worker     start = ctxt->input->cur;
324*6777b538SAndroid Build Coastguard Worker     end = ctxt->input->end;
325*6777b538SAndroid Build Coastguard Worker     /* we also expect the input buffer to be zero terminated */
326*6777b538SAndroid Build Coastguard Worker     if (*end != 0)
327*6777b538SAndroid Build Coastguard Worker         return(NULL);
328*6777b538SAndroid Build Coastguard Worker 
329*6777b538SAndroid Build Coastguard Worker     cur = xmlStrcasestr(start, BAD_CAST "HTTP-EQUIV");
330*6777b538SAndroid Build Coastguard Worker     if (cur == NULL)
331*6777b538SAndroid Build Coastguard Worker         return(NULL);
332*6777b538SAndroid Build Coastguard Worker     cur = xmlStrcasestr(cur, BAD_CAST  "CONTENT");
333*6777b538SAndroid Build Coastguard Worker     if (cur == NULL)
334*6777b538SAndroid Build Coastguard Worker         return(NULL);
335*6777b538SAndroid Build Coastguard Worker     cur = xmlStrcasestr(cur, BAD_CAST  "CHARSET=");
336*6777b538SAndroid Build Coastguard Worker     if (cur == NULL)
337*6777b538SAndroid Build Coastguard Worker         return(NULL);
338*6777b538SAndroid Build Coastguard Worker     cur += 8;
339*6777b538SAndroid Build Coastguard Worker     start = cur;
340*6777b538SAndroid Build Coastguard Worker     while (((*cur >= 'A') && (*cur <= 'Z')) ||
341*6777b538SAndroid Build Coastguard Worker            ((*cur >= 'a') && (*cur <= 'z')) ||
342*6777b538SAndroid Build Coastguard Worker            ((*cur >= '0') && (*cur <= '9')) ||
343*6777b538SAndroid Build Coastguard Worker            (*cur == '-') || (*cur == '_') || (*cur == ':') || (*cur == '/'))
344*6777b538SAndroid Build Coastguard Worker            cur++;
345*6777b538SAndroid Build Coastguard Worker     if (cur == start)
346*6777b538SAndroid Build Coastguard Worker         return(NULL);
347*6777b538SAndroid Build Coastguard Worker     ret = xmlStrndup(start, cur - start);
348*6777b538SAndroid Build Coastguard Worker     if (ret == NULL)
349*6777b538SAndroid Build Coastguard Worker         htmlErrMemory(ctxt);
350*6777b538SAndroid Build Coastguard Worker     return(ret);
351*6777b538SAndroid Build Coastguard Worker }
352*6777b538SAndroid Build Coastguard Worker 
353*6777b538SAndroid Build Coastguard Worker /**
354*6777b538SAndroid Build Coastguard Worker  * htmlCurrentChar:
355*6777b538SAndroid Build Coastguard Worker  * @ctxt:  the HTML parser context
356*6777b538SAndroid Build Coastguard Worker  * @len:  pointer to the length of the char read
357*6777b538SAndroid Build Coastguard Worker  *
358*6777b538SAndroid Build Coastguard Worker  * The current char value, if using UTF-8 this may actually span multiple
359*6777b538SAndroid Build Coastguard Worker  * bytes in the input buffer. Implement the end of line normalization:
360*6777b538SAndroid Build Coastguard Worker  * 2.11 End-of-Line Handling
361*6777b538SAndroid Build Coastguard Worker  * If the encoding is unspecified, in the case we find an ISO-Latin-1
362*6777b538SAndroid Build Coastguard Worker  * char, then the encoding converter is plugged in automatically.
363*6777b538SAndroid Build Coastguard Worker  *
364*6777b538SAndroid Build Coastguard Worker  * Returns the current char value and its length
365*6777b538SAndroid Build Coastguard Worker  */
366*6777b538SAndroid Build Coastguard Worker 
367*6777b538SAndroid Build Coastguard Worker static int
htmlCurrentChar(xmlParserCtxtPtr ctxt,int * len)368*6777b538SAndroid Build Coastguard Worker htmlCurrentChar(xmlParserCtxtPtr ctxt, int *len) {
369*6777b538SAndroid Build Coastguard Worker     const unsigned char *cur;
370*6777b538SAndroid Build Coastguard Worker     unsigned char c;
371*6777b538SAndroid Build Coastguard Worker     unsigned int val;
372*6777b538SAndroid Build Coastguard Worker 
373*6777b538SAndroid Build Coastguard Worker     if (ctxt->input->end - ctxt->input->cur < INPUT_CHUNK)
374*6777b538SAndroid Build Coastguard Worker         xmlParserGrow(ctxt);
375*6777b538SAndroid Build Coastguard Worker 
376*6777b538SAndroid Build Coastguard Worker     if ((ctxt->input->flags & XML_INPUT_HAS_ENCODING) == 0) {
377*6777b538SAndroid Build Coastguard Worker         xmlChar * guess;
378*6777b538SAndroid Build Coastguard Worker 
379*6777b538SAndroid Build Coastguard Worker         /*
380*6777b538SAndroid Build Coastguard Worker          * Assume it's a fixed length encoding (1) with
381*6777b538SAndroid Build Coastguard Worker          * a compatible encoding for the ASCII set, since
382*6777b538SAndroid Build Coastguard Worker          * HTML constructs only use < 128 chars
383*6777b538SAndroid Build Coastguard Worker          */
384*6777b538SAndroid Build Coastguard Worker         if (*ctxt->input->cur < 0x80) {
385*6777b538SAndroid Build Coastguard Worker             if (*ctxt->input->cur == 0) {
386*6777b538SAndroid Build Coastguard Worker                 if (ctxt->input->cur < ctxt->input->end) {
387*6777b538SAndroid Build Coastguard Worker                     htmlParseErrInt(ctxt, XML_ERR_INVALID_CHAR,
388*6777b538SAndroid Build Coastguard Worker                                     "Char 0x%X out of allowed range\n", 0);
389*6777b538SAndroid Build Coastguard Worker                     *len = 1;
390*6777b538SAndroid Build Coastguard Worker                     return(' ');
391*6777b538SAndroid Build Coastguard Worker                 } else {
392*6777b538SAndroid Build Coastguard Worker                     *len = 0;
393*6777b538SAndroid Build Coastguard Worker                     return(0);
394*6777b538SAndroid Build Coastguard Worker                 }
395*6777b538SAndroid Build Coastguard Worker             }
396*6777b538SAndroid Build Coastguard Worker             *len = 1;
397*6777b538SAndroid Build Coastguard Worker             return(*ctxt->input->cur);
398*6777b538SAndroid Build Coastguard Worker         }
399*6777b538SAndroid Build Coastguard Worker 
400*6777b538SAndroid Build Coastguard Worker         /*
401*6777b538SAndroid Build Coastguard Worker          * Humm this is bad, do an automatic flow conversion
402*6777b538SAndroid Build Coastguard Worker          */
403*6777b538SAndroid Build Coastguard Worker         guess = htmlFindEncoding(ctxt);
404*6777b538SAndroid Build Coastguard Worker         if (guess == NULL) {
405*6777b538SAndroid Build Coastguard Worker             xmlSwitchEncoding(ctxt, XML_CHAR_ENCODING_8859_1);
406*6777b538SAndroid Build Coastguard Worker         } else {
407*6777b538SAndroid Build Coastguard Worker             xmlSwitchEncodingName(ctxt, (const char *) guess);
408*6777b538SAndroid Build Coastguard Worker             xmlFree(guess);
409*6777b538SAndroid Build Coastguard Worker         }
410*6777b538SAndroid Build Coastguard Worker         ctxt->input->flags |= XML_INPUT_HAS_ENCODING;
411*6777b538SAndroid Build Coastguard Worker     }
412*6777b538SAndroid Build Coastguard Worker 
413*6777b538SAndroid Build Coastguard Worker     /*
414*6777b538SAndroid Build Coastguard Worker      * We are supposed to handle UTF8, check it's valid
415*6777b538SAndroid Build Coastguard Worker      * From rfc2044: encoding of the Unicode values on UTF-8:
416*6777b538SAndroid Build Coastguard Worker      *
417*6777b538SAndroid Build Coastguard Worker      * UCS-4 range (hex.)           UTF-8 octet sequence (binary)
418*6777b538SAndroid Build Coastguard Worker      * 0000 0000-0000 007F   0xxxxxxx
419*6777b538SAndroid Build Coastguard Worker      * 0000 0080-0000 07FF   110xxxxx 10xxxxxx
420*6777b538SAndroid Build Coastguard Worker      * 0000 0800-0000 FFFF   1110xxxx 10xxxxxx 10xxxxxx
421*6777b538SAndroid Build Coastguard Worker      *
422*6777b538SAndroid Build Coastguard Worker      * Check for the 0x110000 limit too
423*6777b538SAndroid Build Coastguard Worker      */
424*6777b538SAndroid Build Coastguard Worker     cur = ctxt->input->cur;
425*6777b538SAndroid Build Coastguard Worker     c = *cur;
426*6777b538SAndroid Build Coastguard Worker     if (c & 0x80) {
427*6777b538SAndroid Build Coastguard Worker         size_t avail;
428*6777b538SAndroid Build Coastguard Worker 
429*6777b538SAndroid Build Coastguard Worker         if ((c & 0x40) == 0)
430*6777b538SAndroid Build Coastguard Worker             goto encoding_error;
431*6777b538SAndroid Build Coastguard Worker 
432*6777b538SAndroid Build Coastguard Worker         avail = ctxt->input->end - ctxt->input->cur;
433*6777b538SAndroid Build Coastguard Worker 
434*6777b538SAndroid Build Coastguard Worker         if ((avail < 2) || ((cur[1] & 0xc0) != 0x80))
435*6777b538SAndroid Build Coastguard Worker             goto encoding_error;
436*6777b538SAndroid Build Coastguard Worker         if ((c & 0xe0) == 0xe0) {
437*6777b538SAndroid Build Coastguard Worker             if ((avail < 3) || ((cur[2] & 0xc0) != 0x80))
438*6777b538SAndroid Build Coastguard Worker                 goto encoding_error;
439*6777b538SAndroid Build Coastguard Worker             if ((c & 0xf0) == 0xf0) {
440*6777b538SAndroid Build Coastguard Worker                 if (((c & 0xf8) != 0xf0) ||
441*6777b538SAndroid Build Coastguard Worker                     (avail < 4) || ((cur[3] & 0xc0) != 0x80))
442*6777b538SAndroid Build Coastguard Worker                     goto encoding_error;
443*6777b538SAndroid Build Coastguard Worker                 /* 4-byte code */
444*6777b538SAndroid Build Coastguard Worker                 *len = 4;
445*6777b538SAndroid Build Coastguard Worker                 val = (cur[0] & 0x7) << 18;
446*6777b538SAndroid Build Coastguard Worker                 val |= (cur[1] & 0x3f) << 12;
447*6777b538SAndroid Build Coastguard Worker                 val |= (cur[2] & 0x3f) << 6;
448*6777b538SAndroid Build Coastguard Worker                 val |= cur[3] & 0x3f;
449*6777b538SAndroid Build Coastguard Worker                 if (val < 0x10000)
450*6777b538SAndroid Build Coastguard Worker                     goto encoding_error;
451*6777b538SAndroid Build Coastguard Worker             } else {
452*6777b538SAndroid Build Coastguard Worker               /* 3-byte code */
453*6777b538SAndroid Build Coastguard Worker                 *len = 3;
454*6777b538SAndroid Build Coastguard Worker                 val = (cur[0] & 0xf) << 12;
455*6777b538SAndroid Build Coastguard Worker                 val |= (cur[1] & 0x3f) << 6;
456*6777b538SAndroid Build Coastguard Worker                 val |= cur[2] & 0x3f;
457*6777b538SAndroid Build Coastguard Worker                 if (val < 0x800)
458*6777b538SAndroid Build Coastguard Worker                     goto encoding_error;
459*6777b538SAndroid Build Coastguard Worker             }
460*6777b538SAndroid Build Coastguard Worker         } else {
461*6777b538SAndroid Build Coastguard Worker           /* 2-byte code */
462*6777b538SAndroid Build Coastguard Worker             *len = 2;
463*6777b538SAndroid Build Coastguard Worker             val = (cur[0] & 0x1f) << 6;
464*6777b538SAndroid Build Coastguard Worker             val |= cur[1] & 0x3f;
465*6777b538SAndroid Build Coastguard Worker             if (val < 0x80)
466*6777b538SAndroid Build Coastguard Worker                 goto encoding_error;
467*6777b538SAndroid Build Coastguard Worker         }
468*6777b538SAndroid Build Coastguard Worker         if (!IS_CHAR(val)) {
469*6777b538SAndroid Build Coastguard Worker             htmlParseErrInt(ctxt, XML_ERR_INVALID_CHAR,
470*6777b538SAndroid Build Coastguard Worker                             "Char 0x%X out of allowed range\n", val);
471*6777b538SAndroid Build Coastguard Worker         }
472*6777b538SAndroid Build Coastguard Worker         return(val);
473*6777b538SAndroid Build Coastguard Worker     } else {
474*6777b538SAndroid Build Coastguard Worker         if (*ctxt->input->cur == 0) {
475*6777b538SAndroid Build Coastguard Worker             if (ctxt->input->cur < ctxt->input->end) {
476*6777b538SAndroid Build Coastguard Worker                 htmlParseErrInt(ctxt, XML_ERR_INVALID_CHAR,
477*6777b538SAndroid Build Coastguard Worker                                 "Char 0x%X out of allowed range\n", 0);
478*6777b538SAndroid Build Coastguard Worker                 *len = 1;
479*6777b538SAndroid Build Coastguard Worker                 return(' ');
480*6777b538SAndroid Build Coastguard Worker             } else {
481*6777b538SAndroid Build Coastguard Worker                 *len = 0;
482*6777b538SAndroid Build Coastguard Worker                 return(0);
483*6777b538SAndroid Build Coastguard Worker             }
484*6777b538SAndroid Build Coastguard Worker         }
485*6777b538SAndroid Build Coastguard Worker         /* 1-byte code */
486*6777b538SAndroid Build Coastguard Worker         *len = 1;
487*6777b538SAndroid Build Coastguard Worker         return(*ctxt->input->cur);
488*6777b538SAndroid Build Coastguard Worker     }
489*6777b538SAndroid Build Coastguard Worker 
490*6777b538SAndroid Build Coastguard Worker encoding_error:
491*6777b538SAndroid Build Coastguard Worker     xmlCtxtErrIO(ctxt, XML_ERR_INVALID_ENCODING, NULL);
492*6777b538SAndroid Build Coastguard Worker 
493*6777b538SAndroid Build Coastguard Worker     if ((ctxt->input->flags & XML_INPUT_HAS_ENCODING) == 0)
494*6777b538SAndroid Build Coastguard Worker         xmlSwitchEncoding(ctxt, XML_CHAR_ENCODING_8859_1);
495*6777b538SAndroid Build Coastguard Worker     *len = 1;
496*6777b538SAndroid Build Coastguard Worker     return(*ctxt->input->cur);
497*6777b538SAndroid Build Coastguard Worker }
498*6777b538SAndroid Build Coastguard Worker 
499*6777b538SAndroid Build Coastguard Worker /**
500*6777b538SAndroid Build Coastguard Worker  * htmlSkipBlankChars:
501*6777b538SAndroid Build Coastguard Worker  * @ctxt:  the HTML parser context
502*6777b538SAndroid Build Coastguard Worker  *
503*6777b538SAndroid Build Coastguard Worker  * skip all blanks character found at that point in the input streams.
504*6777b538SAndroid Build Coastguard Worker  *
505*6777b538SAndroid Build Coastguard Worker  * Returns the number of space chars skipped
506*6777b538SAndroid Build Coastguard Worker  */
507*6777b538SAndroid Build Coastguard Worker 
508*6777b538SAndroid Build Coastguard Worker static int
htmlSkipBlankChars(xmlParserCtxtPtr ctxt)509*6777b538SAndroid Build Coastguard Worker htmlSkipBlankChars(xmlParserCtxtPtr ctxt) {
510*6777b538SAndroid Build Coastguard Worker     int res = 0;
511*6777b538SAndroid Build Coastguard Worker 
512*6777b538SAndroid Build Coastguard Worker     while (IS_BLANK_CH(*(ctxt->input->cur))) {
513*6777b538SAndroid Build Coastguard Worker         if (*(ctxt->input->cur) == '\n') {
514*6777b538SAndroid Build Coastguard Worker             ctxt->input->line++; ctxt->input->col = 1;
515*6777b538SAndroid Build Coastguard Worker         } else ctxt->input->col++;
516*6777b538SAndroid Build Coastguard Worker         ctxt->input->cur++;
517*6777b538SAndroid Build Coastguard Worker         if (*ctxt->input->cur == 0)
518*6777b538SAndroid Build Coastguard Worker             xmlParserGrow(ctxt);
519*6777b538SAndroid Build Coastguard Worker 	if (res < INT_MAX)
520*6777b538SAndroid Build Coastguard Worker 	    res++;
521*6777b538SAndroid Build Coastguard Worker     }
522*6777b538SAndroid Build Coastguard Worker     return(res);
523*6777b538SAndroid Build Coastguard Worker }
524*6777b538SAndroid Build Coastguard Worker 
525*6777b538SAndroid Build Coastguard Worker 
526*6777b538SAndroid Build Coastguard Worker 
527*6777b538SAndroid Build Coastguard Worker /************************************************************************
528*6777b538SAndroid Build Coastguard Worker  *									*
529*6777b538SAndroid Build Coastguard Worker  *	The list of HTML elements and their properties		*
530*6777b538SAndroid Build Coastguard Worker  *									*
531*6777b538SAndroid Build Coastguard Worker  ************************************************************************/
532*6777b538SAndroid Build Coastguard Worker 
533*6777b538SAndroid Build Coastguard Worker /*
534*6777b538SAndroid Build Coastguard Worker  *  Start Tag: 1 means the start tag can be omitted
535*6777b538SAndroid Build Coastguard Worker  *  End Tag:   1 means the end tag can be omitted
536*6777b538SAndroid Build Coastguard Worker  *             2 means it's forbidden (empty elements)
537*6777b538SAndroid Build Coastguard Worker  *             3 means the tag is stylistic and should be closed easily
538*6777b538SAndroid Build Coastguard Worker  *  Depr:      this element is deprecated
539*6777b538SAndroid Build Coastguard Worker  *  DTD:       1 means that this element is valid only in the Loose DTD
540*6777b538SAndroid Build Coastguard Worker  *             2 means that this element is valid only in the Frameset DTD
541*6777b538SAndroid Build Coastguard Worker  *
542*6777b538SAndroid Build Coastguard Worker  * Name,Start Tag,End Tag,Save End,Empty,Deprecated,DTD,inline,Description
543*6777b538SAndroid Build Coastguard Worker 	, subElements , impliedsubelt , Attributes, userdata
544*6777b538SAndroid Build Coastguard Worker  */
545*6777b538SAndroid Build Coastguard Worker 
546*6777b538SAndroid Build Coastguard Worker /* Definitions and a couple of vars for HTML Elements */
547*6777b538SAndroid Build Coastguard Worker 
548*6777b538SAndroid Build Coastguard Worker #define FONTSTYLE "tt", "i", "b", "u", "s", "strike", "big", "small"
549*6777b538SAndroid Build Coastguard Worker #define NB_FONTSTYLE 8
550*6777b538SAndroid Build Coastguard Worker #define PHRASE "em", "strong", "dfn", "code", "samp", "kbd", "var", "cite", "abbr", "acronym"
551*6777b538SAndroid Build Coastguard Worker #define NB_PHRASE 10
552*6777b538SAndroid Build Coastguard Worker #define SPECIAL "a", "img", "applet", "embed", "object", "font", "basefont", "br", "script", "map", "q", "sub", "sup", "span", "bdo", "iframe"
553*6777b538SAndroid Build Coastguard Worker #define NB_SPECIAL 16
554*6777b538SAndroid Build Coastguard Worker #define INLINE FONTSTYLE, PHRASE, SPECIAL, FORMCTRL
555*6777b538SAndroid Build Coastguard Worker #define NB_INLINE NB_PCDATA + NB_FONTSTYLE + NB_PHRASE + NB_SPECIAL + NB_FORMCTRL
556*6777b538SAndroid Build Coastguard Worker #define BLOCK HEADING, LIST, "pre", "p", "dl", "div", "center", "noscript", "noframes", "blockquote", "form", "isindex", "hr", "table", "fieldset", "address"
557*6777b538SAndroid Build Coastguard Worker #define NB_BLOCK NB_HEADING + NB_LIST + 14
558*6777b538SAndroid Build Coastguard Worker #define FORMCTRL "input", "select", "textarea", "label", "button"
559*6777b538SAndroid Build Coastguard Worker #define NB_FORMCTRL 5
560*6777b538SAndroid Build Coastguard Worker #define PCDATA
561*6777b538SAndroid Build Coastguard Worker #define NB_PCDATA 0
562*6777b538SAndroid Build Coastguard Worker #define HEADING "h1", "h2", "h3", "h4", "h5", "h6"
563*6777b538SAndroid Build Coastguard Worker #define NB_HEADING 6
564*6777b538SAndroid Build Coastguard Worker #define LIST "ul", "ol", "dir", "menu"
565*6777b538SAndroid Build Coastguard Worker #define NB_LIST 4
566*6777b538SAndroid Build Coastguard Worker #define MODIFIER
567*6777b538SAndroid Build Coastguard Worker #define NB_MODIFIER 0
568*6777b538SAndroid Build Coastguard Worker #define FLOW BLOCK,INLINE
569*6777b538SAndroid Build Coastguard Worker #define NB_FLOW NB_BLOCK + NB_INLINE
570*6777b538SAndroid Build Coastguard Worker #define EMPTY NULL
571*6777b538SAndroid Build Coastguard Worker 
572*6777b538SAndroid Build Coastguard Worker 
573*6777b538SAndroid Build Coastguard Worker static const char* const html_flow[] = { FLOW, NULL } ;
574*6777b538SAndroid Build Coastguard Worker static const char* const html_inline[] = { INLINE, NULL } ;
575*6777b538SAndroid Build Coastguard Worker 
576*6777b538SAndroid Build Coastguard Worker /* placeholders: elts with content but no subelements */
577*6777b538SAndroid Build Coastguard Worker static const char* const html_pcdata[] = { NULL } ;
578*6777b538SAndroid Build Coastguard Worker #define html_cdata html_pcdata
579*6777b538SAndroid Build Coastguard Worker 
580*6777b538SAndroid Build Coastguard Worker 
581*6777b538SAndroid Build Coastguard Worker /* ... and for HTML Attributes */
582*6777b538SAndroid Build Coastguard Worker 
583*6777b538SAndroid Build Coastguard Worker #define COREATTRS "id", "class", "style", "title"
584*6777b538SAndroid Build Coastguard Worker #define NB_COREATTRS 4
585*6777b538SAndroid Build Coastguard Worker #define I18N "lang", "dir"
586*6777b538SAndroid Build Coastguard Worker #define NB_I18N 2
587*6777b538SAndroid Build Coastguard Worker #define EVENTS "onclick", "ondblclick", "onmousedown", "onmouseup", "onmouseover", "onmouseout", "onkeypress", "onkeydown", "onkeyup"
588*6777b538SAndroid Build Coastguard Worker #define NB_EVENTS 9
589*6777b538SAndroid Build Coastguard Worker #define ATTRS COREATTRS,I18N,EVENTS
590*6777b538SAndroid Build Coastguard Worker #define NB_ATTRS NB_NB_COREATTRS + NB_I18N + NB_EVENTS
591*6777b538SAndroid Build Coastguard Worker #define CELLHALIGN "align", "char", "charoff"
592*6777b538SAndroid Build Coastguard Worker #define NB_CELLHALIGN 3
593*6777b538SAndroid Build Coastguard Worker #define CELLVALIGN "valign"
594*6777b538SAndroid Build Coastguard Worker #define NB_CELLVALIGN 1
595*6777b538SAndroid Build Coastguard Worker 
596*6777b538SAndroid Build Coastguard Worker static const char* const html_attrs[] = { ATTRS, NULL } ;
597*6777b538SAndroid Build Coastguard Worker static const char* const core_i18n_attrs[] = { COREATTRS, I18N, NULL } ;
598*6777b538SAndroid Build Coastguard Worker static const char* const core_attrs[] = { COREATTRS, NULL } ;
599*6777b538SAndroid Build Coastguard Worker static const char* const i18n_attrs[] = { I18N, NULL } ;
600*6777b538SAndroid Build Coastguard Worker 
601*6777b538SAndroid Build Coastguard Worker 
602*6777b538SAndroid Build Coastguard Worker /* Other declarations that should go inline ... */
603*6777b538SAndroid Build Coastguard Worker static const char* const a_attrs[] = { ATTRS, "charset", "type", "name",
604*6777b538SAndroid Build Coastguard Worker 	"href", "hreflang", "rel", "rev", "accesskey", "shape", "coords",
605*6777b538SAndroid Build Coastguard Worker 	"tabindex", "onfocus", "onblur", NULL } ;
606*6777b538SAndroid Build Coastguard Worker static const char* const target_attr[] = { "target", NULL } ;
607*6777b538SAndroid Build Coastguard Worker static const char* const rows_cols_attr[] = { "rows", "cols", NULL } ;
608*6777b538SAndroid Build Coastguard Worker static const char* const alt_attr[] = { "alt", NULL } ;
609*6777b538SAndroid Build Coastguard Worker static const char* const src_alt_attrs[] = { "src", "alt", NULL } ;
610*6777b538SAndroid Build Coastguard Worker static const char* const href_attrs[] = { "href", NULL } ;
611*6777b538SAndroid Build Coastguard Worker static const char* const clear_attrs[] = { "clear", NULL } ;
612*6777b538SAndroid Build Coastguard Worker static const char* const inline_p[] = { INLINE, "p", NULL } ;
613*6777b538SAndroid Build Coastguard Worker 
614*6777b538SAndroid Build Coastguard Worker static const char* const flow_param[] = { FLOW, "param", NULL } ;
615*6777b538SAndroid Build Coastguard Worker static const char* const applet_attrs[] = { COREATTRS , "codebase",
616*6777b538SAndroid Build Coastguard Worker 		"archive", "alt", "name", "height", "width", "align",
617*6777b538SAndroid Build Coastguard Worker 		"hspace", "vspace", NULL } ;
618*6777b538SAndroid Build Coastguard Worker static const char* const area_attrs[] = { "shape", "coords", "href", "nohref",
619*6777b538SAndroid Build Coastguard Worker 	"tabindex", "accesskey", "onfocus", "onblur", NULL } ;
620*6777b538SAndroid Build Coastguard Worker static const char* const basefont_attrs[] =
621*6777b538SAndroid Build Coastguard Worker 	{ "id", "size", "color", "face", NULL } ;
622*6777b538SAndroid Build Coastguard Worker static const char* const quote_attrs[] = { ATTRS, "cite", NULL } ;
623*6777b538SAndroid Build Coastguard Worker static const char* const body_contents[] = { FLOW, "ins", "del", NULL } ;
624*6777b538SAndroid Build Coastguard Worker static const char* const body_attrs[] = { ATTRS, "onload", "onunload", NULL } ;
625*6777b538SAndroid Build Coastguard Worker static const char* const body_depr[] = { "background", "bgcolor", "text",
626*6777b538SAndroid Build Coastguard Worker 	"link", "vlink", "alink", NULL } ;
627*6777b538SAndroid Build Coastguard Worker static const char* const button_attrs[] = { ATTRS, "name", "value", "type",
628*6777b538SAndroid Build Coastguard Worker 	"disabled", "tabindex", "accesskey", "onfocus", "onblur", NULL } ;
629*6777b538SAndroid Build Coastguard Worker 
630*6777b538SAndroid Build Coastguard Worker 
631*6777b538SAndroid Build Coastguard Worker static const char* const col_attrs[] = { ATTRS, "span", "width", CELLHALIGN, CELLVALIGN, NULL } ;
632*6777b538SAndroid Build Coastguard Worker static const char* const col_elt[] = { "col", NULL } ;
633*6777b538SAndroid Build Coastguard Worker static const char* const edit_attrs[] = { ATTRS, "datetime", "cite", NULL } ;
634*6777b538SAndroid Build Coastguard Worker static const char* const compact_attrs[] = { ATTRS, "compact", NULL } ;
635*6777b538SAndroid Build Coastguard Worker static const char* const dl_contents[] = { "dt", "dd", NULL } ;
636*6777b538SAndroid Build Coastguard Worker static const char* const compact_attr[] = { "compact", NULL } ;
637*6777b538SAndroid Build Coastguard Worker static const char* const label_attr[] = { "label", NULL } ;
638*6777b538SAndroid Build Coastguard Worker static const char* const fieldset_contents[] = { FLOW, "legend" } ;
639*6777b538SAndroid Build Coastguard Worker static const char* const font_attrs[] = { COREATTRS, I18N, "size", "color", "face" , NULL } ;
640*6777b538SAndroid Build Coastguard Worker static const char* const form_contents[] = { HEADING, LIST, INLINE, "pre", "p", "div", "center", "noscript", "noframes", "blockquote", "isindex", "hr", "table", "fieldset", "address", NULL } ;
641*6777b538SAndroid Build Coastguard Worker static const char* const form_attrs[] = { ATTRS, "method", "enctype", "accept", "name", "onsubmit", "onreset", "accept-charset", NULL } ;
642*6777b538SAndroid Build Coastguard Worker static const char* const frame_attrs[] = { COREATTRS, "longdesc", "name", "src", "frameborder", "marginwidth", "marginheight", "noresize", "scrolling" , NULL } ;
643*6777b538SAndroid Build Coastguard Worker static const char* const frameset_attrs[] = { COREATTRS, "rows", "cols", "onload", "onunload", NULL } ;
644*6777b538SAndroid Build Coastguard Worker static const char* const frameset_contents[] = { "frameset", "frame", "noframes", NULL } ;
645*6777b538SAndroid Build Coastguard Worker static const char* const head_attrs[] = { I18N, "profile", NULL } ;
646*6777b538SAndroid Build Coastguard Worker static const char* const head_contents[] = { "title", "isindex", "base", "script", "style", "meta", "link", "object", NULL } ;
647*6777b538SAndroid Build Coastguard Worker static const char* const hr_depr[] = { "align", "noshade", "size", "width", NULL } ;
648*6777b538SAndroid Build Coastguard Worker static const char* const version_attr[] = { "version", NULL } ;
649*6777b538SAndroid Build Coastguard Worker static const char* const html_content[] = { "head", "body", "frameset", NULL } ;
650*6777b538SAndroid Build Coastguard Worker static const char* const iframe_attrs[] = { COREATTRS, "longdesc", "name", "src", "frameborder", "marginwidth", "marginheight", "scrolling", "align", "height", "width", NULL } ;
651*6777b538SAndroid Build Coastguard Worker static const char* const img_attrs[] = { ATTRS, "longdesc", "name", "height", "width", "usemap", "ismap", NULL } ;
652*6777b538SAndroid Build Coastguard Worker static const char* const embed_attrs[] = { COREATTRS, "align", "alt", "border", "code", "codebase", "frameborder", "height", "hidden", "hspace", "name", "palette", "pluginspace", "pluginurl", "src", "type", "units", "vspace", "width", NULL } ;
653*6777b538SAndroid Build Coastguard Worker static const char* const input_attrs[] = { ATTRS, "type", "name", "value", "checked", "disabled", "readonly", "size", "maxlength", "src", "alt", "usemap", "ismap", "tabindex", "accesskey", "onfocus", "onblur", "onselect", "onchange", "accept", NULL } ;
654*6777b538SAndroid Build Coastguard Worker static const char* const prompt_attrs[] = { COREATTRS, I18N, "prompt", NULL } ;
655*6777b538SAndroid Build Coastguard Worker static const char* const label_attrs[] = { ATTRS, "for", "accesskey", "onfocus", "onblur", NULL } ;
656*6777b538SAndroid Build Coastguard Worker static const char* const legend_attrs[] = { ATTRS, "accesskey", NULL } ;
657*6777b538SAndroid Build Coastguard Worker static const char* const align_attr[] = { "align", NULL } ;
658*6777b538SAndroid Build Coastguard Worker static const char* const link_attrs[] = { ATTRS, "charset", "href", "hreflang", "type", "rel", "rev", "media", NULL } ;
659*6777b538SAndroid Build Coastguard Worker static const char* const map_contents[] = { BLOCK, "area", NULL } ;
660*6777b538SAndroid Build Coastguard Worker static const char* const name_attr[] = { "name", NULL } ;
661*6777b538SAndroid Build Coastguard Worker static const char* const action_attr[] = { "action", NULL } ;
662*6777b538SAndroid Build Coastguard Worker static const char* const blockli_elt[] = { BLOCK, "li", NULL } ;
663*6777b538SAndroid Build Coastguard Worker static const char* const meta_attrs[] = { I18N, "http-equiv", "name", "scheme", "charset", NULL } ;
664*6777b538SAndroid Build Coastguard Worker static const char* const content_attr[] = { "content", NULL } ;
665*6777b538SAndroid Build Coastguard Worker static const char* const type_attr[] = { "type", NULL } ;
666*6777b538SAndroid Build Coastguard Worker static const char* const noframes_content[] = { "body", FLOW MODIFIER, NULL } ;
667*6777b538SAndroid Build Coastguard Worker static const char* const object_contents[] = { FLOW, "param", NULL } ;
668*6777b538SAndroid Build Coastguard Worker static const char* const object_attrs[] = { ATTRS, "declare", "classid", "codebase", "data", "type", "codetype", "archive", "standby", "height", "width", "usemap", "name", "tabindex", NULL } ;
669*6777b538SAndroid Build Coastguard Worker static const char* const object_depr[] = { "align", "border", "hspace", "vspace", NULL } ;
670*6777b538SAndroid Build Coastguard Worker static const char* const ol_attrs[] = { "type", "compact", "start", NULL} ;
671*6777b538SAndroid Build Coastguard Worker static const char* const option_elt[] = { "option", NULL } ;
672*6777b538SAndroid Build Coastguard Worker static const char* const optgroup_attrs[] = { ATTRS, "disabled", NULL } ;
673*6777b538SAndroid Build Coastguard Worker static const char* const option_attrs[] = { ATTRS, "disabled", "label", "selected", "value", NULL } ;
674*6777b538SAndroid Build Coastguard Worker static const char* const param_attrs[] = { "id", "value", "valuetype", "type", NULL } ;
675*6777b538SAndroid Build Coastguard Worker static const char* const width_attr[] = { "width", NULL } ;
676*6777b538SAndroid Build Coastguard Worker static const char* const pre_content[] = { PHRASE, "tt", "i", "b", "u", "s", "strike", "a", "br", "script", "map", "q", "span", "bdo", "iframe", NULL } ;
677*6777b538SAndroid Build Coastguard Worker static const char* const script_attrs[] = { "charset", "src", "defer", "event", "for", NULL } ;
678*6777b538SAndroid Build Coastguard Worker static const char* const language_attr[] = { "language", NULL } ;
679*6777b538SAndroid Build Coastguard Worker static const char* const select_content[] = { "optgroup", "option", NULL } ;
680*6777b538SAndroid Build Coastguard Worker static const char* const select_attrs[] = { ATTRS, "name", "size", "multiple", "disabled", "tabindex", "onfocus", "onblur", "onchange", NULL } ;
681*6777b538SAndroid Build Coastguard Worker static const char* const style_attrs[] = { I18N, "media", "title", NULL } ;
682*6777b538SAndroid Build Coastguard Worker static const char* const table_attrs[] = { ATTRS, "summary", "width", "border", "frame", "rules", "cellspacing", "cellpadding", "datapagesize", NULL } ;
683*6777b538SAndroid Build Coastguard Worker static const char* const table_depr[] = { "align", "bgcolor", NULL } ;
684*6777b538SAndroid Build Coastguard Worker static const char* const table_contents[] = { "caption", "col", "colgroup", "thead", "tfoot", "tbody", "tr", NULL} ;
685*6777b538SAndroid Build Coastguard Worker static const char* const tr_elt[] = { "tr", NULL } ;
686*6777b538SAndroid Build Coastguard Worker static const char* const talign_attrs[] = { ATTRS, CELLHALIGN, CELLVALIGN, NULL} ;
687*6777b538SAndroid Build Coastguard Worker static const char* const th_td_depr[] = { "nowrap", "bgcolor", "width", "height", NULL } ;
688*6777b538SAndroid Build Coastguard Worker static const char* const th_td_attr[] = { ATTRS, "abbr", "axis", "headers", "scope", "rowspan", "colspan", CELLHALIGN, CELLVALIGN, NULL } ;
689*6777b538SAndroid Build Coastguard Worker static const char* const textarea_attrs[] = { ATTRS, "name", "disabled", "readonly", "tabindex", "accesskey", "onfocus", "onblur", "onselect", "onchange", NULL } ;
690*6777b538SAndroid Build Coastguard Worker static const char* const tr_contents[] = { "th", "td", NULL } ;
691*6777b538SAndroid Build Coastguard Worker static const char* const bgcolor_attr[] = { "bgcolor", NULL } ;
692*6777b538SAndroid Build Coastguard Worker static const char* const li_elt[] = { "li", NULL } ;
693*6777b538SAndroid Build Coastguard Worker static const char* const ul_depr[] = { "type", "compact", NULL} ;
694*6777b538SAndroid Build Coastguard Worker static const char* const dir_attr[] = { "dir", NULL} ;
695*6777b538SAndroid Build Coastguard Worker 
696*6777b538SAndroid Build Coastguard Worker #define DECL (const char**)
697*6777b538SAndroid Build Coastguard Worker 
698*6777b538SAndroid Build Coastguard Worker static const htmlElemDesc
699*6777b538SAndroid Build Coastguard Worker html40ElementTable[] = {
700*6777b538SAndroid Build Coastguard Worker { "a",		0, 0, 0, 0, 0, 0, 1, "anchor ",
701*6777b538SAndroid Build Coastguard Worker 	DECL html_inline , NULL , DECL a_attrs , DECL target_attr, NULL
702*6777b538SAndroid Build Coastguard Worker },
703*6777b538SAndroid Build Coastguard Worker { "abbr",	0, 0, 0, 0, 0, 0, 1, "abbreviated form",
704*6777b538SAndroid Build Coastguard Worker 	DECL html_inline , NULL , DECL html_attrs, NULL, NULL
705*6777b538SAndroid Build Coastguard Worker },
706*6777b538SAndroid Build Coastguard Worker { "acronym",	0, 0, 0, 0, 0, 0, 1, "",
707*6777b538SAndroid Build Coastguard Worker 	DECL html_inline , NULL , DECL html_attrs, NULL, NULL
708*6777b538SAndroid Build Coastguard Worker },
709*6777b538SAndroid Build Coastguard Worker { "address",	0, 0, 0, 0, 0, 0, 0, "information on author ",
710*6777b538SAndroid Build Coastguard Worker 	DECL inline_p  , NULL , DECL html_attrs, NULL, NULL
711*6777b538SAndroid Build Coastguard Worker },
712*6777b538SAndroid Build Coastguard Worker { "applet",	0, 0, 0, 0, 1, 1, 2, "java applet ",
713*6777b538SAndroid Build Coastguard Worker 	DECL flow_param , NULL , NULL , DECL applet_attrs, NULL
714*6777b538SAndroid Build Coastguard Worker },
715*6777b538SAndroid Build Coastguard Worker { "area",	0, 2, 2, 1, 0, 0, 0, "client-side image map area ",
716*6777b538SAndroid Build Coastguard Worker 	EMPTY ,  NULL , DECL area_attrs , DECL target_attr, DECL alt_attr
717*6777b538SAndroid Build Coastguard Worker },
718*6777b538SAndroid Build Coastguard Worker { "b",		0, 3, 0, 0, 0, 0, 1, "bold text style",
719*6777b538SAndroid Build Coastguard Worker 	DECL html_inline , NULL , DECL html_attrs, NULL, NULL
720*6777b538SAndroid Build Coastguard Worker },
721*6777b538SAndroid Build Coastguard Worker { "base",	0, 2, 2, 1, 0, 0, 0, "document base uri ",
722*6777b538SAndroid Build Coastguard Worker 	EMPTY , NULL , NULL , DECL target_attr, DECL href_attrs
723*6777b538SAndroid Build Coastguard Worker },
724*6777b538SAndroid Build Coastguard Worker { "basefont",	0, 2, 2, 1, 1, 1, 1, "base font size " ,
725*6777b538SAndroid Build Coastguard Worker 	EMPTY , NULL , NULL, DECL basefont_attrs, NULL
726*6777b538SAndroid Build Coastguard Worker },
727*6777b538SAndroid Build Coastguard Worker { "bdo",	0, 0, 0, 0, 0, 0, 1, "i18n bidi over-ride ",
728*6777b538SAndroid Build Coastguard Worker 	DECL html_inline , NULL , DECL core_i18n_attrs, NULL, DECL dir_attr
729*6777b538SAndroid Build Coastguard Worker },
730*6777b538SAndroid Build Coastguard Worker { "big",	0, 3, 0, 0, 0, 0, 1, "large text style",
731*6777b538SAndroid Build Coastguard Worker 	DECL html_inline , NULL , DECL html_attrs, NULL, NULL
732*6777b538SAndroid Build Coastguard Worker },
733*6777b538SAndroid Build Coastguard Worker { "blockquote",	0, 0, 0, 0, 0, 0, 0, "long quotation ",
734*6777b538SAndroid Build Coastguard Worker 	DECL html_flow , NULL , DECL quote_attrs , NULL, NULL
735*6777b538SAndroid Build Coastguard Worker },
736*6777b538SAndroid Build Coastguard Worker { "body",	1, 1, 0, 0, 0, 0, 0, "document body ",
737*6777b538SAndroid Build Coastguard Worker 	DECL body_contents , "div" , DECL body_attrs, DECL body_depr, NULL
738*6777b538SAndroid Build Coastguard Worker },
739*6777b538SAndroid Build Coastguard Worker { "br",		0, 2, 2, 1, 0, 0, 1, "forced line break ",
740*6777b538SAndroid Build Coastguard Worker 	EMPTY , NULL , DECL core_attrs, DECL clear_attrs , NULL
741*6777b538SAndroid Build Coastguard Worker },
742*6777b538SAndroid Build Coastguard Worker { "button",	0, 0, 0, 0, 0, 0, 2, "push button ",
743*6777b538SAndroid Build Coastguard Worker 	DECL html_flow MODIFIER , NULL , DECL button_attrs, NULL, NULL
744*6777b538SAndroid Build Coastguard Worker },
745*6777b538SAndroid Build Coastguard Worker { "caption",	0, 0, 0, 0, 0, 0, 0, "table caption ",
746*6777b538SAndroid Build Coastguard Worker 	DECL html_inline , NULL , DECL html_attrs, NULL, NULL
747*6777b538SAndroid Build Coastguard Worker },
748*6777b538SAndroid Build Coastguard Worker { "center",	0, 3, 0, 0, 1, 1, 0, "shorthand for div align=center ",
749*6777b538SAndroid Build Coastguard Worker 	DECL html_flow , NULL , NULL, DECL html_attrs, NULL
750*6777b538SAndroid Build Coastguard Worker },
751*6777b538SAndroid Build Coastguard Worker { "cite",	0, 0, 0, 0, 0, 0, 1, "citation",
752*6777b538SAndroid Build Coastguard Worker 	DECL html_inline , NULL , DECL html_attrs, NULL, NULL
753*6777b538SAndroid Build Coastguard Worker },
754*6777b538SAndroid Build Coastguard Worker { "code",	0, 0, 0, 0, 0, 0, 1, "computer code fragment",
755*6777b538SAndroid Build Coastguard Worker 	DECL html_inline , NULL , DECL html_attrs, NULL, NULL
756*6777b538SAndroid Build Coastguard Worker },
757*6777b538SAndroid Build Coastguard Worker { "col",	0, 2, 2, 1, 0, 0, 0, "table column ",
758*6777b538SAndroid Build Coastguard Worker 	EMPTY , NULL , DECL col_attrs , NULL, NULL
759*6777b538SAndroid Build Coastguard Worker },
760*6777b538SAndroid Build Coastguard Worker { "colgroup",	0, 1, 0, 0, 0, 0, 0, "table column group ",
761*6777b538SAndroid Build Coastguard Worker 	DECL col_elt , "col" , DECL col_attrs , NULL, NULL
762*6777b538SAndroid Build Coastguard Worker },
763*6777b538SAndroid Build Coastguard Worker { "dd",		0, 1, 0, 0, 0, 0, 0, "definition description ",
764*6777b538SAndroid Build Coastguard Worker 	DECL html_flow , NULL , DECL html_attrs, NULL, NULL
765*6777b538SAndroid Build Coastguard Worker },
766*6777b538SAndroid Build Coastguard Worker { "del",	0, 0, 0, 0, 0, 0, 2, "deleted text ",
767*6777b538SAndroid Build Coastguard Worker 	DECL html_flow , NULL , DECL edit_attrs , NULL, NULL
768*6777b538SAndroid Build Coastguard Worker },
769*6777b538SAndroid Build Coastguard Worker { "dfn",	0, 0, 0, 0, 0, 0, 1, "instance definition",
770*6777b538SAndroid Build Coastguard Worker 	DECL html_inline , NULL , DECL html_attrs, NULL, NULL
771*6777b538SAndroid Build Coastguard Worker },
772*6777b538SAndroid Build Coastguard Worker { "dir",	0, 0, 0, 0, 1, 1, 0, "directory list",
773*6777b538SAndroid Build Coastguard Worker 	DECL blockli_elt, "li" , NULL, DECL compact_attrs, NULL
774*6777b538SAndroid Build Coastguard Worker },
775*6777b538SAndroid Build Coastguard Worker { "div",	0, 0, 0, 0, 0, 0, 0, "generic language/style container",
776*6777b538SAndroid Build Coastguard Worker 	DECL html_flow, NULL, DECL html_attrs, DECL align_attr, NULL
777*6777b538SAndroid Build Coastguard Worker },
778*6777b538SAndroid Build Coastguard Worker { "dl",		0, 0, 0, 0, 0, 0, 0, "definition list ",
779*6777b538SAndroid Build Coastguard Worker 	DECL dl_contents , "dd" , DECL html_attrs, DECL compact_attr, NULL
780*6777b538SAndroid Build Coastguard Worker },
781*6777b538SAndroid Build Coastguard Worker { "dt",		0, 1, 0, 0, 0, 0, 0, "definition term ",
782*6777b538SAndroid Build Coastguard Worker 	DECL html_inline, NULL, DECL html_attrs, NULL, NULL
783*6777b538SAndroid Build Coastguard Worker },
784*6777b538SAndroid Build Coastguard Worker { "em",		0, 3, 0, 0, 0, 0, 1, "emphasis",
785*6777b538SAndroid Build Coastguard Worker 	DECL html_inline, NULL, DECL html_attrs, NULL, NULL
786*6777b538SAndroid Build Coastguard Worker },
787*6777b538SAndroid Build Coastguard Worker { "embed",	0, 1, 0, 0, 1, 1, 1, "generic embedded object ",
788*6777b538SAndroid Build Coastguard Worker 	EMPTY, NULL, DECL embed_attrs, NULL, NULL
789*6777b538SAndroid Build Coastguard Worker },
790*6777b538SAndroid Build Coastguard Worker { "fieldset",	0, 0, 0, 0, 0, 0, 0, "form control group ",
791*6777b538SAndroid Build Coastguard Worker 	DECL fieldset_contents , NULL, DECL html_attrs, NULL, NULL
792*6777b538SAndroid Build Coastguard Worker },
793*6777b538SAndroid Build Coastguard Worker { "font",	0, 3, 0, 0, 1, 1, 1, "local change to font ",
794*6777b538SAndroid Build Coastguard Worker 	DECL html_inline, NULL, NULL, DECL font_attrs, NULL
795*6777b538SAndroid Build Coastguard Worker },
796*6777b538SAndroid Build Coastguard Worker { "form",	0, 0, 0, 0, 0, 0, 0, "interactive form ",
797*6777b538SAndroid Build Coastguard Worker 	DECL form_contents, "fieldset", DECL form_attrs , DECL target_attr, DECL action_attr
798*6777b538SAndroid Build Coastguard Worker },
799*6777b538SAndroid Build Coastguard Worker { "frame",	0, 2, 2, 1, 0, 2, 0, "subwindow " ,
800*6777b538SAndroid Build Coastguard Worker 	EMPTY, NULL, NULL, DECL frame_attrs, NULL
801*6777b538SAndroid Build Coastguard Worker },
802*6777b538SAndroid Build Coastguard Worker { "frameset",	0, 0, 0, 0, 0, 2, 0, "window subdivision" ,
803*6777b538SAndroid Build Coastguard Worker 	DECL frameset_contents, "noframes" , NULL , DECL frameset_attrs, NULL
804*6777b538SAndroid Build Coastguard Worker },
805*6777b538SAndroid Build Coastguard Worker { "h1",		0, 0, 0, 0, 0, 0, 0, "heading ",
806*6777b538SAndroid Build Coastguard Worker 	DECL html_inline, NULL, DECL html_attrs, DECL align_attr, NULL
807*6777b538SAndroid Build Coastguard Worker },
808*6777b538SAndroid Build Coastguard Worker { "h2",		0, 0, 0, 0, 0, 0, 0, "heading ",
809*6777b538SAndroid Build Coastguard Worker 	DECL html_inline, NULL, DECL html_attrs, DECL align_attr, NULL
810*6777b538SAndroid Build Coastguard Worker },
811*6777b538SAndroid Build Coastguard Worker { "h3",		0, 0, 0, 0, 0, 0, 0, "heading ",
812*6777b538SAndroid Build Coastguard Worker 	DECL html_inline, NULL, DECL html_attrs, DECL align_attr, NULL
813*6777b538SAndroid Build Coastguard Worker },
814*6777b538SAndroid Build Coastguard Worker { "h4",		0, 0, 0, 0, 0, 0, 0, "heading ",
815*6777b538SAndroid Build Coastguard Worker 	DECL html_inline, NULL, DECL html_attrs, DECL align_attr, NULL
816*6777b538SAndroid Build Coastguard Worker },
817*6777b538SAndroid Build Coastguard Worker { "h5",		0, 0, 0, 0, 0, 0, 0, "heading ",
818*6777b538SAndroid Build Coastguard Worker 	DECL html_inline, NULL, DECL html_attrs, DECL align_attr, NULL
819*6777b538SAndroid Build Coastguard Worker },
820*6777b538SAndroid Build Coastguard Worker { "h6",		0, 0, 0, 0, 0, 0, 0, "heading ",
821*6777b538SAndroid Build Coastguard Worker 	DECL html_inline, NULL, DECL html_attrs, DECL align_attr, NULL
822*6777b538SAndroid Build Coastguard Worker },
823*6777b538SAndroid Build Coastguard Worker { "head",	1, 1, 0, 0, 0, 0, 0, "document head ",
824*6777b538SAndroid Build Coastguard Worker 	DECL head_contents, NULL, DECL head_attrs, NULL, NULL
825*6777b538SAndroid Build Coastguard Worker },
826*6777b538SAndroid Build Coastguard Worker { "hr",		0, 2, 2, 1, 0, 0, 0, "horizontal rule " ,
827*6777b538SAndroid Build Coastguard Worker 	EMPTY, NULL, DECL html_attrs, DECL hr_depr, NULL
828*6777b538SAndroid Build Coastguard Worker },
829*6777b538SAndroid Build Coastguard Worker { "html",	1, 1, 0, 0, 0, 0, 0, "document root element ",
830*6777b538SAndroid Build Coastguard Worker 	DECL html_content , NULL , DECL i18n_attrs, DECL version_attr, NULL
831*6777b538SAndroid Build Coastguard Worker },
832*6777b538SAndroid Build Coastguard Worker { "i",		0, 3, 0, 0, 0, 0, 1, "italic text style",
833*6777b538SAndroid Build Coastguard Worker 	DECL html_inline, NULL, DECL html_attrs, NULL, NULL
834*6777b538SAndroid Build Coastguard Worker },
835*6777b538SAndroid Build Coastguard Worker { "iframe",	0, 0, 0, 0, 0, 1, 2, "inline subwindow ",
836*6777b538SAndroid Build Coastguard Worker 	DECL html_flow, NULL, NULL, DECL iframe_attrs, NULL
837*6777b538SAndroid Build Coastguard Worker },
838*6777b538SAndroid Build Coastguard Worker { "img",	0, 2, 2, 1, 0, 0, 1, "embedded image ",
839*6777b538SAndroid Build Coastguard Worker 	EMPTY, NULL, DECL img_attrs, DECL align_attr, DECL src_alt_attrs
840*6777b538SAndroid Build Coastguard Worker },
841*6777b538SAndroid Build Coastguard Worker { "input",	0, 2, 2, 1, 0, 0, 1, "form control ",
842*6777b538SAndroid Build Coastguard Worker 	EMPTY, NULL, DECL input_attrs , DECL align_attr, NULL
843*6777b538SAndroid Build Coastguard Worker },
844*6777b538SAndroid Build Coastguard Worker { "ins",	0, 0, 0, 0, 0, 0, 2, "inserted text",
845*6777b538SAndroid Build Coastguard Worker 	DECL html_flow, NULL, DECL edit_attrs, NULL, NULL
846*6777b538SAndroid Build Coastguard Worker },
847*6777b538SAndroid Build Coastguard Worker { "isindex",	0, 2, 2, 1, 1, 1, 0, "single line prompt ",
848*6777b538SAndroid Build Coastguard Worker 	EMPTY, NULL, NULL, DECL prompt_attrs, NULL
849*6777b538SAndroid Build Coastguard Worker },
850*6777b538SAndroid Build Coastguard Worker { "kbd",	0, 0, 0, 0, 0, 0, 1, "text to be entered by the user",
851*6777b538SAndroid Build Coastguard Worker 	DECL html_inline, NULL, DECL html_attrs, NULL, NULL
852*6777b538SAndroid Build Coastguard Worker },
853*6777b538SAndroid Build Coastguard Worker { "label",	0, 0, 0, 0, 0, 0, 1, "form field label text ",
854*6777b538SAndroid Build Coastguard Worker 	DECL html_inline MODIFIER, NULL, DECL label_attrs , NULL, NULL
855*6777b538SAndroid Build Coastguard Worker },
856*6777b538SAndroid Build Coastguard Worker { "legend",	0, 0, 0, 0, 0, 0, 0, "fieldset legend ",
857*6777b538SAndroid Build Coastguard Worker 	DECL html_inline, NULL, DECL legend_attrs , DECL align_attr, NULL
858*6777b538SAndroid Build Coastguard Worker },
859*6777b538SAndroid Build Coastguard Worker { "li",		0, 1, 1, 0, 0, 0, 0, "list item ",
860*6777b538SAndroid Build Coastguard Worker 	DECL html_flow, NULL, DECL html_attrs, NULL, NULL
861*6777b538SAndroid Build Coastguard Worker },
862*6777b538SAndroid Build Coastguard Worker { "link",	0, 2, 2, 1, 0, 0, 0, "a media-independent link ",
863*6777b538SAndroid Build Coastguard Worker 	EMPTY, NULL, DECL link_attrs, DECL target_attr, NULL
864*6777b538SAndroid Build Coastguard Worker },
865*6777b538SAndroid Build Coastguard Worker { "map",	0, 0, 0, 0, 0, 0, 2, "client-side image map ",
866*6777b538SAndroid Build Coastguard Worker 	DECL map_contents , NULL, DECL html_attrs , NULL, DECL name_attr
867*6777b538SAndroid Build Coastguard Worker },
868*6777b538SAndroid Build Coastguard Worker { "menu",	0, 0, 0, 0, 1, 1, 0, "menu list ",
869*6777b538SAndroid Build Coastguard Worker 	DECL blockli_elt , NULL, NULL, DECL compact_attrs, NULL
870*6777b538SAndroid Build Coastguard Worker },
871*6777b538SAndroid Build Coastguard Worker { "meta",	0, 2, 2, 1, 0, 0, 0, "generic metainformation ",
872*6777b538SAndroid Build Coastguard Worker 	EMPTY, NULL, DECL meta_attrs , NULL , DECL content_attr
873*6777b538SAndroid Build Coastguard Worker },
874*6777b538SAndroid Build Coastguard Worker { "noframes",	0, 0, 0, 0, 0, 2, 0, "alternate content container for non frame-based rendering ",
875*6777b538SAndroid Build Coastguard Worker 	DECL noframes_content, "body" , DECL html_attrs, NULL, NULL
876*6777b538SAndroid Build Coastguard Worker },
877*6777b538SAndroid Build Coastguard Worker { "noscript",	0, 0, 0, 0, 0, 0, 0, "alternate content container for non script-based rendering ",
878*6777b538SAndroid Build Coastguard Worker 	DECL html_flow, "div", DECL html_attrs, NULL, NULL
879*6777b538SAndroid Build Coastguard Worker },
880*6777b538SAndroid Build Coastguard Worker { "object",	0, 0, 0, 0, 0, 0, 2, "generic embedded object ",
881*6777b538SAndroid Build Coastguard Worker 	DECL object_contents , "div" , DECL object_attrs, DECL object_depr, NULL
882*6777b538SAndroid Build Coastguard Worker },
883*6777b538SAndroid Build Coastguard Worker { "ol",		0, 0, 0, 0, 0, 0, 0, "ordered list ",
884*6777b538SAndroid Build Coastguard Worker 	DECL li_elt , "li" , DECL html_attrs, DECL ol_attrs, NULL
885*6777b538SAndroid Build Coastguard Worker },
886*6777b538SAndroid Build Coastguard Worker { "optgroup",	0, 0, 0, 0, 0, 0, 0, "option group ",
887*6777b538SAndroid Build Coastguard Worker 	DECL option_elt , "option", DECL optgroup_attrs, NULL, DECL label_attr
888*6777b538SAndroid Build Coastguard Worker },
889*6777b538SAndroid Build Coastguard Worker { "option",	0, 1, 0, 0, 0, 0, 0, "selectable choice " ,
890*6777b538SAndroid Build Coastguard Worker 	DECL html_pcdata, NULL, DECL option_attrs, NULL, NULL
891*6777b538SAndroid Build Coastguard Worker },
892*6777b538SAndroid Build Coastguard Worker { "p",		0, 1, 0, 0, 0, 0, 0, "paragraph ",
893*6777b538SAndroid Build Coastguard Worker 	DECL html_inline, NULL, DECL html_attrs, DECL align_attr, NULL
894*6777b538SAndroid Build Coastguard Worker },
895*6777b538SAndroid Build Coastguard Worker { "param",	0, 2, 2, 1, 0, 0, 0, "named property value ",
896*6777b538SAndroid Build Coastguard Worker 	EMPTY, NULL, DECL param_attrs, NULL, DECL name_attr
897*6777b538SAndroid Build Coastguard Worker },
898*6777b538SAndroid Build Coastguard Worker { "pre",	0, 0, 0, 0, 0, 0, 0, "preformatted text ",
899*6777b538SAndroid Build Coastguard Worker 	DECL pre_content, NULL, DECL html_attrs, DECL width_attr, NULL
900*6777b538SAndroid Build Coastguard Worker },
901*6777b538SAndroid Build Coastguard Worker { "q",		0, 0, 0, 0, 0, 0, 1, "short inline quotation ",
902*6777b538SAndroid Build Coastguard Worker 	DECL html_inline, NULL, DECL quote_attrs, NULL, NULL
903*6777b538SAndroid Build Coastguard Worker },
904*6777b538SAndroid Build Coastguard Worker { "s",		0, 3, 0, 0, 1, 1, 1, "strike-through text style",
905*6777b538SAndroid Build Coastguard Worker 	DECL html_inline, NULL, NULL, DECL html_attrs, NULL
906*6777b538SAndroid Build Coastguard Worker },
907*6777b538SAndroid Build Coastguard Worker { "samp",	0, 0, 0, 0, 0, 0, 1, "sample program output, scripts, etc.",
908*6777b538SAndroid Build Coastguard Worker 	DECL html_inline, NULL, DECL html_attrs, NULL, NULL
909*6777b538SAndroid Build Coastguard Worker },
910*6777b538SAndroid Build Coastguard Worker { "script",	0, 0, 0, 0, 0, 0, 2, "script statements ",
911*6777b538SAndroid Build Coastguard Worker 	DECL html_cdata, NULL, DECL script_attrs, DECL language_attr, DECL type_attr
912*6777b538SAndroid Build Coastguard Worker },
913*6777b538SAndroid Build Coastguard Worker { "select",	0, 0, 0, 0, 0, 0, 1, "option selector ",
914*6777b538SAndroid Build Coastguard Worker 	DECL select_content, NULL, DECL select_attrs, NULL, NULL
915*6777b538SAndroid Build Coastguard Worker },
916*6777b538SAndroid Build Coastguard Worker { "small",	0, 3, 0, 0, 0, 0, 1, "small text style",
917*6777b538SAndroid Build Coastguard Worker 	DECL html_inline, NULL, DECL html_attrs, NULL, NULL
918*6777b538SAndroid Build Coastguard Worker },
919*6777b538SAndroid Build Coastguard Worker { "span",	0, 0, 0, 0, 0, 0, 1, "generic language/style container ",
920*6777b538SAndroid Build Coastguard Worker 	DECL html_inline, NULL, DECL html_attrs, NULL, NULL
921*6777b538SAndroid Build Coastguard Worker },
922*6777b538SAndroid Build Coastguard Worker { "strike",	0, 3, 0, 0, 1, 1, 1, "strike-through text",
923*6777b538SAndroid Build Coastguard Worker 	DECL html_inline, NULL, NULL, DECL html_attrs, NULL
924*6777b538SAndroid Build Coastguard Worker },
925*6777b538SAndroid Build Coastguard Worker { "strong",	0, 3, 0, 0, 0, 0, 1, "strong emphasis",
926*6777b538SAndroid Build Coastguard Worker 	DECL html_inline, NULL, DECL html_attrs, NULL, NULL
927*6777b538SAndroid Build Coastguard Worker },
928*6777b538SAndroid Build Coastguard Worker { "style",	0, 0, 0, 0, 0, 0, 0, "style info ",
929*6777b538SAndroid Build Coastguard Worker 	DECL html_cdata, NULL, DECL style_attrs, NULL, DECL type_attr
930*6777b538SAndroid Build Coastguard Worker },
931*6777b538SAndroid Build Coastguard Worker { "sub",	0, 3, 0, 0, 0, 0, 1, "subscript",
932*6777b538SAndroid Build Coastguard Worker 	DECL html_inline, NULL, DECL html_attrs, NULL, NULL
933*6777b538SAndroid Build Coastguard Worker },
934*6777b538SAndroid Build Coastguard Worker { "sup",	0, 3, 0, 0, 0, 0, 1, "superscript ",
935*6777b538SAndroid Build Coastguard Worker 	DECL html_inline, NULL, DECL html_attrs, NULL, NULL
936*6777b538SAndroid Build Coastguard Worker },
937*6777b538SAndroid Build Coastguard Worker { "table",	0, 0, 0, 0, 0, 0, 0, "",
938*6777b538SAndroid Build Coastguard Worker 	DECL table_contents , "tr" , DECL table_attrs , DECL table_depr, NULL
939*6777b538SAndroid Build Coastguard Worker },
940*6777b538SAndroid Build Coastguard Worker { "tbody",	1, 0, 0, 0, 0, 0, 0, "table body ",
941*6777b538SAndroid Build Coastguard Worker 	DECL tr_elt , "tr" , DECL talign_attrs, NULL, NULL
942*6777b538SAndroid Build Coastguard Worker },
943*6777b538SAndroid Build Coastguard Worker { "td",		0, 0, 0, 0, 0, 0, 0, "table data cell",
944*6777b538SAndroid Build Coastguard Worker 	DECL html_flow, NULL, DECL th_td_attr, DECL th_td_depr, NULL
945*6777b538SAndroid Build Coastguard Worker },
946*6777b538SAndroid Build Coastguard Worker { "textarea",	0, 0, 0, 0, 0, 0, 1, "multi-line text field ",
947*6777b538SAndroid Build Coastguard Worker 	DECL html_pcdata, NULL, DECL textarea_attrs, NULL, DECL rows_cols_attr
948*6777b538SAndroid Build Coastguard Worker },
949*6777b538SAndroid Build Coastguard Worker { "tfoot",	0, 1, 0, 0, 0, 0, 0, "table footer ",
950*6777b538SAndroid Build Coastguard Worker 	DECL tr_elt , "tr" , DECL talign_attrs, NULL, NULL
951*6777b538SAndroid Build Coastguard Worker },
952*6777b538SAndroid Build Coastguard Worker { "th",		0, 1, 0, 0, 0, 0, 0, "table header cell",
953*6777b538SAndroid Build Coastguard Worker 	DECL html_flow, NULL, DECL th_td_attr, DECL th_td_depr, NULL
954*6777b538SAndroid Build Coastguard Worker },
955*6777b538SAndroid Build Coastguard Worker { "thead",	0, 1, 0, 0, 0, 0, 0, "table header ",
956*6777b538SAndroid Build Coastguard Worker 	DECL tr_elt , "tr" , DECL talign_attrs, NULL, NULL
957*6777b538SAndroid Build Coastguard Worker },
958*6777b538SAndroid Build Coastguard Worker { "title",	0, 0, 0, 0, 0, 0, 0, "document title ",
959*6777b538SAndroid Build Coastguard Worker 	DECL html_pcdata, NULL, DECL i18n_attrs, NULL, NULL
960*6777b538SAndroid Build Coastguard Worker },
961*6777b538SAndroid Build Coastguard Worker { "tr",		0, 0, 0, 0, 0, 0, 0, "table row ",
962*6777b538SAndroid Build Coastguard Worker 	DECL tr_contents , "td" , DECL talign_attrs, DECL bgcolor_attr, NULL
963*6777b538SAndroid Build Coastguard Worker },
964*6777b538SAndroid Build Coastguard Worker { "tt",		0, 3, 0, 0, 0, 0, 1, "teletype or monospaced text style",
965*6777b538SAndroid Build Coastguard Worker 	DECL html_inline, NULL, DECL html_attrs, NULL, NULL
966*6777b538SAndroid Build Coastguard Worker },
967*6777b538SAndroid Build Coastguard Worker { "u",		0, 3, 0, 0, 1, 1, 1, "underlined text style",
968*6777b538SAndroid Build Coastguard Worker 	DECL html_inline, NULL, NULL, DECL html_attrs, NULL
969*6777b538SAndroid Build Coastguard Worker },
970*6777b538SAndroid Build Coastguard Worker { "ul",		0, 0, 0, 0, 0, 0, 0, "unordered list ",
971*6777b538SAndroid Build Coastguard Worker 	DECL li_elt , "li" , DECL html_attrs, DECL ul_depr, NULL
972*6777b538SAndroid Build Coastguard Worker },
973*6777b538SAndroid Build Coastguard Worker { "var",	0, 0, 0, 0, 0, 0, 1, "instance of a variable or program argument",
974*6777b538SAndroid Build Coastguard Worker 	DECL html_inline, NULL, DECL html_attrs, NULL, NULL
975*6777b538SAndroid Build Coastguard Worker }
976*6777b538SAndroid Build Coastguard Worker };
977*6777b538SAndroid Build Coastguard Worker 
978*6777b538SAndroid Build Coastguard Worker typedef struct {
979*6777b538SAndroid Build Coastguard Worker     const char *oldTag;
980*6777b538SAndroid Build Coastguard Worker     const char *newTag;
981*6777b538SAndroid Build Coastguard Worker } htmlStartCloseEntry;
982*6777b538SAndroid Build Coastguard Worker 
983*6777b538SAndroid Build Coastguard Worker /*
984*6777b538SAndroid Build Coastguard Worker  * start tags that imply the end of current element
985*6777b538SAndroid Build Coastguard Worker  */
986*6777b538SAndroid Build Coastguard Worker static const htmlStartCloseEntry htmlStartClose[] = {
987*6777b538SAndroid Build Coastguard Worker     { "a", "a" },
988*6777b538SAndroid Build Coastguard Worker     { "a", "fieldset" },
989*6777b538SAndroid Build Coastguard Worker     { "a", "table" },
990*6777b538SAndroid Build Coastguard Worker     { "a", "td" },
991*6777b538SAndroid Build Coastguard Worker     { "a", "th" },
992*6777b538SAndroid Build Coastguard Worker     { "address", "dd" },
993*6777b538SAndroid Build Coastguard Worker     { "address", "dl" },
994*6777b538SAndroid Build Coastguard Worker     { "address", "dt" },
995*6777b538SAndroid Build Coastguard Worker     { "address", "form" },
996*6777b538SAndroid Build Coastguard Worker     { "address", "li" },
997*6777b538SAndroid Build Coastguard Worker     { "address", "ul" },
998*6777b538SAndroid Build Coastguard Worker     { "b", "center" },
999*6777b538SAndroid Build Coastguard Worker     { "b", "p" },
1000*6777b538SAndroid Build Coastguard Worker     { "b", "td" },
1001*6777b538SAndroid Build Coastguard Worker     { "b", "th" },
1002*6777b538SAndroid Build Coastguard Worker     { "big", "p" },
1003*6777b538SAndroid Build Coastguard Worker     { "caption", "col" },
1004*6777b538SAndroid Build Coastguard Worker     { "caption", "colgroup" },
1005*6777b538SAndroid Build Coastguard Worker     { "caption", "tbody" },
1006*6777b538SAndroid Build Coastguard Worker     { "caption", "tfoot" },
1007*6777b538SAndroid Build Coastguard Worker     { "caption", "thead" },
1008*6777b538SAndroid Build Coastguard Worker     { "caption", "tr" },
1009*6777b538SAndroid Build Coastguard Worker     { "col", "col" },
1010*6777b538SAndroid Build Coastguard Worker     { "col", "colgroup" },
1011*6777b538SAndroid Build Coastguard Worker     { "col", "tbody" },
1012*6777b538SAndroid Build Coastguard Worker     { "col", "tfoot" },
1013*6777b538SAndroid Build Coastguard Worker     { "col", "thead" },
1014*6777b538SAndroid Build Coastguard Worker     { "col", "tr" },
1015*6777b538SAndroid Build Coastguard Worker     { "colgroup", "colgroup" },
1016*6777b538SAndroid Build Coastguard Worker     { "colgroup", "tbody" },
1017*6777b538SAndroid Build Coastguard Worker     { "colgroup", "tfoot" },
1018*6777b538SAndroid Build Coastguard Worker     { "colgroup", "thead" },
1019*6777b538SAndroid Build Coastguard Worker     { "colgroup", "tr" },
1020*6777b538SAndroid Build Coastguard Worker     { "dd", "dt" },
1021*6777b538SAndroid Build Coastguard Worker     { "dir", "dd" },
1022*6777b538SAndroid Build Coastguard Worker     { "dir", "dl" },
1023*6777b538SAndroid Build Coastguard Worker     { "dir", "dt" },
1024*6777b538SAndroid Build Coastguard Worker     { "dir", "form" },
1025*6777b538SAndroid Build Coastguard Worker     { "dir", "ul" },
1026*6777b538SAndroid Build Coastguard Worker     { "dl", "form" },
1027*6777b538SAndroid Build Coastguard Worker     { "dl", "li" },
1028*6777b538SAndroid Build Coastguard Worker     { "dt", "dd" },
1029*6777b538SAndroid Build Coastguard Worker     { "dt", "dl" },
1030*6777b538SAndroid Build Coastguard Worker     { "font", "center" },
1031*6777b538SAndroid Build Coastguard Worker     { "font", "td" },
1032*6777b538SAndroid Build Coastguard Worker     { "font", "th" },
1033*6777b538SAndroid Build Coastguard Worker     { "form", "form" },
1034*6777b538SAndroid Build Coastguard Worker     { "h1", "fieldset" },
1035*6777b538SAndroid Build Coastguard Worker     { "h1", "form" },
1036*6777b538SAndroid Build Coastguard Worker     { "h1", "li" },
1037*6777b538SAndroid Build Coastguard Worker     { "h1", "p" },
1038*6777b538SAndroid Build Coastguard Worker     { "h1", "table" },
1039*6777b538SAndroid Build Coastguard Worker     { "h2", "fieldset" },
1040*6777b538SAndroid Build Coastguard Worker     { "h2", "form" },
1041*6777b538SAndroid Build Coastguard Worker     { "h2", "li" },
1042*6777b538SAndroid Build Coastguard Worker     { "h2", "p" },
1043*6777b538SAndroid Build Coastguard Worker     { "h2", "table" },
1044*6777b538SAndroid Build Coastguard Worker     { "h3", "fieldset" },
1045*6777b538SAndroid Build Coastguard Worker     { "h3", "form" },
1046*6777b538SAndroid Build Coastguard Worker     { "h3", "li" },
1047*6777b538SAndroid Build Coastguard Worker     { "h3", "p" },
1048*6777b538SAndroid Build Coastguard Worker     { "h3", "table" },
1049*6777b538SAndroid Build Coastguard Worker     { "h4", "fieldset" },
1050*6777b538SAndroid Build Coastguard Worker     { "h4", "form" },
1051*6777b538SAndroid Build Coastguard Worker     { "h4", "li" },
1052*6777b538SAndroid Build Coastguard Worker     { "h4", "p" },
1053*6777b538SAndroid Build Coastguard Worker     { "h4", "table" },
1054*6777b538SAndroid Build Coastguard Worker     { "h5", "fieldset" },
1055*6777b538SAndroid Build Coastguard Worker     { "h5", "form" },
1056*6777b538SAndroid Build Coastguard Worker     { "h5", "li" },
1057*6777b538SAndroid Build Coastguard Worker     { "h5", "p" },
1058*6777b538SAndroid Build Coastguard Worker     { "h5", "table" },
1059*6777b538SAndroid Build Coastguard Worker     { "h6", "fieldset" },
1060*6777b538SAndroid Build Coastguard Worker     { "h6", "form" },
1061*6777b538SAndroid Build Coastguard Worker     { "h6", "li" },
1062*6777b538SAndroid Build Coastguard Worker     { "h6", "p" },
1063*6777b538SAndroid Build Coastguard Worker     { "h6", "table" },
1064*6777b538SAndroid Build Coastguard Worker     { "head", "a" },
1065*6777b538SAndroid Build Coastguard Worker     { "head", "abbr" },
1066*6777b538SAndroid Build Coastguard Worker     { "head", "acronym" },
1067*6777b538SAndroid Build Coastguard Worker     { "head", "address" },
1068*6777b538SAndroid Build Coastguard Worker     { "head", "b" },
1069*6777b538SAndroid Build Coastguard Worker     { "head", "bdo" },
1070*6777b538SAndroid Build Coastguard Worker     { "head", "big" },
1071*6777b538SAndroid Build Coastguard Worker     { "head", "blockquote" },
1072*6777b538SAndroid Build Coastguard Worker     { "head", "body" },
1073*6777b538SAndroid Build Coastguard Worker     { "head", "br" },
1074*6777b538SAndroid Build Coastguard Worker     { "head", "center" },
1075*6777b538SAndroid Build Coastguard Worker     { "head", "cite" },
1076*6777b538SAndroid Build Coastguard Worker     { "head", "code" },
1077*6777b538SAndroid Build Coastguard Worker     { "head", "dd" },
1078*6777b538SAndroid Build Coastguard Worker     { "head", "dfn" },
1079*6777b538SAndroid Build Coastguard Worker     { "head", "dir" },
1080*6777b538SAndroid Build Coastguard Worker     { "head", "div" },
1081*6777b538SAndroid Build Coastguard Worker     { "head", "dl" },
1082*6777b538SAndroid Build Coastguard Worker     { "head", "dt" },
1083*6777b538SAndroid Build Coastguard Worker     { "head", "em" },
1084*6777b538SAndroid Build Coastguard Worker     { "head", "fieldset" },
1085*6777b538SAndroid Build Coastguard Worker     { "head", "font" },
1086*6777b538SAndroid Build Coastguard Worker     { "head", "form" },
1087*6777b538SAndroid Build Coastguard Worker     { "head", "frameset" },
1088*6777b538SAndroid Build Coastguard Worker     { "head", "h1" },
1089*6777b538SAndroid Build Coastguard Worker     { "head", "h2" },
1090*6777b538SAndroid Build Coastguard Worker     { "head", "h3" },
1091*6777b538SAndroid Build Coastguard Worker     { "head", "h4" },
1092*6777b538SAndroid Build Coastguard Worker     { "head", "h5" },
1093*6777b538SAndroid Build Coastguard Worker     { "head", "h6" },
1094*6777b538SAndroid Build Coastguard Worker     { "head", "hr" },
1095*6777b538SAndroid Build Coastguard Worker     { "head", "i" },
1096*6777b538SAndroid Build Coastguard Worker     { "head", "iframe" },
1097*6777b538SAndroid Build Coastguard Worker     { "head", "img" },
1098*6777b538SAndroid Build Coastguard Worker     { "head", "kbd" },
1099*6777b538SAndroid Build Coastguard Worker     { "head", "li" },
1100*6777b538SAndroid Build Coastguard Worker     { "head", "listing" },
1101*6777b538SAndroid Build Coastguard Worker     { "head", "map" },
1102*6777b538SAndroid Build Coastguard Worker     { "head", "menu" },
1103*6777b538SAndroid Build Coastguard Worker     { "head", "ol" },
1104*6777b538SAndroid Build Coastguard Worker     { "head", "p" },
1105*6777b538SAndroid Build Coastguard Worker     { "head", "pre" },
1106*6777b538SAndroid Build Coastguard Worker     { "head", "q" },
1107*6777b538SAndroid Build Coastguard Worker     { "head", "s" },
1108*6777b538SAndroid Build Coastguard Worker     { "head", "samp" },
1109*6777b538SAndroid Build Coastguard Worker     { "head", "small" },
1110*6777b538SAndroid Build Coastguard Worker     { "head", "span" },
1111*6777b538SAndroid Build Coastguard Worker     { "head", "strike" },
1112*6777b538SAndroid Build Coastguard Worker     { "head", "strong" },
1113*6777b538SAndroid Build Coastguard Worker     { "head", "sub" },
1114*6777b538SAndroid Build Coastguard Worker     { "head", "sup" },
1115*6777b538SAndroid Build Coastguard Worker     { "head", "table" },
1116*6777b538SAndroid Build Coastguard Worker     { "head", "tt" },
1117*6777b538SAndroid Build Coastguard Worker     { "head", "u" },
1118*6777b538SAndroid Build Coastguard Worker     { "head", "ul" },
1119*6777b538SAndroid Build Coastguard Worker     { "head", "var" },
1120*6777b538SAndroid Build Coastguard Worker     { "head", "xmp" },
1121*6777b538SAndroid Build Coastguard Worker     { "hr", "form" },
1122*6777b538SAndroid Build Coastguard Worker     { "i", "center" },
1123*6777b538SAndroid Build Coastguard Worker     { "i", "p" },
1124*6777b538SAndroid Build Coastguard Worker     { "i", "td" },
1125*6777b538SAndroid Build Coastguard Worker     { "i", "th" },
1126*6777b538SAndroid Build Coastguard Worker     { "legend", "fieldset" },
1127*6777b538SAndroid Build Coastguard Worker     { "li", "li" },
1128*6777b538SAndroid Build Coastguard Worker     { "link", "body" },
1129*6777b538SAndroid Build Coastguard Worker     { "link", "frameset" },
1130*6777b538SAndroid Build Coastguard Worker     { "listing", "dd" },
1131*6777b538SAndroid Build Coastguard Worker     { "listing", "dl" },
1132*6777b538SAndroid Build Coastguard Worker     { "listing", "dt" },
1133*6777b538SAndroid Build Coastguard Worker     { "listing", "fieldset" },
1134*6777b538SAndroid Build Coastguard Worker     { "listing", "form" },
1135*6777b538SAndroid Build Coastguard Worker     { "listing", "li" },
1136*6777b538SAndroid Build Coastguard Worker     { "listing", "table" },
1137*6777b538SAndroid Build Coastguard Worker     { "listing", "ul" },
1138*6777b538SAndroid Build Coastguard Worker     { "menu", "dd" },
1139*6777b538SAndroid Build Coastguard Worker     { "menu", "dl" },
1140*6777b538SAndroid Build Coastguard Worker     { "menu", "dt" },
1141*6777b538SAndroid Build Coastguard Worker     { "menu", "form" },
1142*6777b538SAndroid Build Coastguard Worker     { "menu", "ul" },
1143*6777b538SAndroid Build Coastguard Worker     { "ol", "form" },
1144*6777b538SAndroid Build Coastguard Worker     { "option", "optgroup" },
1145*6777b538SAndroid Build Coastguard Worker     { "option", "option" },
1146*6777b538SAndroid Build Coastguard Worker     { "p", "address" },
1147*6777b538SAndroid Build Coastguard Worker     { "p", "blockquote" },
1148*6777b538SAndroid Build Coastguard Worker     { "p", "body" },
1149*6777b538SAndroid Build Coastguard Worker     { "p", "caption" },
1150*6777b538SAndroid Build Coastguard Worker     { "p", "center" },
1151*6777b538SAndroid Build Coastguard Worker     { "p", "col" },
1152*6777b538SAndroid Build Coastguard Worker     { "p", "colgroup" },
1153*6777b538SAndroid Build Coastguard Worker     { "p", "dd" },
1154*6777b538SAndroid Build Coastguard Worker     { "p", "dir" },
1155*6777b538SAndroid Build Coastguard Worker     { "p", "div" },
1156*6777b538SAndroid Build Coastguard Worker     { "p", "dl" },
1157*6777b538SAndroid Build Coastguard Worker     { "p", "dt" },
1158*6777b538SAndroid Build Coastguard Worker     { "p", "fieldset" },
1159*6777b538SAndroid Build Coastguard Worker     { "p", "form" },
1160*6777b538SAndroid Build Coastguard Worker     { "p", "frameset" },
1161*6777b538SAndroid Build Coastguard Worker     { "p", "h1" },
1162*6777b538SAndroid Build Coastguard Worker     { "p", "h2" },
1163*6777b538SAndroid Build Coastguard Worker     { "p", "h3" },
1164*6777b538SAndroid Build Coastguard Worker     { "p", "h4" },
1165*6777b538SAndroid Build Coastguard Worker     { "p", "h5" },
1166*6777b538SAndroid Build Coastguard Worker     { "p", "h6" },
1167*6777b538SAndroid Build Coastguard Worker     { "p", "head" },
1168*6777b538SAndroid Build Coastguard Worker     { "p", "hr" },
1169*6777b538SAndroid Build Coastguard Worker     { "p", "li" },
1170*6777b538SAndroid Build Coastguard Worker     { "p", "listing" },
1171*6777b538SAndroid Build Coastguard Worker     { "p", "menu" },
1172*6777b538SAndroid Build Coastguard Worker     { "p", "ol" },
1173*6777b538SAndroid Build Coastguard Worker     { "p", "p" },
1174*6777b538SAndroid Build Coastguard Worker     { "p", "pre" },
1175*6777b538SAndroid Build Coastguard Worker     { "p", "table" },
1176*6777b538SAndroid Build Coastguard Worker     { "p", "tbody" },
1177*6777b538SAndroid Build Coastguard Worker     { "p", "td" },
1178*6777b538SAndroid Build Coastguard Worker     { "p", "tfoot" },
1179*6777b538SAndroid Build Coastguard Worker     { "p", "th" },
1180*6777b538SAndroid Build Coastguard Worker     { "p", "title" },
1181*6777b538SAndroid Build Coastguard Worker     { "p", "tr" },
1182*6777b538SAndroid Build Coastguard Worker     { "p", "ul" },
1183*6777b538SAndroid Build Coastguard Worker     { "p", "xmp" },
1184*6777b538SAndroid Build Coastguard Worker     { "pre", "dd" },
1185*6777b538SAndroid Build Coastguard Worker     { "pre", "dl" },
1186*6777b538SAndroid Build Coastguard Worker     { "pre", "dt" },
1187*6777b538SAndroid Build Coastguard Worker     { "pre", "fieldset" },
1188*6777b538SAndroid Build Coastguard Worker     { "pre", "form" },
1189*6777b538SAndroid Build Coastguard Worker     { "pre", "li" },
1190*6777b538SAndroid Build Coastguard Worker     { "pre", "table" },
1191*6777b538SAndroid Build Coastguard Worker     { "pre", "ul" },
1192*6777b538SAndroid Build Coastguard Worker     { "s", "p" },
1193*6777b538SAndroid Build Coastguard Worker     { "script", "noscript" },
1194*6777b538SAndroid Build Coastguard Worker     { "small", "p" },
1195*6777b538SAndroid Build Coastguard Worker     { "span", "td" },
1196*6777b538SAndroid Build Coastguard Worker     { "span", "th" },
1197*6777b538SAndroid Build Coastguard Worker     { "strike", "p" },
1198*6777b538SAndroid Build Coastguard Worker     { "style", "body" },
1199*6777b538SAndroid Build Coastguard Worker     { "style", "frameset" },
1200*6777b538SAndroid Build Coastguard Worker     { "tbody", "tbody" },
1201*6777b538SAndroid Build Coastguard Worker     { "tbody", "tfoot" },
1202*6777b538SAndroid Build Coastguard Worker     { "td", "tbody" },
1203*6777b538SAndroid Build Coastguard Worker     { "td", "td" },
1204*6777b538SAndroid Build Coastguard Worker     { "td", "tfoot" },
1205*6777b538SAndroid Build Coastguard Worker     { "td", "th" },
1206*6777b538SAndroid Build Coastguard Worker     { "td", "tr" },
1207*6777b538SAndroid Build Coastguard Worker     { "tfoot", "tbody" },
1208*6777b538SAndroid Build Coastguard Worker     { "th", "tbody" },
1209*6777b538SAndroid Build Coastguard Worker     { "th", "td" },
1210*6777b538SAndroid Build Coastguard Worker     { "th", "tfoot" },
1211*6777b538SAndroid Build Coastguard Worker     { "th", "th" },
1212*6777b538SAndroid Build Coastguard Worker     { "th", "tr" },
1213*6777b538SAndroid Build Coastguard Worker     { "thead", "tbody" },
1214*6777b538SAndroid Build Coastguard Worker     { "thead", "tfoot" },
1215*6777b538SAndroid Build Coastguard Worker     { "title", "body" },
1216*6777b538SAndroid Build Coastguard Worker     { "title", "frameset" },
1217*6777b538SAndroid Build Coastguard Worker     { "tr", "tbody" },
1218*6777b538SAndroid Build Coastguard Worker     { "tr", "tfoot" },
1219*6777b538SAndroid Build Coastguard Worker     { "tr", "tr" },
1220*6777b538SAndroid Build Coastguard Worker     { "tt", "p" },
1221*6777b538SAndroid Build Coastguard Worker     { "u", "p" },
1222*6777b538SAndroid Build Coastguard Worker     { "u", "td" },
1223*6777b538SAndroid Build Coastguard Worker     { "u", "th" },
1224*6777b538SAndroid Build Coastguard Worker     { "ul", "address" },
1225*6777b538SAndroid Build Coastguard Worker     { "ul", "form" },
1226*6777b538SAndroid Build Coastguard Worker     { "ul", "menu" },
1227*6777b538SAndroid Build Coastguard Worker     { "ul", "pre" },
1228*6777b538SAndroid Build Coastguard Worker     { "xmp", "dd" },
1229*6777b538SAndroid Build Coastguard Worker     { "xmp", "dl" },
1230*6777b538SAndroid Build Coastguard Worker     { "xmp", "dt" },
1231*6777b538SAndroid Build Coastguard Worker     { "xmp", "fieldset" },
1232*6777b538SAndroid Build Coastguard Worker     { "xmp", "form" },
1233*6777b538SAndroid Build Coastguard Worker     { "xmp", "li" },
1234*6777b538SAndroid Build Coastguard Worker     { "xmp", "table" },
1235*6777b538SAndroid Build Coastguard Worker     { "xmp", "ul" }
1236*6777b538SAndroid Build Coastguard Worker };
1237*6777b538SAndroid Build Coastguard Worker 
1238*6777b538SAndroid Build Coastguard Worker /*
1239*6777b538SAndroid Build Coastguard Worker  * The list of HTML elements which are supposed not to have
1240*6777b538SAndroid Build Coastguard Worker  * CDATA content and where a p element will be implied
1241*6777b538SAndroid Build Coastguard Worker  *
1242*6777b538SAndroid Build Coastguard Worker  * TODO: extend that list by reading the HTML SGML DTD on
1243*6777b538SAndroid Build Coastguard Worker  *       implied paragraph
1244*6777b538SAndroid Build Coastguard Worker  */
1245*6777b538SAndroid Build Coastguard Worker static const char *const htmlNoContentElements[] = {
1246*6777b538SAndroid Build Coastguard Worker     "html",
1247*6777b538SAndroid Build Coastguard Worker     "head",
1248*6777b538SAndroid Build Coastguard Worker     NULL
1249*6777b538SAndroid Build Coastguard Worker };
1250*6777b538SAndroid Build Coastguard Worker 
1251*6777b538SAndroid Build Coastguard Worker /*
1252*6777b538SAndroid Build Coastguard Worker  * The list of HTML attributes which are of content %Script;
1253*6777b538SAndroid Build Coastguard Worker  * NOTE: when adding ones, check htmlIsScriptAttribute() since
1254*6777b538SAndroid Build Coastguard Worker  *       it assumes the name starts with 'on'
1255*6777b538SAndroid Build Coastguard Worker  */
1256*6777b538SAndroid Build Coastguard Worker static const char *const htmlScriptAttributes[] = {
1257*6777b538SAndroid Build Coastguard Worker     "onclick",
1258*6777b538SAndroid Build Coastguard Worker     "ondblclick",
1259*6777b538SAndroid Build Coastguard Worker     "onmousedown",
1260*6777b538SAndroid Build Coastguard Worker     "onmouseup",
1261*6777b538SAndroid Build Coastguard Worker     "onmouseover",
1262*6777b538SAndroid Build Coastguard Worker     "onmousemove",
1263*6777b538SAndroid Build Coastguard Worker     "onmouseout",
1264*6777b538SAndroid Build Coastguard Worker     "onkeypress",
1265*6777b538SAndroid Build Coastguard Worker     "onkeydown",
1266*6777b538SAndroid Build Coastguard Worker     "onkeyup",
1267*6777b538SAndroid Build Coastguard Worker     "onload",
1268*6777b538SAndroid Build Coastguard Worker     "onunload",
1269*6777b538SAndroid Build Coastguard Worker     "onfocus",
1270*6777b538SAndroid Build Coastguard Worker     "onblur",
1271*6777b538SAndroid Build Coastguard Worker     "onsubmit",
1272*6777b538SAndroid Build Coastguard Worker     "onreset",
1273*6777b538SAndroid Build Coastguard Worker     "onchange",
1274*6777b538SAndroid Build Coastguard Worker     "onselect"
1275*6777b538SAndroid Build Coastguard Worker };
1276*6777b538SAndroid Build Coastguard Worker 
1277*6777b538SAndroid Build Coastguard Worker /*
1278*6777b538SAndroid Build Coastguard Worker  * This table is used by the htmlparser to know what to do with
1279*6777b538SAndroid Build Coastguard Worker  * broken html pages. By assigning different priorities to different
1280*6777b538SAndroid Build Coastguard Worker  * elements the parser can decide how to handle extra endtags.
1281*6777b538SAndroid Build Coastguard Worker  * Endtags are only allowed to close elements with lower or equal
1282*6777b538SAndroid Build Coastguard Worker  * priority.
1283*6777b538SAndroid Build Coastguard Worker  */
1284*6777b538SAndroid Build Coastguard Worker 
1285*6777b538SAndroid Build Coastguard Worker typedef struct {
1286*6777b538SAndroid Build Coastguard Worker     const char *name;
1287*6777b538SAndroid Build Coastguard Worker     int priority;
1288*6777b538SAndroid Build Coastguard Worker } elementPriority;
1289*6777b538SAndroid Build Coastguard Worker 
1290*6777b538SAndroid Build Coastguard Worker static const elementPriority htmlEndPriority[] = {
1291*6777b538SAndroid Build Coastguard Worker     {"div",   150},
1292*6777b538SAndroid Build Coastguard Worker     {"td",    160},
1293*6777b538SAndroid Build Coastguard Worker     {"th",    160},
1294*6777b538SAndroid Build Coastguard Worker     {"tr",    170},
1295*6777b538SAndroid Build Coastguard Worker     {"thead", 180},
1296*6777b538SAndroid Build Coastguard Worker     {"tbody", 180},
1297*6777b538SAndroid Build Coastguard Worker     {"tfoot", 180},
1298*6777b538SAndroid Build Coastguard Worker     {"table", 190},
1299*6777b538SAndroid Build Coastguard Worker     {"head",  200},
1300*6777b538SAndroid Build Coastguard Worker     {"body",  200},
1301*6777b538SAndroid Build Coastguard Worker     {"html",  220},
1302*6777b538SAndroid Build Coastguard Worker     {NULL,    100} /* Default priority */
1303*6777b538SAndroid Build Coastguard Worker };
1304*6777b538SAndroid Build Coastguard Worker 
1305*6777b538SAndroid Build Coastguard Worker /************************************************************************
1306*6777b538SAndroid Build Coastguard Worker  *									*
1307*6777b538SAndroid Build Coastguard Worker  *	functions to handle HTML specific data			*
1308*6777b538SAndroid Build Coastguard Worker  *									*
1309*6777b538SAndroid Build Coastguard Worker  ************************************************************************/
1310*6777b538SAndroid Build Coastguard Worker 
1311*6777b538SAndroid Build Coastguard Worker /**
1312*6777b538SAndroid Build Coastguard Worker  * htmlInitAutoClose:
1313*6777b538SAndroid Build Coastguard Worker  *
1314*6777b538SAndroid Build Coastguard Worker  * DEPRECATED: This is a no-op.
1315*6777b538SAndroid Build Coastguard Worker  */
1316*6777b538SAndroid Build Coastguard Worker void
htmlInitAutoClose(void)1317*6777b538SAndroid Build Coastguard Worker htmlInitAutoClose(void) {
1318*6777b538SAndroid Build Coastguard Worker }
1319*6777b538SAndroid Build Coastguard Worker 
1320*6777b538SAndroid Build Coastguard Worker static int
htmlCompareTags(const void * key,const void * member)1321*6777b538SAndroid Build Coastguard Worker htmlCompareTags(const void *key, const void *member) {
1322*6777b538SAndroid Build Coastguard Worker     const xmlChar *tag = (const xmlChar *) key;
1323*6777b538SAndroid Build Coastguard Worker     const htmlElemDesc *desc = (const htmlElemDesc *) member;
1324*6777b538SAndroid Build Coastguard Worker 
1325*6777b538SAndroid Build Coastguard Worker     return(xmlStrcasecmp(tag, BAD_CAST desc->name));
1326*6777b538SAndroid Build Coastguard Worker }
1327*6777b538SAndroid Build Coastguard Worker 
1328*6777b538SAndroid Build Coastguard Worker /**
1329*6777b538SAndroid Build Coastguard Worker  * htmlTagLookup:
1330*6777b538SAndroid Build Coastguard Worker  * @tag:  The tag name in lowercase
1331*6777b538SAndroid Build Coastguard Worker  *
1332*6777b538SAndroid Build Coastguard Worker  * Lookup the HTML tag in the ElementTable
1333*6777b538SAndroid Build Coastguard Worker  *
1334*6777b538SAndroid Build Coastguard Worker  * Returns the related htmlElemDescPtr or NULL if not found.
1335*6777b538SAndroid Build Coastguard Worker  */
1336*6777b538SAndroid Build Coastguard Worker const htmlElemDesc *
htmlTagLookup(const xmlChar * tag)1337*6777b538SAndroid Build Coastguard Worker htmlTagLookup(const xmlChar *tag) {
1338*6777b538SAndroid Build Coastguard Worker     if (tag == NULL)
1339*6777b538SAndroid Build Coastguard Worker         return(NULL);
1340*6777b538SAndroid Build Coastguard Worker 
1341*6777b538SAndroid Build Coastguard Worker     return((const htmlElemDesc *) bsearch(tag, html40ElementTable,
1342*6777b538SAndroid Build Coastguard Worker                 sizeof(html40ElementTable) / sizeof(htmlElemDesc),
1343*6777b538SAndroid Build Coastguard Worker                 sizeof(htmlElemDesc), htmlCompareTags));
1344*6777b538SAndroid Build Coastguard Worker }
1345*6777b538SAndroid Build Coastguard Worker 
1346*6777b538SAndroid Build Coastguard Worker /**
1347*6777b538SAndroid Build Coastguard Worker  * htmlGetEndPriority:
1348*6777b538SAndroid Build Coastguard Worker  * @name: The name of the element to look up the priority for.
1349*6777b538SAndroid Build Coastguard Worker  *
1350*6777b538SAndroid Build Coastguard Worker  * Return value: The "endtag" priority.
1351*6777b538SAndroid Build Coastguard Worker  **/
1352*6777b538SAndroid Build Coastguard Worker static int
htmlGetEndPriority(const xmlChar * name)1353*6777b538SAndroid Build Coastguard Worker htmlGetEndPriority (const xmlChar *name) {
1354*6777b538SAndroid Build Coastguard Worker     int i = 0;
1355*6777b538SAndroid Build Coastguard Worker 
1356*6777b538SAndroid Build Coastguard Worker     while ((htmlEndPriority[i].name != NULL) &&
1357*6777b538SAndroid Build Coastguard Worker 	   (!xmlStrEqual((const xmlChar *)htmlEndPriority[i].name, name)))
1358*6777b538SAndroid Build Coastguard Worker 	i++;
1359*6777b538SAndroid Build Coastguard Worker 
1360*6777b538SAndroid Build Coastguard Worker     return(htmlEndPriority[i].priority);
1361*6777b538SAndroid Build Coastguard Worker }
1362*6777b538SAndroid Build Coastguard Worker 
1363*6777b538SAndroid Build Coastguard Worker 
1364*6777b538SAndroid Build Coastguard Worker static int
htmlCompareStartClose(const void * vkey,const void * member)1365*6777b538SAndroid Build Coastguard Worker htmlCompareStartClose(const void *vkey, const void *member) {
1366*6777b538SAndroid Build Coastguard Worker     const htmlStartCloseEntry *key = (const htmlStartCloseEntry *) vkey;
1367*6777b538SAndroid Build Coastguard Worker     const htmlStartCloseEntry *entry = (const htmlStartCloseEntry *) member;
1368*6777b538SAndroid Build Coastguard Worker     int ret;
1369*6777b538SAndroid Build Coastguard Worker 
1370*6777b538SAndroid Build Coastguard Worker     ret = strcmp(key->oldTag, entry->oldTag);
1371*6777b538SAndroid Build Coastguard Worker     if (ret == 0)
1372*6777b538SAndroid Build Coastguard Worker         ret = strcmp(key->newTag, entry->newTag);
1373*6777b538SAndroid Build Coastguard Worker 
1374*6777b538SAndroid Build Coastguard Worker     return(ret);
1375*6777b538SAndroid Build Coastguard Worker }
1376*6777b538SAndroid Build Coastguard Worker 
1377*6777b538SAndroid Build Coastguard Worker /**
1378*6777b538SAndroid Build Coastguard Worker  * htmlCheckAutoClose:
1379*6777b538SAndroid Build Coastguard Worker  * @newtag:  The new tag name
1380*6777b538SAndroid Build Coastguard Worker  * @oldtag:  The old tag name
1381*6777b538SAndroid Build Coastguard Worker  *
1382*6777b538SAndroid Build Coastguard Worker  * Checks whether the new tag is one of the registered valid tags for
1383*6777b538SAndroid Build Coastguard Worker  * closing old.
1384*6777b538SAndroid Build Coastguard Worker  *
1385*6777b538SAndroid Build Coastguard Worker  * Returns 0 if no, 1 if yes.
1386*6777b538SAndroid Build Coastguard Worker  */
1387*6777b538SAndroid Build Coastguard Worker static int
htmlCheckAutoClose(const xmlChar * newtag,const xmlChar * oldtag)1388*6777b538SAndroid Build Coastguard Worker htmlCheckAutoClose(const xmlChar * newtag, const xmlChar * oldtag)
1389*6777b538SAndroid Build Coastguard Worker {
1390*6777b538SAndroid Build Coastguard Worker     htmlStartCloseEntry key;
1391*6777b538SAndroid Build Coastguard Worker     void *res;
1392*6777b538SAndroid Build Coastguard Worker 
1393*6777b538SAndroid Build Coastguard Worker     key.oldTag = (const char *) oldtag;
1394*6777b538SAndroid Build Coastguard Worker     key.newTag = (const char *) newtag;
1395*6777b538SAndroid Build Coastguard Worker     res = bsearch(&key, htmlStartClose,
1396*6777b538SAndroid Build Coastguard Worker             sizeof(htmlStartClose) / sizeof(htmlStartCloseEntry),
1397*6777b538SAndroid Build Coastguard Worker             sizeof(htmlStartCloseEntry), htmlCompareStartClose);
1398*6777b538SAndroid Build Coastguard Worker     return(res != NULL);
1399*6777b538SAndroid Build Coastguard Worker }
1400*6777b538SAndroid Build Coastguard Worker 
1401*6777b538SAndroid Build Coastguard Worker /**
1402*6777b538SAndroid Build Coastguard Worker  * htmlAutoCloseOnClose:
1403*6777b538SAndroid Build Coastguard Worker  * @ctxt:  an HTML parser context
1404*6777b538SAndroid Build Coastguard Worker  * @newtag:  The new tag name
1405*6777b538SAndroid Build Coastguard Worker  * @force:  force the tag closure
1406*6777b538SAndroid Build Coastguard Worker  *
1407*6777b538SAndroid Build Coastguard Worker  * The HTML DTD allows an ending tag to implicitly close other tags.
1408*6777b538SAndroid Build Coastguard Worker  */
1409*6777b538SAndroid Build Coastguard Worker static void
htmlAutoCloseOnClose(htmlParserCtxtPtr ctxt,const xmlChar * newtag)1410*6777b538SAndroid Build Coastguard Worker htmlAutoCloseOnClose(htmlParserCtxtPtr ctxt, const xmlChar * newtag)
1411*6777b538SAndroid Build Coastguard Worker {
1412*6777b538SAndroid Build Coastguard Worker     const htmlElemDesc *info;
1413*6777b538SAndroid Build Coastguard Worker     int i, priority;
1414*6777b538SAndroid Build Coastguard Worker 
1415*6777b538SAndroid Build Coastguard Worker     priority = htmlGetEndPriority(newtag);
1416*6777b538SAndroid Build Coastguard Worker 
1417*6777b538SAndroid Build Coastguard Worker     for (i = (ctxt->nameNr - 1); i >= 0; i--) {
1418*6777b538SAndroid Build Coastguard Worker 
1419*6777b538SAndroid Build Coastguard Worker         if (xmlStrEqual(newtag, ctxt->nameTab[i]))
1420*6777b538SAndroid Build Coastguard Worker             break;
1421*6777b538SAndroid Build Coastguard Worker         /*
1422*6777b538SAndroid Build Coastguard Worker          * A misplaced endtag can only close elements with lower
1423*6777b538SAndroid Build Coastguard Worker          * or equal priority, so if we find an element with higher
1424*6777b538SAndroid Build Coastguard Worker          * priority before we find an element with
1425*6777b538SAndroid Build Coastguard Worker          * matching name, we just ignore this endtag
1426*6777b538SAndroid Build Coastguard Worker          */
1427*6777b538SAndroid Build Coastguard Worker         if (htmlGetEndPriority(ctxt->nameTab[i]) > priority)
1428*6777b538SAndroid Build Coastguard Worker             return;
1429*6777b538SAndroid Build Coastguard Worker     }
1430*6777b538SAndroid Build Coastguard Worker     if (i < 0)
1431*6777b538SAndroid Build Coastguard Worker         return;
1432*6777b538SAndroid Build Coastguard Worker 
1433*6777b538SAndroid Build Coastguard Worker     while (!xmlStrEqual(newtag, ctxt->name)) {
1434*6777b538SAndroid Build Coastguard Worker         info = htmlTagLookup(ctxt->name);
1435*6777b538SAndroid Build Coastguard Worker         if ((info != NULL) && (info->endTag == 3)) {
1436*6777b538SAndroid Build Coastguard Worker             htmlParseErr(ctxt, XML_ERR_TAG_NAME_MISMATCH,
1437*6777b538SAndroid Build Coastguard Worker 	                 "Opening and ending tag mismatch: %s and %s\n",
1438*6777b538SAndroid Build Coastguard Worker 			 newtag, ctxt->name);
1439*6777b538SAndroid Build Coastguard Worker         }
1440*6777b538SAndroid Build Coastguard Worker         if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
1441*6777b538SAndroid Build Coastguard Worker             ctxt->sax->endElement(ctxt->userData, ctxt->name);
1442*6777b538SAndroid Build Coastguard Worker 	htmlnamePop(ctxt);
1443*6777b538SAndroid Build Coastguard Worker     }
1444*6777b538SAndroid Build Coastguard Worker }
1445*6777b538SAndroid Build Coastguard Worker 
1446*6777b538SAndroid Build Coastguard Worker /**
1447*6777b538SAndroid Build Coastguard Worker  * htmlAutoCloseOnEnd:
1448*6777b538SAndroid Build Coastguard Worker  * @ctxt:  an HTML parser context
1449*6777b538SAndroid Build Coastguard Worker  *
1450*6777b538SAndroid Build Coastguard Worker  * Close all remaining tags at the end of the stream
1451*6777b538SAndroid Build Coastguard Worker  */
1452*6777b538SAndroid Build Coastguard Worker static void
htmlAutoCloseOnEnd(htmlParserCtxtPtr ctxt)1453*6777b538SAndroid Build Coastguard Worker htmlAutoCloseOnEnd(htmlParserCtxtPtr ctxt)
1454*6777b538SAndroid Build Coastguard Worker {
1455*6777b538SAndroid Build Coastguard Worker     int i;
1456*6777b538SAndroid Build Coastguard Worker 
1457*6777b538SAndroid Build Coastguard Worker     if (ctxt->nameNr == 0)
1458*6777b538SAndroid Build Coastguard Worker         return;
1459*6777b538SAndroid Build Coastguard Worker     for (i = (ctxt->nameNr - 1); i >= 0; i--) {
1460*6777b538SAndroid Build Coastguard Worker         if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
1461*6777b538SAndroid Build Coastguard Worker             ctxt->sax->endElement(ctxt->userData, ctxt->name);
1462*6777b538SAndroid Build Coastguard Worker 	htmlnamePop(ctxt);
1463*6777b538SAndroid Build Coastguard Worker     }
1464*6777b538SAndroid Build Coastguard Worker }
1465*6777b538SAndroid Build Coastguard Worker 
1466*6777b538SAndroid Build Coastguard Worker /**
1467*6777b538SAndroid Build Coastguard Worker  * htmlAutoClose:
1468*6777b538SAndroid Build Coastguard Worker  * @ctxt:  an HTML parser context
1469*6777b538SAndroid Build Coastguard Worker  * @newtag:  The new tag name or NULL
1470*6777b538SAndroid Build Coastguard Worker  *
1471*6777b538SAndroid Build Coastguard Worker  * The HTML DTD allows a tag to implicitly close other tags.
1472*6777b538SAndroid Build Coastguard Worker  * The list is kept in htmlStartClose array. This function is
1473*6777b538SAndroid Build Coastguard Worker  * called when a new tag has been detected and generates the
1474*6777b538SAndroid Build Coastguard Worker  * appropriates closes if possible/needed.
1475*6777b538SAndroid Build Coastguard Worker  * If newtag is NULL this mean we are at the end of the resource
1476*6777b538SAndroid Build Coastguard Worker  * and we should check
1477*6777b538SAndroid Build Coastguard Worker  */
1478*6777b538SAndroid Build Coastguard Worker static void
htmlAutoClose(htmlParserCtxtPtr ctxt,const xmlChar * newtag)1479*6777b538SAndroid Build Coastguard Worker htmlAutoClose(htmlParserCtxtPtr ctxt, const xmlChar * newtag)
1480*6777b538SAndroid Build Coastguard Worker {
1481*6777b538SAndroid Build Coastguard Worker     if (newtag == NULL)
1482*6777b538SAndroid Build Coastguard Worker         return;
1483*6777b538SAndroid Build Coastguard Worker 
1484*6777b538SAndroid Build Coastguard Worker     while ((ctxt->name != NULL) &&
1485*6777b538SAndroid Build Coastguard Worker            (htmlCheckAutoClose(newtag, ctxt->name))) {
1486*6777b538SAndroid Build Coastguard Worker         if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
1487*6777b538SAndroid Build Coastguard Worker             ctxt->sax->endElement(ctxt->userData, ctxt->name);
1488*6777b538SAndroid Build Coastguard Worker 	htmlnamePop(ctxt);
1489*6777b538SAndroid Build Coastguard Worker     }
1490*6777b538SAndroid Build Coastguard Worker }
1491*6777b538SAndroid Build Coastguard Worker 
1492*6777b538SAndroid Build Coastguard Worker /**
1493*6777b538SAndroid Build Coastguard Worker  * htmlAutoCloseTag:
1494*6777b538SAndroid Build Coastguard Worker  * @doc:  the HTML document
1495*6777b538SAndroid Build Coastguard Worker  * @name:  The tag name
1496*6777b538SAndroid Build Coastguard Worker  * @elem:  the HTML element
1497*6777b538SAndroid Build Coastguard Worker  *
1498*6777b538SAndroid Build Coastguard Worker  * The HTML DTD allows a tag to implicitly close other tags.
1499*6777b538SAndroid Build Coastguard Worker  * The list is kept in htmlStartClose array. This function checks
1500*6777b538SAndroid Build Coastguard Worker  * if the element or one of it's children would autoclose the
1501*6777b538SAndroid Build Coastguard Worker  * given tag.
1502*6777b538SAndroid Build Coastguard Worker  *
1503*6777b538SAndroid Build Coastguard Worker  * Returns 1 if autoclose, 0 otherwise
1504*6777b538SAndroid Build Coastguard Worker  */
1505*6777b538SAndroid Build Coastguard Worker int
htmlAutoCloseTag(htmlDocPtr doc,const xmlChar * name,htmlNodePtr elem)1506*6777b538SAndroid Build Coastguard Worker htmlAutoCloseTag(htmlDocPtr doc, const xmlChar *name, htmlNodePtr elem) {
1507*6777b538SAndroid Build Coastguard Worker     htmlNodePtr child;
1508*6777b538SAndroid Build Coastguard Worker 
1509*6777b538SAndroid Build Coastguard Worker     if (elem == NULL) return(1);
1510*6777b538SAndroid Build Coastguard Worker     if (xmlStrEqual(name, elem->name)) return(0);
1511*6777b538SAndroid Build Coastguard Worker     if (htmlCheckAutoClose(elem->name, name)) return(1);
1512*6777b538SAndroid Build Coastguard Worker     child = elem->children;
1513*6777b538SAndroid Build Coastguard Worker     while (child != NULL) {
1514*6777b538SAndroid Build Coastguard Worker         if (htmlAutoCloseTag(doc, name, child)) return(1);
1515*6777b538SAndroid Build Coastguard Worker 	child = child->next;
1516*6777b538SAndroid Build Coastguard Worker     }
1517*6777b538SAndroid Build Coastguard Worker     return(0);
1518*6777b538SAndroid Build Coastguard Worker }
1519*6777b538SAndroid Build Coastguard Worker 
1520*6777b538SAndroid Build Coastguard Worker /**
1521*6777b538SAndroid Build Coastguard Worker  * htmlIsAutoClosed:
1522*6777b538SAndroid Build Coastguard Worker  * @doc:  the HTML document
1523*6777b538SAndroid Build Coastguard Worker  * @elem:  the HTML element
1524*6777b538SAndroid Build Coastguard Worker  *
1525*6777b538SAndroid Build Coastguard Worker  * The HTML DTD allows a tag to implicitly close other tags.
1526*6777b538SAndroid Build Coastguard Worker  * The list is kept in htmlStartClose array. This function checks
1527*6777b538SAndroid Build Coastguard Worker  * if a tag is autoclosed by one of it's child
1528*6777b538SAndroid Build Coastguard Worker  *
1529*6777b538SAndroid Build Coastguard Worker  * Returns 1 if autoclosed, 0 otherwise
1530*6777b538SAndroid Build Coastguard Worker  */
1531*6777b538SAndroid Build Coastguard Worker int
htmlIsAutoClosed(htmlDocPtr doc,htmlNodePtr elem)1532*6777b538SAndroid Build Coastguard Worker htmlIsAutoClosed(htmlDocPtr doc, htmlNodePtr elem) {
1533*6777b538SAndroid Build Coastguard Worker     htmlNodePtr child;
1534*6777b538SAndroid Build Coastguard Worker 
1535*6777b538SAndroid Build Coastguard Worker     if (elem == NULL) return(1);
1536*6777b538SAndroid Build Coastguard Worker     child = elem->children;
1537*6777b538SAndroid Build Coastguard Worker     while (child != NULL) {
1538*6777b538SAndroid Build Coastguard Worker 	if (htmlAutoCloseTag(doc, elem->name, child)) return(1);
1539*6777b538SAndroid Build Coastguard Worker 	child = child->next;
1540*6777b538SAndroid Build Coastguard Worker     }
1541*6777b538SAndroid Build Coastguard Worker     return(0);
1542*6777b538SAndroid Build Coastguard Worker }
1543*6777b538SAndroid Build Coastguard Worker 
1544*6777b538SAndroid Build Coastguard Worker /**
1545*6777b538SAndroid Build Coastguard Worker  * htmlCheckImplied:
1546*6777b538SAndroid Build Coastguard Worker  * @ctxt:  an HTML parser context
1547*6777b538SAndroid Build Coastguard Worker  * @newtag:  The new tag name
1548*6777b538SAndroid Build Coastguard Worker  *
1549*6777b538SAndroid Build Coastguard Worker  * The HTML DTD allows a tag to exists only implicitly
1550*6777b538SAndroid Build Coastguard Worker  * called when a new tag has been detected and generates the
1551*6777b538SAndroid Build Coastguard Worker  * appropriates implicit tags if missing
1552*6777b538SAndroid Build Coastguard Worker  */
1553*6777b538SAndroid Build Coastguard Worker static void
htmlCheckImplied(htmlParserCtxtPtr ctxt,const xmlChar * newtag)1554*6777b538SAndroid Build Coastguard Worker htmlCheckImplied(htmlParserCtxtPtr ctxt, const xmlChar *newtag) {
1555*6777b538SAndroid Build Coastguard Worker     int i;
1556*6777b538SAndroid Build Coastguard Worker 
1557*6777b538SAndroid Build Coastguard Worker     if (ctxt->options & HTML_PARSE_NOIMPLIED)
1558*6777b538SAndroid Build Coastguard Worker         return;
1559*6777b538SAndroid Build Coastguard Worker     if (!htmlOmittedDefaultValue)
1560*6777b538SAndroid Build Coastguard Worker 	return;
1561*6777b538SAndroid Build Coastguard Worker     if (xmlStrEqual(newtag, BAD_CAST"html"))
1562*6777b538SAndroid Build Coastguard Worker 	return;
1563*6777b538SAndroid Build Coastguard Worker     if (ctxt->nameNr <= 0) {
1564*6777b538SAndroid Build Coastguard Worker 	htmlnamePush(ctxt, BAD_CAST"html");
1565*6777b538SAndroid Build Coastguard Worker 	if ((ctxt->sax != NULL) && (ctxt->sax->startElement != NULL))
1566*6777b538SAndroid Build Coastguard Worker 	    ctxt->sax->startElement(ctxt->userData, BAD_CAST"html", NULL);
1567*6777b538SAndroid Build Coastguard Worker     }
1568*6777b538SAndroid Build Coastguard Worker     if ((xmlStrEqual(newtag, BAD_CAST"body")) || (xmlStrEqual(newtag, BAD_CAST"head")))
1569*6777b538SAndroid Build Coastguard Worker         return;
1570*6777b538SAndroid Build Coastguard Worker     if ((ctxt->nameNr <= 1) &&
1571*6777b538SAndroid Build Coastguard Worker         ((xmlStrEqual(newtag, BAD_CAST"script")) ||
1572*6777b538SAndroid Build Coastguard Worker 	 (xmlStrEqual(newtag, BAD_CAST"style")) ||
1573*6777b538SAndroid Build Coastguard Worker 	 (xmlStrEqual(newtag, BAD_CAST"meta")) ||
1574*6777b538SAndroid Build Coastguard Worker 	 (xmlStrEqual(newtag, BAD_CAST"link")) ||
1575*6777b538SAndroid Build Coastguard Worker 	 (xmlStrEqual(newtag, BAD_CAST"title")) ||
1576*6777b538SAndroid Build Coastguard Worker 	 (xmlStrEqual(newtag, BAD_CAST"base")))) {
1577*6777b538SAndroid Build Coastguard Worker         if (ctxt->html >= 3) {
1578*6777b538SAndroid Build Coastguard Worker             /* we already saw or generated an <head> before */
1579*6777b538SAndroid Build Coastguard Worker             return;
1580*6777b538SAndroid Build Coastguard Worker         }
1581*6777b538SAndroid Build Coastguard Worker         /*
1582*6777b538SAndroid Build Coastguard Worker          * dropped OBJECT ... i you put it first BODY will be
1583*6777b538SAndroid Build Coastguard Worker          * assumed !
1584*6777b538SAndroid Build Coastguard Worker          */
1585*6777b538SAndroid Build Coastguard Worker         htmlnamePush(ctxt, BAD_CAST"head");
1586*6777b538SAndroid Build Coastguard Worker         if ((ctxt->sax != NULL) && (ctxt->sax->startElement != NULL))
1587*6777b538SAndroid Build Coastguard Worker             ctxt->sax->startElement(ctxt->userData, BAD_CAST"head", NULL);
1588*6777b538SAndroid Build Coastguard Worker     } else if ((!xmlStrEqual(newtag, BAD_CAST"noframes")) &&
1589*6777b538SAndroid Build Coastguard Worker 	       (!xmlStrEqual(newtag, BAD_CAST"frame")) &&
1590*6777b538SAndroid Build Coastguard Worker 	       (!xmlStrEqual(newtag, BAD_CAST"frameset"))) {
1591*6777b538SAndroid Build Coastguard Worker         if (ctxt->html >= 10) {
1592*6777b538SAndroid Build Coastguard Worker             /* we already saw or generated a <body> before */
1593*6777b538SAndroid Build Coastguard Worker             return;
1594*6777b538SAndroid Build Coastguard Worker         }
1595*6777b538SAndroid Build Coastguard Worker 	for (i = 0;i < ctxt->nameNr;i++) {
1596*6777b538SAndroid Build Coastguard Worker 	    if (xmlStrEqual(ctxt->nameTab[i], BAD_CAST"body")) {
1597*6777b538SAndroid Build Coastguard Worker 		return;
1598*6777b538SAndroid Build Coastguard Worker 	    }
1599*6777b538SAndroid Build Coastguard Worker 	    if (xmlStrEqual(ctxt->nameTab[i], BAD_CAST"head")) {
1600*6777b538SAndroid Build Coastguard Worker 		return;
1601*6777b538SAndroid Build Coastguard Worker 	    }
1602*6777b538SAndroid Build Coastguard Worker 	}
1603*6777b538SAndroid Build Coastguard Worker 
1604*6777b538SAndroid Build Coastguard Worker 	htmlnamePush(ctxt, BAD_CAST"body");
1605*6777b538SAndroid Build Coastguard Worker 	if ((ctxt->sax != NULL) && (ctxt->sax->startElement != NULL))
1606*6777b538SAndroid Build Coastguard Worker 	    ctxt->sax->startElement(ctxt->userData, BAD_CAST"body", NULL);
1607*6777b538SAndroid Build Coastguard Worker     }
1608*6777b538SAndroid Build Coastguard Worker }
1609*6777b538SAndroid Build Coastguard Worker 
1610*6777b538SAndroid Build Coastguard Worker /**
1611*6777b538SAndroid Build Coastguard Worker  * htmlCheckParagraph
1612*6777b538SAndroid Build Coastguard Worker  * @ctxt:  an HTML parser context
1613*6777b538SAndroid Build Coastguard Worker  *
1614*6777b538SAndroid Build Coastguard Worker  * Check whether a p element need to be implied before inserting
1615*6777b538SAndroid Build Coastguard Worker  * characters in the current element.
1616*6777b538SAndroid Build Coastguard Worker  *
1617*6777b538SAndroid Build Coastguard Worker  * Returns 1 if a paragraph has been inserted, 0 if not and -1
1618*6777b538SAndroid Build Coastguard Worker  *         in case of error.
1619*6777b538SAndroid Build Coastguard Worker  */
1620*6777b538SAndroid Build Coastguard Worker 
1621*6777b538SAndroid Build Coastguard Worker static int
htmlCheckParagraph(htmlParserCtxtPtr ctxt)1622*6777b538SAndroid Build Coastguard Worker htmlCheckParagraph(htmlParserCtxtPtr ctxt) {
1623*6777b538SAndroid Build Coastguard Worker     const xmlChar *tag;
1624*6777b538SAndroid Build Coastguard Worker     int i;
1625*6777b538SAndroid Build Coastguard Worker 
1626*6777b538SAndroid Build Coastguard Worker     if (ctxt == NULL)
1627*6777b538SAndroid Build Coastguard Worker 	return(-1);
1628*6777b538SAndroid Build Coastguard Worker     tag = ctxt->name;
1629*6777b538SAndroid Build Coastguard Worker     if (tag == NULL) {
1630*6777b538SAndroid Build Coastguard Worker 	htmlAutoClose(ctxt, BAD_CAST"p");
1631*6777b538SAndroid Build Coastguard Worker 	htmlCheckImplied(ctxt, BAD_CAST"p");
1632*6777b538SAndroid Build Coastguard Worker 	htmlnamePush(ctxt, BAD_CAST"p");
1633*6777b538SAndroid Build Coastguard Worker 	if ((ctxt->sax != NULL) && (ctxt->sax->startElement != NULL))
1634*6777b538SAndroid Build Coastguard Worker 	    ctxt->sax->startElement(ctxt->userData, BAD_CAST"p", NULL);
1635*6777b538SAndroid Build Coastguard Worker 	return(1);
1636*6777b538SAndroid Build Coastguard Worker     }
1637*6777b538SAndroid Build Coastguard Worker     if (!htmlOmittedDefaultValue)
1638*6777b538SAndroid Build Coastguard Worker 	return(0);
1639*6777b538SAndroid Build Coastguard Worker     for (i = 0; htmlNoContentElements[i] != NULL; i++) {
1640*6777b538SAndroid Build Coastguard Worker 	if (xmlStrEqual(tag, BAD_CAST htmlNoContentElements[i])) {
1641*6777b538SAndroid Build Coastguard Worker 	    htmlAutoClose(ctxt, BAD_CAST"p");
1642*6777b538SAndroid Build Coastguard Worker 	    htmlCheckImplied(ctxt, BAD_CAST"p");
1643*6777b538SAndroid Build Coastguard Worker 	    htmlnamePush(ctxt, BAD_CAST"p");
1644*6777b538SAndroid Build Coastguard Worker 	    if ((ctxt->sax != NULL) && (ctxt->sax->startElement != NULL))
1645*6777b538SAndroid Build Coastguard Worker 		ctxt->sax->startElement(ctxt->userData, BAD_CAST"p", NULL);
1646*6777b538SAndroid Build Coastguard Worker 	    return(1);
1647*6777b538SAndroid Build Coastguard Worker 	}
1648*6777b538SAndroid Build Coastguard Worker     }
1649*6777b538SAndroid Build Coastguard Worker     return(0);
1650*6777b538SAndroid Build Coastguard Worker }
1651*6777b538SAndroid Build Coastguard Worker 
1652*6777b538SAndroid Build Coastguard Worker /**
1653*6777b538SAndroid Build Coastguard Worker  * htmlIsScriptAttribute:
1654*6777b538SAndroid Build Coastguard Worker  * @name:  an attribute name
1655*6777b538SAndroid Build Coastguard Worker  *
1656*6777b538SAndroid Build Coastguard Worker  * Check if an attribute is of content type Script
1657*6777b538SAndroid Build Coastguard Worker  *
1658*6777b538SAndroid Build Coastguard Worker  * Returns 1 is the attribute is a script 0 otherwise
1659*6777b538SAndroid Build Coastguard Worker  */
1660*6777b538SAndroid Build Coastguard Worker int
htmlIsScriptAttribute(const xmlChar * name)1661*6777b538SAndroid Build Coastguard Worker htmlIsScriptAttribute(const xmlChar *name) {
1662*6777b538SAndroid Build Coastguard Worker     unsigned int i;
1663*6777b538SAndroid Build Coastguard Worker 
1664*6777b538SAndroid Build Coastguard Worker     if (name == NULL)
1665*6777b538SAndroid Build Coastguard Worker       return(0);
1666*6777b538SAndroid Build Coastguard Worker     /*
1667*6777b538SAndroid Build Coastguard Worker      * all script attributes start with 'on'
1668*6777b538SAndroid Build Coastguard Worker      */
1669*6777b538SAndroid Build Coastguard Worker     if ((name[0] != 'o') || (name[1] != 'n'))
1670*6777b538SAndroid Build Coastguard Worker       return(0);
1671*6777b538SAndroid Build Coastguard Worker     for (i = 0;
1672*6777b538SAndroid Build Coastguard Worker 	 i < sizeof(htmlScriptAttributes)/sizeof(htmlScriptAttributes[0]);
1673*6777b538SAndroid Build Coastguard Worker 	 i++) {
1674*6777b538SAndroid Build Coastguard Worker 	if (xmlStrEqual(name, (const xmlChar *) htmlScriptAttributes[i]))
1675*6777b538SAndroid Build Coastguard Worker 	    return(1);
1676*6777b538SAndroid Build Coastguard Worker     }
1677*6777b538SAndroid Build Coastguard Worker     return(0);
1678*6777b538SAndroid Build Coastguard Worker }
1679*6777b538SAndroid Build Coastguard Worker 
1680*6777b538SAndroid Build Coastguard Worker /************************************************************************
1681*6777b538SAndroid Build Coastguard Worker  *									*
1682*6777b538SAndroid Build Coastguard Worker  *	The list of HTML predefined entities			*
1683*6777b538SAndroid Build Coastguard Worker  *									*
1684*6777b538SAndroid Build Coastguard Worker  ************************************************************************/
1685*6777b538SAndroid Build Coastguard Worker 
1686*6777b538SAndroid Build Coastguard Worker 
1687*6777b538SAndroid Build Coastguard Worker static const htmlEntityDesc  html40EntitiesTable[] = {
1688*6777b538SAndroid Build Coastguard Worker /*
1689*6777b538SAndroid Build Coastguard Worker  * the 4 absolute ones, plus apostrophe.
1690*6777b538SAndroid Build Coastguard Worker  */
1691*6777b538SAndroid Build Coastguard Worker { 34,	"quot",	"quotation mark = APL quote, U+0022 ISOnum" },
1692*6777b538SAndroid Build Coastguard Worker { 38,	"amp",	"ampersand, U+0026 ISOnum" },
1693*6777b538SAndroid Build Coastguard Worker { 39,	"apos",	"single quote" },
1694*6777b538SAndroid Build Coastguard Worker { 60,	"lt",	"less-than sign, U+003C ISOnum" },
1695*6777b538SAndroid Build Coastguard Worker { 62,	"gt",	"greater-than sign, U+003E ISOnum" },
1696*6777b538SAndroid Build Coastguard Worker 
1697*6777b538SAndroid Build Coastguard Worker /*
1698*6777b538SAndroid Build Coastguard Worker  * A bunch still in the 128-255 range
1699*6777b538SAndroid Build Coastguard Worker  * Replacing them depend really on the charset used.
1700*6777b538SAndroid Build Coastguard Worker  */
1701*6777b538SAndroid Build Coastguard Worker { 160,	"nbsp",	"no-break space = non-breaking space, U+00A0 ISOnum" },
1702*6777b538SAndroid Build Coastguard Worker { 161,	"iexcl","inverted exclamation mark, U+00A1 ISOnum" },
1703*6777b538SAndroid Build Coastguard Worker { 162,	"cent",	"cent sign, U+00A2 ISOnum" },
1704*6777b538SAndroid Build Coastguard Worker { 163,	"pound","pound sign, U+00A3 ISOnum" },
1705*6777b538SAndroid Build Coastguard Worker { 164,	"curren","currency sign, U+00A4 ISOnum" },
1706*6777b538SAndroid Build Coastguard Worker { 165,	"yen",	"yen sign = yuan sign, U+00A5 ISOnum" },
1707*6777b538SAndroid Build Coastguard Worker { 166,	"brvbar","broken bar = broken vertical bar, U+00A6 ISOnum" },
1708*6777b538SAndroid Build Coastguard Worker { 167,	"sect",	"section sign, U+00A7 ISOnum" },
1709*6777b538SAndroid Build Coastguard Worker { 168,	"uml",	"diaeresis = spacing diaeresis, U+00A8 ISOdia" },
1710*6777b538SAndroid Build Coastguard Worker { 169,	"copy",	"copyright sign, U+00A9 ISOnum" },
1711*6777b538SAndroid Build Coastguard Worker { 170,	"ordf",	"feminine ordinal indicator, U+00AA ISOnum" },
1712*6777b538SAndroid Build Coastguard Worker { 171,	"laquo","left-pointing double angle quotation mark = left pointing guillemet, U+00AB ISOnum" },
1713*6777b538SAndroid Build Coastguard Worker { 172,	"not",	"not sign, U+00AC ISOnum" },
1714*6777b538SAndroid Build Coastguard Worker { 173,	"shy",	"soft hyphen = discretionary hyphen, U+00AD ISOnum" },
1715*6777b538SAndroid Build Coastguard Worker { 174,	"reg",	"registered sign = registered trade mark sign, U+00AE ISOnum" },
1716*6777b538SAndroid Build Coastguard Worker { 175,	"macr",	"macron = spacing macron = overline = APL overbar, U+00AF ISOdia" },
1717*6777b538SAndroid Build Coastguard Worker { 176,	"deg",	"degree sign, U+00B0 ISOnum" },
1718*6777b538SAndroid Build Coastguard Worker { 177,	"plusmn","plus-minus sign = plus-or-minus sign, U+00B1 ISOnum" },
1719*6777b538SAndroid Build Coastguard Worker { 178,	"sup2",	"superscript two = superscript digit two = squared, U+00B2 ISOnum" },
1720*6777b538SAndroid Build Coastguard Worker { 179,	"sup3",	"superscript three = superscript digit three = cubed, U+00B3 ISOnum" },
1721*6777b538SAndroid Build Coastguard Worker { 180,	"acute","acute accent = spacing acute, U+00B4 ISOdia" },
1722*6777b538SAndroid Build Coastguard Worker { 181,	"micro","micro sign, U+00B5 ISOnum" },
1723*6777b538SAndroid Build Coastguard Worker { 182,	"para",	"pilcrow sign = paragraph sign, U+00B6 ISOnum" },
1724*6777b538SAndroid Build Coastguard Worker { 183,	"middot","middle dot = Georgian comma Greek middle dot, U+00B7 ISOnum" },
1725*6777b538SAndroid Build Coastguard Worker { 184,	"cedil","cedilla = spacing cedilla, U+00B8 ISOdia" },
1726*6777b538SAndroid Build Coastguard Worker { 185,	"sup1",	"superscript one = superscript digit one, U+00B9 ISOnum" },
1727*6777b538SAndroid Build Coastguard Worker { 186,	"ordm",	"masculine ordinal indicator, U+00BA ISOnum" },
1728*6777b538SAndroid Build Coastguard Worker { 187,	"raquo","right-pointing double angle quotation mark right pointing guillemet, U+00BB ISOnum" },
1729*6777b538SAndroid Build Coastguard Worker { 188,	"frac14","vulgar fraction one quarter = fraction one quarter, U+00BC ISOnum" },
1730*6777b538SAndroid Build Coastguard Worker { 189,	"frac12","vulgar fraction one half = fraction one half, U+00BD ISOnum" },
1731*6777b538SAndroid Build Coastguard Worker { 190,	"frac34","vulgar fraction three quarters = fraction three quarters, U+00BE ISOnum" },
1732*6777b538SAndroid Build Coastguard Worker { 191,	"iquest","inverted question mark = turned question mark, U+00BF ISOnum" },
1733*6777b538SAndroid Build Coastguard Worker { 192,	"Agrave","latin capital letter A with grave = latin capital letter A grave, U+00C0 ISOlat1" },
1734*6777b538SAndroid Build Coastguard Worker { 193,	"Aacute","latin capital letter A with acute, U+00C1 ISOlat1" },
1735*6777b538SAndroid Build Coastguard Worker { 194,	"Acirc","latin capital letter A with circumflex, U+00C2 ISOlat1" },
1736*6777b538SAndroid Build Coastguard Worker { 195,	"Atilde","latin capital letter A with tilde, U+00C3 ISOlat1" },
1737*6777b538SAndroid Build Coastguard Worker { 196,	"Auml",	"latin capital letter A with diaeresis, U+00C4 ISOlat1" },
1738*6777b538SAndroid Build Coastguard Worker { 197,	"Aring","latin capital letter A with ring above = latin capital letter A ring, U+00C5 ISOlat1" },
1739*6777b538SAndroid Build Coastguard Worker { 198,	"AElig","latin capital letter AE = latin capital ligature AE, U+00C6 ISOlat1" },
1740*6777b538SAndroid Build Coastguard Worker { 199,	"Ccedil","latin capital letter C with cedilla, U+00C7 ISOlat1" },
1741*6777b538SAndroid Build Coastguard Worker { 200,	"Egrave","latin capital letter E with grave, U+00C8 ISOlat1" },
1742*6777b538SAndroid Build Coastguard Worker { 201,	"Eacute","latin capital letter E with acute, U+00C9 ISOlat1" },
1743*6777b538SAndroid Build Coastguard Worker { 202,	"Ecirc","latin capital letter E with circumflex, U+00CA ISOlat1" },
1744*6777b538SAndroid Build Coastguard Worker { 203,	"Euml",	"latin capital letter E with diaeresis, U+00CB ISOlat1" },
1745*6777b538SAndroid Build Coastguard Worker { 204,	"Igrave","latin capital letter I with grave, U+00CC ISOlat1" },
1746*6777b538SAndroid Build Coastguard Worker { 205,	"Iacute","latin capital letter I with acute, U+00CD ISOlat1" },
1747*6777b538SAndroid Build Coastguard Worker { 206,	"Icirc","latin capital letter I with circumflex, U+00CE ISOlat1" },
1748*6777b538SAndroid Build Coastguard Worker { 207,	"Iuml",	"latin capital letter I with diaeresis, U+00CF ISOlat1" },
1749*6777b538SAndroid Build Coastguard Worker { 208,	"ETH",	"latin capital letter ETH, U+00D0 ISOlat1" },
1750*6777b538SAndroid Build Coastguard Worker { 209,	"Ntilde","latin capital letter N with tilde, U+00D1 ISOlat1" },
1751*6777b538SAndroid Build Coastguard Worker { 210,	"Ograve","latin capital letter O with grave, U+00D2 ISOlat1" },
1752*6777b538SAndroid Build Coastguard Worker { 211,	"Oacute","latin capital letter O with acute, U+00D3 ISOlat1" },
1753*6777b538SAndroid Build Coastguard Worker { 212,	"Ocirc","latin capital letter O with circumflex, U+00D4 ISOlat1" },
1754*6777b538SAndroid Build Coastguard Worker { 213,	"Otilde","latin capital letter O with tilde, U+00D5 ISOlat1" },
1755*6777b538SAndroid Build Coastguard Worker { 214,	"Ouml",	"latin capital letter O with diaeresis, U+00D6 ISOlat1" },
1756*6777b538SAndroid Build Coastguard Worker { 215,	"times","multiplication sign, U+00D7 ISOnum" },
1757*6777b538SAndroid Build Coastguard Worker { 216,	"Oslash","latin capital letter O with stroke latin capital letter O slash, U+00D8 ISOlat1" },
1758*6777b538SAndroid Build Coastguard Worker { 217,	"Ugrave","latin capital letter U with grave, U+00D9 ISOlat1" },
1759*6777b538SAndroid Build Coastguard Worker { 218,	"Uacute","latin capital letter U with acute, U+00DA ISOlat1" },
1760*6777b538SAndroid Build Coastguard Worker { 219,	"Ucirc","latin capital letter U with circumflex, U+00DB ISOlat1" },
1761*6777b538SAndroid Build Coastguard Worker { 220,	"Uuml",	"latin capital letter U with diaeresis, U+00DC ISOlat1" },
1762*6777b538SAndroid Build Coastguard Worker { 221,	"Yacute","latin capital letter Y with acute, U+00DD ISOlat1" },
1763*6777b538SAndroid Build Coastguard Worker { 222,	"THORN","latin capital letter THORN, U+00DE ISOlat1" },
1764*6777b538SAndroid Build Coastguard Worker { 223,	"szlig","latin small letter sharp s = ess-zed, U+00DF ISOlat1" },
1765*6777b538SAndroid Build Coastguard Worker { 224,	"agrave","latin small letter a with grave = latin small letter a grave, U+00E0 ISOlat1" },
1766*6777b538SAndroid Build Coastguard Worker { 225,	"aacute","latin small letter a with acute, U+00E1 ISOlat1" },
1767*6777b538SAndroid Build Coastguard Worker { 226,	"acirc","latin small letter a with circumflex, U+00E2 ISOlat1" },
1768*6777b538SAndroid Build Coastguard Worker { 227,	"atilde","latin small letter a with tilde, U+00E3 ISOlat1" },
1769*6777b538SAndroid Build Coastguard Worker { 228,	"auml",	"latin small letter a with diaeresis, U+00E4 ISOlat1" },
1770*6777b538SAndroid Build Coastguard Worker { 229,	"aring","latin small letter a with ring above = latin small letter a ring, U+00E5 ISOlat1" },
1771*6777b538SAndroid Build Coastguard Worker { 230,	"aelig","latin small letter ae = latin small ligature ae, U+00E6 ISOlat1" },
1772*6777b538SAndroid Build Coastguard Worker { 231,	"ccedil","latin small letter c with cedilla, U+00E7 ISOlat1" },
1773*6777b538SAndroid Build Coastguard Worker { 232,	"egrave","latin small letter e with grave, U+00E8 ISOlat1" },
1774*6777b538SAndroid Build Coastguard Worker { 233,	"eacute","latin small letter e with acute, U+00E9 ISOlat1" },
1775*6777b538SAndroid Build Coastguard Worker { 234,	"ecirc","latin small letter e with circumflex, U+00EA ISOlat1" },
1776*6777b538SAndroid Build Coastguard Worker { 235,	"euml",	"latin small letter e with diaeresis, U+00EB ISOlat1" },
1777*6777b538SAndroid Build Coastguard Worker { 236,	"igrave","latin small letter i with grave, U+00EC ISOlat1" },
1778*6777b538SAndroid Build Coastguard Worker { 237,	"iacute","latin small letter i with acute, U+00ED ISOlat1" },
1779*6777b538SAndroid Build Coastguard Worker { 238,	"icirc","latin small letter i with circumflex, U+00EE ISOlat1" },
1780*6777b538SAndroid Build Coastguard Worker { 239,	"iuml",	"latin small letter i with diaeresis, U+00EF ISOlat1" },
1781*6777b538SAndroid Build Coastguard Worker { 240,	"eth",	"latin small letter eth, U+00F0 ISOlat1" },
1782*6777b538SAndroid Build Coastguard Worker { 241,	"ntilde","latin small letter n with tilde, U+00F1 ISOlat1" },
1783*6777b538SAndroid Build Coastguard Worker { 242,	"ograve","latin small letter o with grave, U+00F2 ISOlat1" },
1784*6777b538SAndroid Build Coastguard Worker { 243,	"oacute","latin small letter o with acute, U+00F3 ISOlat1" },
1785*6777b538SAndroid Build Coastguard Worker { 244,	"ocirc","latin small letter o with circumflex, U+00F4 ISOlat1" },
1786*6777b538SAndroid Build Coastguard Worker { 245,	"otilde","latin small letter o with tilde, U+00F5 ISOlat1" },
1787*6777b538SAndroid Build Coastguard Worker { 246,	"ouml",	"latin small letter o with diaeresis, U+00F6 ISOlat1" },
1788*6777b538SAndroid Build Coastguard Worker { 247,	"divide","division sign, U+00F7 ISOnum" },
1789*6777b538SAndroid Build Coastguard Worker { 248,	"oslash","latin small letter o with stroke, = latin small letter o slash, U+00F8 ISOlat1" },
1790*6777b538SAndroid Build Coastguard Worker { 249,	"ugrave","latin small letter u with grave, U+00F9 ISOlat1" },
1791*6777b538SAndroid Build Coastguard Worker { 250,	"uacute","latin small letter u with acute, U+00FA ISOlat1" },
1792*6777b538SAndroid Build Coastguard Worker { 251,	"ucirc","latin small letter u with circumflex, U+00FB ISOlat1" },
1793*6777b538SAndroid Build Coastguard Worker { 252,	"uuml",	"latin small letter u with diaeresis, U+00FC ISOlat1" },
1794*6777b538SAndroid Build Coastguard Worker { 253,	"yacute","latin small letter y with acute, U+00FD ISOlat1" },
1795*6777b538SAndroid Build Coastguard Worker { 254,	"thorn","latin small letter thorn with, U+00FE ISOlat1" },
1796*6777b538SAndroid Build Coastguard Worker { 255,	"yuml",	"latin small letter y with diaeresis, U+00FF ISOlat1" },
1797*6777b538SAndroid Build Coastguard Worker 
1798*6777b538SAndroid Build Coastguard Worker { 338,	"OElig","latin capital ligature OE, U+0152 ISOlat2" },
1799*6777b538SAndroid Build Coastguard Worker { 339,	"oelig","latin small ligature oe, U+0153 ISOlat2" },
1800*6777b538SAndroid Build Coastguard Worker { 352,	"Scaron","latin capital letter S with caron, U+0160 ISOlat2" },
1801*6777b538SAndroid Build Coastguard Worker { 353,	"scaron","latin small letter s with caron, U+0161 ISOlat2" },
1802*6777b538SAndroid Build Coastguard Worker { 376,	"Yuml",	"latin capital letter Y with diaeresis, U+0178 ISOlat2" },
1803*6777b538SAndroid Build Coastguard Worker 
1804*6777b538SAndroid Build Coastguard Worker /*
1805*6777b538SAndroid Build Coastguard Worker  * Anything below should really be kept as entities references
1806*6777b538SAndroid Build Coastguard Worker  */
1807*6777b538SAndroid Build Coastguard Worker { 402,	"fnof",	"latin small f with hook = function = florin, U+0192 ISOtech" },
1808*6777b538SAndroid Build Coastguard Worker 
1809*6777b538SAndroid Build Coastguard Worker { 710,	"circ",	"modifier letter circumflex accent, U+02C6 ISOpub" },
1810*6777b538SAndroid Build Coastguard Worker { 732,	"tilde","small tilde, U+02DC ISOdia" },
1811*6777b538SAndroid Build Coastguard Worker 
1812*6777b538SAndroid Build Coastguard Worker { 913,	"Alpha","greek capital letter alpha, U+0391" },
1813*6777b538SAndroid Build Coastguard Worker { 914,	"Beta",	"greek capital letter beta, U+0392" },
1814*6777b538SAndroid Build Coastguard Worker { 915,	"Gamma","greek capital letter gamma, U+0393 ISOgrk3" },
1815*6777b538SAndroid Build Coastguard Worker { 916,	"Delta","greek capital letter delta, U+0394 ISOgrk3" },
1816*6777b538SAndroid Build Coastguard Worker { 917,	"Epsilon","greek capital letter epsilon, U+0395" },
1817*6777b538SAndroid Build Coastguard Worker { 918,	"Zeta",	"greek capital letter zeta, U+0396" },
1818*6777b538SAndroid Build Coastguard Worker { 919,	"Eta",	"greek capital letter eta, U+0397" },
1819*6777b538SAndroid Build Coastguard Worker { 920,	"Theta","greek capital letter theta, U+0398 ISOgrk3" },
1820*6777b538SAndroid Build Coastguard Worker { 921,	"Iota",	"greek capital letter iota, U+0399" },
1821*6777b538SAndroid Build Coastguard Worker { 922,	"Kappa","greek capital letter kappa, U+039A" },
1822*6777b538SAndroid Build Coastguard Worker { 923,	"Lambda", "greek capital letter lambda, U+039B ISOgrk3" },
1823*6777b538SAndroid Build Coastguard Worker { 924,	"Mu",	"greek capital letter mu, U+039C" },
1824*6777b538SAndroid Build Coastguard Worker { 925,	"Nu",	"greek capital letter nu, U+039D" },
1825*6777b538SAndroid Build Coastguard Worker { 926,	"Xi",	"greek capital letter xi, U+039E ISOgrk3" },
1826*6777b538SAndroid Build Coastguard Worker { 927,	"Omicron","greek capital letter omicron, U+039F" },
1827*6777b538SAndroid Build Coastguard Worker { 928,	"Pi",	"greek capital letter pi, U+03A0 ISOgrk3" },
1828*6777b538SAndroid Build Coastguard Worker { 929,	"Rho",	"greek capital letter rho, U+03A1" },
1829*6777b538SAndroid Build Coastguard Worker { 931,	"Sigma","greek capital letter sigma, U+03A3 ISOgrk3" },
1830*6777b538SAndroid Build Coastguard Worker { 932,	"Tau",	"greek capital letter tau, U+03A4" },
1831*6777b538SAndroid Build Coastguard Worker { 933,	"Upsilon","greek capital letter upsilon, U+03A5 ISOgrk3" },
1832*6777b538SAndroid Build Coastguard Worker { 934,	"Phi",	"greek capital letter phi, U+03A6 ISOgrk3" },
1833*6777b538SAndroid Build Coastguard Worker { 935,	"Chi",	"greek capital letter chi, U+03A7" },
1834*6777b538SAndroid Build Coastguard Worker { 936,	"Psi",	"greek capital letter psi, U+03A8 ISOgrk3" },
1835*6777b538SAndroid Build Coastguard Worker { 937,	"Omega","greek capital letter omega, U+03A9 ISOgrk3" },
1836*6777b538SAndroid Build Coastguard Worker 
1837*6777b538SAndroid Build Coastguard Worker { 945,	"alpha","greek small letter alpha, U+03B1 ISOgrk3" },
1838*6777b538SAndroid Build Coastguard Worker { 946,	"beta",	"greek small letter beta, U+03B2 ISOgrk3" },
1839*6777b538SAndroid Build Coastguard Worker { 947,	"gamma","greek small letter gamma, U+03B3 ISOgrk3" },
1840*6777b538SAndroid Build Coastguard Worker { 948,	"delta","greek small letter delta, U+03B4 ISOgrk3" },
1841*6777b538SAndroid Build Coastguard Worker { 949,	"epsilon","greek small letter epsilon, U+03B5 ISOgrk3" },
1842*6777b538SAndroid Build Coastguard Worker { 950,	"zeta",	"greek small letter zeta, U+03B6 ISOgrk3" },
1843*6777b538SAndroid Build Coastguard Worker { 951,	"eta",	"greek small letter eta, U+03B7 ISOgrk3" },
1844*6777b538SAndroid Build Coastguard Worker { 952,	"theta","greek small letter theta, U+03B8 ISOgrk3" },
1845*6777b538SAndroid Build Coastguard Worker { 953,	"iota",	"greek small letter iota, U+03B9 ISOgrk3" },
1846*6777b538SAndroid Build Coastguard Worker { 954,	"kappa","greek small letter kappa, U+03BA ISOgrk3" },
1847*6777b538SAndroid Build Coastguard Worker { 955,	"lambda","greek small letter lambda, U+03BB ISOgrk3" },
1848*6777b538SAndroid Build Coastguard Worker { 956,	"mu",	"greek small letter mu, U+03BC ISOgrk3" },
1849*6777b538SAndroid Build Coastguard Worker { 957,	"nu",	"greek small letter nu, U+03BD ISOgrk3" },
1850*6777b538SAndroid Build Coastguard Worker { 958,	"xi",	"greek small letter xi, U+03BE ISOgrk3" },
1851*6777b538SAndroid Build Coastguard Worker { 959,	"omicron","greek small letter omicron, U+03BF NEW" },
1852*6777b538SAndroid Build Coastguard Worker { 960,	"pi",	"greek small letter pi, U+03C0 ISOgrk3" },
1853*6777b538SAndroid Build Coastguard Worker { 961,	"rho",	"greek small letter rho, U+03C1 ISOgrk3" },
1854*6777b538SAndroid Build Coastguard Worker { 962,	"sigmaf","greek small letter final sigma, U+03C2 ISOgrk3" },
1855*6777b538SAndroid Build Coastguard Worker { 963,	"sigma","greek small letter sigma, U+03C3 ISOgrk3" },
1856*6777b538SAndroid Build Coastguard Worker { 964,	"tau",	"greek small letter tau, U+03C4 ISOgrk3" },
1857*6777b538SAndroid Build Coastguard Worker { 965,	"upsilon","greek small letter upsilon, U+03C5 ISOgrk3" },
1858*6777b538SAndroid Build Coastguard Worker { 966,	"phi",	"greek small letter phi, U+03C6 ISOgrk3" },
1859*6777b538SAndroid Build Coastguard Worker { 967,	"chi",	"greek small letter chi, U+03C7 ISOgrk3" },
1860*6777b538SAndroid Build Coastguard Worker { 968,	"psi",	"greek small letter psi, U+03C8 ISOgrk3" },
1861*6777b538SAndroid Build Coastguard Worker { 969,	"omega","greek small letter omega, U+03C9 ISOgrk3" },
1862*6777b538SAndroid Build Coastguard Worker { 977,	"thetasym","greek small letter theta symbol, U+03D1 NEW" },
1863*6777b538SAndroid Build Coastguard Worker { 978,	"upsih","greek upsilon with hook symbol, U+03D2 NEW" },
1864*6777b538SAndroid Build Coastguard Worker { 982,	"piv",	"greek pi symbol, U+03D6 ISOgrk3" },
1865*6777b538SAndroid Build Coastguard Worker 
1866*6777b538SAndroid Build Coastguard Worker { 8194,	"ensp",	"en space, U+2002 ISOpub" },
1867*6777b538SAndroid Build Coastguard Worker { 8195,	"emsp",	"em space, U+2003 ISOpub" },
1868*6777b538SAndroid Build Coastguard Worker { 8201,	"thinsp","thin space, U+2009 ISOpub" },
1869*6777b538SAndroid Build Coastguard Worker { 8204,	"zwnj",	"zero width non-joiner, U+200C NEW RFC 2070" },
1870*6777b538SAndroid Build Coastguard Worker { 8205,	"zwj",	"zero width joiner, U+200D NEW RFC 2070" },
1871*6777b538SAndroid Build Coastguard Worker { 8206,	"lrm",	"left-to-right mark, U+200E NEW RFC 2070" },
1872*6777b538SAndroid Build Coastguard Worker { 8207,	"rlm",	"right-to-left mark, U+200F NEW RFC 2070" },
1873*6777b538SAndroid Build Coastguard Worker { 8211,	"ndash","en dash, U+2013 ISOpub" },
1874*6777b538SAndroid Build Coastguard Worker { 8212,	"mdash","em dash, U+2014 ISOpub" },
1875*6777b538SAndroid Build Coastguard Worker { 8216,	"lsquo","left single quotation mark, U+2018 ISOnum" },
1876*6777b538SAndroid Build Coastguard Worker { 8217,	"rsquo","right single quotation mark, U+2019 ISOnum" },
1877*6777b538SAndroid Build Coastguard Worker { 8218,	"sbquo","single low-9 quotation mark, U+201A NEW" },
1878*6777b538SAndroid Build Coastguard Worker { 8220,	"ldquo","left double quotation mark, U+201C ISOnum" },
1879*6777b538SAndroid Build Coastguard Worker { 8221,	"rdquo","right double quotation mark, U+201D ISOnum" },
1880*6777b538SAndroid Build Coastguard Worker { 8222,	"bdquo","double low-9 quotation mark, U+201E NEW" },
1881*6777b538SAndroid Build Coastguard Worker { 8224,	"dagger","dagger, U+2020 ISOpub" },
1882*6777b538SAndroid Build Coastguard Worker { 8225,	"Dagger","double dagger, U+2021 ISOpub" },
1883*6777b538SAndroid Build Coastguard Worker 
1884*6777b538SAndroid Build Coastguard Worker { 8226,	"bull",	"bullet = black small circle, U+2022 ISOpub" },
1885*6777b538SAndroid Build Coastguard Worker { 8230,	"hellip","horizontal ellipsis = three dot leader, U+2026 ISOpub" },
1886*6777b538SAndroid Build Coastguard Worker 
1887*6777b538SAndroid Build Coastguard Worker { 8240,	"permil","per mille sign, U+2030 ISOtech" },
1888*6777b538SAndroid Build Coastguard Worker 
1889*6777b538SAndroid Build Coastguard Worker { 8242,	"prime","prime = minutes = feet, U+2032 ISOtech" },
1890*6777b538SAndroid Build Coastguard Worker { 8243,	"Prime","double prime = seconds = inches, U+2033 ISOtech" },
1891*6777b538SAndroid Build Coastguard Worker 
1892*6777b538SAndroid Build Coastguard Worker { 8249,	"lsaquo","single left-pointing angle quotation mark, U+2039 ISO proposed" },
1893*6777b538SAndroid Build Coastguard Worker { 8250,	"rsaquo","single right-pointing angle quotation mark, U+203A ISO proposed" },
1894*6777b538SAndroid Build Coastguard Worker 
1895*6777b538SAndroid Build Coastguard Worker { 8254,	"oline","overline = spacing overscore, U+203E NEW" },
1896*6777b538SAndroid Build Coastguard Worker { 8260,	"frasl","fraction slash, U+2044 NEW" },
1897*6777b538SAndroid Build Coastguard Worker 
1898*6777b538SAndroid Build Coastguard Worker { 8364,	"euro",	"euro sign, U+20AC NEW" },
1899*6777b538SAndroid Build Coastguard Worker 
1900*6777b538SAndroid Build Coastguard Worker { 8465,	"image","blackletter capital I = imaginary part, U+2111 ISOamso" },
1901*6777b538SAndroid Build Coastguard Worker { 8472,	"weierp","script capital P = power set = Weierstrass p, U+2118 ISOamso" },
1902*6777b538SAndroid Build Coastguard Worker { 8476,	"real",	"blackletter capital R = real part symbol, U+211C ISOamso" },
1903*6777b538SAndroid Build Coastguard Worker { 8482,	"trade","trade mark sign, U+2122 ISOnum" },
1904*6777b538SAndroid Build Coastguard Worker { 8501,	"alefsym","alef symbol = first transfinite cardinal, U+2135 NEW" },
1905*6777b538SAndroid Build Coastguard Worker { 8592,	"larr",	"leftwards arrow, U+2190 ISOnum" },
1906*6777b538SAndroid Build Coastguard Worker { 8593,	"uarr",	"upwards arrow, U+2191 ISOnum" },
1907*6777b538SAndroid Build Coastguard Worker { 8594,	"rarr",	"rightwards arrow, U+2192 ISOnum" },
1908*6777b538SAndroid Build Coastguard Worker { 8595,	"darr",	"downwards arrow, U+2193 ISOnum" },
1909*6777b538SAndroid Build Coastguard Worker { 8596,	"harr",	"left right arrow, U+2194 ISOamsa" },
1910*6777b538SAndroid Build Coastguard Worker { 8629,	"crarr","downwards arrow with corner leftwards = carriage return, U+21B5 NEW" },
1911*6777b538SAndroid Build Coastguard Worker { 8656,	"lArr",	"leftwards double arrow, U+21D0 ISOtech" },
1912*6777b538SAndroid Build Coastguard Worker { 8657,	"uArr",	"upwards double arrow, U+21D1 ISOamsa" },
1913*6777b538SAndroid Build Coastguard Worker { 8658,	"rArr",	"rightwards double arrow, U+21D2 ISOtech" },
1914*6777b538SAndroid Build Coastguard Worker { 8659,	"dArr",	"downwards double arrow, U+21D3 ISOamsa" },
1915*6777b538SAndroid Build Coastguard Worker { 8660,	"hArr",	"left right double arrow, U+21D4 ISOamsa" },
1916*6777b538SAndroid Build Coastguard Worker 
1917*6777b538SAndroid Build Coastguard Worker { 8704,	"forall","for all, U+2200 ISOtech" },
1918*6777b538SAndroid Build Coastguard Worker { 8706,	"part",	"partial differential, U+2202 ISOtech" },
1919*6777b538SAndroid Build Coastguard Worker { 8707,	"exist","there exists, U+2203 ISOtech" },
1920*6777b538SAndroid Build Coastguard Worker { 8709,	"empty","empty set = null set = diameter, U+2205 ISOamso" },
1921*6777b538SAndroid Build Coastguard Worker { 8711,	"nabla","nabla = backward difference, U+2207 ISOtech" },
1922*6777b538SAndroid Build Coastguard Worker { 8712,	"isin",	"element of, U+2208 ISOtech" },
1923*6777b538SAndroid Build Coastguard Worker { 8713,	"notin","not an element of, U+2209 ISOtech" },
1924*6777b538SAndroid Build Coastguard Worker { 8715,	"ni",	"contains as member, U+220B ISOtech" },
1925*6777b538SAndroid Build Coastguard Worker { 8719,	"prod",	"n-ary product = product sign, U+220F ISOamsb" },
1926*6777b538SAndroid Build Coastguard Worker { 8721,	"sum",	"n-ary summation, U+2211 ISOamsb" },
1927*6777b538SAndroid Build Coastguard Worker { 8722,	"minus","minus sign, U+2212 ISOtech" },
1928*6777b538SAndroid Build Coastguard Worker { 8727,	"lowast","asterisk operator, U+2217 ISOtech" },
1929*6777b538SAndroid Build Coastguard Worker { 8730,	"radic","square root = radical sign, U+221A ISOtech" },
1930*6777b538SAndroid Build Coastguard Worker { 8733,	"prop",	"proportional to, U+221D ISOtech" },
1931*6777b538SAndroid Build Coastguard Worker { 8734,	"infin","infinity, U+221E ISOtech" },
1932*6777b538SAndroid Build Coastguard Worker { 8736,	"ang",	"angle, U+2220 ISOamso" },
1933*6777b538SAndroid Build Coastguard Worker { 8743,	"and",	"logical and = wedge, U+2227 ISOtech" },
1934*6777b538SAndroid Build Coastguard Worker { 8744,	"or",	"logical or = vee, U+2228 ISOtech" },
1935*6777b538SAndroid Build Coastguard Worker { 8745,	"cap",	"intersection = cap, U+2229 ISOtech" },
1936*6777b538SAndroid Build Coastguard Worker { 8746,	"cup",	"union = cup, U+222A ISOtech" },
1937*6777b538SAndroid Build Coastguard Worker { 8747,	"int",	"integral, U+222B ISOtech" },
1938*6777b538SAndroid Build Coastguard Worker { 8756,	"there4","therefore, U+2234 ISOtech" },
1939*6777b538SAndroid Build Coastguard Worker { 8764,	"sim",	"tilde operator = varies with = similar to, U+223C ISOtech" },
1940*6777b538SAndroid Build Coastguard Worker { 8773,	"cong",	"approximately equal to, U+2245 ISOtech" },
1941*6777b538SAndroid Build Coastguard Worker { 8776,	"asymp","almost equal to = asymptotic to, U+2248 ISOamsr" },
1942*6777b538SAndroid Build Coastguard Worker { 8800,	"ne",	"not equal to, U+2260 ISOtech" },
1943*6777b538SAndroid Build Coastguard Worker { 8801,	"equiv","identical to, U+2261 ISOtech" },
1944*6777b538SAndroid Build Coastguard Worker { 8804,	"le",	"less-than or equal to, U+2264 ISOtech" },
1945*6777b538SAndroid Build Coastguard Worker { 8805,	"ge",	"greater-than or equal to, U+2265 ISOtech" },
1946*6777b538SAndroid Build Coastguard Worker { 8834,	"sub",	"subset of, U+2282 ISOtech" },
1947*6777b538SAndroid Build Coastguard Worker { 8835,	"sup",	"superset of, U+2283 ISOtech" },
1948*6777b538SAndroid Build Coastguard Worker { 8836,	"nsub",	"not a subset of, U+2284 ISOamsn" },
1949*6777b538SAndroid Build Coastguard Worker { 8838,	"sube",	"subset of or equal to, U+2286 ISOtech" },
1950*6777b538SAndroid Build Coastguard Worker { 8839,	"supe",	"superset of or equal to, U+2287 ISOtech" },
1951*6777b538SAndroid Build Coastguard Worker { 8853,	"oplus","circled plus = direct sum, U+2295 ISOamsb" },
1952*6777b538SAndroid Build Coastguard Worker { 8855,	"otimes","circled times = vector product, U+2297 ISOamsb" },
1953*6777b538SAndroid Build Coastguard Worker { 8869,	"perp",	"up tack = orthogonal to = perpendicular, U+22A5 ISOtech" },
1954*6777b538SAndroid Build Coastguard Worker { 8901,	"sdot",	"dot operator, U+22C5 ISOamsb" },
1955*6777b538SAndroid Build Coastguard Worker { 8968,	"lceil","left ceiling = apl upstile, U+2308 ISOamsc" },
1956*6777b538SAndroid Build Coastguard Worker { 8969,	"rceil","right ceiling, U+2309 ISOamsc" },
1957*6777b538SAndroid Build Coastguard Worker { 8970,	"lfloor","left floor = apl downstile, U+230A ISOamsc" },
1958*6777b538SAndroid Build Coastguard Worker { 8971,	"rfloor","right floor, U+230B ISOamsc" },
1959*6777b538SAndroid Build Coastguard Worker { 9001,	"lang",	"left-pointing angle bracket = bra, U+2329 ISOtech" },
1960*6777b538SAndroid Build Coastguard Worker { 9002,	"rang",	"right-pointing angle bracket = ket, U+232A ISOtech" },
1961*6777b538SAndroid Build Coastguard Worker { 9674,	"loz",	"lozenge, U+25CA ISOpub" },
1962*6777b538SAndroid Build Coastguard Worker 
1963*6777b538SAndroid Build Coastguard Worker { 9824,	"spades","black spade suit, U+2660 ISOpub" },
1964*6777b538SAndroid Build Coastguard Worker { 9827,	"clubs","black club suit = shamrock, U+2663 ISOpub" },
1965*6777b538SAndroid Build Coastguard Worker { 9829,	"hearts","black heart suit = valentine, U+2665 ISOpub" },
1966*6777b538SAndroid Build Coastguard Worker { 9830,	"diams","black diamond suit, U+2666 ISOpub" },
1967*6777b538SAndroid Build Coastguard Worker 
1968*6777b538SAndroid Build Coastguard Worker };
1969*6777b538SAndroid Build Coastguard Worker 
1970*6777b538SAndroid Build Coastguard Worker /************************************************************************
1971*6777b538SAndroid Build Coastguard Worker  *									*
1972*6777b538SAndroid Build Coastguard Worker  *		Commodity functions to handle entities			*
1973*6777b538SAndroid Build Coastguard Worker  *									*
1974*6777b538SAndroid Build Coastguard Worker  ************************************************************************/
1975*6777b538SAndroid Build Coastguard Worker 
1976*6777b538SAndroid Build Coastguard Worker /*
1977*6777b538SAndroid Build Coastguard Worker  * Macro used to grow the current buffer.
1978*6777b538SAndroid Build Coastguard Worker  */
1979*6777b538SAndroid Build Coastguard Worker #define growBuffer(buffer) {						\
1980*6777b538SAndroid Build Coastguard Worker     xmlChar *tmp;							\
1981*6777b538SAndroid Build Coastguard Worker     buffer##_size *= 2;							\
1982*6777b538SAndroid Build Coastguard Worker     tmp = (xmlChar *) xmlRealloc(buffer, buffer##_size); 		\
1983*6777b538SAndroid Build Coastguard Worker     if (tmp == NULL) {							\
1984*6777b538SAndroid Build Coastguard Worker 	htmlErrMemory(ctxt);			\
1985*6777b538SAndroid Build Coastguard Worker 	xmlFree(buffer);						\
1986*6777b538SAndroid Build Coastguard Worker 	return(NULL);							\
1987*6777b538SAndroid Build Coastguard Worker     }									\
1988*6777b538SAndroid Build Coastguard Worker     buffer = tmp;							\
1989*6777b538SAndroid Build Coastguard Worker }
1990*6777b538SAndroid Build Coastguard Worker 
1991*6777b538SAndroid Build Coastguard Worker /**
1992*6777b538SAndroid Build Coastguard Worker  * htmlEntityLookup:
1993*6777b538SAndroid Build Coastguard Worker  * @name: the entity name
1994*6777b538SAndroid Build Coastguard Worker  *
1995*6777b538SAndroid Build Coastguard Worker  * Lookup the given entity in EntitiesTable
1996*6777b538SAndroid Build Coastguard Worker  *
1997*6777b538SAndroid Build Coastguard Worker  * TODO: the linear scan is really ugly, an hash table is really needed.
1998*6777b538SAndroid Build Coastguard Worker  *
1999*6777b538SAndroid Build Coastguard Worker  * Returns the associated htmlEntityDescPtr if found, NULL otherwise.
2000*6777b538SAndroid Build Coastguard Worker  */
2001*6777b538SAndroid Build Coastguard Worker const htmlEntityDesc *
htmlEntityLookup(const xmlChar * name)2002*6777b538SAndroid Build Coastguard Worker htmlEntityLookup(const xmlChar *name) {
2003*6777b538SAndroid Build Coastguard Worker     unsigned int i;
2004*6777b538SAndroid Build Coastguard Worker 
2005*6777b538SAndroid Build Coastguard Worker     for (i = 0;i < (sizeof(html40EntitiesTable)/
2006*6777b538SAndroid Build Coastguard Worker                     sizeof(html40EntitiesTable[0]));i++) {
2007*6777b538SAndroid Build Coastguard Worker         if (xmlStrEqual(name, BAD_CAST html40EntitiesTable[i].name)) {
2008*6777b538SAndroid Build Coastguard Worker             return((htmlEntityDescPtr) &html40EntitiesTable[i]);
2009*6777b538SAndroid Build Coastguard Worker 	}
2010*6777b538SAndroid Build Coastguard Worker     }
2011*6777b538SAndroid Build Coastguard Worker     return(NULL);
2012*6777b538SAndroid Build Coastguard Worker }
2013*6777b538SAndroid Build Coastguard Worker 
2014*6777b538SAndroid Build Coastguard Worker /**
2015*6777b538SAndroid Build Coastguard Worker  * htmlEntityValueLookup:
2016*6777b538SAndroid Build Coastguard Worker  * @value: the entity's unicode value
2017*6777b538SAndroid Build Coastguard Worker  *
2018*6777b538SAndroid Build Coastguard Worker  * Lookup the given entity in EntitiesTable
2019*6777b538SAndroid Build Coastguard Worker  *
2020*6777b538SAndroid Build Coastguard Worker  * TODO: the linear scan is really ugly, an hash table is really needed.
2021*6777b538SAndroid Build Coastguard Worker  *
2022*6777b538SAndroid Build Coastguard Worker  * Returns the associated htmlEntityDescPtr if found, NULL otherwise.
2023*6777b538SAndroid Build Coastguard Worker  */
2024*6777b538SAndroid Build Coastguard Worker const htmlEntityDesc *
htmlEntityValueLookup(unsigned int value)2025*6777b538SAndroid Build Coastguard Worker htmlEntityValueLookup(unsigned int value) {
2026*6777b538SAndroid Build Coastguard Worker     unsigned int i;
2027*6777b538SAndroid Build Coastguard Worker 
2028*6777b538SAndroid Build Coastguard Worker     for (i = 0;i < (sizeof(html40EntitiesTable)/
2029*6777b538SAndroid Build Coastguard Worker                     sizeof(html40EntitiesTable[0]));i++) {
2030*6777b538SAndroid Build Coastguard Worker         if (html40EntitiesTable[i].value >= value) {
2031*6777b538SAndroid Build Coastguard Worker 	    if (html40EntitiesTable[i].value > value)
2032*6777b538SAndroid Build Coastguard Worker 		break;
2033*6777b538SAndroid Build Coastguard Worker             return((htmlEntityDescPtr) &html40EntitiesTable[i]);
2034*6777b538SAndroid Build Coastguard Worker 	}
2035*6777b538SAndroid Build Coastguard Worker     }
2036*6777b538SAndroid Build Coastguard Worker     return(NULL);
2037*6777b538SAndroid Build Coastguard Worker }
2038*6777b538SAndroid Build Coastguard Worker 
2039*6777b538SAndroid Build Coastguard Worker /**
2040*6777b538SAndroid Build Coastguard Worker  * UTF8ToHtml:
2041*6777b538SAndroid Build Coastguard Worker  * @out:  a pointer to an array of bytes to store the result
2042*6777b538SAndroid Build Coastguard Worker  * @outlen:  the length of @out
2043*6777b538SAndroid Build Coastguard Worker  * @in:  a pointer to an array of UTF-8 chars
2044*6777b538SAndroid Build Coastguard Worker  * @inlen:  the length of @in
2045*6777b538SAndroid Build Coastguard Worker  *
2046*6777b538SAndroid Build Coastguard Worker  * Take a block of UTF-8 chars in and try to convert it to an ASCII
2047*6777b538SAndroid Build Coastguard Worker  * plus HTML entities block of chars out.
2048*6777b538SAndroid Build Coastguard Worker  *
2049*6777b538SAndroid Build Coastguard Worker  * Returns 0 if success, -2 if the transcoding fails, or -1 otherwise
2050*6777b538SAndroid Build Coastguard Worker  * The value of @inlen after return is the number of octets consumed
2051*6777b538SAndroid Build Coastguard Worker  *     as the return value is positive, else unpredictable.
2052*6777b538SAndroid Build Coastguard Worker  * The value of @outlen after return is the number of octets consumed.
2053*6777b538SAndroid Build Coastguard Worker  */
2054*6777b538SAndroid Build Coastguard Worker int
UTF8ToHtml(unsigned char * out,int * outlen,const unsigned char * in,int * inlen)2055*6777b538SAndroid Build Coastguard Worker UTF8ToHtml(unsigned char* out, int *outlen,
2056*6777b538SAndroid Build Coastguard Worker               const unsigned char* in, int *inlen) {
2057*6777b538SAndroid Build Coastguard Worker     const unsigned char* processed = in;
2058*6777b538SAndroid Build Coastguard Worker     const unsigned char* outend;
2059*6777b538SAndroid Build Coastguard Worker     const unsigned char* outstart = out;
2060*6777b538SAndroid Build Coastguard Worker     const unsigned char* instart = in;
2061*6777b538SAndroid Build Coastguard Worker     const unsigned char* inend;
2062*6777b538SAndroid Build Coastguard Worker     unsigned int c, d;
2063*6777b538SAndroid Build Coastguard Worker     int trailing;
2064*6777b538SAndroid Build Coastguard Worker 
2065*6777b538SAndroid Build Coastguard Worker     if ((out == NULL) || (outlen == NULL) || (inlen == NULL)) return(-1);
2066*6777b538SAndroid Build Coastguard Worker     if (in == NULL) {
2067*6777b538SAndroid Build Coastguard Worker         /*
2068*6777b538SAndroid Build Coastguard Worker 	 * initialization nothing to do
2069*6777b538SAndroid Build Coastguard Worker 	 */
2070*6777b538SAndroid Build Coastguard Worker 	*outlen = 0;
2071*6777b538SAndroid Build Coastguard Worker 	*inlen = 0;
2072*6777b538SAndroid Build Coastguard Worker 	return(0);
2073*6777b538SAndroid Build Coastguard Worker     }
2074*6777b538SAndroid Build Coastguard Worker     inend = in + (*inlen);
2075*6777b538SAndroid Build Coastguard Worker     outend = out + (*outlen);
2076*6777b538SAndroid Build Coastguard Worker     while (in < inend) {
2077*6777b538SAndroid Build Coastguard Worker 	d = *in++;
2078*6777b538SAndroid Build Coastguard Worker 	if      (d < 0x80)  { c= d; trailing= 0; }
2079*6777b538SAndroid Build Coastguard Worker 	else if (d < 0xC0) {
2080*6777b538SAndroid Build Coastguard Worker 	    /* trailing byte in leading position */
2081*6777b538SAndroid Build Coastguard Worker 	    *outlen = out - outstart;
2082*6777b538SAndroid Build Coastguard Worker 	    *inlen = processed - instart;
2083*6777b538SAndroid Build Coastguard Worker 	    return(-2);
2084*6777b538SAndroid Build Coastguard Worker         } else if (d < 0xE0)  { c= d & 0x1F; trailing= 1; }
2085*6777b538SAndroid Build Coastguard Worker         else if (d < 0xF0)  { c= d & 0x0F; trailing= 2; }
2086*6777b538SAndroid Build Coastguard Worker         else if (d < 0xF8)  { c= d & 0x07; trailing= 3; }
2087*6777b538SAndroid Build Coastguard Worker 	else {
2088*6777b538SAndroid Build Coastguard Worker 	    /* no chance for this in Ascii */
2089*6777b538SAndroid Build Coastguard Worker 	    *outlen = out - outstart;
2090*6777b538SAndroid Build Coastguard Worker 	    *inlen = processed - instart;
2091*6777b538SAndroid Build Coastguard Worker 	    return(-2);
2092*6777b538SAndroid Build Coastguard Worker 	}
2093*6777b538SAndroid Build Coastguard Worker 
2094*6777b538SAndroid Build Coastguard Worker 	if (inend - in < trailing) {
2095*6777b538SAndroid Build Coastguard Worker 	    break;
2096*6777b538SAndroid Build Coastguard Worker 	}
2097*6777b538SAndroid Build Coastguard Worker 
2098*6777b538SAndroid Build Coastguard Worker 	for ( ; trailing; trailing--) {
2099*6777b538SAndroid Build Coastguard Worker 	    if ((in >= inend) || (((d= *in++) & 0xC0) != 0x80))
2100*6777b538SAndroid Build Coastguard Worker 		break;
2101*6777b538SAndroid Build Coastguard Worker 	    c <<= 6;
2102*6777b538SAndroid Build Coastguard Worker 	    c |= d & 0x3F;
2103*6777b538SAndroid Build Coastguard Worker 	}
2104*6777b538SAndroid Build Coastguard Worker 
2105*6777b538SAndroid Build Coastguard Worker 	/* assertion: c is a single UTF-4 value */
2106*6777b538SAndroid Build Coastguard Worker 	if (c < 0x80) {
2107*6777b538SAndroid Build Coastguard Worker 	    if (out + 1 >= outend)
2108*6777b538SAndroid Build Coastguard Worker 		break;
2109*6777b538SAndroid Build Coastguard Worker 	    *out++ = c;
2110*6777b538SAndroid Build Coastguard Worker 	} else {
2111*6777b538SAndroid Build Coastguard Worker 	    int len;
2112*6777b538SAndroid Build Coastguard Worker 	    const htmlEntityDesc * ent;
2113*6777b538SAndroid Build Coastguard Worker 	    const char *cp;
2114*6777b538SAndroid Build Coastguard Worker 	    char nbuf[16];
2115*6777b538SAndroid Build Coastguard Worker 
2116*6777b538SAndroid Build Coastguard Worker 	    /*
2117*6777b538SAndroid Build Coastguard Worker 	     * Try to lookup a predefined HTML entity for it
2118*6777b538SAndroid Build Coastguard Worker 	     */
2119*6777b538SAndroid Build Coastguard Worker 
2120*6777b538SAndroid Build Coastguard Worker 	    ent = htmlEntityValueLookup(c);
2121*6777b538SAndroid Build Coastguard Worker 	    if (ent == NULL) {
2122*6777b538SAndroid Build Coastguard Worker 	      snprintf(nbuf, sizeof(nbuf), "#%u", c);
2123*6777b538SAndroid Build Coastguard Worker 	      cp = nbuf;
2124*6777b538SAndroid Build Coastguard Worker 	    }
2125*6777b538SAndroid Build Coastguard Worker 	    else
2126*6777b538SAndroid Build Coastguard Worker 	      cp = ent->name;
2127*6777b538SAndroid Build Coastguard Worker 	    len = strlen(cp);
2128*6777b538SAndroid Build Coastguard Worker 	    if (out + 2 + len >= outend)
2129*6777b538SAndroid Build Coastguard Worker 		break;
2130*6777b538SAndroid Build Coastguard Worker 	    *out++ = '&';
2131*6777b538SAndroid Build Coastguard Worker 	    memcpy(out, cp, len);
2132*6777b538SAndroid Build Coastguard Worker 	    out += len;
2133*6777b538SAndroid Build Coastguard Worker 	    *out++ = ';';
2134*6777b538SAndroid Build Coastguard Worker 	}
2135*6777b538SAndroid Build Coastguard Worker 	processed = in;
2136*6777b538SAndroid Build Coastguard Worker     }
2137*6777b538SAndroid Build Coastguard Worker     *outlen = out - outstart;
2138*6777b538SAndroid Build Coastguard Worker     *inlen = processed - instart;
2139*6777b538SAndroid Build Coastguard Worker     return(0);
2140*6777b538SAndroid Build Coastguard Worker }
2141*6777b538SAndroid Build Coastguard Worker 
2142*6777b538SAndroid Build Coastguard Worker /**
2143*6777b538SAndroid Build Coastguard Worker  * htmlEncodeEntities:
2144*6777b538SAndroid Build Coastguard Worker  * @out:  a pointer to an array of bytes to store the result
2145*6777b538SAndroid Build Coastguard Worker  * @outlen:  the length of @out
2146*6777b538SAndroid Build Coastguard Worker  * @in:  a pointer to an array of UTF-8 chars
2147*6777b538SAndroid Build Coastguard Worker  * @inlen:  the length of @in
2148*6777b538SAndroid Build Coastguard Worker  * @quoteChar: the quote character to escape (' or ") or zero.
2149*6777b538SAndroid Build Coastguard Worker  *
2150*6777b538SAndroid Build Coastguard Worker  * Take a block of UTF-8 chars in and try to convert it to an ASCII
2151*6777b538SAndroid Build Coastguard Worker  * plus HTML entities block of chars out.
2152*6777b538SAndroid Build Coastguard Worker  *
2153*6777b538SAndroid Build Coastguard Worker  * Returns 0 if success, -2 if the transcoding fails, or -1 otherwise
2154*6777b538SAndroid Build Coastguard Worker  * The value of @inlen after return is the number of octets consumed
2155*6777b538SAndroid Build Coastguard Worker  *     as the return value is positive, else unpredictable.
2156*6777b538SAndroid Build Coastguard Worker  * The value of @outlen after return is the number of octets consumed.
2157*6777b538SAndroid Build Coastguard Worker  */
2158*6777b538SAndroid Build Coastguard Worker int
htmlEncodeEntities(unsigned char * out,int * outlen,const unsigned char * in,int * inlen,int quoteChar)2159*6777b538SAndroid Build Coastguard Worker htmlEncodeEntities(unsigned char* out, int *outlen,
2160*6777b538SAndroid Build Coastguard Worker 		   const unsigned char* in, int *inlen, int quoteChar) {
2161*6777b538SAndroid Build Coastguard Worker     const unsigned char* processed = in;
2162*6777b538SAndroid Build Coastguard Worker     const unsigned char* outend;
2163*6777b538SAndroid Build Coastguard Worker     const unsigned char* outstart = out;
2164*6777b538SAndroid Build Coastguard Worker     const unsigned char* instart = in;
2165*6777b538SAndroid Build Coastguard Worker     const unsigned char* inend;
2166*6777b538SAndroid Build Coastguard Worker     unsigned int c, d;
2167*6777b538SAndroid Build Coastguard Worker     int trailing;
2168*6777b538SAndroid Build Coastguard Worker 
2169*6777b538SAndroid Build Coastguard Worker     if ((out == NULL) || (outlen == NULL) || (inlen == NULL) || (in == NULL))
2170*6777b538SAndroid Build Coastguard Worker         return(-1);
2171*6777b538SAndroid Build Coastguard Worker     outend = out + (*outlen);
2172*6777b538SAndroid Build Coastguard Worker     inend = in + (*inlen);
2173*6777b538SAndroid Build Coastguard Worker     while (in < inend) {
2174*6777b538SAndroid Build Coastguard Worker 	d = *in++;
2175*6777b538SAndroid Build Coastguard Worker 	if      (d < 0x80)  { c= d; trailing= 0; }
2176*6777b538SAndroid Build Coastguard Worker 	else if (d < 0xC0) {
2177*6777b538SAndroid Build Coastguard Worker 	    /* trailing byte in leading position */
2178*6777b538SAndroid Build Coastguard Worker 	    *outlen = out - outstart;
2179*6777b538SAndroid Build Coastguard Worker 	    *inlen = processed - instart;
2180*6777b538SAndroid Build Coastguard Worker 	    return(-2);
2181*6777b538SAndroid Build Coastguard Worker         } else if (d < 0xE0)  { c= d & 0x1F; trailing= 1; }
2182*6777b538SAndroid Build Coastguard Worker         else if (d < 0xF0)  { c= d & 0x0F; trailing= 2; }
2183*6777b538SAndroid Build Coastguard Worker         else if (d < 0xF8)  { c= d & 0x07; trailing= 3; }
2184*6777b538SAndroid Build Coastguard Worker 	else {
2185*6777b538SAndroid Build Coastguard Worker 	    /* no chance for this in Ascii */
2186*6777b538SAndroid Build Coastguard Worker 	    *outlen = out - outstart;
2187*6777b538SAndroid Build Coastguard Worker 	    *inlen = processed - instart;
2188*6777b538SAndroid Build Coastguard Worker 	    return(-2);
2189*6777b538SAndroid Build Coastguard Worker 	}
2190*6777b538SAndroid Build Coastguard Worker 
2191*6777b538SAndroid Build Coastguard Worker 	if (inend - in < trailing)
2192*6777b538SAndroid Build Coastguard Worker 	    break;
2193*6777b538SAndroid Build Coastguard Worker 
2194*6777b538SAndroid Build Coastguard Worker 	while (trailing--) {
2195*6777b538SAndroid Build Coastguard Worker 	    if (((d= *in++) & 0xC0) != 0x80) {
2196*6777b538SAndroid Build Coastguard Worker 		*outlen = out - outstart;
2197*6777b538SAndroid Build Coastguard Worker 		*inlen = processed - instart;
2198*6777b538SAndroid Build Coastguard Worker 		return(-2);
2199*6777b538SAndroid Build Coastguard Worker 	    }
2200*6777b538SAndroid Build Coastguard Worker 	    c <<= 6;
2201*6777b538SAndroid Build Coastguard Worker 	    c |= d & 0x3F;
2202*6777b538SAndroid Build Coastguard Worker 	}
2203*6777b538SAndroid Build Coastguard Worker 
2204*6777b538SAndroid Build Coastguard Worker 	/* assertion: c is a single UTF-4 value */
2205*6777b538SAndroid Build Coastguard Worker 	if ((c < 0x80) && (c != (unsigned int) quoteChar) &&
2206*6777b538SAndroid Build Coastguard Worker 	    (c != '&') && (c != '<') && (c != '>')) {
2207*6777b538SAndroid Build Coastguard Worker 	    if (out >= outend)
2208*6777b538SAndroid Build Coastguard Worker 		break;
2209*6777b538SAndroid Build Coastguard Worker 	    *out++ = c;
2210*6777b538SAndroid Build Coastguard Worker 	} else {
2211*6777b538SAndroid Build Coastguard Worker 	    const htmlEntityDesc * ent;
2212*6777b538SAndroid Build Coastguard Worker 	    const char *cp;
2213*6777b538SAndroid Build Coastguard Worker 	    char nbuf[16];
2214*6777b538SAndroid Build Coastguard Worker 	    int len;
2215*6777b538SAndroid Build Coastguard Worker 
2216*6777b538SAndroid Build Coastguard Worker 	    /*
2217*6777b538SAndroid Build Coastguard Worker 	     * Try to lookup a predefined HTML entity for it
2218*6777b538SAndroid Build Coastguard Worker 	     */
2219*6777b538SAndroid Build Coastguard Worker 	    ent = htmlEntityValueLookup(c);
2220*6777b538SAndroid Build Coastguard Worker 	    if (ent == NULL) {
2221*6777b538SAndroid Build Coastguard Worker 		snprintf(nbuf, sizeof(nbuf), "#%u", c);
2222*6777b538SAndroid Build Coastguard Worker 		cp = nbuf;
2223*6777b538SAndroid Build Coastguard Worker 	    }
2224*6777b538SAndroid Build Coastguard Worker 	    else
2225*6777b538SAndroid Build Coastguard Worker 		cp = ent->name;
2226*6777b538SAndroid Build Coastguard Worker 	    len = strlen(cp);
2227*6777b538SAndroid Build Coastguard Worker 	    if (outend - out < len + 2)
2228*6777b538SAndroid Build Coastguard Worker 		break;
2229*6777b538SAndroid Build Coastguard Worker 	    *out++ = '&';
2230*6777b538SAndroid Build Coastguard Worker 	    memcpy(out, cp, len);
2231*6777b538SAndroid Build Coastguard Worker 	    out += len;
2232*6777b538SAndroid Build Coastguard Worker 	    *out++ = ';';
2233*6777b538SAndroid Build Coastguard Worker 	}
2234*6777b538SAndroid Build Coastguard Worker 	processed = in;
2235*6777b538SAndroid Build Coastguard Worker     }
2236*6777b538SAndroid Build Coastguard Worker     *outlen = out - outstart;
2237*6777b538SAndroid Build Coastguard Worker     *inlen = processed - instart;
2238*6777b538SAndroid Build Coastguard Worker     return(0);
2239*6777b538SAndroid Build Coastguard Worker }
2240*6777b538SAndroid Build Coastguard Worker 
2241*6777b538SAndroid Build Coastguard Worker /************************************************************************
2242*6777b538SAndroid Build Coastguard Worker  *									*
2243*6777b538SAndroid Build Coastguard Worker  *		Commodity functions, cleanup needed ?			*
2244*6777b538SAndroid Build Coastguard Worker  *									*
2245*6777b538SAndroid Build Coastguard Worker  ************************************************************************/
2246*6777b538SAndroid Build Coastguard Worker /*
2247*6777b538SAndroid Build Coastguard Worker  * all tags allowing pc data from the html 4.01 loose dtd
2248*6777b538SAndroid Build Coastguard Worker  * NOTE: it might be more appropriate to integrate this information
2249*6777b538SAndroid Build Coastguard Worker  * into the html40ElementTable array but I don't want to risk any
2250*6777b538SAndroid Build Coastguard Worker  * binary incompatibility
2251*6777b538SAndroid Build Coastguard Worker  */
2252*6777b538SAndroid Build Coastguard Worker static const char *allowPCData[] = {
2253*6777b538SAndroid Build Coastguard Worker     "a", "abbr", "acronym", "address", "applet", "b", "bdo", "big",
2254*6777b538SAndroid Build Coastguard Worker     "blockquote", "body", "button", "caption", "center", "cite", "code",
2255*6777b538SAndroid Build Coastguard Worker     "dd", "del", "dfn", "div", "dt", "em", "font", "form", "h1", "h2",
2256*6777b538SAndroid Build Coastguard Worker     "h3", "h4", "h5", "h6", "i", "iframe", "ins", "kbd", "label", "legend",
2257*6777b538SAndroid Build Coastguard Worker     "li", "noframes", "noscript", "object", "p", "pre", "q", "s", "samp",
2258*6777b538SAndroid Build Coastguard Worker     "small", "span", "strike", "strong", "td", "th", "tt", "u", "var"
2259*6777b538SAndroid Build Coastguard Worker };
2260*6777b538SAndroid Build Coastguard Worker 
2261*6777b538SAndroid Build Coastguard Worker /**
2262*6777b538SAndroid Build Coastguard Worker  * areBlanks:
2263*6777b538SAndroid Build Coastguard Worker  * @ctxt:  an HTML parser context
2264*6777b538SAndroid Build Coastguard Worker  * @str:  a xmlChar *
2265*6777b538SAndroid Build Coastguard Worker  * @len:  the size of @str
2266*6777b538SAndroid Build Coastguard Worker  *
2267*6777b538SAndroid Build Coastguard Worker  * Is this a sequence of blank chars that one can ignore ?
2268*6777b538SAndroid Build Coastguard Worker  *
2269*6777b538SAndroid Build Coastguard Worker  * Returns 1 if ignorable 0 otherwise.
2270*6777b538SAndroid Build Coastguard Worker  */
2271*6777b538SAndroid Build Coastguard Worker 
areBlanks(htmlParserCtxtPtr ctxt,const xmlChar * str,int len)2272*6777b538SAndroid Build Coastguard Worker static int areBlanks(htmlParserCtxtPtr ctxt, const xmlChar *str, int len) {
2273*6777b538SAndroid Build Coastguard Worker     unsigned int i;
2274*6777b538SAndroid Build Coastguard Worker     int j;
2275*6777b538SAndroid Build Coastguard Worker     xmlNodePtr lastChild;
2276*6777b538SAndroid Build Coastguard Worker     xmlDtdPtr dtd;
2277*6777b538SAndroid Build Coastguard Worker 
2278*6777b538SAndroid Build Coastguard Worker     for (j = 0;j < len;j++)
2279*6777b538SAndroid Build Coastguard Worker         if (!(IS_BLANK_CH(str[j]))) return(0);
2280*6777b538SAndroid Build Coastguard Worker 
2281*6777b538SAndroid Build Coastguard Worker     if (CUR == 0) return(1);
2282*6777b538SAndroid Build Coastguard Worker     if (CUR != '<') return(0);
2283*6777b538SAndroid Build Coastguard Worker     if (ctxt->name == NULL)
2284*6777b538SAndroid Build Coastguard Worker 	return(1);
2285*6777b538SAndroid Build Coastguard Worker     if (xmlStrEqual(ctxt->name, BAD_CAST"html"))
2286*6777b538SAndroid Build Coastguard Worker 	return(1);
2287*6777b538SAndroid Build Coastguard Worker     if (xmlStrEqual(ctxt->name, BAD_CAST"head"))
2288*6777b538SAndroid Build Coastguard Worker 	return(1);
2289*6777b538SAndroid Build Coastguard Worker 
2290*6777b538SAndroid Build Coastguard Worker     /* Only strip CDATA children of the body tag for strict HTML DTDs */
2291*6777b538SAndroid Build Coastguard Worker     if (xmlStrEqual(ctxt->name, BAD_CAST "body") && ctxt->myDoc != NULL) {
2292*6777b538SAndroid Build Coastguard Worker         dtd = xmlGetIntSubset(ctxt->myDoc);
2293*6777b538SAndroid Build Coastguard Worker         if (dtd != NULL && dtd->ExternalID != NULL) {
2294*6777b538SAndroid Build Coastguard Worker             if (!xmlStrcasecmp(dtd->ExternalID, BAD_CAST "-//W3C//DTD HTML 4.01//EN") ||
2295*6777b538SAndroid Build Coastguard Worker                     !xmlStrcasecmp(dtd->ExternalID, BAD_CAST "-//W3C//DTD HTML 4//EN"))
2296*6777b538SAndroid Build Coastguard Worker                 return(1);
2297*6777b538SAndroid Build Coastguard Worker         }
2298*6777b538SAndroid Build Coastguard Worker     }
2299*6777b538SAndroid Build Coastguard Worker 
2300*6777b538SAndroid Build Coastguard Worker     if (ctxt->node == NULL) return(0);
2301*6777b538SAndroid Build Coastguard Worker     lastChild = xmlGetLastChild(ctxt->node);
2302*6777b538SAndroid Build Coastguard Worker     while ((lastChild) && (lastChild->type == XML_COMMENT_NODE))
2303*6777b538SAndroid Build Coastguard Worker 	lastChild = lastChild->prev;
2304*6777b538SAndroid Build Coastguard Worker     if (lastChild == NULL) {
2305*6777b538SAndroid Build Coastguard Worker         if ((ctxt->node->type != XML_ELEMENT_NODE) &&
2306*6777b538SAndroid Build Coastguard Worker             (ctxt->node->content != NULL)) return(0);
2307*6777b538SAndroid Build Coastguard Worker 	/* keep ws in constructs like ...<b> </b>...
2308*6777b538SAndroid Build Coastguard Worker 	   for all tags "b" allowing PCDATA */
2309*6777b538SAndroid Build Coastguard Worker 	for ( i = 0; i < sizeof(allowPCData)/sizeof(allowPCData[0]); i++ ) {
2310*6777b538SAndroid Build Coastguard Worker 	    if ( xmlStrEqual(ctxt->name, BAD_CAST allowPCData[i]) ) {
2311*6777b538SAndroid Build Coastguard Worker 		return(0);
2312*6777b538SAndroid Build Coastguard Worker 	    }
2313*6777b538SAndroid Build Coastguard Worker 	}
2314*6777b538SAndroid Build Coastguard Worker     } else if (xmlNodeIsText(lastChild)) {
2315*6777b538SAndroid Build Coastguard Worker         return(0);
2316*6777b538SAndroid Build Coastguard Worker     } else {
2317*6777b538SAndroid Build Coastguard Worker 	/* keep ws in constructs like <p><b>xy</b> <i>z</i><p>
2318*6777b538SAndroid Build Coastguard Worker 	   for all tags "p" allowing PCDATA */
2319*6777b538SAndroid Build Coastguard Worker 	for ( i = 0; i < sizeof(allowPCData)/sizeof(allowPCData[0]); i++ ) {
2320*6777b538SAndroid Build Coastguard Worker 	    if ( xmlStrEqual(lastChild->name, BAD_CAST allowPCData[i]) ) {
2321*6777b538SAndroid Build Coastguard Worker 		return(0);
2322*6777b538SAndroid Build Coastguard Worker 	    }
2323*6777b538SAndroid Build Coastguard Worker 	}
2324*6777b538SAndroid Build Coastguard Worker     }
2325*6777b538SAndroid Build Coastguard Worker     return(1);
2326*6777b538SAndroid Build Coastguard Worker }
2327*6777b538SAndroid Build Coastguard Worker 
2328*6777b538SAndroid Build Coastguard Worker /**
2329*6777b538SAndroid Build Coastguard Worker  * htmlNewDocNoDtD:
2330*6777b538SAndroid Build Coastguard Worker  * @URI:  URI for the dtd, or NULL
2331*6777b538SAndroid Build Coastguard Worker  * @ExternalID:  the external ID of the DTD, or NULL
2332*6777b538SAndroid Build Coastguard Worker  *
2333*6777b538SAndroid Build Coastguard Worker  * Creates a new HTML document without a DTD node if @URI and @ExternalID
2334*6777b538SAndroid Build Coastguard Worker  * are NULL
2335*6777b538SAndroid Build Coastguard Worker  *
2336*6777b538SAndroid Build Coastguard Worker  * Returns a new document, do not initialize the DTD if not provided
2337*6777b538SAndroid Build Coastguard Worker  */
2338*6777b538SAndroid Build Coastguard Worker htmlDocPtr
htmlNewDocNoDtD(const xmlChar * URI,const xmlChar * ExternalID)2339*6777b538SAndroid Build Coastguard Worker htmlNewDocNoDtD(const xmlChar *URI, const xmlChar *ExternalID) {
2340*6777b538SAndroid Build Coastguard Worker     xmlDocPtr cur;
2341*6777b538SAndroid Build Coastguard Worker 
2342*6777b538SAndroid Build Coastguard Worker     /*
2343*6777b538SAndroid Build Coastguard Worker      * Allocate a new document and fill the fields.
2344*6777b538SAndroid Build Coastguard Worker      */
2345*6777b538SAndroid Build Coastguard Worker     cur = (xmlDocPtr) xmlMalloc(sizeof(xmlDoc));
2346*6777b538SAndroid Build Coastguard Worker     if (cur == NULL)
2347*6777b538SAndroid Build Coastguard Worker 	return(NULL);
2348*6777b538SAndroid Build Coastguard Worker     memset(cur, 0, sizeof(xmlDoc));
2349*6777b538SAndroid Build Coastguard Worker 
2350*6777b538SAndroid Build Coastguard Worker     cur->type = XML_HTML_DOCUMENT_NODE;
2351*6777b538SAndroid Build Coastguard Worker     cur->version = NULL;
2352*6777b538SAndroid Build Coastguard Worker     cur->intSubset = NULL;
2353*6777b538SAndroid Build Coastguard Worker     cur->doc = cur;
2354*6777b538SAndroid Build Coastguard Worker     cur->name = NULL;
2355*6777b538SAndroid Build Coastguard Worker     cur->children = NULL;
2356*6777b538SAndroid Build Coastguard Worker     cur->extSubset = NULL;
2357*6777b538SAndroid Build Coastguard Worker     cur->oldNs = NULL;
2358*6777b538SAndroid Build Coastguard Worker     cur->encoding = NULL;
2359*6777b538SAndroid Build Coastguard Worker     cur->standalone = 1;
2360*6777b538SAndroid Build Coastguard Worker     cur->compression = 0;
2361*6777b538SAndroid Build Coastguard Worker     cur->ids = NULL;
2362*6777b538SAndroid Build Coastguard Worker     cur->refs = NULL;
2363*6777b538SAndroid Build Coastguard Worker     cur->_private = NULL;
2364*6777b538SAndroid Build Coastguard Worker     cur->charset = XML_CHAR_ENCODING_UTF8;
2365*6777b538SAndroid Build Coastguard Worker     cur->properties = XML_DOC_HTML | XML_DOC_USERBUILT;
2366*6777b538SAndroid Build Coastguard Worker     if ((ExternalID != NULL) ||
2367*6777b538SAndroid Build Coastguard Worker 	(URI != NULL)) {
2368*6777b538SAndroid Build Coastguard Worker         xmlDtdPtr intSubset;
2369*6777b538SAndroid Build Coastguard Worker 
2370*6777b538SAndroid Build Coastguard Worker 	intSubset = xmlCreateIntSubset(cur, BAD_CAST "html", ExternalID, URI);
2371*6777b538SAndroid Build Coastguard Worker         if (intSubset == NULL) {
2372*6777b538SAndroid Build Coastguard Worker             xmlFree(cur);
2373*6777b538SAndroid Build Coastguard Worker             return(NULL);
2374*6777b538SAndroid Build Coastguard Worker         }
2375*6777b538SAndroid Build Coastguard Worker     }
2376*6777b538SAndroid Build Coastguard Worker     if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
2377*6777b538SAndroid Build Coastguard Worker 	xmlRegisterNodeDefaultValue((xmlNodePtr)cur);
2378*6777b538SAndroid Build Coastguard Worker     return(cur);
2379*6777b538SAndroid Build Coastguard Worker }
2380*6777b538SAndroid Build Coastguard Worker 
2381*6777b538SAndroid Build Coastguard Worker /**
2382*6777b538SAndroid Build Coastguard Worker  * htmlNewDoc:
2383*6777b538SAndroid Build Coastguard Worker  * @URI:  URI for the dtd, or NULL
2384*6777b538SAndroid Build Coastguard Worker  * @ExternalID:  the external ID of the DTD, or NULL
2385*6777b538SAndroid Build Coastguard Worker  *
2386*6777b538SAndroid Build Coastguard Worker  * Creates a new HTML document
2387*6777b538SAndroid Build Coastguard Worker  *
2388*6777b538SAndroid Build Coastguard Worker  * Returns a new document
2389*6777b538SAndroid Build Coastguard Worker  */
2390*6777b538SAndroid Build Coastguard Worker htmlDocPtr
htmlNewDoc(const xmlChar * URI,const xmlChar * ExternalID)2391*6777b538SAndroid Build Coastguard Worker htmlNewDoc(const xmlChar *URI, const xmlChar *ExternalID) {
2392*6777b538SAndroid Build Coastguard Worker     if ((URI == NULL) && (ExternalID == NULL))
2393*6777b538SAndroid Build Coastguard Worker 	return(htmlNewDocNoDtD(
2394*6777b538SAndroid Build Coastguard Worker 		    BAD_CAST "http://www.w3.org/TR/REC-html40/loose.dtd",
2395*6777b538SAndroid Build Coastguard Worker 		    BAD_CAST "-//W3C//DTD HTML 4.0 Transitional//EN"));
2396*6777b538SAndroid Build Coastguard Worker 
2397*6777b538SAndroid Build Coastguard Worker     return(htmlNewDocNoDtD(URI, ExternalID));
2398*6777b538SAndroid Build Coastguard Worker }
2399*6777b538SAndroid Build Coastguard Worker 
2400*6777b538SAndroid Build Coastguard Worker 
2401*6777b538SAndroid Build Coastguard Worker /************************************************************************
2402*6777b538SAndroid Build Coastguard Worker  *									*
2403*6777b538SAndroid Build Coastguard Worker  *			The parser itself				*
2404*6777b538SAndroid Build Coastguard Worker  *	Relates to http://www.w3.org/TR/html40				*
2405*6777b538SAndroid Build Coastguard Worker  *									*
2406*6777b538SAndroid Build Coastguard Worker  ************************************************************************/
2407*6777b538SAndroid Build Coastguard Worker 
2408*6777b538SAndroid Build Coastguard Worker /************************************************************************
2409*6777b538SAndroid Build Coastguard Worker  *									*
2410*6777b538SAndroid Build Coastguard Worker  *			The parser itself				*
2411*6777b538SAndroid Build Coastguard Worker  *									*
2412*6777b538SAndroid Build Coastguard Worker  ************************************************************************/
2413*6777b538SAndroid Build Coastguard Worker 
2414*6777b538SAndroid Build Coastguard Worker static const xmlChar * htmlParseNameComplex(xmlParserCtxtPtr ctxt);
2415*6777b538SAndroid Build Coastguard Worker 
2416*6777b538SAndroid Build Coastguard Worker static void
htmlSkipBogusComment(htmlParserCtxtPtr ctxt)2417*6777b538SAndroid Build Coastguard Worker htmlSkipBogusComment(htmlParserCtxtPtr ctxt) {
2418*6777b538SAndroid Build Coastguard Worker     int c;
2419*6777b538SAndroid Build Coastguard Worker 
2420*6777b538SAndroid Build Coastguard Worker     htmlParseErr(ctxt, XML_HTML_INCORRECTLY_OPENED_COMMENT,
2421*6777b538SAndroid Build Coastguard Worker                  "Incorrectly opened comment\n", NULL, NULL);
2422*6777b538SAndroid Build Coastguard Worker 
2423*6777b538SAndroid Build Coastguard Worker     while (PARSER_STOPPED(ctxt) == 0) {
2424*6777b538SAndroid Build Coastguard Worker         c = CUR;
2425*6777b538SAndroid Build Coastguard Worker         if (c == 0)
2426*6777b538SAndroid Build Coastguard Worker             break;
2427*6777b538SAndroid Build Coastguard Worker         NEXT;
2428*6777b538SAndroid Build Coastguard Worker         if (c == '>')
2429*6777b538SAndroid Build Coastguard Worker             break;
2430*6777b538SAndroid Build Coastguard Worker     }
2431*6777b538SAndroid Build Coastguard Worker }
2432*6777b538SAndroid Build Coastguard Worker 
2433*6777b538SAndroid Build Coastguard Worker /**
2434*6777b538SAndroid Build Coastguard Worker  * htmlParseHTMLName:
2435*6777b538SAndroid Build Coastguard Worker  * @ctxt:  an HTML parser context
2436*6777b538SAndroid Build Coastguard Worker  *
2437*6777b538SAndroid Build Coastguard Worker  * parse an HTML tag or attribute name, note that we convert it to lowercase
2438*6777b538SAndroid Build Coastguard Worker  * since HTML names are not case-sensitive.
2439*6777b538SAndroid Build Coastguard Worker  *
2440*6777b538SAndroid Build Coastguard Worker  * Returns the Tag Name parsed or NULL
2441*6777b538SAndroid Build Coastguard Worker  */
2442*6777b538SAndroid Build Coastguard Worker 
2443*6777b538SAndroid Build Coastguard Worker static const xmlChar *
htmlParseHTMLName(htmlParserCtxtPtr ctxt)2444*6777b538SAndroid Build Coastguard Worker htmlParseHTMLName(htmlParserCtxtPtr ctxt) {
2445*6777b538SAndroid Build Coastguard Worker     const xmlChar *ret;
2446*6777b538SAndroid Build Coastguard Worker     int i = 0;
2447*6777b538SAndroid Build Coastguard Worker     xmlChar loc[HTML_PARSER_BUFFER_SIZE];
2448*6777b538SAndroid Build Coastguard Worker 
2449*6777b538SAndroid Build Coastguard Worker     if (!IS_ASCII_LETTER(CUR) && (CUR != '_') &&
2450*6777b538SAndroid Build Coastguard Worker         (CUR != ':') && (CUR != '.')) return(NULL);
2451*6777b538SAndroid Build Coastguard Worker 
2452*6777b538SAndroid Build Coastguard Worker     while ((i < HTML_PARSER_BUFFER_SIZE) &&
2453*6777b538SAndroid Build Coastguard Worker            ((IS_ASCII_LETTER(CUR)) || (IS_ASCII_DIGIT(CUR)) ||
2454*6777b538SAndroid Build Coastguard Worker 	   (CUR == ':') || (CUR == '-') || (CUR == '_') ||
2455*6777b538SAndroid Build Coastguard Worker            (CUR == '.'))) {
2456*6777b538SAndroid Build Coastguard Worker 	if ((CUR >= 'A') && (CUR <= 'Z')) loc[i] = CUR + 0x20;
2457*6777b538SAndroid Build Coastguard Worker         else loc[i] = CUR;
2458*6777b538SAndroid Build Coastguard Worker 	i++;
2459*6777b538SAndroid Build Coastguard Worker 
2460*6777b538SAndroid Build Coastguard Worker 	NEXT;
2461*6777b538SAndroid Build Coastguard Worker     }
2462*6777b538SAndroid Build Coastguard Worker 
2463*6777b538SAndroid Build Coastguard Worker     ret = xmlDictLookup(ctxt->dict, loc, i);
2464*6777b538SAndroid Build Coastguard Worker     if (ret == NULL)
2465*6777b538SAndroid Build Coastguard Worker         htmlErrMemory(ctxt);
2466*6777b538SAndroid Build Coastguard Worker 
2467*6777b538SAndroid Build Coastguard Worker     return(ret);
2468*6777b538SAndroid Build Coastguard Worker }
2469*6777b538SAndroid Build Coastguard Worker 
2470*6777b538SAndroid Build Coastguard Worker 
2471*6777b538SAndroid Build Coastguard Worker /**
2472*6777b538SAndroid Build Coastguard Worker  * htmlParseHTMLName_nonInvasive:
2473*6777b538SAndroid Build Coastguard Worker  * @ctxt:  an HTML parser context
2474*6777b538SAndroid Build Coastguard Worker  *
2475*6777b538SAndroid Build Coastguard Worker  * parse an HTML tag or attribute name, note that we convert it to lowercase
2476*6777b538SAndroid Build Coastguard Worker  * since HTML names are not case-sensitive, this doesn't consume the data
2477*6777b538SAndroid Build Coastguard Worker  * from the stream, it's a look-ahead
2478*6777b538SAndroid Build Coastguard Worker  *
2479*6777b538SAndroid Build Coastguard Worker  * Returns the Tag Name parsed or NULL
2480*6777b538SAndroid Build Coastguard Worker  */
2481*6777b538SAndroid Build Coastguard Worker 
2482*6777b538SAndroid Build Coastguard Worker static const xmlChar *
htmlParseHTMLName_nonInvasive(htmlParserCtxtPtr ctxt)2483*6777b538SAndroid Build Coastguard Worker htmlParseHTMLName_nonInvasive(htmlParserCtxtPtr ctxt) {
2484*6777b538SAndroid Build Coastguard Worker     int i = 0;
2485*6777b538SAndroid Build Coastguard Worker     xmlChar loc[HTML_PARSER_BUFFER_SIZE];
2486*6777b538SAndroid Build Coastguard Worker     const xmlChar *ret;
2487*6777b538SAndroid Build Coastguard Worker 
2488*6777b538SAndroid Build Coastguard Worker     if (!IS_ASCII_LETTER(NXT(1)) && (NXT(1) != '_') &&
2489*6777b538SAndroid Build Coastguard Worker         (NXT(1) != ':')) return(NULL);
2490*6777b538SAndroid Build Coastguard Worker 
2491*6777b538SAndroid Build Coastguard Worker     while ((i < HTML_PARSER_BUFFER_SIZE) &&
2492*6777b538SAndroid Build Coastguard Worker            ((IS_ASCII_LETTER(NXT(1+i))) || (IS_ASCII_DIGIT(NXT(1+i))) ||
2493*6777b538SAndroid Build Coastguard Worker 	   (NXT(1+i) == ':') || (NXT(1+i) == '-') || (NXT(1+i) == '_'))) {
2494*6777b538SAndroid Build Coastguard Worker 	if ((NXT(1+i) >= 'A') && (NXT(1+i) <= 'Z')) loc[i] = NXT(1+i) + 0x20;
2495*6777b538SAndroid Build Coastguard Worker         else loc[i] = NXT(1+i);
2496*6777b538SAndroid Build Coastguard Worker 	i++;
2497*6777b538SAndroid Build Coastguard Worker     }
2498*6777b538SAndroid Build Coastguard Worker 
2499*6777b538SAndroid Build Coastguard Worker     ret = xmlDictLookup(ctxt->dict, loc, i);
2500*6777b538SAndroid Build Coastguard Worker     if (ret == NULL)
2501*6777b538SAndroid Build Coastguard Worker         htmlErrMemory(ctxt);
2502*6777b538SAndroid Build Coastguard Worker 
2503*6777b538SAndroid Build Coastguard Worker     return(ret);
2504*6777b538SAndroid Build Coastguard Worker }
2505*6777b538SAndroid Build Coastguard Worker 
2506*6777b538SAndroid Build Coastguard Worker 
2507*6777b538SAndroid Build Coastguard Worker /**
2508*6777b538SAndroid Build Coastguard Worker  * htmlParseName:
2509*6777b538SAndroid Build Coastguard Worker  * @ctxt:  an HTML parser context
2510*6777b538SAndroid Build Coastguard Worker  *
2511*6777b538SAndroid Build Coastguard Worker  * parse an HTML name, this routine is case sensitive.
2512*6777b538SAndroid Build Coastguard Worker  *
2513*6777b538SAndroid Build Coastguard Worker  * Returns the Name parsed or NULL
2514*6777b538SAndroid Build Coastguard Worker  */
2515*6777b538SAndroid Build Coastguard Worker 
2516*6777b538SAndroid Build Coastguard Worker static const xmlChar *
htmlParseName(htmlParserCtxtPtr ctxt)2517*6777b538SAndroid Build Coastguard Worker htmlParseName(htmlParserCtxtPtr ctxt) {
2518*6777b538SAndroid Build Coastguard Worker     const xmlChar *in;
2519*6777b538SAndroid Build Coastguard Worker     const xmlChar *ret;
2520*6777b538SAndroid Build Coastguard Worker     int count = 0;
2521*6777b538SAndroid Build Coastguard Worker 
2522*6777b538SAndroid Build Coastguard Worker     GROW;
2523*6777b538SAndroid Build Coastguard Worker 
2524*6777b538SAndroid Build Coastguard Worker     /*
2525*6777b538SAndroid Build Coastguard Worker      * Accelerator for simple ASCII names
2526*6777b538SAndroid Build Coastguard Worker      */
2527*6777b538SAndroid Build Coastguard Worker     in = ctxt->input->cur;
2528*6777b538SAndroid Build Coastguard Worker     if (((*in >= 0x61) && (*in <= 0x7A)) ||
2529*6777b538SAndroid Build Coastguard Worker 	((*in >= 0x41) && (*in <= 0x5A)) ||
2530*6777b538SAndroid Build Coastguard Worker 	(*in == '_') || (*in == ':')) {
2531*6777b538SAndroid Build Coastguard Worker 	in++;
2532*6777b538SAndroid Build Coastguard Worker 	while (((*in >= 0x61) && (*in <= 0x7A)) ||
2533*6777b538SAndroid Build Coastguard Worker 	       ((*in >= 0x41) && (*in <= 0x5A)) ||
2534*6777b538SAndroid Build Coastguard Worker 	       ((*in >= 0x30) && (*in <= 0x39)) ||
2535*6777b538SAndroid Build Coastguard Worker 	       (*in == '_') || (*in == '-') ||
2536*6777b538SAndroid Build Coastguard Worker 	       (*in == ':') || (*in == '.'))
2537*6777b538SAndroid Build Coastguard Worker 	    in++;
2538*6777b538SAndroid Build Coastguard Worker 
2539*6777b538SAndroid Build Coastguard Worker 	if (in == ctxt->input->end)
2540*6777b538SAndroid Build Coastguard Worker 	    return(NULL);
2541*6777b538SAndroid Build Coastguard Worker 
2542*6777b538SAndroid Build Coastguard Worker 	if ((*in > 0) && (*in < 0x80)) {
2543*6777b538SAndroid Build Coastguard Worker 	    count = in - ctxt->input->cur;
2544*6777b538SAndroid Build Coastguard Worker 	    ret = xmlDictLookup(ctxt->dict, ctxt->input->cur, count);
2545*6777b538SAndroid Build Coastguard Worker             if (ret == NULL)
2546*6777b538SAndroid Build Coastguard Worker                 htmlErrMemory(ctxt);
2547*6777b538SAndroid Build Coastguard Worker 	    ctxt->input->cur = in;
2548*6777b538SAndroid Build Coastguard Worker 	    ctxt->input->col += count;
2549*6777b538SAndroid Build Coastguard Worker 	    return(ret);
2550*6777b538SAndroid Build Coastguard Worker 	}
2551*6777b538SAndroid Build Coastguard Worker     }
2552*6777b538SAndroid Build Coastguard Worker     return(htmlParseNameComplex(ctxt));
2553*6777b538SAndroid Build Coastguard Worker }
2554*6777b538SAndroid Build Coastguard Worker 
2555*6777b538SAndroid Build Coastguard Worker static const xmlChar *
htmlParseNameComplex(xmlParserCtxtPtr ctxt)2556*6777b538SAndroid Build Coastguard Worker htmlParseNameComplex(xmlParserCtxtPtr ctxt) {
2557*6777b538SAndroid Build Coastguard Worker     int len = 0, l;
2558*6777b538SAndroid Build Coastguard Worker     int c;
2559*6777b538SAndroid Build Coastguard Worker     int maxLength = (ctxt->options & XML_PARSE_HUGE) ?
2560*6777b538SAndroid Build Coastguard Worker                     XML_MAX_TEXT_LENGTH :
2561*6777b538SAndroid Build Coastguard Worker                     XML_MAX_NAME_LENGTH;
2562*6777b538SAndroid Build Coastguard Worker     const xmlChar *base = ctxt->input->base;
2563*6777b538SAndroid Build Coastguard Worker     const xmlChar *ret;
2564*6777b538SAndroid Build Coastguard Worker 
2565*6777b538SAndroid Build Coastguard Worker     /*
2566*6777b538SAndroid Build Coastguard Worker      * Handler for more complex cases
2567*6777b538SAndroid Build Coastguard Worker      */
2568*6777b538SAndroid Build Coastguard Worker     c = CUR_CHAR(l);
2569*6777b538SAndroid Build Coastguard Worker     if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
2570*6777b538SAndroid Build Coastguard Worker 	(!IS_LETTER(c) && (c != '_') &&
2571*6777b538SAndroid Build Coastguard Worker          (c != ':'))) {
2572*6777b538SAndroid Build Coastguard Worker 	return(NULL);
2573*6777b538SAndroid Build Coastguard Worker     }
2574*6777b538SAndroid Build Coastguard Worker 
2575*6777b538SAndroid Build Coastguard Worker     while ((c != ' ') && (c != '>') && (c != '/') && /* test bigname.xml */
2576*6777b538SAndroid Build Coastguard Worker 	   ((IS_LETTER(c)) || (IS_DIGIT(c)) ||
2577*6777b538SAndroid Build Coastguard Worker             (c == '.') || (c == '-') ||
2578*6777b538SAndroid Build Coastguard Worker 	    (c == '_') || (c == ':') ||
2579*6777b538SAndroid Build Coastguard Worker 	    (IS_COMBINING(c)) ||
2580*6777b538SAndroid Build Coastguard Worker 	    (IS_EXTENDER(c)))) {
2581*6777b538SAndroid Build Coastguard Worker 	len += l;
2582*6777b538SAndroid Build Coastguard Worker         if (len > maxLength) {
2583*6777b538SAndroid Build Coastguard Worker             htmlParseErr(ctxt, XML_ERR_NAME_TOO_LONG, "name too long", NULL, NULL);
2584*6777b538SAndroid Build Coastguard Worker             return(NULL);
2585*6777b538SAndroid Build Coastguard Worker         }
2586*6777b538SAndroid Build Coastguard Worker 	NEXTL(l);
2587*6777b538SAndroid Build Coastguard Worker 	c = CUR_CHAR(l);
2588*6777b538SAndroid Build Coastguard Worker 	if (ctxt->input->base != base) {
2589*6777b538SAndroid Build Coastguard Worker 	    /*
2590*6777b538SAndroid Build Coastguard Worker 	     * We changed encoding from an unknown encoding
2591*6777b538SAndroid Build Coastguard Worker 	     * Input buffer changed location, so we better start again
2592*6777b538SAndroid Build Coastguard Worker 	     */
2593*6777b538SAndroid Build Coastguard Worker 	    return(htmlParseNameComplex(ctxt));
2594*6777b538SAndroid Build Coastguard Worker 	}
2595*6777b538SAndroid Build Coastguard Worker     }
2596*6777b538SAndroid Build Coastguard Worker 
2597*6777b538SAndroid Build Coastguard Worker     if (ctxt->input->cur - ctxt->input->base < len) {
2598*6777b538SAndroid Build Coastguard Worker         /* Sanity check */
2599*6777b538SAndroid Build Coastguard Worker 	htmlParseErr(ctxt, XML_ERR_INTERNAL_ERROR,
2600*6777b538SAndroid Build Coastguard Worker                      "unexpected change of input buffer", NULL, NULL);
2601*6777b538SAndroid Build Coastguard Worker         return (NULL);
2602*6777b538SAndroid Build Coastguard Worker     }
2603*6777b538SAndroid Build Coastguard Worker 
2604*6777b538SAndroid Build Coastguard Worker     ret = xmlDictLookup(ctxt->dict, ctxt->input->cur - len, len);
2605*6777b538SAndroid Build Coastguard Worker     if (ret == NULL)
2606*6777b538SAndroid Build Coastguard Worker         htmlErrMemory(ctxt);
2607*6777b538SAndroid Build Coastguard Worker 
2608*6777b538SAndroid Build Coastguard Worker     return(ret);
2609*6777b538SAndroid Build Coastguard Worker }
2610*6777b538SAndroid Build Coastguard Worker 
2611*6777b538SAndroid Build Coastguard Worker 
2612*6777b538SAndroid Build Coastguard Worker /**
2613*6777b538SAndroid Build Coastguard Worker  * htmlParseHTMLAttribute:
2614*6777b538SAndroid Build Coastguard Worker  * @ctxt:  an HTML parser context
2615*6777b538SAndroid Build Coastguard Worker  * @stop:  a char stop value
2616*6777b538SAndroid Build Coastguard Worker  *
2617*6777b538SAndroid Build Coastguard Worker  * parse an HTML attribute value till the stop (quote), if
2618*6777b538SAndroid Build Coastguard Worker  * stop is 0 then it stops at the first space
2619*6777b538SAndroid Build Coastguard Worker  *
2620*6777b538SAndroid Build Coastguard Worker  * Returns the attribute parsed or NULL
2621*6777b538SAndroid Build Coastguard Worker  */
2622*6777b538SAndroid Build Coastguard Worker 
2623*6777b538SAndroid Build Coastguard Worker static xmlChar *
htmlParseHTMLAttribute(htmlParserCtxtPtr ctxt,const xmlChar stop)2624*6777b538SAndroid Build Coastguard Worker htmlParseHTMLAttribute(htmlParserCtxtPtr ctxt, const xmlChar stop) {
2625*6777b538SAndroid Build Coastguard Worker     xmlChar *buffer = NULL;
2626*6777b538SAndroid Build Coastguard Worker     int buffer_size = 0;
2627*6777b538SAndroid Build Coastguard Worker     int maxLength = (ctxt->options & XML_PARSE_HUGE) ?
2628*6777b538SAndroid Build Coastguard Worker                     XML_MAX_HUGE_LENGTH :
2629*6777b538SAndroid Build Coastguard Worker                     XML_MAX_TEXT_LENGTH;
2630*6777b538SAndroid Build Coastguard Worker     xmlChar *out = NULL;
2631*6777b538SAndroid Build Coastguard Worker     const xmlChar *name = NULL;
2632*6777b538SAndroid Build Coastguard Worker     const xmlChar *cur = NULL;
2633*6777b538SAndroid Build Coastguard Worker     const htmlEntityDesc * ent;
2634*6777b538SAndroid Build Coastguard Worker 
2635*6777b538SAndroid Build Coastguard Worker     /*
2636*6777b538SAndroid Build Coastguard Worker      * allocate a translation buffer.
2637*6777b538SAndroid Build Coastguard Worker      */
2638*6777b538SAndroid Build Coastguard Worker     buffer_size = HTML_PARSER_BUFFER_SIZE;
2639*6777b538SAndroid Build Coastguard Worker     buffer = (xmlChar *) xmlMallocAtomic(buffer_size);
2640*6777b538SAndroid Build Coastguard Worker     if (buffer == NULL) {
2641*6777b538SAndroid Build Coastguard Worker 	htmlErrMemory(ctxt);
2642*6777b538SAndroid Build Coastguard Worker 	return(NULL);
2643*6777b538SAndroid Build Coastguard Worker     }
2644*6777b538SAndroid Build Coastguard Worker     out = buffer;
2645*6777b538SAndroid Build Coastguard Worker 
2646*6777b538SAndroid Build Coastguard Worker     /*
2647*6777b538SAndroid Build Coastguard Worker      * Ok loop until we reach one of the ending chars
2648*6777b538SAndroid Build Coastguard Worker      */
2649*6777b538SAndroid Build Coastguard Worker     while ((PARSER_STOPPED(ctxt) == 0) &&
2650*6777b538SAndroid Build Coastguard Worker            (CUR != 0) && (CUR != stop)) {
2651*6777b538SAndroid Build Coastguard Worker 	if ((stop == 0) && (CUR == '>')) break;
2652*6777b538SAndroid Build Coastguard Worker 	if ((stop == 0) && (IS_BLANK_CH(CUR))) break;
2653*6777b538SAndroid Build Coastguard Worker         if (CUR == '&') {
2654*6777b538SAndroid Build Coastguard Worker 	    if (NXT(1) == '#') {
2655*6777b538SAndroid Build Coastguard Worker 		unsigned int c;
2656*6777b538SAndroid Build Coastguard Worker 		int bits;
2657*6777b538SAndroid Build Coastguard Worker 
2658*6777b538SAndroid Build Coastguard Worker 		c = htmlParseCharRef(ctxt);
2659*6777b538SAndroid Build Coastguard Worker 		if      (c <    0x80)
2660*6777b538SAndroid Build Coastguard Worker 		        { *out++  = c;                bits= -6; }
2661*6777b538SAndroid Build Coastguard Worker 		else if (c <   0x800)
2662*6777b538SAndroid Build Coastguard Worker 		        { *out++  =((c >>  6) & 0x1F) | 0xC0;  bits=  0; }
2663*6777b538SAndroid Build Coastguard Worker 		else if (c < 0x10000)
2664*6777b538SAndroid Build Coastguard Worker 		        { *out++  =((c >> 12) & 0x0F) | 0xE0;  bits=  6; }
2665*6777b538SAndroid Build Coastguard Worker 		else
2666*6777b538SAndroid Build Coastguard Worker 		        { *out++  =((c >> 18) & 0x07) | 0xF0;  bits= 12; }
2667*6777b538SAndroid Build Coastguard Worker 
2668*6777b538SAndroid Build Coastguard Worker 		for ( ; bits >= 0; bits-= 6) {
2669*6777b538SAndroid Build Coastguard Worker 		    *out++  = ((c >> bits) & 0x3F) | 0x80;
2670*6777b538SAndroid Build Coastguard Worker 		}
2671*6777b538SAndroid Build Coastguard Worker 
2672*6777b538SAndroid Build Coastguard Worker 		if (out - buffer > buffer_size - 100) {
2673*6777b538SAndroid Build Coastguard Worker 			int indx = out - buffer;
2674*6777b538SAndroid Build Coastguard Worker 
2675*6777b538SAndroid Build Coastguard Worker 			growBuffer(buffer);
2676*6777b538SAndroid Build Coastguard Worker 			out = &buffer[indx];
2677*6777b538SAndroid Build Coastguard Worker 		}
2678*6777b538SAndroid Build Coastguard Worker 	    } else {
2679*6777b538SAndroid Build Coastguard Worker 		ent = htmlParseEntityRef(ctxt, &name);
2680*6777b538SAndroid Build Coastguard Worker 		if (name == NULL) {
2681*6777b538SAndroid Build Coastguard Worker 		    *out++ = '&';
2682*6777b538SAndroid Build Coastguard Worker 		    if (out - buffer > buffer_size - 100) {
2683*6777b538SAndroid Build Coastguard Worker 			int indx = out - buffer;
2684*6777b538SAndroid Build Coastguard Worker 
2685*6777b538SAndroid Build Coastguard Worker 			growBuffer(buffer);
2686*6777b538SAndroid Build Coastguard Worker 			out = &buffer[indx];
2687*6777b538SAndroid Build Coastguard Worker 		    }
2688*6777b538SAndroid Build Coastguard Worker 		} else if (ent == NULL) {
2689*6777b538SAndroid Build Coastguard Worker 		    *out++ = '&';
2690*6777b538SAndroid Build Coastguard Worker 		    cur = name;
2691*6777b538SAndroid Build Coastguard Worker 		    while (*cur != 0) {
2692*6777b538SAndroid Build Coastguard Worker 			if (out - buffer > buffer_size - 100) {
2693*6777b538SAndroid Build Coastguard Worker 			    int indx = out - buffer;
2694*6777b538SAndroid Build Coastguard Worker 
2695*6777b538SAndroid Build Coastguard Worker 			    growBuffer(buffer);
2696*6777b538SAndroid Build Coastguard Worker 			    out = &buffer[indx];
2697*6777b538SAndroid Build Coastguard Worker 			}
2698*6777b538SAndroid Build Coastguard Worker 			*out++ = *cur++;
2699*6777b538SAndroid Build Coastguard Worker 		    }
2700*6777b538SAndroid Build Coastguard Worker 		} else {
2701*6777b538SAndroid Build Coastguard Worker 		    unsigned int c;
2702*6777b538SAndroid Build Coastguard Worker 		    int bits;
2703*6777b538SAndroid Build Coastguard Worker 
2704*6777b538SAndroid Build Coastguard Worker 		    if (out - buffer > buffer_size - 100) {
2705*6777b538SAndroid Build Coastguard Worker 			int indx = out - buffer;
2706*6777b538SAndroid Build Coastguard Worker 
2707*6777b538SAndroid Build Coastguard Worker 			growBuffer(buffer);
2708*6777b538SAndroid Build Coastguard Worker 			out = &buffer[indx];
2709*6777b538SAndroid Build Coastguard Worker 		    }
2710*6777b538SAndroid Build Coastguard Worker 		    c = ent->value;
2711*6777b538SAndroid Build Coastguard Worker 		    if      (c <    0x80)
2712*6777b538SAndroid Build Coastguard Worker 			{ *out++  = c;                bits= -6; }
2713*6777b538SAndroid Build Coastguard Worker 		    else if (c <   0x800)
2714*6777b538SAndroid Build Coastguard Worker 			{ *out++  =((c >>  6) & 0x1F) | 0xC0;  bits=  0; }
2715*6777b538SAndroid Build Coastguard Worker 		    else if (c < 0x10000)
2716*6777b538SAndroid Build Coastguard Worker 			{ *out++  =((c >> 12) & 0x0F) | 0xE0;  bits=  6; }
2717*6777b538SAndroid Build Coastguard Worker 		    else
2718*6777b538SAndroid Build Coastguard Worker 			{ *out++  =((c >> 18) & 0x07) | 0xF0;  bits= 12; }
2719*6777b538SAndroid Build Coastguard Worker 
2720*6777b538SAndroid Build Coastguard Worker 		    for ( ; bits >= 0; bits-= 6) {
2721*6777b538SAndroid Build Coastguard Worker 			*out++  = ((c >> bits) & 0x3F) | 0x80;
2722*6777b538SAndroid Build Coastguard Worker 		    }
2723*6777b538SAndroid Build Coastguard Worker 		}
2724*6777b538SAndroid Build Coastguard Worker 	    }
2725*6777b538SAndroid Build Coastguard Worker 	} else {
2726*6777b538SAndroid Build Coastguard Worker 	    unsigned int c;
2727*6777b538SAndroid Build Coastguard Worker 	    int bits, l;
2728*6777b538SAndroid Build Coastguard Worker 
2729*6777b538SAndroid Build Coastguard Worker 	    if (out - buffer > buffer_size - 100) {
2730*6777b538SAndroid Build Coastguard Worker 		int indx = out - buffer;
2731*6777b538SAndroid Build Coastguard Worker 
2732*6777b538SAndroid Build Coastguard Worker 		growBuffer(buffer);
2733*6777b538SAndroid Build Coastguard Worker 		out = &buffer[indx];
2734*6777b538SAndroid Build Coastguard Worker 	    }
2735*6777b538SAndroid Build Coastguard Worker 	    c = CUR_CHAR(l);
2736*6777b538SAndroid Build Coastguard Worker 	    if      (c <    0x80)
2737*6777b538SAndroid Build Coastguard Worker 		    { *out++  = c;                bits= -6; }
2738*6777b538SAndroid Build Coastguard Worker 	    else if (c <   0x800)
2739*6777b538SAndroid Build Coastguard Worker 		    { *out++  =((c >>  6) & 0x1F) | 0xC0;  bits=  0; }
2740*6777b538SAndroid Build Coastguard Worker 	    else if (c < 0x10000)
2741*6777b538SAndroid Build Coastguard Worker 		    { *out++  =((c >> 12) & 0x0F) | 0xE0;  bits=  6; }
2742*6777b538SAndroid Build Coastguard Worker 	    else
2743*6777b538SAndroid Build Coastguard Worker 		    { *out++  =((c >> 18) & 0x07) | 0xF0;  bits= 12; }
2744*6777b538SAndroid Build Coastguard Worker 
2745*6777b538SAndroid Build Coastguard Worker 	    for ( ; bits >= 0; bits-= 6) {
2746*6777b538SAndroid Build Coastguard Worker 		*out++  = ((c >> bits) & 0x3F) | 0x80;
2747*6777b538SAndroid Build Coastguard Worker 	    }
2748*6777b538SAndroid Build Coastguard Worker 	    NEXTL(l);
2749*6777b538SAndroid Build Coastguard Worker 	}
2750*6777b538SAndroid Build Coastguard Worker         if (out - buffer > maxLength) {
2751*6777b538SAndroid Build Coastguard Worker             htmlParseErr(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
2752*6777b538SAndroid Build Coastguard Worker                          "attribute value too long\n", NULL, NULL);
2753*6777b538SAndroid Build Coastguard Worker             xmlFree(buffer);
2754*6777b538SAndroid Build Coastguard Worker             return(NULL);
2755*6777b538SAndroid Build Coastguard Worker         }
2756*6777b538SAndroid Build Coastguard Worker     }
2757*6777b538SAndroid Build Coastguard Worker     *out = 0;
2758*6777b538SAndroid Build Coastguard Worker     return(buffer);
2759*6777b538SAndroid Build Coastguard Worker }
2760*6777b538SAndroid Build Coastguard Worker 
2761*6777b538SAndroid Build Coastguard Worker /**
2762*6777b538SAndroid Build Coastguard Worker  * htmlParseEntityRef:
2763*6777b538SAndroid Build Coastguard Worker  * @ctxt:  an HTML parser context
2764*6777b538SAndroid Build Coastguard Worker  * @str:  location to store the entity name
2765*6777b538SAndroid Build Coastguard Worker  *
2766*6777b538SAndroid Build Coastguard Worker  * DEPRECATED: Internal function, don't use.
2767*6777b538SAndroid Build Coastguard Worker  *
2768*6777b538SAndroid Build Coastguard Worker  * parse an HTML ENTITY references
2769*6777b538SAndroid Build Coastguard Worker  *
2770*6777b538SAndroid Build Coastguard Worker  * [68] EntityRef ::= '&' Name ';'
2771*6777b538SAndroid Build Coastguard Worker  *
2772*6777b538SAndroid Build Coastguard Worker  * Returns the associated htmlEntityDescPtr if found, or NULL otherwise,
2773*6777b538SAndroid Build Coastguard Worker  *         if non-NULL *str will have to be freed by the caller.
2774*6777b538SAndroid Build Coastguard Worker  */
2775*6777b538SAndroid Build Coastguard Worker const htmlEntityDesc *
htmlParseEntityRef(htmlParserCtxtPtr ctxt,const xmlChar ** str)2776*6777b538SAndroid Build Coastguard Worker htmlParseEntityRef(htmlParserCtxtPtr ctxt, const xmlChar **str) {
2777*6777b538SAndroid Build Coastguard Worker     const xmlChar *name;
2778*6777b538SAndroid Build Coastguard Worker     const htmlEntityDesc * ent = NULL;
2779*6777b538SAndroid Build Coastguard Worker 
2780*6777b538SAndroid Build Coastguard Worker     if (str != NULL) *str = NULL;
2781*6777b538SAndroid Build Coastguard Worker     if ((ctxt == NULL) || (ctxt->input == NULL)) return(NULL);
2782*6777b538SAndroid Build Coastguard Worker 
2783*6777b538SAndroid Build Coastguard Worker     if (CUR == '&') {
2784*6777b538SAndroid Build Coastguard Worker         NEXT;
2785*6777b538SAndroid Build Coastguard Worker         name = htmlParseName(ctxt);
2786*6777b538SAndroid Build Coastguard Worker 	if (name == NULL) {
2787*6777b538SAndroid Build Coastguard Worker 	    htmlParseErr(ctxt, XML_ERR_NAME_REQUIRED,
2788*6777b538SAndroid Build Coastguard Worker 	                 "htmlParseEntityRef: no name\n", NULL, NULL);
2789*6777b538SAndroid Build Coastguard Worker 	} else {
2790*6777b538SAndroid Build Coastguard Worker 	    GROW;
2791*6777b538SAndroid Build Coastguard Worker 	    if (CUR == ';') {
2792*6777b538SAndroid Build Coastguard Worker 	        if (str != NULL)
2793*6777b538SAndroid Build Coastguard Worker 		    *str = name;
2794*6777b538SAndroid Build Coastguard Worker 
2795*6777b538SAndroid Build Coastguard Worker 		/*
2796*6777b538SAndroid Build Coastguard Worker 		 * Lookup the entity in the table.
2797*6777b538SAndroid Build Coastguard Worker 		 */
2798*6777b538SAndroid Build Coastguard Worker 		ent = htmlEntityLookup(name);
2799*6777b538SAndroid Build Coastguard Worker 		if (ent != NULL) /* OK that's ugly !!! */
2800*6777b538SAndroid Build Coastguard Worker 		    NEXT;
2801*6777b538SAndroid Build Coastguard Worker 	    } else {
2802*6777b538SAndroid Build Coastguard Worker 		htmlParseErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING,
2803*6777b538SAndroid Build Coastguard Worker 		             "htmlParseEntityRef: expecting ';'\n",
2804*6777b538SAndroid Build Coastguard Worker 			     NULL, NULL);
2805*6777b538SAndroid Build Coastguard Worker 	        if (str != NULL)
2806*6777b538SAndroid Build Coastguard Worker 		    *str = name;
2807*6777b538SAndroid Build Coastguard Worker 	    }
2808*6777b538SAndroid Build Coastguard Worker 	}
2809*6777b538SAndroid Build Coastguard Worker     }
2810*6777b538SAndroid Build Coastguard Worker     return(ent);
2811*6777b538SAndroid Build Coastguard Worker }
2812*6777b538SAndroid Build Coastguard Worker 
2813*6777b538SAndroid Build Coastguard Worker /**
2814*6777b538SAndroid Build Coastguard Worker  * htmlParseAttValue:
2815*6777b538SAndroid Build Coastguard Worker  * @ctxt:  an HTML parser context
2816*6777b538SAndroid Build Coastguard Worker  *
2817*6777b538SAndroid Build Coastguard Worker  * parse a value for an attribute
2818*6777b538SAndroid Build Coastguard Worker  * Note: the parser won't do substitution of entities here, this
2819*6777b538SAndroid Build Coastguard Worker  * will be handled later in xmlStringGetNodeList, unless it was
2820*6777b538SAndroid Build Coastguard Worker  * asked for ctxt->replaceEntities != 0
2821*6777b538SAndroid Build Coastguard Worker  *
2822*6777b538SAndroid Build Coastguard Worker  * Returns the AttValue parsed or NULL.
2823*6777b538SAndroid Build Coastguard Worker  */
2824*6777b538SAndroid Build Coastguard Worker 
2825*6777b538SAndroid Build Coastguard Worker static xmlChar *
htmlParseAttValue(htmlParserCtxtPtr ctxt)2826*6777b538SAndroid Build Coastguard Worker htmlParseAttValue(htmlParserCtxtPtr ctxt) {
2827*6777b538SAndroid Build Coastguard Worker     xmlChar *ret = NULL;
2828*6777b538SAndroid Build Coastguard Worker 
2829*6777b538SAndroid Build Coastguard Worker     if (CUR == '"') {
2830*6777b538SAndroid Build Coastguard Worker         NEXT;
2831*6777b538SAndroid Build Coastguard Worker 	ret = htmlParseHTMLAttribute(ctxt, '"');
2832*6777b538SAndroid Build Coastguard Worker         if (CUR != '"') {
2833*6777b538SAndroid Build Coastguard Worker 	    htmlParseErr(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
2834*6777b538SAndroid Build Coastguard Worker 	                 "AttValue: \" expected\n", NULL, NULL);
2835*6777b538SAndroid Build Coastguard Worker 	} else
2836*6777b538SAndroid Build Coastguard Worker 	    NEXT;
2837*6777b538SAndroid Build Coastguard Worker     } else if (CUR == '\'') {
2838*6777b538SAndroid Build Coastguard Worker         NEXT;
2839*6777b538SAndroid Build Coastguard Worker 	ret = htmlParseHTMLAttribute(ctxt, '\'');
2840*6777b538SAndroid Build Coastguard Worker         if (CUR != '\'') {
2841*6777b538SAndroid Build Coastguard Worker 	    htmlParseErr(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
2842*6777b538SAndroid Build Coastguard Worker 	                 "AttValue: ' expected\n", NULL, NULL);
2843*6777b538SAndroid Build Coastguard Worker 	} else
2844*6777b538SAndroid Build Coastguard Worker 	    NEXT;
2845*6777b538SAndroid Build Coastguard Worker     } else {
2846*6777b538SAndroid Build Coastguard Worker         /*
2847*6777b538SAndroid Build Coastguard Worker 	 * That's an HTMLism, the attribute value may not be quoted
2848*6777b538SAndroid Build Coastguard Worker 	 */
2849*6777b538SAndroid Build Coastguard Worker 	ret = htmlParseHTMLAttribute(ctxt, 0);
2850*6777b538SAndroid Build Coastguard Worker 	if (ret == NULL) {
2851*6777b538SAndroid Build Coastguard Worker 	    htmlParseErr(ctxt, XML_ERR_ATTRIBUTE_WITHOUT_VALUE,
2852*6777b538SAndroid Build Coastguard Worker 	                 "AttValue: no value found\n", NULL, NULL);
2853*6777b538SAndroid Build Coastguard Worker 	}
2854*6777b538SAndroid Build Coastguard Worker     }
2855*6777b538SAndroid Build Coastguard Worker     return(ret);
2856*6777b538SAndroid Build Coastguard Worker }
2857*6777b538SAndroid Build Coastguard Worker 
2858*6777b538SAndroid Build Coastguard Worker /**
2859*6777b538SAndroid Build Coastguard Worker  * htmlParseSystemLiteral:
2860*6777b538SAndroid Build Coastguard Worker  * @ctxt:  an HTML parser context
2861*6777b538SAndroid Build Coastguard Worker  *
2862*6777b538SAndroid Build Coastguard Worker  * parse an HTML Literal
2863*6777b538SAndroid Build Coastguard Worker  *
2864*6777b538SAndroid Build Coastguard Worker  * [11] SystemLiteral ::= ('"' [^"]* '"') | ("'" [^']* "'")
2865*6777b538SAndroid Build Coastguard Worker  *
2866*6777b538SAndroid Build Coastguard Worker  * Returns the SystemLiteral parsed or NULL
2867*6777b538SAndroid Build Coastguard Worker  */
2868*6777b538SAndroid Build Coastguard Worker 
2869*6777b538SAndroid Build Coastguard Worker static xmlChar *
htmlParseSystemLiteral(htmlParserCtxtPtr ctxt)2870*6777b538SAndroid Build Coastguard Worker htmlParseSystemLiteral(htmlParserCtxtPtr ctxt) {
2871*6777b538SAndroid Build Coastguard Worker     size_t len = 0, startPosition = 0;
2872*6777b538SAndroid Build Coastguard Worker     int err = 0;
2873*6777b538SAndroid Build Coastguard Worker     int quote;
2874*6777b538SAndroid Build Coastguard Worker     xmlChar *ret = NULL;
2875*6777b538SAndroid Build Coastguard Worker 
2876*6777b538SAndroid Build Coastguard Worker     if ((CUR != '"') && (CUR != '\'')) {
2877*6777b538SAndroid Build Coastguard Worker 	htmlParseErr(ctxt, XML_ERR_LITERAL_NOT_STARTED,
2878*6777b538SAndroid Build Coastguard Worker 	             "SystemLiteral \" or ' expected\n", NULL, NULL);
2879*6777b538SAndroid Build Coastguard Worker         return(NULL);
2880*6777b538SAndroid Build Coastguard Worker     }
2881*6777b538SAndroid Build Coastguard Worker     quote = CUR;
2882*6777b538SAndroid Build Coastguard Worker     NEXT;
2883*6777b538SAndroid Build Coastguard Worker 
2884*6777b538SAndroid Build Coastguard Worker     if (CUR_PTR < BASE_PTR)
2885*6777b538SAndroid Build Coastguard Worker         return(ret);
2886*6777b538SAndroid Build Coastguard Worker     startPosition = CUR_PTR - BASE_PTR;
2887*6777b538SAndroid Build Coastguard Worker 
2888*6777b538SAndroid Build Coastguard Worker     while ((PARSER_STOPPED(ctxt) == 0) &&
2889*6777b538SAndroid Build Coastguard Worker            (CUR != 0) && (CUR != quote)) {
2890*6777b538SAndroid Build Coastguard Worker         /* TODO: Handle UTF-8 */
2891*6777b538SAndroid Build Coastguard Worker         if (!IS_CHAR_CH(CUR)) {
2892*6777b538SAndroid Build Coastguard Worker             htmlParseErrInt(ctxt, XML_ERR_INVALID_CHAR,
2893*6777b538SAndroid Build Coastguard Worker                             "Invalid char in SystemLiteral 0x%X\n", CUR);
2894*6777b538SAndroid Build Coastguard Worker             err = 1;
2895*6777b538SAndroid Build Coastguard Worker         }
2896*6777b538SAndroid Build Coastguard Worker         NEXT;
2897*6777b538SAndroid Build Coastguard Worker         len++;
2898*6777b538SAndroid Build Coastguard Worker     }
2899*6777b538SAndroid Build Coastguard Worker     if (CUR != quote) {
2900*6777b538SAndroid Build Coastguard Worker         htmlParseErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED,
2901*6777b538SAndroid Build Coastguard Worker                      "Unfinished SystemLiteral\n", NULL, NULL);
2902*6777b538SAndroid Build Coastguard Worker     } else {
2903*6777b538SAndroid Build Coastguard Worker         if (err == 0) {
2904*6777b538SAndroid Build Coastguard Worker             ret = xmlStrndup((BASE_PTR+startPosition), len);
2905*6777b538SAndroid Build Coastguard Worker             if (ret == NULL) {
2906*6777b538SAndroid Build Coastguard Worker                 htmlErrMemory(ctxt);
2907*6777b538SAndroid Build Coastguard Worker                 return(NULL);
2908*6777b538SAndroid Build Coastguard Worker             }
2909*6777b538SAndroid Build Coastguard Worker         }
2910*6777b538SAndroid Build Coastguard Worker         NEXT;
2911*6777b538SAndroid Build Coastguard Worker     }
2912*6777b538SAndroid Build Coastguard Worker 
2913*6777b538SAndroid Build Coastguard Worker     return(ret);
2914*6777b538SAndroid Build Coastguard Worker }
2915*6777b538SAndroid Build Coastguard Worker 
2916*6777b538SAndroid Build Coastguard Worker /**
2917*6777b538SAndroid Build Coastguard Worker  * htmlParsePubidLiteral:
2918*6777b538SAndroid Build Coastguard Worker  * @ctxt:  an HTML parser context
2919*6777b538SAndroid Build Coastguard Worker  *
2920*6777b538SAndroid Build Coastguard Worker  * parse an HTML public literal
2921*6777b538SAndroid Build Coastguard Worker  *
2922*6777b538SAndroid Build Coastguard Worker  * [12] PubidLiteral ::= '"' PubidChar* '"' | "'" (PubidChar - "'")* "'"
2923*6777b538SAndroid Build Coastguard Worker  *
2924*6777b538SAndroid Build Coastguard Worker  * Returns the PubidLiteral parsed or NULL.
2925*6777b538SAndroid Build Coastguard Worker  */
2926*6777b538SAndroid Build Coastguard Worker 
2927*6777b538SAndroid Build Coastguard Worker static xmlChar *
htmlParsePubidLiteral(htmlParserCtxtPtr ctxt)2928*6777b538SAndroid Build Coastguard Worker htmlParsePubidLiteral(htmlParserCtxtPtr ctxt) {
2929*6777b538SAndroid Build Coastguard Worker     size_t len = 0, startPosition = 0;
2930*6777b538SAndroid Build Coastguard Worker     int err = 0;
2931*6777b538SAndroid Build Coastguard Worker     int quote;
2932*6777b538SAndroid Build Coastguard Worker     xmlChar *ret = NULL;
2933*6777b538SAndroid Build Coastguard Worker 
2934*6777b538SAndroid Build Coastguard Worker     if ((CUR != '"') && (CUR != '\'')) {
2935*6777b538SAndroid Build Coastguard Worker 	htmlParseErr(ctxt, XML_ERR_LITERAL_NOT_STARTED,
2936*6777b538SAndroid Build Coastguard Worker 	             "PubidLiteral \" or ' expected\n", NULL, NULL);
2937*6777b538SAndroid Build Coastguard Worker         return(NULL);
2938*6777b538SAndroid Build Coastguard Worker     }
2939*6777b538SAndroid Build Coastguard Worker     quote = CUR;
2940*6777b538SAndroid Build Coastguard Worker     NEXT;
2941*6777b538SAndroid Build Coastguard Worker 
2942*6777b538SAndroid Build Coastguard Worker     /*
2943*6777b538SAndroid Build Coastguard Worker      * Name ::= (Letter | '_') (NameChar)*
2944*6777b538SAndroid Build Coastguard Worker      */
2945*6777b538SAndroid Build Coastguard Worker     if (CUR_PTR < BASE_PTR)
2946*6777b538SAndroid Build Coastguard Worker         return(ret);
2947*6777b538SAndroid Build Coastguard Worker     startPosition = CUR_PTR - BASE_PTR;
2948*6777b538SAndroid Build Coastguard Worker 
2949*6777b538SAndroid Build Coastguard Worker     while ((PARSER_STOPPED(ctxt) == 0) &&
2950*6777b538SAndroid Build Coastguard Worker            (CUR != 0) && (CUR != quote)) {
2951*6777b538SAndroid Build Coastguard Worker         if (!IS_PUBIDCHAR_CH(CUR)) {
2952*6777b538SAndroid Build Coastguard Worker             htmlParseErrInt(ctxt, XML_ERR_INVALID_CHAR,
2953*6777b538SAndroid Build Coastguard Worker                             "Invalid char in PubidLiteral 0x%X\n", CUR);
2954*6777b538SAndroid Build Coastguard Worker             err = 1;
2955*6777b538SAndroid Build Coastguard Worker         }
2956*6777b538SAndroid Build Coastguard Worker         len++;
2957*6777b538SAndroid Build Coastguard Worker         NEXT;
2958*6777b538SAndroid Build Coastguard Worker     }
2959*6777b538SAndroid Build Coastguard Worker 
2960*6777b538SAndroid Build Coastguard Worker     if (CUR != quote) {
2961*6777b538SAndroid Build Coastguard Worker         htmlParseErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED,
2962*6777b538SAndroid Build Coastguard Worker                      "Unfinished PubidLiteral\n", NULL, NULL);
2963*6777b538SAndroid Build Coastguard Worker     } else {
2964*6777b538SAndroid Build Coastguard Worker         if (err == 0) {
2965*6777b538SAndroid Build Coastguard Worker             ret = xmlStrndup((BASE_PTR + startPosition), len);
2966*6777b538SAndroid Build Coastguard Worker             if (ret == NULL) {
2967*6777b538SAndroid Build Coastguard Worker                 htmlErrMemory(ctxt);
2968*6777b538SAndroid Build Coastguard Worker                 return(NULL);
2969*6777b538SAndroid Build Coastguard Worker             }
2970*6777b538SAndroid Build Coastguard Worker         }
2971*6777b538SAndroid Build Coastguard Worker         NEXT;
2972*6777b538SAndroid Build Coastguard Worker     }
2973*6777b538SAndroid Build Coastguard Worker 
2974*6777b538SAndroid Build Coastguard Worker     return(ret);
2975*6777b538SAndroid Build Coastguard Worker }
2976*6777b538SAndroid Build Coastguard Worker 
2977*6777b538SAndroid Build Coastguard Worker /**
2978*6777b538SAndroid Build Coastguard Worker  * htmlParseScript:
2979*6777b538SAndroid Build Coastguard Worker  * @ctxt:  an HTML parser context
2980*6777b538SAndroid Build Coastguard Worker  *
2981*6777b538SAndroid Build Coastguard Worker  * parse the content of an HTML SCRIPT or STYLE element
2982*6777b538SAndroid Build Coastguard Worker  * http://www.w3.org/TR/html4/sgml/dtd.html#Script
2983*6777b538SAndroid Build Coastguard Worker  * http://www.w3.org/TR/html4/sgml/dtd.html#StyleSheet
2984*6777b538SAndroid Build Coastguard Worker  * http://www.w3.org/TR/html4/types.html#type-script
2985*6777b538SAndroid Build Coastguard Worker  * http://www.w3.org/TR/html4/types.html#h-6.15
2986*6777b538SAndroid Build Coastguard Worker  * http://www.w3.org/TR/html4/appendix/notes.html#h-B.3.2.1
2987*6777b538SAndroid Build Coastguard Worker  *
2988*6777b538SAndroid Build Coastguard Worker  * Script data ( %Script; in the DTD) can be the content of the SCRIPT
2989*6777b538SAndroid Build Coastguard Worker  * element and the value of intrinsic event attributes. User agents must
2990*6777b538SAndroid Build Coastguard Worker  * not evaluate script data as HTML markup but instead must pass it on as
2991*6777b538SAndroid Build Coastguard Worker  * data to a script engine.
2992*6777b538SAndroid Build Coastguard Worker  * NOTES:
2993*6777b538SAndroid Build Coastguard Worker  * - The content is passed like CDATA
2994*6777b538SAndroid Build Coastguard Worker  * - the attributes for style and scripting "onXXX" are also described
2995*6777b538SAndroid Build Coastguard Worker  *   as CDATA but SGML allows entities references in attributes so their
2996*6777b538SAndroid Build Coastguard Worker  *   processing is identical as other attributes
2997*6777b538SAndroid Build Coastguard Worker  */
2998*6777b538SAndroid Build Coastguard Worker static void
htmlParseScript(htmlParserCtxtPtr ctxt)2999*6777b538SAndroid Build Coastguard Worker htmlParseScript(htmlParserCtxtPtr ctxt) {
3000*6777b538SAndroid Build Coastguard Worker     xmlChar buf[HTML_PARSER_BIG_BUFFER_SIZE + 5];
3001*6777b538SAndroid Build Coastguard Worker     int nbchar = 0;
3002*6777b538SAndroid Build Coastguard Worker     int cur,l;
3003*6777b538SAndroid Build Coastguard Worker 
3004*6777b538SAndroid Build Coastguard Worker     cur = CUR_CHAR(l);
3005*6777b538SAndroid Build Coastguard Worker     while (cur != 0) {
3006*6777b538SAndroid Build Coastguard Worker 	if ((cur == '<') && (NXT(1) == '/')) {
3007*6777b538SAndroid Build Coastguard Worker             /*
3008*6777b538SAndroid Build Coastguard Worker              * One should break here, the specification is clear:
3009*6777b538SAndroid Build Coastguard Worker              * Authors should therefore escape "</" within the content.
3010*6777b538SAndroid Build Coastguard Worker              * Escape mechanisms are specific to each scripting or
3011*6777b538SAndroid Build Coastguard Worker              * style sheet language.
3012*6777b538SAndroid Build Coastguard Worker              *
3013*6777b538SAndroid Build Coastguard Worker              * In recovery mode, only break if end tag match the
3014*6777b538SAndroid Build Coastguard Worker              * current tag, effectively ignoring all tags inside the
3015*6777b538SAndroid Build Coastguard Worker              * script/style block and treating the entire block as
3016*6777b538SAndroid Build Coastguard Worker              * CDATA.
3017*6777b538SAndroid Build Coastguard Worker              */
3018*6777b538SAndroid Build Coastguard Worker             if (ctxt->recovery) {
3019*6777b538SAndroid Build Coastguard Worker                 if (xmlStrncasecmp(ctxt->name, ctxt->input->cur+2,
3020*6777b538SAndroid Build Coastguard Worker 				   xmlStrlen(ctxt->name)) == 0)
3021*6777b538SAndroid Build Coastguard Worker                 {
3022*6777b538SAndroid Build Coastguard Worker                     break; /* while */
3023*6777b538SAndroid Build Coastguard Worker                 } else {
3024*6777b538SAndroid Build Coastguard Worker 		    htmlParseErr(ctxt, XML_ERR_TAG_NAME_MISMATCH,
3025*6777b538SAndroid Build Coastguard Worker 				 "Element %s embeds close tag\n",
3026*6777b538SAndroid Build Coastguard Worker 		                 ctxt->name, NULL);
3027*6777b538SAndroid Build Coastguard Worker 		}
3028*6777b538SAndroid Build Coastguard Worker             } else {
3029*6777b538SAndroid Build Coastguard Worker                 if (((NXT(2) >= 'A') && (NXT(2) <= 'Z')) ||
3030*6777b538SAndroid Build Coastguard Worker                     ((NXT(2) >= 'a') && (NXT(2) <= 'z')))
3031*6777b538SAndroid Build Coastguard Worker                 {
3032*6777b538SAndroid Build Coastguard Worker                     break; /* while */
3033*6777b538SAndroid Build Coastguard Worker                 }
3034*6777b538SAndroid Build Coastguard Worker             }
3035*6777b538SAndroid Build Coastguard Worker 	}
3036*6777b538SAndroid Build Coastguard Worker         if (IS_CHAR(cur)) {
3037*6777b538SAndroid Build Coastguard Worker 	    COPY_BUF(l,buf,nbchar,cur);
3038*6777b538SAndroid Build Coastguard Worker         } else {
3039*6777b538SAndroid Build Coastguard Worker             htmlParseErrInt(ctxt, XML_ERR_INVALID_CHAR,
3040*6777b538SAndroid Build Coastguard Worker                             "Invalid char in CDATA 0x%X\n", cur);
3041*6777b538SAndroid Build Coastguard Worker         }
3042*6777b538SAndroid Build Coastguard Worker 	NEXTL(l);
3043*6777b538SAndroid Build Coastguard Worker 	if (nbchar >= HTML_PARSER_BIG_BUFFER_SIZE) {
3044*6777b538SAndroid Build Coastguard Worker             buf[nbchar] = 0;
3045*6777b538SAndroid Build Coastguard Worker 	    if (ctxt->sax->cdataBlock!= NULL) {
3046*6777b538SAndroid Build Coastguard Worker 		/*
3047*6777b538SAndroid Build Coastguard Worker 		 * Insert as CDATA, which is the same as HTML_PRESERVE_NODE
3048*6777b538SAndroid Build Coastguard Worker 		 */
3049*6777b538SAndroid Build Coastguard Worker 		ctxt->sax->cdataBlock(ctxt->userData, buf, nbchar);
3050*6777b538SAndroid Build Coastguard Worker 	    } else if (ctxt->sax->characters != NULL) {
3051*6777b538SAndroid Build Coastguard Worker 		ctxt->sax->characters(ctxt->userData, buf, nbchar);
3052*6777b538SAndroid Build Coastguard Worker 	    }
3053*6777b538SAndroid Build Coastguard Worker 	    nbchar = 0;
3054*6777b538SAndroid Build Coastguard Worker             SHRINK;
3055*6777b538SAndroid Build Coastguard Worker 	}
3056*6777b538SAndroid Build Coastguard Worker 	cur = CUR_CHAR(l);
3057*6777b538SAndroid Build Coastguard Worker     }
3058*6777b538SAndroid Build Coastguard Worker 
3059*6777b538SAndroid Build Coastguard Worker     if ((nbchar != 0) && (ctxt->sax != NULL) && (!ctxt->disableSAX)) {
3060*6777b538SAndroid Build Coastguard Worker         buf[nbchar] = 0;
3061*6777b538SAndroid Build Coastguard Worker 	if (ctxt->sax->cdataBlock!= NULL) {
3062*6777b538SAndroid Build Coastguard Worker 	    /*
3063*6777b538SAndroid Build Coastguard Worker 	     * Insert as CDATA, which is the same as HTML_PRESERVE_NODE
3064*6777b538SAndroid Build Coastguard Worker 	     */
3065*6777b538SAndroid Build Coastguard Worker 	    ctxt->sax->cdataBlock(ctxt->userData, buf, nbchar);
3066*6777b538SAndroid Build Coastguard Worker 	} else if (ctxt->sax->characters != NULL) {
3067*6777b538SAndroid Build Coastguard Worker 	    ctxt->sax->characters(ctxt->userData, buf, nbchar);
3068*6777b538SAndroid Build Coastguard Worker 	}
3069*6777b538SAndroid Build Coastguard Worker     }
3070*6777b538SAndroid Build Coastguard Worker }
3071*6777b538SAndroid Build Coastguard Worker 
3072*6777b538SAndroid Build Coastguard Worker 
3073*6777b538SAndroid Build Coastguard Worker /**
3074*6777b538SAndroid Build Coastguard Worker  * htmlParseCharDataInternal:
3075*6777b538SAndroid Build Coastguard Worker  * @ctxt:  an HTML parser context
3076*6777b538SAndroid Build Coastguard Worker  * @readahead: optional read ahead character in ascii range
3077*6777b538SAndroid Build Coastguard Worker  *
3078*6777b538SAndroid Build Coastguard Worker  * parse a CharData section.
3079*6777b538SAndroid Build Coastguard Worker  * if we are within a CDATA section ']]>' marks an end of section.
3080*6777b538SAndroid Build Coastguard Worker  *
3081*6777b538SAndroid Build Coastguard Worker  * [14] CharData ::= [^<&]* - ([^<&]* ']]>' [^<&]*)
3082*6777b538SAndroid Build Coastguard Worker  */
3083*6777b538SAndroid Build Coastguard Worker 
3084*6777b538SAndroid Build Coastguard Worker static void
htmlParseCharDataInternal(htmlParserCtxtPtr ctxt,int readahead)3085*6777b538SAndroid Build Coastguard Worker htmlParseCharDataInternal(htmlParserCtxtPtr ctxt, int readahead) {
3086*6777b538SAndroid Build Coastguard Worker     xmlChar buf[HTML_PARSER_BIG_BUFFER_SIZE + 6];
3087*6777b538SAndroid Build Coastguard Worker     int nbchar = 0;
3088*6777b538SAndroid Build Coastguard Worker     int cur, l;
3089*6777b538SAndroid Build Coastguard Worker 
3090*6777b538SAndroid Build Coastguard Worker     if (readahead)
3091*6777b538SAndroid Build Coastguard Worker         buf[nbchar++] = readahead;
3092*6777b538SAndroid Build Coastguard Worker 
3093*6777b538SAndroid Build Coastguard Worker     cur = CUR_CHAR(l);
3094*6777b538SAndroid Build Coastguard Worker     while ((cur != '<') &&
3095*6777b538SAndroid Build Coastguard Worker            (cur != '&') &&
3096*6777b538SAndroid Build Coastguard Worker 	   (cur != 0) &&
3097*6777b538SAndroid Build Coastguard Worker            (!PARSER_STOPPED(ctxt))) {
3098*6777b538SAndroid Build Coastguard Worker 	if (!(IS_CHAR(cur))) {
3099*6777b538SAndroid Build Coastguard Worker 	    htmlParseErrInt(ctxt, XML_ERR_INVALID_CHAR,
3100*6777b538SAndroid Build Coastguard Worker 	                "Invalid char in CDATA 0x%X\n", cur);
3101*6777b538SAndroid Build Coastguard Worker 	} else {
3102*6777b538SAndroid Build Coastguard Worker 	    COPY_BUF(l,buf,nbchar,cur);
3103*6777b538SAndroid Build Coastguard Worker 	}
3104*6777b538SAndroid Build Coastguard Worker 	NEXTL(l);
3105*6777b538SAndroid Build Coastguard Worker 	if (nbchar >= HTML_PARSER_BIG_BUFFER_SIZE) {
3106*6777b538SAndroid Build Coastguard Worker             buf[nbchar] = 0;
3107*6777b538SAndroid Build Coastguard Worker 
3108*6777b538SAndroid Build Coastguard Worker 	    /*
3109*6777b538SAndroid Build Coastguard Worker 	     * Ok the segment is to be consumed as chars.
3110*6777b538SAndroid Build Coastguard Worker 	     */
3111*6777b538SAndroid Build Coastguard Worker 	    if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
3112*6777b538SAndroid Build Coastguard Worker 		if (areBlanks(ctxt, buf, nbchar)) {
3113*6777b538SAndroid Build Coastguard Worker 		    if (ctxt->keepBlanks) {
3114*6777b538SAndroid Build Coastguard Worker 			if (ctxt->sax->characters != NULL)
3115*6777b538SAndroid Build Coastguard Worker 			    ctxt->sax->characters(ctxt->userData, buf, nbchar);
3116*6777b538SAndroid Build Coastguard Worker 		    } else {
3117*6777b538SAndroid Build Coastguard Worker 			if (ctxt->sax->ignorableWhitespace != NULL)
3118*6777b538SAndroid Build Coastguard Worker 			    ctxt->sax->ignorableWhitespace(ctxt->userData,
3119*6777b538SAndroid Build Coastguard Worker 			                                   buf, nbchar);
3120*6777b538SAndroid Build Coastguard Worker 		    }
3121*6777b538SAndroid Build Coastguard Worker 		} else {
3122*6777b538SAndroid Build Coastguard Worker 		    htmlCheckParagraph(ctxt);
3123*6777b538SAndroid Build Coastguard Worker 		    if (ctxt->sax->characters != NULL)
3124*6777b538SAndroid Build Coastguard Worker 			ctxt->sax->characters(ctxt->userData, buf, nbchar);
3125*6777b538SAndroid Build Coastguard Worker 		}
3126*6777b538SAndroid Build Coastguard Worker 	    }
3127*6777b538SAndroid Build Coastguard Worker 	    nbchar = 0;
3128*6777b538SAndroid Build Coastguard Worker             SHRINK;
3129*6777b538SAndroid Build Coastguard Worker 	}
3130*6777b538SAndroid Build Coastguard Worker 	cur = CUR_CHAR(l);
3131*6777b538SAndroid Build Coastguard Worker     }
3132*6777b538SAndroid Build Coastguard Worker     if (nbchar != 0) {
3133*6777b538SAndroid Build Coastguard Worker         buf[nbchar] = 0;
3134*6777b538SAndroid Build Coastguard Worker 
3135*6777b538SAndroid Build Coastguard Worker 	/*
3136*6777b538SAndroid Build Coastguard Worker 	 * Ok the segment is to be consumed as chars.
3137*6777b538SAndroid Build Coastguard Worker 	 */
3138*6777b538SAndroid Build Coastguard Worker 	if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
3139*6777b538SAndroid Build Coastguard Worker 	    if (areBlanks(ctxt, buf, nbchar)) {
3140*6777b538SAndroid Build Coastguard Worker 		if (ctxt->keepBlanks) {
3141*6777b538SAndroid Build Coastguard Worker 		    if (ctxt->sax->characters != NULL)
3142*6777b538SAndroid Build Coastguard Worker 			ctxt->sax->characters(ctxt->userData, buf, nbchar);
3143*6777b538SAndroid Build Coastguard Worker 		} else {
3144*6777b538SAndroid Build Coastguard Worker 		    if (ctxt->sax->ignorableWhitespace != NULL)
3145*6777b538SAndroid Build Coastguard Worker 			ctxt->sax->ignorableWhitespace(ctxt->userData,
3146*6777b538SAndroid Build Coastguard Worker 			                               buf, nbchar);
3147*6777b538SAndroid Build Coastguard Worker 		}
3148*6777b538SAndroid Build Coastguard Worker 	    } else {
3149*6777b538SAndroid Build Coastguard Worker 		htmlCheckParagraph(ctxt);
3150*6777b538SAndroid Build Coastguard Worker 		if (ctxt->sax->characters != NULL)
3151*6777b538SAndroid Build Coastguard Worker 		    ctxt->sax->characters(ctxt->userData, buf, nbchar);
3152*6777b538SAndroid Build Coastguard Worker 	    }
3153*6777b538SAndroid Build Coastguard Worker 	}
3154*6777b538SAndroid Build Coastguard Worker     }
3155*6777b538SAndroid Build Coastguard Worker }
3156*6777b538SAndroid Build Coastguard Worker 
3157*6777b538SAndroid Build Coastguard Worker /**
3158*6777b538SAndroid Build Coastguard Worker  * htmlParseCharData:
3159*6777b538SAndroid Build Coastguard Worker  * @ctxt:  an HTML parser context
3160*6777b538SAndroid Build Coastguard Worker  *
3161*6777b538SAndroid Build Coastguard Worker  * parse a CharData section.
3162*6777b538SAndroid Build Coastguard Worker  * if we are within a CDATA section ']]>' marks an end of section.
3163*6777b538SAndroid Build Coastguard Worker  *
3164*6777b538SAndroid Build Coastguard Worker  * [14] CharData ::= [^<&]* - ([^<&]* ']]>' [^<&]*)
3165*6777b538SAndroid Build Coastguard Worker  */
3166*6777b538SAndroid Build Coastguard Worker 
3167*6777b538SAndroid Build Coastguard Worker static void
htmlParseCharData(htmlParserCtxtPtr ctxt)3168*6777b538SAndroid Build Coastguard Worker htmlParseCharData(htmlParserCtxtPtr ctxt) {
3169*6777b538SAndroid Build Coastguard Worker     htmlParseCharDataInternal(ctxt, 0);
3170*6777b538SAndroid Build Coastguard Worker }
3171*6777b538SAndroid Build Coastguard Worker 
3172*6777b538SAndroid Build Coastguard Worker /**
3173*6777b538SAndroid Build Coastguard Worker  * htmlParseExternalID:
3174*6777b538SAndroid Build Coastguard Worker  * @ctxt:  an HTML parser context
3175*6777b538SAndroid Build Coastguard Worker  * @publicID:  a xmlChar** receiving PubidLiteral
3176*6777b538SAndroid Build Coastguard Worker  *
3177*6777b538SAndroid Build Coastguard Worker  * Parse an External ID or a Public ID
3178*6777b538SAndroid Build Coastguard Worker  *
3179*6777b538SAndroid Build Coastguard Worker  * [75] ExternalID ::= 'SYSTEM' S SystemLiteral
3180*6777b538SAndroid Build Coastguard Worker  *                   | 'PUBLIC' S PubidLiteral S SystemLiteral
3181*6777b538SAndroid Build Coastguard Worker  *
3182*6777b538SAndroid Build Coastguard Worker  * [83] PublicID ::= 'PUBLIC' S PubidLiteral
3183*6777b538SAndroid Build Coastguard Worker  *
3184*6777b538SAndroid Build Coastguard Worker  * Returns the function returns SystemLiteral and in the second
3185*6777b538SAndroid Build Coastguard Worker  *                case publicID receives PubidLiteral, is strict is off
3186*6777b538SAndroid Build Coastguard Worker  *                it is possible to return NULL and have publicID set.
3187*6777b538SAndroid Build Coastguard Worker  */
3188*6777b538SAndroid Build Coastguard Worker 
3189*6777b538SAndroid Build Coastguard Worker static xmlChar *
htmlParseExternalID(htmlParserCtxtPtr ctxt,xmlChar ** publicID)3190*6777b538SAndroid Build Coastguard Worker htmlParseExternalID(htmlParserCtxtPtr ctxt, xmlChar **publicID) {
3191*6777b538SAndroid Build Coastguard Worker     xmlChar *URI = NULL;
3192*6777b538SAndroid Build Coastguard Worker 
3193*6777b538SAndroid Build Coastguard Worker     if ((UPPER == 'S') && (UPP(1) == 'Y') &&
3194*6777b538SAndroid Build Coastguard Worker          (UPP(2) == 'S') && (UPP(3) == 'T') &&
3195*6777b538SAndroid Build Coastguard Worker 	 (UPP(4) == 'E') && (UPP(5) == 'M')) {
3196*6777b538SAndroid Build Coastguard Worker         SKIP(6);
3197*6777b538SAndroid Build Coastguard Worker 	if (!IS_BLANK_CH(CUR)) {
3198*6777b538SAndroid Build Coastguard Worker 	    htmlParseErr(ctxt, XML_ERR_SPACE_REQUIRED,
3199*6777b538SAndroid Build Coastguard Worker 	                 "Space required after 'SYSTEM'\n", NULL, NULL);
3200*6777b538SAndroid Build Coastguard Worker 	}
3201*6777b538SAndroid Build Coastguard Worker         SKIP_BLANKS;
3202*6777b538SAndroid Build Coastguard Worker 	URI = htmlParseSystemLiteral(ctxt);
3203*6777b538SAndroid Build Coastguard Worker 	if (URI == NULL) {
3204*6777b538SAndroid Build Coastguard Worker 	    htmlParseErr(ctxt, XML_ERR_URI_REQUIRED,
3205*6777b538SAndroid Build Coastguard Worker 	                 "htmlParseExternalID: SYSTEM, no URI\n", NULL, NULL);
3206*6777b538SAndroid Build Coastguard Worker         }
3207*6777b538SAndroid Build Coastguard Worker     } else if ((UPPER == 'P') && (UPP(1) == 'U') &&
3208*6777b538SAndroid Build Coastguard Worker 	       (UPP(2) == 'B') && (UPP(3) == 'L') &&
3209*6777b538SAndroid Build Coastguard Worker 	       (UPP(4) == 'I') && (UPP(5) == 'C')) {
3210*6777b538SAndroid Build Coastguard Worker         SKIP(6);
3211*6777b538SAndroid Build Coastguard Worker 	if (!IS_BLANK_CH(CUR)) {
3212*6777b538SAndroid Build Coastguard Worker 	    htmlParseErr(ctxt, XML_ERR_SPACE_REQUIRED,
3213*6777b538SAndroid Build Coastguard Worker 	                 "Space required after 'PUBLIC'\n", NULL, NULL);
3214*6777b538SAndroid Build Coastguard Worker 	}
3215*6777b538SAndroid Build Coastguard Worker         SKIP_BLANKS;
3216*6777b538SAndroid Build Coastguard Worker 	*publicID = htmlParsePubidLiteral(ctxt);
3217*6777b538SAndroid Build Coastguard Worker 	if (*publicID == NULL) {
3218*6777b538SAndroid Build Coastguard Worker 	    htmlParseErr(ctxt, XML_ERR_PUBID_REQUIRED,
3219*6777b538SAndroid Build Coastguard Worker 	                 "htmlParseExternalID: PUBLIC, no Public Identifier\n",
3220*6777b538SAndroid Build Coastguard Worker 			 NULL, NULL);
3221*6777b538SAndroid Build Coastguard Worker 	}
3222*6777b538SAndroid Build Coastguard Worker         SKIP_BLANKS;
3223*6777b538SAndroid Build Coastguard Worker         if ((CUR == '"') || (CUR == '\'')) {
3224*6777b538SAndroid Build Coastguard Worker 	    URI = htmlParseSystemLiteral(ctxt);
3225*6777b538SAndroid Build Coastguard Worker 	}
3226*6777b538SAndroid Build Coastguard Worker     }
3227*6777b538SAndroid Build Coastguard Worker     return(URI);
3228*6777b538SAndroid Build Coastguard Worker }
3229*6777b538SAndroid Build Coastguard Worker 
3230*6777b538SAndroid Build Coastguard Worker /**
3231*6777b538SAndroid Build Coastguard Worker  * htmlParsePI:
3232*6777b538SAndroid Build Coastguard Worker  * @ctxt:  an HTML parser context
3233*6777b538SAndroid Build Coastguard Worker  *
3234*6777b538SAndroid Build Coastguard Worker  * Parse an XML Processing Instruction. HTML5 doesn't allow processing
3235*6777b538SAndroid Build Coastguard Worker  * instructions, so this will be removed at some point.
3236*6777b538SAndroid Build Coastguard Worker  */
3237*6777b538SAndroid Build Coastguard Worker static void
htmlParsePI(htmlParserCtxtPtr ctxt)3238*6777b538SAndroid Build Coastguard Worker htmlParsePI(htmlParserCtxtPtr ctxt) {
3239*6777b538SAndroid Build Coastguard Worker     xmlChar *buf = NULL;
3240*6777b538SAndroid Build Coastguard Worker     int len = 0;
3241*6777b538SAndroid Build Coastguard Worker     int size = HTML_PARSER_BUFFER_SIZE;
3242*6777b538SAndroid Build Coastguard Worker     int cur, l;
3243*6777b538SAndroid Build Coastguard Worker     int maxLength = (ctxt->options & XML_PARSE_HUGE) ?
3244*6777b538SAndroid Build Coastguard Worker                     XML_MAX_HUGE_LENGTH :
3245*6777b538SAndroid Build Coastguard Worker                     XML_MAX_TEXT_LENGTH;
3246*6777b538SAndroid Build Coastguard Worker     const xmlChar *target;
3247*6777b538SAndroid Build Coastguard Worker     xmlParserInputState state;
3248*6777b538SAndroid Build Coastguard Worker 
3249*6777b538SAndroid Build Coastguard Worker     if ((RAW == '<') && (NXT(1) == '?')) {
3250*6777b538SAndroid Build Coastguard Worker 	state = ctxt->instate;
3251*6777b538SAndroid Build Coastguard Worker         ctxt->instate = XML_PARSER_PI;
3252*6777b538SAndroid Build Coastguard Worker 	/*
3253*6777b538SAndroid Build Coastguard Worker 	 * this is a Processing Instruction.
3254*6777b538SAndroid Build Coastguard Worker 	 */
3255*6777b538SAndroid Build Coastguard Worker 	SKIP(2);
3256*6777b538SAndroid Build Coastguard Worker 
3257*6777b538SAndroid Build Coastguard Worker 	/*
3258*6777b538SAndroid Build Coastguard Worker 	 * Parse the target name and check for special support like
3259*6777b538SAndroid Build Coastguard Worker 	 * namespace.
3260*6777b538SAndroid Build Coastguard Worker 	 */
3261*6777b538SAndroid Build Coastguard Worker         target = htmlParseName(ctxt);
3262*6777b538SAndroid Build Coastguard Worker 	if (target != NULL) {
3263*6777b538SAndroid Build Coastguard Worker 	    if (RAW == '>') {
3264*6777b538SAndroid Build Coastguard Worker 		SKIP(1);
3265*6777b538SAndroid Build Coastguard Worker 
3266*6777b538SAndroid Build Coastguard Worker 		/*
3267*6777b538SAndroid Build Coastguard Worker 		 * SAX: PI detected.
3268*6777b538SAndroid Build Coastguard Worker 		 */
3269*6777b538SAndroid Build Coastguard Worker 		if ((ctxt->sax) && (!ctxt->disableSAX) &&
3270*6777b538SAndroid Build Coastguard Worker 		    (ctxt->sax->processingInstruction != NULL))
3271*6777b538SAndroid Build Coastguard Worker 		    ctxt->sax->processingInstruction(ctxt->userData,
3272*6777b538SAndroid Build Coastguard Worker 		                                     target, NULL);
3273*6777b538SAndroid Build Coastguard Worker                 goto done;
3274*6777b538SAndroid Build Coastguard Worker 	    }
3275*6777b538SAndroid Build Coastguard Worker 	    buf = (xmlChar *) xmlMallocAtomic(size);
3276*6777b538SAndroid Build Coastguard Worker 	    if (buf == NULL) {
3277*6777b538SAndroid Build Coastguard Worker 		htmlErrMemory(ctxt);
3278*6777b538SAndroid Build Coastguard Worker 		return;
3279*6777b538SAndroid Build Coastguard Worker 	    }
3280*6777b538SAndroid Build Coastguard Worker 	    cur = CUR;
3281*6777b538SAndroid Build Coastguard Worker 	    if (!IS_BLANK(cur)) {
3282*6777b538SAndroid Build Coastguard Worker 		htmlParseErr(ctxt, XML_ERR_SPACE_REQUIRED,
3283*6777b538SAndroid Build Coastguard Worker 			  "ParsePI: PI %s space expected\n", target, NULL);
3284*6777b538SAndroid Build Coastguard Worker 	    }
3285*6777b538SAndroid Build Coastguard Worker             SKIP_BLANKS;
3286*6777b538SAndroid Build Coastguard Worker 	    cur = CUR_CHAR(l);
3287*6777b538SAndroid Build Coastguard Worker 	    while ((cur != 0) && (cur != '>')) {
3288*6777b538SAndroid Build Coastguard Worker 		if (len + 5 >= size) {
3289*6777b538SAndroid Build Coastguard Worker 		    xmlChar *tmp;
3290*6777b538SAndroid Build Coastguard Worker 
3291*6777b538SAndroid Build Coastguard Worker 		    size *= 2;
3292*6777b538SAndroid Build Coastguard Worker 		    tmp = (xmlChar *) xmlRealloc(buf, size);
3293*6777b538SAndroid Build Coastguard Worker 		    if (tmp == NULL) {
3294*6777b538SAndroid Build Coastguard Worker 			htmlErrMemory(ctxt);
3295*6777b538SAndroid Build Coastguard Worker 			xmlFree(buf);
3296*6777b538SAndroid Build Coastguard Worker 			return;
3297*6777b538SAndroid Build Coastguard Worker 		    }
3298*6777b538SAndroid Build Coastguard Worker 		    buf = tmp;
3299*6777b538SAndroid Build Coastguard Worker 		}
3300*6777b538SAndroid Build Coastguard Worker                 if (IS_CHAR(cur)) {
3301*6777b538SAndroid Build Coastguard Worker 		    COPY_BUF(l,buf,len,cur);
3302*6777b538SAndroid Build Coastguard Worker                 } else {
3303*6777b538SAndroid Build Coastguard Worker                     htmlParseErrInt(ctxt, XML_ERR_INVALID_CHAR,
3304*6777b538SAndroid Build Coastguard Worker                                     "Invalid char in processing instruction "
3305*6777b538SAndroid Build Coastguard Worker                                     "0x%X\n", cur);
3306*6777b538SAndroid Build Coastguard Worker                 }
3307*6777b538SAndroid Build Coastguard Worker                 if (len > maxLength) {
3308*6777b538SAndroid Build Coastguard Worker                     htmlParseErr(ctxt, XML_ERR_PI_NOT_FINISHED,
3309*6777b538SAndroid Build Coastguard Worker                                  "PI %s too long", target, NULL);
3310*6777b538SAndroid Build Coastguard Worker                     xmlFree(buf);
3311*6777b538SAndroid Build Coastguard Worker                     goto done;
3312*6777b538SAndroid Build Coastguard Worker                 }
3313*6777b538SAndroid Build Coastguard Worker 		NEXTL(l);
3314*6777b538SAndroid Build Coastguard Worker 		cur = CUR_CHAR(l);
3315*6777b538SAndroid Build Coastguard Worker 	    }
3316*6777b538SAndroid Build Coastguard Worker 	    buf[len] = 0;
3317*6777b538SAndroid Build Coastguard Worker 	    if (cur != '>') {
3318*6777b538SAndroid Build Coastguard Worker 		htmlParseErr(ctxt, XML_ERR_PI_NOT_FINISHED,
3319*6777b538SAndroid Build Coastguard Worker 		      "ParsePI: PI %s never end ...\n", target, NULL);
3320*6777b538SAndroid Build Coastguard Worker 	    } else {
3321*6777b538SAndroid Build Coastguard Worker 		SKIP(1);
3322*6777b538SAndroid Build Coastguard Worker 
3323*6777b538SAndroid Build Coastguard Worker 		/*
3324*6777b538SAndroid Build Coastguard Worker 		 * SAX: PI detected.
3325*6777b538SAndroid Build Coastguard Worker 		 */
3326*6777b538SAndroid Build Coastguard Worker 		if ((ctxt->sax) && (!ctxt->disableSAX) &&
3327*6777b538SAndroid Build Coastguard Worker 		    (ctxt->sax->processingInstruction != NULL))
3328*6777b538SAndroid Build Coastguard Worker 		    ctxt->sax->processingInstruction(ctxt->userData,
3329*6777b538SAndroid Build Coastguard Worker 		                                     target, buf);
3330*6777b538SAndroid Build Coastguard Worker 	    }
3331*6777b538SAndroid Build Coastguard Worker 	    xmlFree(buf);
3332*6777b538SAndroid Build Coastguard Worker 	} else {
3333*6777b538SAndroid Build Coastguard Worker 	    htmlParseErr(ctxt, XML_ERR_PI_NOT_STARTED,
3334*6777b538SAndroid Build Coastguard Worker                          "PI is not started correctly", NULL, NULL);
3335*6777b538SAndroid Build Coastguard Worker 	}
3336*6777b538SAndroid Build Coastguard Worker 
3337*6777b538SAndroid Build Coastguard Worker done:
3338*6777b538SAndroid Build Coastguard Worker 	ctxt->instate = state;
3339*6777b538SAndroid Build Coastguard Worker     }
3340*6777b538SAndroid Build Coastguard Worker }
3341*6777b538SAndroid Build Coastguard Worker 
3342*6777b538SAndroid Build Coastguard Worker /**
3343*6777b538SAndroid Build Coastguard Worker  * htmlParseComment:
3344*6777b538SAndroid Build Coastguard Worker  * @ctxt:  an HTML parser context
3345*6777b538SAndroid Build Coastguard Worker  *
3346*6777b538SAndroid Build Coastguard Worker  * Parse an HTML comment
3347*6777b538SAndroid Build Coastguard Worker  */
3348*6777b538SAndroid Build Coastguard Worker static void
htmlParseComment(htmlParserCtxtPtr ctxt)3349*6777b538SAndroid Build Coastguard Worker htmlParseComment(htmlParserCtxtPtr ctxt) {
3350*6777b538SAndroid Build Coastguard Worker     xmlChar *buf = NULL;
3351*6777b538SAndroid Build Coastguard Worker     int len;
3352*6777b538SAndroid Build Coastguard Worker     int size = HTML_PARSER_BUFFER_SIZE;
3353*6777b538SAndroid Build Coastguard Worker     int q, ql;
3354*6777b538SAndroid Build Coastguard Worker     int r, rl;
3355*6777b538SAndroid Build Coastguard Worker     int cur, l;
3356*6777b538SAndroid Build Coastguard Worker     int next, nl;
3357*6777b538SAndroid Build Coastguard Worker     int maxLength = (ctxt->options & XML_PARSE_HUGE) ?
3358*6777b538SAndroid Build Coastguard Worker                     XML_MAX_HUGE_LENGTH :
3359*6777b538SAndroid Build Coastguard Worker                     XML_MAX_TEXT_LENGTH;
3360*6777b538SAndroid Build Coastguard Worker     xmlParserInputState state;
3361*6777b538SAndroid Build Coastguard Worker 
3362*6777b538SAndroid Build Coastguard Worker     /*
3363*6777b538SAndroid Build Coastguard Worker      * Check that there is a comment right here.
3364*6777b538SAndroid Build Coastguard Worker      */
3365*6777b538SAndroid Build Coastguard Worker     if ((RAW != '<') || (NXT(1) != '!') ||
3366*6777b538SAndroid Build Coastguard Worker         (NXT(2) != '-') || (NXT(3) != '-')) return;
3367*6777b538SAndroid Build Coastguard Worker 
3368*6777b538SAndroid Build Coastguard Worker     state = ctxt->instate;
3369*6777b538SAndroid Build Coastguard Worker     ctxt->instate = XML_PARSER_COMMENT;
3370*6777b538SAndroid Build Coastguard Worker     SKIP(4);
3371*6777b538SAndroid Build Coastguard Worker     buf = (xmlChar *) xmlMallocAtomic(size);
3372*6777b538SAndroid Build Coastguard Worker     if (buf == NULL) {
3373*6777b538SAndroid Build Coastguard Worker         htmlErrMemory(ctxt);
3374*6777b538SAndroid Build Coastguard Worker 	return;
3375*6777b538SAndroid Build Coastguard Worker     }
3376*6777b538SAndroid Build Coastguard Worker     len = 0;
3377*6777b538SAndroid Build Coastguard Worker     buf[len] = 0;
3378*6777b538SAndroid Build Coastguard Worker     q = CUR_CHAR(ql);
3379*6777b538SAndroid Build Coastguard Worker     if (q == 0)
3380*6777b538SAndroid Build Coastguard Worker         goto unfinished;
3381*6777b538SAndroid Build Coastguard Worker     if (q == '>') {
3382*6777b538SAndroid Build Coastguard Worker         htmlParseErr(ctxt, XML_ERR_COMMENT_ABRUPTLY_ENDED, "Comment abruptly ended", NULL, NULL);
3383*6777b538SAndroid Build Coastguard Worker         cur = '>';
3384*6777b538SAndroid Build Coastguard Worker         goto finished;
3385*6777b538SAndroid Build Coastguard Worker     }
3386*6777b538SAndroid Build Coastguard Worker     NEXTL(ql);
3387*6777b538SAndroid Build Coastguard Worker     r = CUR_CHAR(rl);
3388*6777b538SAndroid Build Coastguard Worker     if (r == 0)
3389*6777b538SAndroid Build Coastguard Worker         goto unfinished;
3390*6777b538SAndroid Build Coastguard Worker     if (q == '-' && r == '>') {
3391*6777b538SAndroid Build Coastguard Worker         htmlParseErr(ctxt, XML_ERR_COMMENT_ABRUPTLY_ENDED, "Comment abruptly ended", NULL, NULL);
3392*6777b538SAndroid Build Coastguard Worker         cur = '>';
3393*6777b538SAndroid Build Coastguard Worker         goto finished;
3394*6777b538SAndroid Build Coastguard Worker     }
3395*6777b538SAndroid Build Coastguard Worker     NEXTL(rl);
3396*6777b538SAndroid Build Coastguard Worker     cur = CUR_CHAR(l);
3397*6777b538SAndroid Build Coastguard Worker     while ((cur != 0) &&
3398*6777b538SAndroid Build Coastguard Worker            ((cur != '>') ||
3399*6777b538SAndroid Build Coastguard Worker 	    (r != '-') || (q != '-'))) {
3400*6777b538SAndroid Build Coastguard Worker 	NEXTL(l);
3401*6777b538SAndroid Build Coastguard Worker 	next = CUR_CHAR(nl);
3402*6777b538SAndroid Build Coastguard Worker 
3403*6777b538SAndroid Build Coastguard Worker 	if ((q == '-') && (r == '-') && (cur == '!') && (next == '>')) {
3404*6777b538SAndroid Build Coastguard Worker 	  htmlParseErr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
3405*6777b538SAndroid Build Coastguard Worker 		       "Comment incorrectly closed by '--!>'", NULL, NULL);
3406*6777b538SAndroid Build Coastguard Worker 	  cur = '>';
3407*6777b538SAndroid Build Coastguard Worker 	  break;
3408*6777b538SAndroid Build Coastguard Worker 	}
3409*6777b538SAndroid Build Coastguard Worker 
3410*6777b538SAndroid Build Coastguard Worker 	if (len + 5 >= size) {
3411*6777b538SAndroid Build Coastguard Worker 	    xmlChar *tmp;
3412*6777b538SAndroid Build Coastguard Worker 
3413*6777b538SAndroid Build Coastguard Worker 	    size *= 2;
3414*6777b538SAndroid Build Coastguard Worker 	    tmp = (xmlChar *) xmlRealloc(buf, size);
3415*6777b538SAndroid Build Coastguard Worker 	    if (tmp == NULL) {
3416*6777b538SAndroid Build Coastguard Worker 	        xmlFree(buf);
3417*6777b538SAndroid Build Coastguard Worker 	        htmlErrMemory(ctxt);
3418*6777b538SAndroid Build Coastguard Worker 		return;
3419*6777b538SAndroid Build Coastguard Worker 	    }
3420*6777b538SAndroid Build Coastguard Worker 	    buf = tmp;
3421*6777b538SAndroid Build Coastguard Worker 	}
3422*6777b538SAndroid Build Coastguard Worker         if (IS_CHAR(q)) {
3423*6777b538SAndroid Build Coastguard Worker 	    COPY_BUF(ql,buf,len,q);
3424*6777b538SAndroid Build Coastguard Worker         } else {
3425*6777b538SAndroid Build Coastguard Worker             htmlParseErrInt(ctxt, XML_ERR_INVALID_CHAR,
3426*6777b538SAndroid Build Coastguard Worker                             "Invalid char in comment 0x%X\n", q);
3427*6777b538SAndroid Build Coastguard Worker         }
3428*6777b538SAndroid Build Coastguard Worker         if (len > maxLength) {
3429*6777b538SAndroid Build Coastguard Worker             htmlParseErr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
3430*6777b538SAndroid Build Coastguard Worker                          "comment too long", NULL, NULL);
3431*6777b538SAndroid Build Coastguard Worker             xmlFree(buf);
3432*6777b538SAndroid Build Coastguard Worker             ctxt->instate = state;
3433*6777b538SAndroid Build Coastguard Worker             return;
3434*6777b538SAndroid Build Coastguard Worker         }
3435*6777b538SAndroid Build Coastguard Worker 
3436*6777b538SAndroid Build Coastguard Worker 	q = r;
3437*6777b538SAndroid Build Coastguard Worker 	ql = rl;
3438*6777b538SAndroid Build Coastguard Worker 	r = cur;
3439*6777b538SAndroid Build Coastguard Worker 	rl = l;
3440*6777b538SAndroid Build Coastguard Worker 	cur = next;
3441*6777b538SAndroid Build Coastguard Worker 	l = nl;
3442*6777b538SAndroid Build Coastguard Worker     }
3443*6777b538SAndroid Build Coastguard Worker finished:
3444*6777b538SAndroid Build Coastguard Worker     buf[len] = 0;
3445*6777b538SAndroid Build Coastguard Worker     if (cur == '>') {
3446*6777b538SAndroid Build Coastguard Worker         NEXT;
3447*6777b538SAndroid Build Coastguard Worker 	if ((ctxt->sax != NULL) && (ctxt->sax->comment != NULL) &&
3448*6777b538SAndroid Build Coastguard Worker 	    (!ctxt->disableSAX))
3449*6777b538SAndroid Build Coastguard Worker 	    ctxt->sax->comment(ctxt->userData, buf);
3450*6777b538SAndroid Build Coastguard Worker 	xmlFree(buf);
3451*6777b538SAndroid Build Coastguard Worker 	ctxt->instate = state;
3452*6777b538SAndroid Build Coastguard Worker 	return;
3453*6777b538SAndroid Build Coastguard Worker     }
3454*6777b538SAndroid Build Coastguard Worker 
3455*6777b538SAndroid Build Coastguard Worker unfinished:
3456*6777b538SAndroid Build Coastguard Worker     htmlParseErr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
3457*6777b538SAndroid Build Coastguard Worker 		 "Comment not terminated \n<!--%.50s\n", buf, NULL);
3458*6777b538SAndroid Build Coastguard Worker     xmlFree(buf);
3459*6777b538SAndroid Build Coastguard Worker }
3460*6777b538SAndroid Build Coastguard Worker 
3461*6777b538SAndroid Build Coastguard Worker /**
3462*6777b538SAndroid Build Coastguard Worker  * htmlParseCharRef:
3463*6777b538SAndroid Build Coastguard Worker  * @ctxt:  an HTML parser context
3464*6777b538SAndroid Build Coastguard Worker  *
3465*6777b538SAndroid Build Coastguard Worker  * DEPRECATED: Internal function, don't use.
3466*6777b538SAndroid Build Coastguard Worker  *
3467*6777b538SAndroid Build Coastguard Worker  * parse Reference declarations
3468*6777b538SAndroid Build Coastguard Worker  *
3469*6777b538SAndroid Build Coastguard Worker  * [66] CharRef ::= '&#' [0-9]+ ';' |
3470*6777b538SAndroid Build Coastguard Worker  *                  '&#x' [0-9a-fA-F]+ ';'
3471*6777b538SAndroid Build Coastguard Worker  *
3472*6777b538SAndroid Build Coastguard Worker  * Returns the value parsed (as an int)
3473*6777b538SAndroid Build Coastguard Worker  */
3474*6777b538SAndroid Build Coastguard Worker int
htmlParseCharRef(htmlParserCtxtPtr ctxt)3475*6777b538SAndroid Build Coastguard Worker htmlParseCharRef(htmlParserCtxtPtr ctxt) {
3476*6777b538SAndroid Build Coastguard Worker     int val = 0;
3477*6777b538SAndroid Build Coastguard Worker 
3478*6777b538SAndroid Build Coastguard Worker     if ((ctxt == NULL) || (ctxt->input == NULL))
3479*6777b538SAndroid Build Coastguard Worker         return(0);
3480*6777b538SAndroid Build Coastguard Worker     if ((CUR == '&') && (NXT(1) == '#') &&
3481*6777b538SAndroid Build Coastguard Worker         ((NXT(2) == 'x') || NXT(2) == 'X')) {
3482*6777b538SAndroid Build Coastguard Worker 	SKIP(3);
3483*6777b538SAndroid Build Coastguard Worker 	while (CUR != ';') {
3484*6777b538SAndroid Build Coastguard Worker 	    if ((CUR >= '0') && (CUR <= '9')) {
3485*6777b538SAndroid Build Coastguard Worker                 if (val < 0x110000)
3486*6777b538SAndroid Build Coastguard Worker 	            val = val * 16 + (CUR - '0');
3487*6777b538SAndroid Build Coastguard Worker             } else if ((CUR >= 'a') && (CUR <= 'f')) {
3488*6777b538SAndroid Build Coastguard Worker                 if (val < 0x110000)
3489*6777b538SAndroid Build Coastguard Worker 	            val = val * 16 + (CUR - 'a') + 10;
3490*6777b538SAndroid Build Coastguard Worker             } else if ((CUR >= 'A') && (CUR <= 'F')) {
3491*6777b538SAndroid Build Coastguard Worker                 if (val < 0x110000)
3492*6777b538SAndroid Build Coastguard Worker 	            val = val * 16 + (CUR - 'A') + 10;
3493*6777b538SAndroid Build Coastguard Worker             } else {
3494*6777b538SAndroid Build Coastguard Worker 	        htmlParseErr(ctxt, XML_ERR_INVALID_HEX_CHARREF,
3495*6777b538SAndroid Build Coastguard Worker 		             "htmlParseCharRef: missing semicolon\n",
3496*6777b538SAndroid Build Coastguard Worker 			     NULL, NULL);
3497*6777b538SAndroid Build Coastguard Worker 		break;
3498*6777b538SAndroid Build Coastguard Worker 	    }
3499*6777b538SAndroid Build Coastguard Worker 	    NEXT;
3500*6777b538SAndroid Build Coastguard Worker 	}
3501*6777b538SAndroid Build Coastguard Worker 	if (CUR == ';')
3502*6777b538SAndroid Build Coastguard Worker 	    NEXT;
3503*6777b538SAndroid Build Coastguard Worker     } else if  ((CUR == '&') && (NXT(1) == '#')) {
3504*6777b538SAndroid Build Coastguard Worker 	SKIP(2);
3505*6777b538SAndroid Build Coastguard Worker 	while (CUR != ';') {
3506*6777b538SAndroid Build Coastguard Worker 	    if ((CUR >= '0') && (CUR <= '9')) {
3507*6777b538SAndroid Build Coastguard Worker                 if (val < 0x110000)
3508*6777b538SAndroid Build Coastguard Worker 	            val = val * 10 + (CUR - '0');
3509*6777b538SAndroid Build Coastguard Worker             } else {
3510*6777b538SAndroid Build Coastguard Worker 	        htmlParseErr(ctxt, XML_ERR_INVALID_DEC_CHARREF,
3511*6777b538SAndroid Build Coastguard Worker 		             "htmlParseCharRef: missing semicolon\n",
3512*6777b538SAndroid Build Coastguard Worker 			     NULL, NULL);
3513*6777b538SAndroid Build Coastguard Worker 		break;
3514*6777b538SAndroid Build Coastguard Worker 	    }
3515*6777b538SAndroid Build Coastguard Worker 	    NEXT;
3516*6777b538SAndroid Build Coastguard Worker 	}
3517*6777b538SAndroid Build Coastguard Worker 	if (CUR == ';')
3518*6777b538SAndroid Build Coastguard Worker 	    NEXT;
3519*6777b538SAndroid Build Coastguard Worker     } else {
3520*6777b538SAndroid Build Coastguard Worker 	htmlParseErr(ctxt, XML_ERR_INVALID_CHARREF,
3521*6777b538SAndroid Build Coastguard Worker 	             "htmlParseCharRef: invalid value\n", NULL, NULL);
3522*6777b538SAndroid Build Coastguard Worker     }
3523*6777b538SAndroid Build Coastguard Worker     /*
3524*6777b538SAndroid Build Coastguard Worker      * Check the value IS_CHAR ...
3525*6777b538SAndroid Build Coastguard Worker      */
3526*6777b538SAndroid Build Coastguard Worker     if (IS_CHAR(val)) {
3527*6777b538SAndroid Build Coastguard Worker         return(val);
3528*6777b538SAndroid Build Coastguard Worker     } else if (val >= 0x110000) {
3529*6777b538SAndroid Build Coastguard Worker 	htmlParseErr(ctxt, XML_ERR_INVALID_CHAR,
3530*6777b538SAndroid Build Coastguard Worker 		     "htmlParseCharRef: value too large\n", NULL, NULL);
3531*6777b538SAndroid Build Coastguard Worker     } else {
3532*6777b538SAndroid Build Coastguard Worker 	htmlParseErrInt(ctxt, XML_ERR_INVALID_CHAR,
3533*6777b538SAndroid Build Coastguard Worker 			"htmlParseCharRef: invalid xmlChar value %d\n",
3534*6777b538SAndroid Build Coastguard Worker 			val);
3535*6777b538SAndroid Build Coastguard Worker     }
3536*6777b538SAndroid Build Coastguard Worker     return(0);
3537*6777b538SAndroid Build Coastguard Worker }
3538*6777b538SAndroid Build Coastguard Worker 
3539*6777b538SAndroid Build Coastguard Worker 
3540*6777b538SAndroid Build Coastguard Worker /**
3541*6777b538SAndroid Build Coastguard Worker  * htmlParseDocTypeDecl:
3542*6777b538SAndroid Build Coastguard Worker  * @ctxt:  an HTML parser context
3543*6777b538SAndroid Build Coastguard Worker  *
3544*6777b538SAndroid Build Coastguard Worker  * parse a DOCTYPE declaration
3545*6777b538SAndroid Build Coastguard Worker  *
3546*6777b538SAndroid Build Coastguard Worker  * [28] doctypedecl ::= '<!DOCTYPE' S Name (S ExternalID)? S?
3547*6777b538SAndroid Build Coastguard Worker  *                      ('[' (markupdecl | PEReference | S)* ']' S?)? '>'
3548*6777b538SAndroid Build Coastguard Worker  */
3549*6777b538SAndroid Build Coastguard Worker 
3550*6777b538SAndroid Build Coastguard Worker static void
htmlParseDocTypeDecl(htmlParserCtxtPtr ctxt)3551*6777b538SAndroid Build Coastguard Worker htmlParseDocTypeDecl(htmlParserCtxtPtr ctxt) {
3552*6777b538SAndroid Build Coastguard Worker     const xmlChar *name;
3553*6777b538SAndroid Build Coastguard Worker     xmlChar *ExternalID = NULL;
3554*6777b538SAndroid Build Coastguard Worker     xmlChar *URI = NULL;
3555*6777b538SAndroid Build Coastguard Worker 
3556*6777b538SAndroid Build Coastguard Worker     /*
3557*6777b538SAndroid Build Coastguard Worker      * We know that '<!DOCTYPE' has been detected.
3558*6777b538SAndroid Build Coastguard Worker      */
3559*6777b538SAndroid Build Coastguard Worker     SKIP(9);
3560*6777b538SAndroid Build Coastguard Worker 
3561*6777b538SAndroid Build Coastguard Worker     SKIP_BLANKS;
3562*6777b538SAndroid Build Coastguard Worker 
3563*6777b538SAndroid Build Coastguard Worker     /*
3564*6777b538SAndroid Build Coastguard Worker      * Parse the DOCTYPE name.
3565*6777b538SAndroid Build Coastguard Worker      */
3566*6777b538SAndroid Build Coastguard Worker     name = htmlParseName(ctxt);
3567*6777b538SAndroid Build Coastguard Worker     if (name == NULL) {
3568*6777b538SAndroid Build Coastguard Worker 	htmlParseErr(ctxt, XML_ERR_NAME_REQUIRED,
3569*6777b538SAndroid Build Coastguard Worker 	             "htmlParseDocTypeDecl : no DOCTYPE name !\n",
3570*6777b538SAndroid Build Coastguard Worker 		     NULL, NULL);
3571*6777b538SAndroid Build Coastguard Worker     }
3572*6777b538SAndroid Build Coastguard Worker     /*
3573*6777b538SAndroid Build Coastguard Worker      * Check that upper(name) == "HTML" !!!!!!!!!!!!!
3574*6777b538SAndroid Build Coastguard Worker      */
3575*6777b538SAndroid Build Coastguard Worker 
3576*6777b538SAndroid Build Coastguard Worker     SKIP_BLANKS;
3577*6777b538SAndroid Build Coastguard Worker 
3578*6777b538SAndroid Build Coastguard Worker     /*
3579*6777b538SAndroid Build Coastguard Worker      * Check for SystemID and ExternalID
3580*6777b538SAndroid Build Coastguard Worker      */
3581*6777b538SAndroid Build Coastguard Worker     URI = htmlParseExternalID(ctxt, &ExternalID);
3582*6777b538SAndroid Build Coastguard Worker     SKIP_BLANKS;
3583*6777b538SAndroid Build Coastguard Worker 
3584*6777b538SAndroid Build Coastguard Worker     /*
3585*6777b538SAndroid Build Coastguard Worker      * We should be at the end of the DOCTYPE declaration.
3586*6777b538SAndroid Build Coastguard Worker      */
3587*6777b538SAndroid Build Coastguard Worker     if (CUR != '>') {
3588*6777b538SAndroid Build Coastguard Worker 	htmlParseErr(ctxt, XML_ERR_DOCTYPE_NOT_FINISHED,
3589*6777b538SAndroid Build Coastguard Worker 	             "DOCTYPE improperly terminated\n", NULL, NULL);
3590*6777b538SAndroid Build Coastguard Worker         /* Ignore bogus content */
3591*6777b538SAndroid Build Coastguard Worker         while ((CUR != 0) && (CUR != '>') &&
3592*6777b538SAndroid Build Coastguard Worker                (PARSER_STOPPED(ctxt) == 0))
3593*6777b538SAndroid Build Coastguard Worker             NEXT;
3594*6777b538SAndroid Build Coastguard Worker     }
3595*6777b538SAndroid Build Coastguard Worker     if (CUR == '>')
3596*6777b538SAndroid Build Coastguard Worker         NEXT;
3597*6777b538SAndroid Build Coastguard Worker 
3598*6777b538SAndroid Build Coastguard Worker     /*
3599*6777b538SAndroid Build Coastguard Worker      * Create or update the document accordingly to the DOCTYPE
3600*6777b538SAndroid Build Coastguard Worker      */
3601*6777b538SAndroid Build Coastguard Worker     if ((ctxt->sax != NULL) && (ctxt->sax->internalSubset != NULL) &&
3602*6777b538SAndroid Build Coastguard Worker 	(!ctxt->disableSAX))
3603*6777b538SAndroid Build Coastguard Worker 	ctxt->sax->internalSubset(ctxt->userData, name, ExternalID, URI);
3604*6777b538SAndroid Build Coastguard Worker 
3605*6777b538SAndroid Build Coastguard Worker     /*
3606*6777b538SAndroid Build Coastguard Worker      * Cleanup, since we don't use all those identifiers
3607*6777b538SAndroid Build Coastguard Worker      */
3608*6777b538SAndroid Build Coastguard Worker     if (URI != NULL) xmlFree(URI);
3609*6777b538SAndroid Build Coastguard Worker     if (ExternalID != NULL) xmlFree(ExternalID);
3610*6777b538SAndroid Build Coastguard Worker }
3611*6777b538SAndroid Build Coastguard Worker 
3612*6777b538SAndroid Build Coastguard Worker /**
3613*6777b538SAndroid Build Coastguard Worker  * htmlParseAttribute:
3614*6777b538SAndroid Build Coastguard Worker  * @ctxt:  an HTML parser context
3615*6777b538SAndroid Build Coastguard Worker  * @value:  a xmlChar ** used to store the value of the attribute
3616*6777b538SAndroid Build Coastguard Worker  *
3617*6777b538SAndroid Build Coastguard Worker  * parse an attribute
3618*6777b538SAndroid Build Coastguard Worker  *
3619*6777b538SAndroid Build Coastguard Worker  * [41] Attribute ::= Name Eq AttValue
3620*6777b538SAndroid Build Coastguard Worker  *
3621*6777b538SAndroid Build Coastguard Worker  * [25] Eq ::= S? '=' S?
3622*6777b538SAndroid Build Coastguard Worker  *
3623*6777b538SAndroid Build Coastguard Worker  * With namespace:
3624*6777b538SAndroid Build Coastguard Worker  *
3625*6777b538SAndroid Build Coastguard Worker  * [NS 11] Attribute ::= QName Eq AttValue
3626*6777b538SAndroid Build Coastguard Worker  *
3627*6777b538SAndroid Build Coastguard Worker  * Also the case QName == xmlns:??? is handled independently as a namespace
3628*6777b538SAndroid Build Coastguard Worker  * definition.
3629*6777b538SAndroid Build Coastguard Worker  *
3630*6777b538SAndroid Build Coastguard Worker  * Returns the attribute name, and the value in *value.
3631*6777b538SAndroid Build Coastguard Worker  */
3632*6777b538SAndroid Build Coastguard Worker 
3633*6777b538SAndroid Build Coastguard Worker static const xmlChar *
htmlParseAttribute(htmlParserCtxtPtr ctxt,xmlChar ** value)3634*6777b538SAndroid Build Coastguard Worker htmlParseAttribute(htmlParserCtxtPtr ctxt, xmlChar **value) {
3635*6777b538SAndroid Build Coastguard Worker     const xmlChar *name;
3636*6777b538SAndroid Build Coastguard Worker     xmlChar *val = NULL;
3637*6777b538SAndroid Build Coastguard Worker 
3638*6777b538SAndroid Build Coastguard Worker     *value = NULL;
3639*6777b538SAndroid Build Coastguard Worker     name = htmlParseHTMLName(ctxt);
3640*6777b538SAndroid Build Coastguard Worker     if (name == NULL) {
3641*6777b538SAndroid Build Coastguard Worker 	htmlParseErr(ctxt, XML_ERR_NAME_REQUIRED,
3642*6777b538SAndroid Build Coastguard Worker 	             "error parsing attribute name\n", NULL, NULL);
3643*6777b538SAndroid Build Coastguard Worker         return(NULL);
3644*6777b538SAndroid Build Coastguard Worker     }
3645*6777b538SAndroid Build Coastguard Worker 
3646*6777b538SAndroid Build Coastguard Worker     /*
3647*6777b538SAndroid Build Coastguard Worker      * read the value
3648*6777b538SAndroid Build Coastguard Worker      */
3649*6777b538SAndroid Build Coastguard Worker     SKIP_BLANKS;
3650*6777b538SAndroid Build Coastguard Worker     if (CUR == '=') {
3651*6777b538SAndroid Build Coastguard Worker         NEXT;
3652*6777b538SAndroid Build Coastguard Worker 	SKIP_BLANKS;
3653*6777b538SAndroid Build Coastguard Worker 	val = htmlParseAttValue(ctxt);
3654*6777b538SAndroid Build Coastguard Worker     }
3655*6777b538SAndroid Build Coastguard Worker 
3656*6777b538SAndroid Build Coastguard Worker     *value = val;
3657*6777b538SAndroid Build Coastguard Worker     return(name);
3658*6777b538SAndroid Build Coastguard Worker }
3659*6777b538SAndroid Build Coastguard Worker 
3660*6777b538SAndroid Build Coastguard Worker /**
3661*6777b538SAndroid Build Coastguard Worker  * htmlCheckEncoding:
3662*6777b538SAndroid Build Coastguard Worker  * @ctxt:  an HTML parser context
3663*6777b538SAndroid Build Coastguard Worker  * @attvalue: the attribute value
3664*6777b538SAndroid Build Coastguard Worker  *
3665*6777b538SAndroid Build Coastguard Worker  * Checks an http-equiv attribute from a Meta tag to detect
3666*6777b538SAndroid Build Coastguard Worker  * the encoding
3667*6777b538SAndroid Build Coastguard Worker  * If a new encoding is detected the parser is switched to decode
3668*6777b538SAndroid Build Coastguard Worker  * it and pass UTF8
3669*6777b538SAndroid Build Coastguard Worker  */
3670*6777b538SAndroid Build Coastguard Worker static void
htmlCheckEncoding(htmlParserCtxtPtr ctxt,const xmlChar * attvalue)3671*6777b538SAndroid Build Coastguard Worker htmlCheckEncoding(htmlParserCtxtPtr ctxt, const xmlChar *attvalue) {
3672*6777b538SAndroid Build Coastguard Worker     const xmlChar *encoding;
3673*6777b538SAndroid Build Coastguard Worker     xmlChar *copy;
3674*6777b538SAndroid Build Coastguard Worker 
3675*6777b538SAndroid Build Coastguard Worker     if (!attvalue)
3676*6777b538SAndroid Build Coastguard Worker 	return;
3677*6777b538SAndroid Build Coastguard Worker 
3678*6777b538SAndroid Build Coastguard Worker     encoding = xmlStrcasestr(attvalue, BAD_CAST"charset");
3679*6777b538SAndroid Build Coastguard Worker     if (encoding != NULL) {
3680*6777b538SAndroid Build Coastguard Worker 	encoding += 7;
3681*6777b538SAndroid Build Coastguard Worker     }
3682*6777b538SAndroid Build Coastguard Worker     /*
3683*6777b538SAndroid Build Coastguard Worker      * skip blank
3684*6777b538SAndroid Build Coastguard Worker      */
3685*6777b538SAndroid Build Coastguard Worker     if (encoding && IS_BLANK_CH(*encoding))
3686*6777b538SAndroid Build Coastguard Worker 	encoding = xmlStrcasestr(attvalue, BAD_CAST"=");
3687*6777b538SAndroid Build Coastguard Worker     if (encoding && *encoding == '=') {
3688*6777b538SAndroid Build Coastguard Worker 	encoding ++;
3689*6777b538SAndroid Build Coastguard Worker         copy = xmlStrdup(encoding);
3690*6777b538SAndroid Build Coastguard Worker         if (copy == NULL)
3691*6777b538SAndroid Build Coastguard Worker             htmlErrMemory(ctxt);
3692*6777b538SAndroid Build Coastguard Worker 	xmlSetDeclaredEncoding(ctxt, copy);
3693*6777b538SAndroid Build Coastguard Worker     }
3694*6777b538SAndroid Build Coastguard Worker }
3695*6777b538SAndroid Build Coastguard Worker 
3696*6777b538SAndroid Build Coastguard Worker /**
3697*6777b538SAndroid Build Coastguard Worker  * htmlCheckMeta:
3698*6777b538SAndroid Build Coastguard Worker  * @ctxt:  an HTML parser context
3699*6777b538SAndroid Build Coastguard Worker  * @atts:  the attributes values
3700*6777b538SAndroid Build Coastguard Worker  *
3701*6777b538SAndroid Build Coastguard Worker  * Checks an attributes from a Meta tag
3702*6777b538SAndroid Build Coastguard Worker  */
3703*6777b538SAndroid Build Coastguard Worker static void
htmlCheckMeta(htmlParserCtxtPtr ctxt,const xmlChar ** atts)3704*6777b538SAndroid Build Coastguard Worker htmlCheckMeta(htmlParserCtxtPtr ctxt, const xmlChar **atts) {
3705*6777b538SAndroid Build Coastguard Worker     int i;
3706*6777b538SAndroid Build Coastguard Worker     const xmlChar *att, *value;
3707*6777b538SAndroid Build Coastguard Worker     int http = 0;
3708*6777b538SAndroid Build Coastguard Worker     const xmlChar *content = NULL;
3709*6777b538SAndroid Build Coastguard Worker 
3710*6777b538SAndroid Build Coastguard Worker     if ((ctxt == NULL) || (atts == NULL))
3711*6777b538SAndroid Build Coastguard Worker 	return;
3712*6777b538SAndroid Build Coastguard Worker 
3713*6777b538SAndroid Build Coastguard Worker     i = 0;
3714*6777b538SAndroid Build Coastguard Worker     att = atts[i++];
3715*6777b538SAndroid Build Coastguard Worker     while (att != NULL) {
3716*6777b538SAndroid Build Coastguard Worker 	value = atts[i++];
3717*6777b538SAndroid Build Coastguard Worker         if (value != NULL) {
3718*6777b538SAndroid Build Coastguard Worker             if ((!xmlStrcasecmp(att, BAD_CAST "http-equiv")) &&
3719*6777b538SAndroid Build Coastguard Worker                 (!xmlStrcasecmp(value, BAD_CAST "Content-Type"))) {
3720*6777b538SAndroid Build Coastguard Worker                 http = 1;
3721*6777b538SAndroid Build Coastguard Worker             } else if (!xmlStrcasecmp(att, BAD_CAST "charset")) {
3722*6777b538SAndroid Build Coastguard Worker                 xmlChar *copy;
3723*6777b538SAndroid Build Coastguard Worker 
3724*6777b538SAndroid Build Coastguard Worker                 copy = xmlStrdup(value);
3725*6777b538SAndroid Build Coastguard Worker                 if (copy == NULL)
3726*6777b538SAndroid Build Coastguard Worker                     htmlErrMemory(ctxt);
3727*6777b538SAndroid Build Coastguard Worker                 xmlSetDeclaredEncoding(ctxt, copy);
3728*6777b538SAndroid Build Coastguard Worker             } else if (!xmlStrcasecmp(att, BAD_CAST "content")) {
3729*6777b538SAndroid Build Coastguard Worker                 content = value;
3730*6777b538SAndroid Build Coastguard Worker             }
3731*6777b538SAndroid Build Coastguard Worker         }
3732*6777b538SAndroid Build Coastguard Worker 	att = atts[i++];
3733*6777b538SAndroid Build Coastguard Worker     }
3734*6777b538SAndroid Build Coastguard Worker     if ((http) && (content != NULL))
3735*6777b538SAndroid Build Coastguard Worker 	htmlCheckEncoding(ctxt, content);
3736*6777b538SAndroid Build Coastguard Worker 
3737*6777b538SAndroid Build Coastguard Worker }
3738*6777b538SAndroid Build Coastguard Worker 
3739*6777b538SAndroid Build Coastguard Worker /**
3740*6777b538SAndroid Build Coastguard Worker  * htmlParseStartTag:
3741*6777b538SAndroid Build Coastguard Worker  * @ctxt:  an HTML parser context
3742*6777b538SAndroid Build Coastguard Worker  *
3743*6777b538SAndroid Build Coastguard Worker  * parse a start of tag either for rule element or
3744*6777b538SAndroid Build Coastguard Worker  * EmptyElement. In both case we don't parse the tag closing chars.
3745*6777b538SAndroid Build Coastguard Worker  *
3746*6777b538SAndroid Build Coastguard Worker  * [40] STag ::= '<' Name (S Attribute)* S? '>'
3747*6777b538SAndroid Build Coastguard Worker  *
3748*6777b538SAndroid Build Coastguard Worker  * [44] EmptyElemTag ::= '<' Name (S Attribute)* S? '/>'
3749*6777b538SAndroid Build Coastguard Worker  *
3750*6777b538SAndroid Build Coastguard Worker  * With namespace:
3751*6777b538SAndroid Build Coastguard Worker  *
3752*6777b538SAndroid Build Coastguard Worker  * [NS 8] STag ::= '<' QName (S Attribute)* S? '>'
3753*6777b538SAndroid Build Coastguard Worker  *
3754*6777b538SAndroid Build Coastguard Worker  * [NS 10] EmptyElement ::= '<' QName (S Attribute)* S? '/>'
3755*6777b538SAndroid Build Coastguard Worker  *
3756*6777b538SAndroid Build Coastguard Worker  * Returns 0 in case of success, -1 in case of error and 1 if discarded
3757*6777b538SAndroid Build Coastguard Worker  */
3758*6777b538SAndroid Build Coastguard Worker 
3759*6777b538SAndroid Build Coastguard Worker static int
htmlParseStartTag(htmlParserCtxtPtr ctxt)3760*6777b538SAndroid Build Coastguard Worker htmlParseStartTag(htmlParserCtxtPtr ctxt) {
3761*6777b538SAndroid Build Coastguard Worker     const xmlChar *name;
3762*6777b538SAndroid Build Coastguard Worker     const xmlChar *attname;
3763*6777b538SAndroid Build Coastguard Worker     xmlChar *attvalue;
3764*6777b538SAndroid Build Coastguard Worker     const xmlChar **atts;
3765*6777b538SAndroid Build Coastguard Worker     int nbatts = 0;
3766*6777b538SAndroid Build Coastguard Worker     int maxatts;
3767*6777b538SAndroid Build Coastguard Worker     int meta = 0;
3768*6777b538SAndroid Build Coastguard Worker     int i;
3769*6777b538SAndroid Build Coastguard Worker     int discardtag = 0;
3770*6777b538SAndroid Build Coastguard Worker 
3771*6777b538SAndroid Build Coastguard Worker     if ((ctxt == NULL) || (ctxt->input == NULL))
3772*6777b538SAndroid Build Coastguard Worker 	return -1;
3773*6777b538SAndroid Build Coastguard Worker     if (CUR != '<') return -1;
3774*6777b538SAndroid Build Coastguard Worker     NEXT;
3775*6777b538SAndroid Build Coastguard Worker 
3776*6777b538SAndroid Build Coastguard Worker     atts = ctxt->atts;
3777*6777b538SAndroid Build Coastguard Worker     maxatts = ctxt->maxatts;
3778*6777b538SAndroid Build Coastguard Worker 
3779*6777b538SAndroid Build Coastguard Worker     GROW;
3780*6777b538SAndroid Build Coastguard Worker     name = htmlParseHTMLName(ctxt);
3781*6777b538SAndroid Build Coastguard Worker     if (name == NULL) {
3782*6777b538SAndroid Build Coastguard Worker 	htmlParseErr(ctxt, XML_ERR_NAME_REQUIRED,
3783*6777b538SAndroid Build Coastguard Worker 	             "htmlParseStartTag: invalid element name\n",
3784*6777b538SAndroid Build Coastguard Worker 		     NULL, NULL);
3785*6777b538SAndroid Build Coastguard Worker 	/* Dump the bogus tag like browsers do */
3786*6777b538SAndroid Build Coastguard Worker 	while ((CUR != 0) && (CUR != '>') &&
3787*6777b538SAndroid Build Coastguard Worker                (PARSER_STOPPED(ctxt) == 0))
3788*6777b538SAndroid Build Coastguard Worker 	    NEXT;
3789*6777b538SAndroid Build Coastguard Worker         return -1;
3790*6777b538SAndroid Build Coastguard Worker     }
3791*6777b538SAndroid Build Coastguard Worker     if (xmlStrEqual(name, BAD_CAST"meta"))
3792*6777b538SAndroid Build Coastguard Worker 	meta = 1;
3793*6777b538SAndroid Build Coastguard Worker 
3794*6777b538SAndroid Build Coastguard Worker     /*
3795*6777b538SAndroid Build Coastguard Worker      * Check for auto-closure of HTML elements.
3796*6777b538SAndroid Build Coastguard Worker      */
3797*6777b538SAndroid Build Coastguard Worker     htmlAutoClose(ctxt, name);
3798*6777b538SAndroid Build Coastguard Worker 
3799*6777b538SAndroid Build Coastguard Worker     /*
3800*6777b538SAndroid Build Coastguard Worker      * Check for implied HTML elements.
3801*6777b538SAndroid Build Coastguard Worker      */
3802*6777b538SAndroid Build Coastguard Worker     htmlCheckImplied(ctxt, name);
3803*6777b538SAndroid Build Coastguard Worker 
3804*6777b538SAndroid Build Coastguard Worker     /*
3805*6777b538SAndroid Build Coastguard Worker      * Avoid html at any level > 0, head at any level != 1
3806*6777b538SAndroid Build Coastguard Worker      * or any attempt to recurse body
3807*6777b538SAndroid Build Coastguard Worker      */
3808*6777b538SAndroid Build Coastguard Worker     if ((ctxt->nameNr > 0) && (xmlStrEqual(name, BAD_CAST"html"))) {
3809*6777b538SAndroid Build Coastguard Worker 	htmlParseErr(ctxt, XML_HTML_STRUCURE_ERROR,
3810*6777b538SAndroid Build Coastguard Worker 	             "htmlParseStartTag: misplaced <html> tag\n",
3811*6777b538SAndroid Build Coastguard Worker 		     name, NULL);
3812*6777b538SAndroid Build Coastguard Worker 	discardtag = 1;
3813*6777b538SAndroid Build Coastguard Worker 	ctxt->depth++;
3814*6777b538SAndroid Build Coastguard Worker     }
3815*6777b538SAndroid Build Coastguard Worker     if ((ctxt->nameNr != 1) &&
3816*6777b538SAndroid Build Coastguard Worker 	(xmlStrEqual(name, BAD_CAST"head"))) {
3817*6777b538SAndroid Build Coastguard Worker 	htmlParseErr(ctxt, XML_HTML_STRUCURE_ERROR,
3818*6777b538SAndroid Build Coastguard Worker 	             "htmlParseStartTag: misplaced <head> tag\n",
3819*6777b538SAndroid Build Coastguard Worker 		     name, NULL);
3820*6777b538SAndroid Build Coastguard Worker 	discardtag = 1;
3821*6777b538SAndroid Build Coastguard Worker 	ctxt->depth++;
3822*6777b538SAndroid Build Coastguard Worker     }
3823*6777b538SAndroid Build Coastguard Worker     if (xmlStrEqual(name, BAD_CAST"body")) {
3824*6777b538SAndroid Build Coastguard Worker 	int indx;
3825*6777b538SAndroid Build Coastguard Worker 	for (indx = 0;indx < ctxt->nameNr;indx++) {
3826*6777b538SAndroid Build Coastguard Worker 	    if (xmlStrEqual(ctxt->nameTab[indx], BAD_CAST"body")) {
3827*6777b538SAndroid Build Coastguard Worker 		htmlParseErr(ctxt, XML_HTML_STRUCURE_ERROR,
3828*6777b538SAndroid Build Coastguard Worker 		             "htmlParseStartTag: misplaced <body> tag\n",
3829*6777b538SAndroid Build Coastguard Worker 			     name, NULL);
3830*6777b538SAndroid Build Coastguard Worker 		discardtag = 1;
3831*6777b538SAndroid Build Coastguard Worker 		ctxt->depth++;
3832*6777b538SAndroid Build Coastguard Worker 	    }
3833*6777b538SAndroid Build Coastguard Worker 	}
3834*6777b538SAndroid Build Coastguard Worker     }
3835*6777b538SAndroid Build Coastguard Worker 
3836*6777b538SAndroid Build Coastguard Worker     /*
3837*6777b538SAndroid Build Coastguard Worker      * Now parse the attributes, it ends up with the ending
3838*6777b538SAndroid Build Coastguard Worker      *
3839*6777b538SAndroid Build Coastguard Worker      * (S Attribute)* S?
3840*6777b538SAndroid Build Coastguard Worker      */
3841*6777b538SAndroid Build Coastguard Worker     SKIP_BLANKS;
3842*6777b538SAndroid Build Coastguard Worker     while ((CUR != 0) &&
3843*6777b538SAndroid Build Coastguard Worker            (CUR != '>') &&
3844*6777b538SAndroid Build Coastguard Worker 	   ((CUR != '/') || (NXT(1) != '>')) &&
3845*6777b538SAndroid Build Coastguard Worker            (PARSER_STOPPED(ctxt) == 0)) {
3846*6777b538SAndroid Build Coastguard Worker 	GROW;
3847*6777b538SAndroid Build Coastguard Worker 	attname = htmlParseAttribute(ctxt, &attvalue);
3848*6777b538SAndroid Build Coastguard Worker         if (attname != NULL) {
3849*6777b538SAndroid Build Coastguard Worker 
3850*6777b538SAndroid Build Coastguard Worker 	    /*
3851*6777b538SAndroid Build Coastguard Worker 	     * Well formedness requires at most one declaration of an attribute
3852*6777b538SAndroid Build Coastguard Worker 	     */
3853*6777b538SAndroid Build Coastguard Worker 	    for (i = 0; i < nbatts;i += 2) {
3854*6777b538SAndroid Build Coastguard Worker 	        if (xmlStrEqual(atts[i], attname)) {
3855*6777b538SAndroid Build Coastguard Worker 		    htmlParseErr(ctxt, XML_ERR_ATTRIBUTE_REDEFINED,
3856*6777b538SAndroid Build Coastguard Worker 		                 "Attribute %s redefined\n", attname, NULL);
3857*6777b538SAndroid Build Coastguard Worker 		    if (attvalue != NULL)
3858*6777b538SAndroid Build Coastguard Worker 			xmlFree(attvalue);
3859*6777b538SAndroid Build Coastguard Worker 		    goto failed;
3860*6777b538SAndroid Build Coastguard Worker 		}
3861*6777b538SAndroid Build Coastguard Worker 	    }
3862*6777b538SAndroid Build Coastguard Worker 
3863*6777b538SAndroid Build Coastguard Worker 	    /*
3864*6777b538SAndroid Build Coastguard Worker 	     * Add the pair to atts
3865*6777b538SAndroid Build Coastguard Worker 	     */
3866*6777b538SAndroid Build Coastguard Worker 	    if (atts == NULL) {
3867*6777b538SAndroid Build Coastguard Worker 	        maxatts = 22; /* allow for 10 attrs by default */
3868*6777b538SAndroid Build Coastguard Worker 	        atts = (const xmlChar **)
3869*6777b538SAndroid Build Coastguard Worker 		       xmlMalloc(maxatts * sizeof(xmlChar *));
3870*6777b538SAndroid Build Coastguard Worker 		if (atts == NULL) {
3871*6777b538SAndroid Build Coastguard Worker 		    htmlErrMemory(ctxt);
3872*6777b538SAndroid Build Coastguard Worker 		    if (attvalue != NULL)
3873*6777b538SAndroid Build Coastguard Worker 			xmlFree(attvalue);
3874*6777b538SAndroid Build Coastguard Worker 		    goto failed;
3875*6777b538SAndroid Build Coastguard Worker 		}
3876*6777b538SAndroid Build Coastguard Worker 		ctxt->atts = atts;
3877*6777b538SAndroid Build Coastguard Worker 		ctxt->maxatts = maxatts;
3878*6777b538SAndroid Build Coastguard Worker 	    } else if (nbatts + 4 > maxatts) {
3879*6777b538SAndroid Build Coastguard Worker 	        const xmlChar **n;
3880*6777b538SAndroid Build Coastguard Worker 
3881*6777b538SAndroid Build Coastguard Worker 	        maxatts *= 2;
3882*6777b538SAndroid Build Coastguard Worker 	        n = (const xmlChar **) xmlRealloc((void *) atts,
3883*6777b538SAndroid Build Coastguard Worker 					     maxatts * sizeof(const xmlChar *));
3884*6777b538SAndroid Build Coastguard Worker 		if (n == NULL) {
3885*6777b538SAndroid Build Coastguard Worker 		    htmlErrMemory(ctxt);
3886*6777b538SAndroid Build Coastguard Worker 		    if (attvalue != NULL)
3887*6777b538SAndroid Build Coastguard Worker 			xmlFree(attvalue);
3888*6777b538SAndroid Build Coastguard Worker 		    goto failed;
3889*6777b538SAndroid Build Coastguard Worker 		}
3890*6777b538SAndroid Build Coastguard Worker 		atts = n;
3891*6777b538SAndroid Build Coastguard Worker 		ctxt->atts = atts;
3892*6777b538SAndroid Build Coastguard Worker 		ctxt->maxatts = maxatts;
3893*6777b538SAndroid Build Coastguard Worker 	    }
3894*6777b538SAndroid Build Coastguard Worker 	    atts[nbatts++] = attname;
3895*6777b538SAndroid Build Coastguard Worker 	    atts[nbatts++] = attvalue;
3896*6777b538SAndroid Build Coastguard Worker 	    atts[nbatts] = NULL;
3897*6777b538SAndroid Build Coastguard Worker 	    atts[nbatts + 1] = NULL;
3898*6777b538SAndroid Build Coastguard Worker 	}
3899*6777b538SAndroid Build Coastguard Worker 	else {
3900*6777b538SAndroid Build Coastguard Worker 	    if (attvalue != NULL)
3901*6777b538SAndroid Build Coastguard Worker 	        xmlFree(attvalue);
3902*6777b538SAndroid Build Coastguard Worker 	    /* Dump the bogus attribute string up to the next blank or
3903*6777b538SAndroid Build Coastguard Worker 	     * the end of the tag. */
3904*6777b538SAndroid Build Coastguard Worker 	    while ((CUR != 0) &&
3905*6777b538SAndroid Build Coastguard Worker 	           !(IS_BLANK_CH(CUR)) && (CUR != '>') &&
3906*6777b538SAndroid Build Coastguard Worker 		   ((CUR != '/') || (NXT(1) != '>')) &&
3907*6777b538SAndroid Build Coastguard Worker                    (PARSER_STOPPED(ctxt) == 0))
3908*6777b538SAndroid Build Coastguard Worker 		NEXT;
3909*6777b538SAndroid Build Coastguard Worker 	}
3910*6777b538SAndroid Build Coastguard Worker 
3911*6777b538SAndroid Build Coastguard Worker failed:
3912*6777b538SAndroid Build Coastguard Worker 	SKIP_BLANKS;
3913*6777b538SAndroid Build Coastguard Worker     }
3914*6777b538SAndroid Build Coastguard Worker 
3915*6777b538SAndroid Build Coastguard Worker     /*
3916*6777b538SAndroid Build Coastguard Worker      * Handle specific association to the META tag
3917*6777b538SAndroid Build Coastguard Worker      */
3918*6777b538SAndroid Build Coastguard Worker     if (meta && (nbatts != 0))
3919*6777b538SAndroid Build Coastguard Worker 	htmlCheckMeta(ctxt, atts);
3920*6777b538SAndroid Build Coastguard Worker 
3921*6777b538SAndroid Build Coastguard Worker     /*
3922*6777b538SAndroid Build Coastguard Worker      * SAX: Start of Element !
3923*6777b538SAndroid Build Coastguard Worker      */
3924*6777b538SAndroid Build Coastguard Worker     if (!discardtag) {
3925*6777b538SAndroid Build Coastguard Worker 	htmlnamePush(ctxt, name);
3926*6777b538SAndroid Build Coastguard Worker 	if ((ctxt->sax != NULL) && (ctxt->sax->startElement != NULL)) {
3927*6777b538SAndroid Build Coastguard Worker 	    if (nbatts != 0)
3928*6777b538SAndroid Build Coastguard Worker 		ctxt->sax->startElement(ctxt->userData, name, atts);
3929*6777b538SAndroid Build Coastguard Worker 	    else
3930*6777b538SAndroid Build Coastguard Worker 		ctxt->sax->startElement(ctxt->userData, name, NULL);
3931*6777b538SAndroid Build Coastguard Worker 	}
3932*6777b538SAndroid Build Coastguard Worker     }
3933*6777b538SAndroid Build Coastguard Worker 
3934*6777b538SAndroid Build Coastguard Worker     if (atts != NULL) {
3935*6777b538SAndroid Build Coastguard Worker         for (i = 1;i < nbatts;i += 2) {
3936*6777b538SAndroid Build Coastguard Worker 	    if (atts[i] != NULL)
3937*6777b538SAndroid Build Coastguard Worker 		xmlFree((xmlChar *) atts[i]);
3938*6777b538SAndroid Build Coastguard Worker 	}
3939*6777b538SAndroid Build Coastguard Worker     }
3940*6777b538SAndroid Build Coastguard Worker 
3941*6777b538SAndroid Build Coastguard Worker     return(discardtag);
3942*6777b538SAndroid Build Coastguard Worker }
3943*6777b538SAndroid Build Coastguard Worker 
3944*6777b538SAndroid Build Coastguard Worker /**
3945*6777b538SAndroid Build Coastguard Worker  * htmlParseEndTag:
3946*6777b538SAndroid Build Coastguard Worker  * @ctxt:  an HTML parser context
3947*6777b538SAndroid Build Coastguard Worker  *
3948*6777b538SAndroid Build Coastguard Worker  * parse an end of tag
3949*6777b538SAndroid Build Coastguard Worker  *
3950*6777b538SAndroid Build Coastguard Worker  * [42] ETag ::= '</' Name S? '>'
3951*6777b538SAndroid Build Coastguard Worker  *
3952*6777b538SAndroid Build Coastguard Worker  * With namespace
3953*6777b538SAndroid Build Coastguard Worker  *
3954*6777b538SAndroid Build Coastguard Worker  * [NS 9] ETag ::= '</' QName S? '>'
3955*6777b538SAndroid Build Coastguard Worker  *
3956*6777b538SAndroid Build Coastguard Worker  * Returns 1 if the current level should be closed.
3957*6777b538SAndroid Build Coastguard Worker  */
3958*6777b538SAndroid Build Coastguard Worker 
3959*6777b538SAndroid Build Coastguard Worker static int
htmlParseEndTag(htmlParserCtxtPtr ctxt)3960*6777b538SAndroid Build Coastguard Worker htmlParseEndTag(htmlParserCtxtPtr ctxt)
3961*6777b538SAndroid Build Coastguard Worker {
3962*6777b538SAndroid Build Coastguard Worker     const xmlChar *name;
3963*6777b538SAndroid Build Coastguard Worker     const xmlChar *oldname;
3964*6777b538SAndroid Build Coastguard Worker     int i, ret;
3965*6777b538SAndroid Build Coastguard Worker 
3966*6777b538SAndroid Build Coastguard Worker     if ((CUR != '<') || (NXT(1) != '/')) {
3967*6777b538SAndroid Build Coastguard Worker         htmlParseErr(ctxt, XML_ERR_LTSLASH_REQUIRED,
3968*6777b538SAndroid Build Coastguard Worker 	             "htmlParseEndTag: '</' not found\n", NULL, NULL);
3969*6777b538SAndroid Build Coastguard Worker         return (0);
3970*6777b538SAndroid Build Coastguard Worker     }
3971*6777b538SAndroid Build Coastguard Worker     SKIP(2);
3972*6777b538SAndroid Build Coastguard Worker 
3973*6777b538SAndroid Build Coastguard Worker     name = htmlParseHTMLName(ctxt);
3974*6777b538SAndroid Build Coastguard Worker     if (name == NULL)
3975*6777b538SAndroid Build Coastguard Worker         return (0);
3976*6777b538SAndroid Build Coastguard Worker     /*
3977*6777b538SAndroid Build Coastguard Worker      * We should definitely be at the ending "S? '>'" part
3978*6777b538SAndroid Build Coastguard Worker      */
3979*6777b538SAndroid Build Coastguard Worker     SKIP_BLANKS;
3980*6777b538SAndroid Build Coastguard Worker     if (CUR != '>') {
3981*6777b538SAndroid Build Coastguard Worker         htmlParseErr(ctxt, XML_ERR_GT_REQUIRED,
3982*6777b538SAndroid Build Coastguard Worker 	             "End tag : expected '>'\n", NULL, NULL);
3983*6777b538SAndroid Build Coastguard Worker         /* Skip to next '>' */
3984*6777b538SAndroid Build Coastguard Worker         while ((PARSER_STOPPED(ctxt) == 0) &&
3985*6777b538SAndroid Build Coastguard Worker                (CUR != 0) && (CUR != '>'))
3986*6777b538SAndroid Build Coastguard Worker             NEXT;
3987*6777b538SAndroid Build Coastguard Worker     }
3988*6777b538SAndroid Build Coastguard Worker     if (CUR == '>')
3989*6777b538SAndroid Build Coastguard Worker         NEXT;
3990*6777b538SAndroid Build Coastguard Worker 
3991*6777b538SAndroid Build Coastguard Worker     /*
3992*6777b538SAndroid Build Coastguard Worker      * if we ignored misplaced tags in htmlParseStartTag don't pop them
3993*6777b538SAndroid Build Coastguard Worker      * out now.
3994*6777b538SAndroid Build Coastguard Worker      */
3995*6777b538SAndroid Build Coastguard Worker     if ((ctxt->depth > 0) &&
3996*6777b538SAndroid Build Coastguard Worker         (xmlStrEqual(name, BAD_CAST "html") ||
3997*6777b538SAndroid Build Coastguard Worker          xmlStrEqual(name, BAD_CAST "body") ||
3998*6777b538SAndroid Build Coastguard Worker 	 xmlStrEqual(name, BAD_CAST "head"))) {
3999*6777b538SAndroid Build Coastguard Worker 	ctxt->depth--;
4000*6777b538SAndroid Build Coastguard Worker 	return (0);
4001*6777b538SAndroid Build Coastguard Worker     }
4002*6777b538SAndroid Build Coastguard Worker 
4003*6777b538SAndroid Build Coastguard Worker     /*
4004*6777b538SAndroid Build Coastguard Worker      * If the name read is not one of the element in the parsing stack
4005*6777b538SAndroid Build Coastguard Worker      * then return, it's just an error.
4006*6777b538SAndroid Build Coastguard Worker      */
4007*6777b538SAndroid Build Coastguard Worker     for (i = (ctxt->nameNr - 1); i >= 0; i--) {
4008*6777b538SAndroid Build Coastguard Worker         if (xmlStrEqual(name, ctxt->nameTab[i]))
4009*6777b538SAndroid Build Coastguard Worker             break;
4010*6777b538SAndroid Build Coastguard Worker     }
4011*6777b538SAndroid Build Coastguard Worker     if (i < 0) {
4012*6777b538SAndroid Build Coastguard Worker         htmlParseErr(ctxt, XML_ERR_TAG_NAME_MISMATCH,
4013*6777b538SAndroid Build Coastguard Worker 	             "Unexpected end tag : %s\n", name, NULL);
4014*6777b538SAndroid Build Coastguard Worker         return (0);
4015*6777b538SAndroid Build Coastguard Worker     }
4016*6777b538SAndroid Build Coastguard Worker 
4017*6777b538SAndroid Build Coastguard Worker 
4018*6777b538SAndroid Build Coastguard Worker     /*
4019*6777b538SAndroid Build Coastguard Worker      * Check for auto-closure of HTML elements.
4020*6777b538SAndroid Build Coastguard Worker      */
4021*6777b538SAndroid Build Coastguard Worker 
4022*6777b538SAndroid Build Coastguard Worker     htmlAutoCloseOnClose(ctxt, name);
4023*6777b538SAndroid Build Coastguard Worker 
4024*6777b538SAndroid Build Coastguard Worker     /*
4025*6777b538SAndroid Build Coastguard Worker      * Well formedness constraints, opening and closing must match.
4026*6777b538SAndroid Build Coastguard Worker      * With the exception that the autoclose may have popped stuff out
4027*6777b538SAndroid Build Coastguard Worker      * of the stack.
4028*6777b538SAndroid Build Coastguard Worker      */
4029*6777b538SAndroid Build Coastguard Worker     if ((ctxt->name != NULL) && (!xmlStrEqual(ctxt->name, name))) {
4030*6777b538SAndroid Build Coastguard Worker         htmlParseErr(ctxt, XML_ERR_TAG_NAME_MISMATCH,
4031*6777b538SAndroid Build Coastguard Worker                      "Opening and ending tag mismatch: %s and %s\n",
4032*6777b538SAndroid Build Coastguard Worker                      name, ctxt->name);
4033*6777b538SAndroid Build Coastguard Worker     }
4034*6777b538SAndroid Build Coastguard Worker 
4035*6777b538SAndroid Build Coastguard Worker     /*
4036*6777b538SAndroid Build Coastguard Worker      * SAX: End of Tag
4037*6777b538SAndroid Build Coastguard Worker      */
4038*6777b538SAndroid Build Coastguard Worker     oldname = ctxt->name;
4039*6777b538SAndroid Build Coastguard Worker     if ((oldname != NULL) && (xmlStrEqual(oldname, name))) {
4040*6777b538SAndroid Build Coastguard Worker         if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
4041*6777b538SAndroid Build Coastguard Worker             ctxt->sax->endElement(ctxt->userData, name);
4042*6777b538SAndroid Build Coastguard Worker 	htmlNodeInfoPop(ctxt);
4043*6777b538SAndroid Build Coastguard Worker         htmlnamePop(ctxt);
4044*6777b538SAndroid Build Coastguard Worker         ret = 1;
4045*6777b538SAndroid Build Coastguard Worker     } else {
4046*6777b538SAndroid Build Coastguard Worker         ret = 0;
4047*6777b538SAndroid Build Coastguard Worker     }
4048*6777b538SAndroid Build Coastguard Worker 
4049*6777b538SAndroid Build Coastguard Worker     return (ret);
4050*6777b538SAndroid Build Coastguard Worker }
4051*6777b538SAndroid Build Coastguard Worker 
4052*6777b538SAndroid Build Coastguard Worker 
4053*6777b538SAndroid Build Coastguard Worker /**
4054*6777b538SAndroid Build Coastguard Worker  * htmlParseReference:
4055*6777b538SAndroid Build Coastguard Worker  * @ctxt:  an HTML parser context
4056*6777b538SAndroid Build Coastguard Worker  *
4057*6777b538SAndroid Build Coastguard Worker  * parse and handle entity references in content,
4058*6777b538SAndroid Build Coastguard Worker  * this will end-up in a call to character() since this is either a
4059*6777b538SAndroid Build Coastguard Worker  * CharRef, or a predefined entity.
4060*6777b538SAndroid Build Coastguard Worker  */
4061*6777b538SAndroid Build Coastguard Worker static void
htmlParseReference(htmlParserCtxtPtr ctxt)4062*6777b538SAndroid Build Coastguard Worker htmlParseReference(htmlParserCtxtPtr ctxt) {
4063*6777b538SAndroid Build Coastguard Worker     const htmlEntityDesc * ent;
4064*6777b538SAndroid Build Coastguard Worker     xmlChar out[6];
4065*6777b538SAndroid Build Coastguard Worker     const xmlChar *name;
4066*6777b538SAndroid Build Coastguard Worker     if (CUR != '&') return;
4067*6777b538SAndroid Build Coastguard Worker 
4068*6777b538SAndroid Build Coastguard Worker     if (NXT(1) == '#') {
4069*6777b538SAndroid Build Coastguard Worker 	unsigned int c;
4070*6777b538SAndroid Build Coastguard Worker 	int bits, i = 0;
4071*6777b538SAndroid Build Coastguard Worker 
4072*6777b538SAndroid Build Coastguard Worker 	c = htmlParseCharRef(ctxt);
4073*6777b538SAndroid Build Coastguard Worker 	if (c == 0)
4074*6777b538SAndroid Build Coastguard Worker 	    return;
4075*6777b538SAndroid Build Coastguard Worker 
4076*6777b538SAndroid Build Coastguard Worker         if      (c <    0x80) { out[i++]= c;                bits= -6; }
4077*6777b538SAndroid Build Coastguard Worker         else if (c <   0x800) { out[i++]=((c >>  6) & 0x1F) | 0xC0;  bits=  0; }
4078*6777b538SAndroid Build Coastguard Worker         else if (c < 0x10000) { out[i++]=((c >> 12) & 0x0F) | 0xE0;  bits=  6; }
4079*6777b538SAndroid Build Coastguard Worker         else                  { out[i++]=((c >> 18) & 0x07) | 0xF0;  bits= 12; }
4080*6777b538SAndroid Build Coastguard Worker 
4081*6777b538SAndroid Build Coastguard Worker         for ( ; bits >= 0; bits-= 6) {
4082*6777b538SAndroid Build Coastguard Worker             out[i++]= ((c >> bits) & 0x3F) | 0x80;
4083*6777b538SAndroid Build Coastguard Worker         }
4084*6777b538SAndroid Build Coastguard Worker 	out[i] = 0;
4085*6777b538SAndroid Build Coastguard Worker 
4086*6777b538SAndroid Build Coastguard Worker 	htmlCheckParagraph(ctxt);
4087*6777b538SAndroid Build Coastguard Worker 	if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL))
4088*6777b538SAndroid Build Coastguard Worker 	    ctxt->sax->characters(ctxt->userData, out, i);
4089*6777b538SAndroid Build Coastguard Worker     } else {
4090*6777b538SAndroid Build Coastguard Worker 	ent = htmlParseEntityRef(ctxt, &name);
4091*6777b538SAndroid Build Coastguard Worker 	if (name == NULL) {
4092*6777b538SAndroid Build Coastguard Worker 	    htmlCheckParagraph(ctxt);
4093*6777b538SAndroid Build Coastguard Worker 	    if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL))
4094*6777b538SAndroid Build Coastguard Worker 	        ctxt->sax->characters(ctxt->userData, BAD_CAST "&", 1);
4095*6777b538SAndroid Build Coastguard Worker 	    return;
4096*6777b538SAndroid Build Coastguard Worker 	}
4097*6777b538SAndroid Build Coastguard Worker 	if ((ent == NULL) || !(ent->value > 0)) {
4098*6777b538SAndroid Build Coastguard Worker 	    htmlCheckParagraph(ctxt);
4099*6777b538SAndroid Build Coastguard Worker 	    if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL)) {
4100*6777b538SAndroid Build Coastguard Worker 		ctxt->sax->characters(ctxt->userData, BAD_CAST "&", 1);
4101*6777b538SAndroid Build Coastguard Worker 		ctxt->sax->characters(ctxt->userData, name, xmlStrlen(name));
4102*6777b538SAndroid Build Coastguard Worker 		/* ctxt->sax->characters(ctxt->userData, BAD_CAST ";", 1); */
4103*6777b538SAndroid Build Coastguard Worker 	    }
4104*6777b538SAndroid Build Coastguard Worker 	} else {
4105*6777b538SAndroid Build Coastguard Worker 	    unsigned int c;
4106*6777b538SAndroid Build Coastguard Worker 	    int bits, i = 0;
4107*6777b538SAndroid Build Coastguard Worker 
4108*6777b538SAndroid Build Coastguard Worker 	    c = ent->value;
4109*6777b538SAndroid Build Coastguard Worker 	    if      (c <    0x80)
4110*6777b538SAndroid Build Coastguard Worker 	            { out[i++]= c;                bits= -6; }
4111*6777b538SAndroid Build Coastguard Worker 	    else if (c <   0x800)
4112*6777b538SAndroid Build Coastguard Worker 	            { out[i++]=((c >>  6) & 0x1F) | 0xC0;  bits=  0; }
4113*6777b538SAndroid Build Coastguard Worker 	    else if (c < 0x10000)
4114*6777b538SAndroid Build Coastguard Worker 	            { out[i++]=((c >> 12) & 0x0F) | 0xE0;  bits=  6; }
4115*6777b538SAndroid Build Coastguard Worker 	    else
4116*6777b538SAndroid Build Coastguard Worker 	            { out[i++]=((c >> 18) & 0x07) | 0xF0;  bits= 12; }
4117*6777b538SAndroid Build Coastguard Worker 
4118*6777b538SAndroid Build Coastguard Worker 	    for ( ; bits >= 0; bits-= 6) {
4119*6777b538SAndroid Build Coastguard Worker 		out[i++]= ((c >> bits) & 0x3F) | 0x80;
4120*6777b538SAndroid Build Coastguard Worker 	    }
4121*6777b538SAndroid Build Coastguard Worker 	    out[i] = 0;
4122*6777b538SAndroid Build Coastguard Worker 
4123*6777b538SAndroid Build Coastguard Worker 	    htmlCheckParagraph(ctxt);
4124*6777b538SAndroid Build Coastguard Worker 	    if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL))
4125*6777b538SAndroid Build Coastguard Worker 		ctxt->sax->characters(ctxt->userData, out, i);
4126*6777b538SAndroid Build Coastguard Worker 	}
4127*6777b538SAndroid Build Coastguard Worker     }
4128*6777b538SAndroid Build Coastguard Worker }
4129*6777b538SAndroid Build Coastguard Worker 
4130*6777b538SAndroid Build Coastguard Worker /**
4131*6777b538SAndroid Build Coastguard Worker  * htmlParseContent:
4132*6777b538SAndroid Build Coastguard Worker  * @ctxt:  an HTML parser context
4133*6777b538SAndroid Build Coastguard Worker  *
4134*6777b538SAndroid Build Coastguard Worker  * Parse a content: comment, sub-element, reference or text.
4135*6777b538SAndroid Build Coastguard Worker  * Kept for compatibility with old code
4136*6777b538SAndroid Build Coastguard Worker  */
4137*6777b538SAndroid Build Coastguard Worker 
4138*6777b538SAndroid Build Coastguard Worker static void
htmlParseContent(htmlParserCtxtPtr ctxt)4139*6777b538SAndroid Build Coastguard Worker htmlParseContent(htmlParserCtxtPtr ctxt) {
4140*6777b538SAndroid Build Coastguard Worker     xmlChar *currentNode;
4141*6777b538SAndroid Build Coastguard Worker     int depth;
4142*6777b538SAndroid Build Coastguard Worker     const xmlChar *name;
4143*6777b538SAndroid Build Coastguard Worker 
4144*6777b538SAndroid Build Coastguard Worker     currentNode = xmlStrdup(ctxt->name);
4145*6777b538SAndroid Build Coastguard Worker     depth = ctxt->nameNr;
4146*6777b538SAndroid Build Coastguard Worker     while (!PARSER_STOPPED(ctxt)) {
4147*6777b538SAndroid Build Coastguard Worker         GROW;
4148*6777b538SAndroid Build Coastguard Worker 
4149*6777b538SAndroid Build Coastguard Worker 	/*
4150*6777b538SAndroid Build Coastguard Worker 	 * Our tag or one of it's parent or children is ending.
4151*6777b538SAndroid Build Coastguard Worker 	 */
4152*6777b538SAndroid Build Coastguard Worker         if ((CUR == '<') && (NXT(1) == '/')) {
4153*6777b538SAndroid Build Coastguard Worker 	    if (htmlParseEndTag(ctxt) &&
4154*6777b538SAndroid Build Coastguard Worker 		((currentNode != NULL) || (ctxt->nameNr == 0))) {
4155*6777b538SAndroid Build Coastguard Worker 		if (currentNode != NULL)
4156*6777b538SAndroid Build Coastguard Worker 		    xmlFree(currentNode);
4157*6777b538SAndroid Build Coastguard Worker 		return;
4158*6777b538SAndroid Build Coastguard Worker 	    }
4159*6777b538SAndroid Build Coastguard Worker 	    continue; /* while */
4160*6777b538SAndroid Build Coastguard Worker         }
4161*6777b538SAndroid Build Coastguard Worker 
4162*6777b538SAndroid Build Coastguard Worker 	else if ((CUR == '<') &&
4163*6777b538SAndroid Build Coastguard Worker 	         ((IS_ASCII_LETTER(NXT(1))) ||
4164*6777b538SAndroid Build Coastguard Worker 		  (NXT(1) == '_') || (NXT(1) == ':'))) {
4165*6777b538SAndroid Build Coastguard Worker 	    name = htmlParseHTMLName_nonInvasive(ctxt);
4166*6777b538SAndroid Build Coastguard Worker 	    if (name == NULL) {
4167*6777b538SAndroid Build Coastguard Worker 	        htmlParseErr(ctxt, XML_ERR_NAME_REQUIRED,
4168*6777b538SAndroid Build Coastguard Worker 			 "htmlParseStartTag: invalid element name\n",
4169*6777b538SAndroid Build Coastguard Worker 			 NULL, NULL);
4170*6777b538SAndroid Build Coastguard Worker 	        /* Dump the bogus tag like browsers do */
4171*6777b538SAndroid Build Coastguard Worker                 while ((CUR != 0) && (CUR != '>'))
4172*6777b538SAndroid Build Coastguard Worker 	            NEXT;
4173*6777b538SAndroid Build Coastguard Worker 
4174*6777b538SAndroid Build Coastguard Worker 	        if (currentNode != NULL)
4175*6777b538SAndroid Build Coastguard Worker 	            xmlFree(currentNode);
4176*6777b538SAndroid Build Coastguard Worker 	        return;
4177*6777b538SAndroid Build Coastguard Worker 	    }
4178*6777b538SAndroid Build Coastguard Worker 
4179*6777b538SAndroid Build Coastguard Worker 	    if (ctxt->name != NULL) {
4180*6777b538SAndroid Build Coastguard Worker 	        if (htmlCheckAutoClose(name, ctxt->name) == 1) {
4181*6777b538SAndroid Build Coastguard Worker 	            htmlAutoClose(ctxt, name);
4182*6777b538SAndroid Build Coastguard Worker 	            continue;
4183*6777b538SAndroid Build Coastguard Worker 	        }
4184*6777b538SAndroid Build Coastguard Worker 	    }
4185*6777b538SAndroid Build Coastguard Worker 	}
4186*6777b538SAndroid Build Coastguard Worker 
4187*6777b538SAndroid Build Coastguard Worker 	/*
4188*6777b538SAndroid Build Coastguard Worker 	 * Has this node been popped out during parsing of
4189*6777b538SAndroid Build Coastguard Worker 	 * the next element
4190*6777b538SAndroid Build Coastguard Worker 	 */
4191*6777b538SAndroid Build Coastguard Worker         if ((ctxt->nameNr > 0) && (depth >= ctxt->nameNr) &&
4192*6777b538SAndroid Build Coastguard Worker 	    (!xmlStrEqual(currentNode, ctxt->name)))
4193*6777b538SAndroid Build Coastguard Worker 	     {
4194*6777b538SAndroid Build Coastguard Worker 	    if (currentNode != NULL) xmlFree(currentNode);
4195*6777b538SAndroid Build Coastguard Worker 	    return;
4196*6777b538SAndroid Build Coastguard Worker 	}
4197*6777b538SAndroid Build Coastguard Worker 
4198*6777b538SAndroid Build Coastguard Worker 	if ((CUR != 0) && ((xmlStrEqual(currentNode, BAD_CAST"script")) ||
4199*6777b538SAndroid Build Coastguard Worker 	    (xmlStrEqual(currentNode, BAD_CAST"style")))) {
4200*6777b538SAndroid Build Coastguard Worker 	    /*
4201*6777b538SAndroid Build Coastguard Worker 	     * Handle SCRIPT/STYLE separately
4202*6777b538SAndroid Build Coastguard Worker 	     */
4203*6777b538SAndroid Build Coastguard Worker 	    htmlParseScript(ctxt);
4204*6777b538SAndroid Build Coastguard Worker 	}
4205*6777b538SAndroid Build Coastguard Worker 
4206*6777b538SAndroid Build Coastguard Worker         else if ((CUR == '<') && (NXT(1) == '!')) {
4207*6777b538SAndroid Build Coastguard Worker             /*
4208*6777b538SAndroid Build Coastguard Worker              * Sometimes DOCTYPE arrives in the middle of the document
4209*6777b538SAndroid Build Coastguard Worker              */
4210*6777b538SAndroid Build Coastguard Worker             if ((UPP(2) == 'D') && (UPP(3) == 'O') &&
4211*6777b538SAndroid Build Coastguard Worker                 (UPP(4) == 'C') && (UPP(5) == 'T') &&
4212*6777b538SAndroid Build Coastguard Worker                 (UPP(6) == 'Y') && (UPP(7) == 'P') &&
4213*6777b538SAndroid Build Coastguard Worker                 (UPP(8) == 'E')) {
4214*6777b538SAndroid Build Coastguard Worker                 htmlParseErr(ctxt, XML_HTML_STRUCURE_ERROR,
4215*6777b538SAndroid Build Coastguard Worker                              "Misplaced DOCTYPE declaration\n",
4216*6777b538SAndroid Build Coastguard Worker                              BAD_CAST "DOCTYPE" , NULL);
4217*6777b538SAndroid Build Coastguard Worker                 htmlParseDocTypeDecl(ctxt);
4218*6777b538SAndroid Build Coastguard Worker             }
4219*6777b538SAndroid Build Coastguard Worker             /*
4220*6777b538SAndroid Build Coastguard Worker              * First case :  a comment
4221*6777b538SAndroid Build Coastguard Worker              */
4222*6777b538SAndroid Build Coastguard Worker             else if ((NXT(2) == '-') && (NXT(3) == '-')) {
4223*6777b538SAndroid Build Coastguard Worker                 htmlParseComment(ctxt);
4224*6777b538SAndroid Build Coastguard Worker             }
4225*6777b538SAndroid Build Coastguard Worker             else {
4226*6777b538SAndroid Build Coastguard Worker                 htmlSkipBogusComment(ctxt);
4227*6777b538SAndroid Build Coastguard Worker             }
4228*6777b538SAndroid Build Coastguard Worker         }
4229*6777b538SAndroid Build Coastguard Worker 
4230*6777b538SAndroid Build Coastguard Worker         /*
4231*6777b538SAndroid Build Coastguard Worker          * Second case : a Processing Instruction.
4232*6777b538SAndroid Build Coastguard Worker          */
4233*6777b538SAndroid Build Coastguard Worker         else if ((CUR == '<') && (NXT(1) == '?')) {
4234*6777b538SAndroid Build Coastguard Worker             htmlParsePI(ctxt);
4235*6777b538SAndroid Build Coastguard Worker         }
4236*6777b538SAndroid Build Coastguard Worker 
4237*6777b538SAndroid Build Coastguard Worker         /*
4238*6777b538SAndroid Build Coastguard Worker          * Third case :  a sub-element.
4239*6777b538SAndroid Build Coastguard Worker          */
4240*6777b538SAndroid Build Coastguard Worker         else if ((CUR == '<') && IS_ASCII_LETTER(NXT(1))) {
4241*6777b538SAndroid Build Coastguard Worker             htmlParseElement(ctxt);
4242*6777b538SAndroid Build Coastguard Worker         }
4243*6777b538SAndroid Build Coastguard Worker         else if (CUR == '<') {
4244*6777b538SAndroid Build Coastguard Worker             if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
4245*6777b538SAndroid Build Coastguard Worker                 (ctxt->sax->characters != NULL))
4246*6777b538SAndroid Build Coastguard Worker                 ctxt->sax->characters(ctxt->userData, BAD_CAST "<", 1);
4247*6777b538SAndroid Build Coastguard Worker             NEXT;
4248*6777b538SAndroid Build Coastguard Worker         }
4249*6777b538SAndroid Build Coastguard Worker 
4250*6777b538SAndroid Build Coastguard Worker         /*
4251*6777b538SAndroid Build Coastguard Worker          * Fourth case : a reference. If if has not been resolved,
4252*6777b538SAndroid Build Coastguard Worker          *    parsing returns it's Name, create the node
4253*6777b538SAndroid Build Coastguard Worker          */
4254*6777b538SAndroid Build Coastguard Worker         else if (CUR == '&') {
4255*6777b538SAndroid Build Coastguard Worker             htmlParseReference(ctxt);
4256*6777b538SAndroid Build Coastguard Worker         }
4257*6777b538SAndroid Build Coastguard Worker 
4258*6777b538SAndroid Build Coastguard Worker         /*
4259*6777b538SAndroid Build Coastguard Worker          * Fifth case : end of the resource
4260*6777b538SAndroid Build Coastguard Worker          */
4261*6777b538SAndroid Build Coastguard Worker         else if (CUR == 0) {
4262*6777b538SAndroid Build Coastguard Worker             htmlAutoCloseOnEnd(ctxt);
4263*6777b538SAndroid Build Coastguard Worker             break;
4264*6777b538SAndroid Build Coastguard Worker         }
4265*6777b538SAndroid Build Coastguard Worker 
4266*6777b538SAndroid Build Coastguard Worker         /*
4267*6777b538SAndroid Build Coastguard Worker          * Last case, text. Note that References are handled directly.
4268*6777b538SAndroid Build Coastguard Worker          */
4269*6777b538SAndroid Build Coastguard Worker         else {
4270*6777b538SAndroid Build Coastguard Worker             htmlParseCharData(ctxt);
4271*6777b538SAndroid Build Coastguard Worker         }
4272*6777b538SAndroid Build Coastguard Worker 
4273*6777b538SAndroid Build Coastguard Worker         SHRINK;
4274*6777b538SAndroid Build Coastguard Worker         GROW;
4275*6777b538SAndroid Build Coastguard Worker     }
4276*6777b538SAndroid Build Coastguard Worker     if (currentNode != NULL) xmlFree(currentNode);
4277*6777b538SAndroid Build Coastguard Worker }
4278*6777b538SAndroid Build Coastguard Worker 
4279*6777b538SAndroid Build Coastguard Worker /**
4280*6777b538SAndroid Build Coastguard Worker  * htmlParseElement:
4281*6777b538SAndroid Build Coastguard Worker  * @ctxt:  an HTML parser context
4282*6777b538SAndroid Build Coastguard Worker  *
4283*6777b538SAndroid Build Coastguard Worker  * DEPRECATED: Internal function, don't use.
4284*6777b538SAndroid Build Coastguard Worker  *
4285*6777b538SAndroid Build Coastguard Worker  * parse an HTML element, this is highly recursive
4286*6777b538SAndroid Build Coastguard Worker  * this is kept for compatibility with previous code versions
4287*6777b538SAndroid Build Coastguard Worker  *
4288*6777b538SAndroid Build Coastguard Worker  * [39] element ::= EmptyElemTag | STag content ETag
4289*6777b538SAndroid Build Coastguard Worker  *
4290*6777b538SAndroid Build Coastguard Worker  * [41] Attribute ::= Name Eq AttValue
4291*6777b538SAndroid Build Coastguard Worker  */
4292*6777b538SAndroid Build Coastguard Worker 
4293*6777b538SAndroid Build Coastguard Worker void
htmlParseElement(htmlParserCtxtPtr ctxt)4294*6777b538SAndroid Build Coastguard Worker htmlParseElement(htmlParserCtxtPtr ctxt) {
4295*6777b538SAndroid Build Coastguard Worker     const xmlChar *name;
4296*6777b538SAndroid Build Coastguard Worker     xmlChar *currentNode = NULL;
4297*6777b538SAndroid Build Coastguard Worker     const htmlElemDesc * info;
4298*6777b538SAndroid Build Coastguard Worker     htmlParserNodeInfo node_info;
4299*6777b538SAndroid Build Coastguard Worker     int failed;
4300*6777b538SAndroid Build Coastguard Worker     int depth;
4301*6777b538SAndroid Build Coastguard Worker     const xmlChar *oldptr;
4302*6777b538SAndroid Build Coastguard Worker 
4303*6777b538SAndroid Build Coastguard Worker     if ((ctxt == NULL) || (ctxt->input == NULL))
4304*6777b538SAndroid Build Coastguard Worker 	return;
4305*6777b538SAndroid Build Coastguard Worker 
4306*6777b538SAndroid Build Coastguard Worker     /* Capture start position */
4307*6777b538SAndroid Build Coastguard Worker     if (ctxt->record_info) {
4308*6777b538SAndroid Build Coastguard Worker         node_info.begin_pos = ctxt->input->consumed +
4309*6777b538SAndroid Build Coastguard Worker                           (CUR_PTR - ctxt->input->base);
4310*6777b538SAndroid Build Coastguard Worker 	node_info.begin_line = ctxt->input->line;
4311*6777b538SAndroid Build Coastguard Worker     }
4312*6777b538SAndroid Build Coastguard Worker 
4313*6777b538SAndroid Build Coastguard Worker     failed = htmlParseStartTag(ctxt);
4314*6777b538SAndroid Build Coastguard Worker     name = ctxt->name;
4315*6777b538SAndroid Build Coastguard Worker     if ((failed == -1) || (name == NULL)) {
4316*6777b538SAndroid Build Coastguard Worker 	if (CUR == '>')
4317*6777b538SAndroid Build Coastguard Worker 	    NEXT;
4318*6777b538SAndroid Build Coastguard Worker         return;
4319*6777b538SAndroid Build Coastguard Worker     }
4320*6777b538SAndroid Build Coastguard Worker 
4321*6777b538SAndroid Build Coastguard Worker     /*
4322*6777b538SAndroid Build Coastguard Worker      * Lookup the info for that element.
4323*6777b538SAndroid Build Coastguard Worker      */
4324*6777b538SAndroid Build Coastguard Worker     info = htmlTagLookup(name);
4325*6777b538SAndroid Build Coastguard Worker     if (info == NULL) {
4326*6777b538SAndroid Build Coastguard Worker 	htmlParseErr(ctxt, XML_HTML_UNKNOWN_TAG,
4327*6777b538SAndroid Build Coastguard Worker 	             "Tag %s invalid\n", name, NULL);
4328*6777b538SAndroid Build Coastguard Worker     }
4329*6777b538SAndroid Build Coastguard Worker 
4330*6777b538SAndroid Build Coastguard Worker     /*
4331*6777b538SAndroid Build Coastguard Worker      * Check for an Empty Element labeled the XML/SGML way
4332*6777b538SAndroid Build Coastguard Worker      */
4333*6777b538SAndroid Build Coastguard Worker     if ((CUR == '/') && (NXT(1) == '>')) {
4334*6777b538SAndroid Build Coastguard Worker         SKIP(2);
4335*6777b538SAndroid Build Coastguard Worker 	if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
4336*6777b538SAndroid Build Coastguard Worker 	    ctxt->sax->endElement(ctxt->userData, name);
4337*6777b538SAndroid Build Coastguard Worker 	htmlnamePop(ctxt);
4338*6777b538SAndroid Build Coastguard Worker 	return;
4339*6777b538SAndroid Build Coastguard Worker     }
4340*6777b538SAndroid Build Coastguard Worker 
4341*6777b538SAndroid Build Coastguard Worker     if (CUR == '>') {
4342*6777b538SAndroid Build Coastguard Worker         NEXT;
4343*6777b538SAndroid Build Coastguard Worker     } else {
4344*6777b538SAndroid Build Coastguard Worker 	htmlParseErr(ctxt, XML_ERR_GT_REQUIRED,
4345*6777b538SAndroid Build Coastguard Worker 	             "Couldn't find end of Start Tag %s\n", name, NULL);
4346*6777b538SAndroid Build Coastguard Worker 
4347*6777b538SAndroid Build Coastguard Worker 	/*
4348*6777b538SAndroid Build Coastguard Worker 	 * end of parsing of this node.
4349*6777b538SAndroid Build Coastguard Worker 	 */
4350*6777b538SAndroid Build Coastguard Worker 	if (xmlStrEqual(name, ctxt->name)) {
4351*6777b538SAndroid Build Coastguard Worker 	    nodePop(ctxt);
4352*6777b538SAndroid Build Coastguard Worker 	    htmlnamePop(ctxt);
4353*6777b538SAndroid Build Coastguard Worker 	}
4354*6777b538SAndroid Build Coastguard Worker 
4355*6777b538SAndroid Build Coastguard Worker 	/*
4356*6777b538SAndroid Build Coastguard Worker 	 * Capture end position and add node
4357*6777b538SAndroid Build Coastguard Worker 	 */
4358*6777b538SAndroid Build Coastguard Worker 	if (ctxt->record_info) {
4359*6777b538SAndroid Build Coastguard Worker 	   node_info.end_pos = ctxt->input->consumed +
4360*6777b538SAndroid Build Coastguard Worker 			      (CUR_PTR - ctxt->input->base);
4361*6777b538SAndroid Build Coastguard Worker 	   node_info.end_line = ctxt->input->line;
4362*6777b538SAndroid Build Coastguard Worker 	   node_info.node = ctxt->node;
4363*6777b538SAndroid Build Coastguard Worker 	   xmlParserAddNodeInfo(ctxt, &node_info);
4364*6777b538SAndroid Build Coastguard Worker 	}
4365*6777b538SAndroid Build Coastguard Worker 	return;
4366*6777b538SAndroid Build Coastguard Worker     }
4367*6777b538SAndroid Build Coastguard Worker 
4368*6777b538SAndroid Build Coastguard Worker     /*
4369*6777b538SAndroid Build Coastguard Worker      * Check for an Empty Element from DTD definition
4370*6777b538SAndroid Build Coastguard Worker      */
4371*6777b538SAndroid Build Coastguard Worker     if ((info != NULL) && (info->empty)) {
4372*6777b538SAndroid Build Coastguard Worker 	if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
4373*6777b538SAndroid Build Coastguard Worker 	    ctxt->sax->endElement(ctxt->userData, name);
4374*6777b538SAndroid Build Coastguard Worker 	htmlnamePop(ctxt);
4375*6777b538SAndroid Build Coastguard Worker 	return;
4376*6777b538SAndroid Build Coastguard Worker     }
4377*6777b538SAndroid Build Coastguard Worker 
4378*6777b538SAndroid Build Coastguard Worker     /*
4379*6777b538SAndroid Build Coastguard Worker      * Parse the content of the element:
4380*6777b538SAndroid Build Coastguard Worker      */
4381*6777b538SAndroid Build Coastguard Worker     currentNode = xmlStrdup(ctxt->name);
4382*6777b538SAndroid Build Coastguard Worker     depth = ctxt->nameNr;
4383*6777b538SAndroid Build Coastguard Worker     while (CUR != 0) {
4384*6777b538SAndroid Build Coastguard Worker 	oldptr = ctxt->input->cur;
4385*6777b538SAndroid Build Coastguard Worker 	htmlParseContent(ctxt);
4386*6777b538SAndroid Build Coastguard Worker 	if (oldptr==ctxt->input->cur) break;
4387*6777b538SAndroid Build Coastguard Worker 	if (ctxt->nameNr < depth) break;
4388*6777b538SAndroid Build Coastguard Worker     }
4389*6777b538SAndroid Build Coastguard Worker 
4390*6777b538SAndroid Build Coastguard Worker     /*
4391*6777b538SAndroid Build Coastguard Worker      * Capture end position and add node
4392*6777b538SAndroid Build Coastguard Worker      */
4393*6777b538SAndroid Build Coastguard Worker     if ( currentNode != NULL && ctxt->record_info ) {
4394*6777b538SAndroid Build Coastguard Worker        node_info.end_pos = ctxt->input->consumed +
4395*6777b538SAndroid Build Coastguard Worker                           (CUR_PTR - ctxt->input->base);
4396*6777b538SAndroid Build Coastguard Worker        node_info.end_line = ctxt->input->line;
4397*6777b538SAndroid Build Coastguard Worker        node_info.node = ctxt->node;
4398*6777b538SAndroid Build Coastguard Worker        xmlParserAddNodeInfo(ctxt, &node_info);
4399*6777b538SAndroid Build Coastguard Worker     }
4400*6777b538SAndroid Build Coastguard Worker     if (CUR == 0) {
4401*6777b538SAndroid Build Coastguard Worker 	htmlAutoCloseOnEnd(ctxt);
4402*6777b538SAndroid Build Coastguard Worker     }
4403*6777b538SAndroid Build Coastguard Worker 
4404*6777b538SAndroid Build Coastguard Worker     if (currentNode != NULL)
4405*6777b538SAndroid Build Coastguard Worker 	xmlFree(currentNode);
4406*6777b538SAndroid Build Coastguard Worker }
4407*6777b538SAndroid Build Coastguard Worker 
4408*6777b538SAndroid Build Coastguard Worker static void
htmlParserFinishElementParsing(htmlParserCtxtPtr ctxt)4409*6777b538SAndroid Build Coastguard Worker htmlParserFinishElementParsing(htmlParserCtxtPtr ctxt) {
4410*6777b538SAndroid Build Coastguard Worker     /*
4411*6777b538SAndroid Build Coastguard Worker      * Capture end position and add node
4412*6777b538SAndroid Build Coastguard Worker      */
4413*6777b538SAndroid Build Coastguard Worker     if ( ctxt->node != NULL && ctxt->record_info ) {
4414*6777b538SAndroid Build Coastguard Worker        ctxt->nodeInfo->end_pos = ctxt->input->consumed +
4415*6777b538SAndroid Build Coastguard Worker                                 (CUR_PTR - ctxt->input->base);
4416*6777b538SAndroid Build Coastguard Worker        ctxt->nodeInfo->end_line = ctxt->input->line;
4417*6777b538SAndroid Build Coastguard Worker        ctxt->nodeInfo->node = ctxt->node;
4418*6777b538SAndroid Build Coastguard Worker        xmlParserAddNodeInfo(ctxt, ctxt->nodeInfo);
4419*6777b538SAndroid Build Coastguard Worker        htmlNodeInfoPop(ctxt);
4420*6777b538SAndroid Build Coastguard Worker     }
4421*6777b538SAndroid Build Coastguard Worker     if (CUR == 0) {
4422*6777b538SAndroid Build Coastguard Worker        htmlAutoCloseOnEnd(ctxt);
4423*6777b538SAndroid Build Coastguard Worker     }
4424*6777b538SAndroid Build Coastguard Worker }
4425*6777b538SAndroid Build Coastguard Worker 
4426*6777b538SAndroid Build Coastguard Worker /**
4427*6777b538SAndroid Build Coastguard Worker  * htmlParseElementInternal:
4428*6777b538SAndroid Build Coastguard Worker  * @ctxt:  an HTML parser context
4429*6777b538SAndroid Build Coastguard Worker  *
4430*6777b538SAndroid Build Coastguard Worker  * parse an HTML element, new version, non recursive
4431*6777b538SAndroid Build Coastguard Worker  *
4432*6777b538SAndroid Build Coastguard Worker  * [39] element ::= EmptyElemTag | STag content ETag
4433*6777b538SAndroid Build Coastguard Worker  *
4434*6777b538SAndroid Build Coastguard Worker  * [41] Attribute ::= Name Eq AttValue
4435*6777b538SAndroid Build Coastguard Worker  */
4436*6777b538SAndroid Build Coastguard Worker 
4437*6777b538SAndroid Build Coastguard Worker static void
htmlParseElementInternal(htmlParserCtxtPtr ctxt)4438*6777b538SAndroid Build Coastguard Worker htmlParseElementInternal(htmlParserCtxtPtr ctxt) {
4439*6777b538SAndroid Build Coastguard Worker     const xmlChar *name;
4440*6777b538SAndroid Build Coastguard Worker     const htmlElemDesc * info;
4441*6777b538SAndroid Build Coastguard Worker     htmlParserNodeInfo node_info = { NULL, 0, 0, 0, 0 };
4442*6777b538SAndroid Build Coastguard Worker     int failed;
4443*6777b538SAndroid Build Coastguard Worker 
4444*6777b538SAndroid Build Coastguard Worker     if ((ctxt == NULL) || (ctxt->input == NULL))
4445*6777b538SAndroid Build Coastguard Worker 	return;
4446*6777b538SAndroid Build Coastguard Worker 
4447*6777b538SAndroid Build Coastguard Worker     /* Capture start position */
4448*6777b538SAndroid Build Coastguard Worker     if (ctxt->record_info) {
4449*6777b538SAndroid Build Coastguard Worker         node_info.begin_pos = ctxt->input->consumed +
4450*6777b538SAndroid Build Coastguard Worker                           (CUR_PTR - ctxt->input->base);
4451*6777b538SAndroid Build Coastguard Worker 	node_info.begin_line = ctxt->input->line;
4452*6777b538SAndroid Build Coastguard Worker     }
4453*6777b538SAndroid Build Coastguard Worker 
4454*6777b538SAndroid Build Coastguard Worker     failed = htmlParseStartTag(ctxt);
4455*6777b538SAndroid Build Coastguard Worker     name = ctxt->name;
4456*6777b538SAndroid Build Coastguard Worker     if ((failed == -1) || (name == NULL)) {
4457*6777b538SAndroid Build Coastguard Worker 	if (CUR == '>')
4458*6777b538SAndroid Build Coastguard Worker 	    NEXT;
4459*6777b538SAndroid Build Coastguard Worker         return;
4460*6777b538SAndroid Build Coastguard Worker     }
4461*6777b538SAndroid Build Coastguard Worker 
4462*6777b538SAndroid Build Coastguard Worker     /*
4463*6777b538SAndroid Build Coastguard Worker      * Lookup the info for that element.
4464*6777b538SAndroid Build Coastguard Worker      */
4465*6777b538SAndroid Build Coastguard Worker     info = htmlTagLookup(name);
4466*6777b538SAndroid Build Coastguard Worker     if (info == NULL) {
4467*6777b538SAndroid Build Coastguard Worker 	htmlParseErr(ctxt, XML_HTML_UNKNOWN_TAG,
4468*6777b538SAndroid Build Coastguard Worker 	             "Tag %s invalid\n", name, NULL);
4469*6777b538SAndroid Build Coastguard Worker     }
4470*6777b538SAndroid Build Coastguard Worker 
4471*6777b538SAndroid Build Coastguard Worker     /*
4472*6777b538SAndroid Build Coastguard Worker      * Check for an Empty Element labeled the XML/SGML way
4473*6777b538SAndroid Build Coastguard Worker      */
4474*6777b538SAndroid Build Coastguard Worker     if ((CUR == '/') && (NXT(1) == '>')) {
4475*6777b538SAndroid Build Coastguard Worker         SKIP(2);
4476*6777b538SAndroid Build Coastguard Worker 	if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
4477*6777b538SAndroid Build Coastguard Worker 	    ctxt->sax->endElement(ctxt->userData, name);
4478*6777b538SAndroid Build Coastguard Worker 	htmlnamePop(ctxt);
4479*6777b538SAndroid Build Coastguard Worker 	return;
4480*6777b538SAndroid Build Coastguard Worker     }
4481*6777b538SAndroid Build Coastguard Worker 
4482*6777b538SAndroid Build Coastguard Worker     if (CUR == '>') {
4483*6777b538SAndroid Build Coastguard Worker         NEXT;
4484*6777b538SAndroid Build Coastguard Worker     } else {
4485*6777b538SAndroid Build Coastguard Worker 	htmlParseErr(ctxt, XML_ERR_GT_REQUIRED,
4486*6777b538SAndroid Build Coastguard Worker 	             "Couldn't find end of Start Tag %s\n", name, NULL);
4487*6777b538SAndroid Build Coastguard Worker 
4488*6777b538SAndroid Build Coastguard Worker 	/*
4489*6777b538SAndroid Build Coastguard Worker 	 * end of parsing of this node.
4490*6777b538SAndroid Build Coastguard Worker 	 */
4491*6777b538SAndroid Build Coastguard Worker 	if (xmlStrEqual(name, ctxt->name)) {
4492*6777b538SAndroid Build Coastguard Worker 	    nodePop(ctxt);
4493*6777b538SAndroid Build Coastguard Worker 	    htmlnamePop(ctxt);
4494*6777b538SAndroid Build Coastguard Worker 	}
4495*6777b538SAndroid Build Coastguard Worker 
4496*6777b538SAndroid Build Coastguard Worker         if (ctxt->record_info)
4497*6777b538SAndroid Build Coastguard Worker             htmlNodeInfoPush(ctxt, &node_info);
4498*6777b538SAndroid Build Coastguard Worker         htmlParserFinishElementParsing(ctxt);
4499*6777b538SAndroid Build Coastguard Worker 	return;
4500*6777b538SAndroid Build Coastguard Worker     }
4501*6777b538SAndroid Build Coastguard Worker 
4502*6777b538SAndroid Build Coastguard Worker     /*
4503*6777b538SAndroid Build Coastguard Worker      * Check for an Empty Element from DTD definition
4504*6777b538SAndroid Build Coastguard Worker      */
4505*6777b538SAndroid Build Coastguard Worker     if ((info != NULL) && (info->empty)) {
4506*6777b538SAndroid Build Coastguard Worker 	if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
4507*6777b538SAndroid Build Coastguard Worker 	    ctxt->sax->endElement(ctxt->userData, name);
4508*6777b538SAndroid Build Coastguard Worker 	htmlnamePop(ctxt);
4509*6777b538SAndroid Build Coastguard Worker 	return;
4510*6777b538SAndroid Build Coastguard Worker     }
4511*6777b538SAndroid Build Coastguard Worker 
4512*6777b538SAndroid Build Coastguard Worker     if (ctxt->record_info)
4513*6777b538SAndroid Build Coastguard Worker         htmlNodeInfoPush(ctxt, &node_info);
4514*6777b538SAndroid Build Coastguard Worker }
4515*6777b538SAndroid Build Coastguard Worker 
4516*6777b538SAndroid Build Coastguard Worker /**
4517*6777b538SAndroid Build Coastguard Worker  * htmlParseContentInternal:
4518*6777b538SAndroid Build Coastguard Worker  * @ctxt:  an HTML parser context
4519*6777b538SAndroid Build Coastguard Worker  *
4520*6777b538SAndroid Build Coastguard Worker  * Parse a content: comment, sub-element, reference or text.
4521*6777b538SAndroid Build Coastguard Worker  * New version for non recursive htmlParseElementInternal
4522*6777b538SAndroid Build Coastguard Worker  */
4523*6777b538SAndroid Build Coastguard Worker 
4524*6777b538SAndroid Build Coastguard Worker static void
htmlParseContentInternal(htmlParserCtxtPtr ctxt)4525*6777b538SAndroid Build Coastguard Worker htmlParseContentInternal(htmlParserCtxtPtr ctxt) {
4526*6777b538SAndroid Build Coastguard Worker     xmlChar *currentNode;
4527*6777b538SAndroid Build Coastguard Worker     int depth;
4528*6777b538SAndroid Build Coastguard Worker     const xmlChar *name;
4529*6777b538SAndroid Build Coastguard Worker 
4530*6777b538SAndroid Build Coastguard Worker     depth = ctxt->nameNr;
4531*6777b538SAndroid Build Coastguard Worker     if (depth <= 0) {
4532*6777b538SAndroid Build Coastguard Worker         currentNode = NULL;
4533*6777b538SAndroid Build Coastguard Worker     } else {
4534*6777b538SAndroid Build Coastguard Worker         currentNode = xmlStrdup(ctxt->name);
4535*6777b538SAndroid Build Coastguard Worker         if (currentNode == NULL) {
4536*6777b538SAndroid Build Coastguard Worker             htmlErrMemory(ctxt);
4537*6777b538SAndroid Build Coastguard Worker             return;
4538*6777b538SAndroid Build Coastguard Worker         }
4539*6777b538SAndroid Build Coastguard Worker     }
4540*6777b538SAndroid Build Coastguard Worker     while (PARSER_STOPPED(ctxt) == 0) {
4541*6777b538SAndroid Build Coastguard Worker         GROW;
4542*6777b538SAndroid Build Coastguard Worker 
4543*6777b538SAndroid Build Coastguard Worker 	/*
4544*6777b538SAndroid Build Coastguard Worker 	 * Our tag or one of it's parent or children is ending.
4545*6777b538SAndroid Build Coastguard Worker 	 */
4546*6777b538SAndroid Build Coastguard Worker         if ((CUR == '<') && (NXT(1) == '/')) {
4547*6777b538SAndroid Build Coastguard Worker 	    if (htmlParseEndTag(ctxt) &&
4548*6777b538SAndroid Build Coastguard Worker 		((currentNode != NULL) || (ctxt->nameNr == 0))) {
4549*6777b538SAndroid Build Coastguard Worker 		if (currentNode != NULL)
4550*6777b538SAndroid Build Coastguard Worker 		    xmlFree(currentNode);
4551*6777b538SAndroid Build Coastguard Worker 
4552*6777b538SAndroid Build Coastguard Worker 	        depth = ctxt->nameNr;
4553*6777b538SAndroid Build Coastguard Worker                 if (depth <= 0) {
4554*6777b538SAndroid Build Coastguard Worker                     currentNode = NULL;
4555*6777b538SAndroid Build Coastguard Worker                 } else {
4556*6777b538SAndroid Build Coastguard Worker                     currentNode = xmlStrdup(ctxt->name);
4557*6777b538SAndroid Build Coastguard Worker                     if (currentNode == NULL) {
4558*6777b538SAndroid Build Coastguard Worker                         htmlErrMemory(ctxt);
4559*6777b538SAndroid Build Coastguard Worker                         break;
4560*6777b538SAndroid Build Coastguard Worker                     }
4561*6777b538SAndroid Build Coastguard Worker                 }
4562*6777b538SAndroid Build Coastguard Worker 	    }
4563*6777b538SAndroid Build Coastguard Worker 	    continue; /* while */
4564*6777b538SAndroid Build Coastguard Worker         }
4565*6777b538SAndroid Build Coastguard Worker 
4566*6777b538SAndroid Build Coastguard Worker 	else if ((CUR == '<') &&
4567*6777b538SAndroid Build Coastguard Worker 	         ((IS_ASCII_LETTER(NXT(1))) ||
4568*6777b538SAndroid Build Coastguard Worker 		  (NXT(1) == '_') || (NXT(1) == ':'))) {
4569*6777b538SAndroid Build Coastguard Worker 	    name = htmlParseHTMLName_nonInvasive(ctxt);
4570*6777b538SAndroid Build Coastguard Worker 	    if (name == NULL) {
4571*6777b538SAndroid Build Coastguard Worker 	        htmlParseErr(ctxt, XML_ERR_NAME_REQUIRED,
4572*6777b538SAndroid Build Coastguard Worker 			 "htmlParseStartTag: invalid element name\n",
4573*6777b538SAndroid Build Coastguard Worker 			 NULL, NULL);
4574*6777b538SAndroid Build Coastguard Worker 	        /* Dump the bogus tag like browsers do */
4575*6777b538SAndroid Build Coastguard Worker 	        while ((CUR == 0) && (CUR != '>'))
4576*6777b538SAndroid Build Coastguard Worker 	            NEXT;
4577*6777b538SAndroid Build Coastguard Worker 
4578*6777b538SAndroid Build Coastguard Worker 	        htmlParserFinishElementParsing(ctxt);
4579*6777b538SAndroid Build Coastguard Worker 	        if (currentNode != NULL)
4580*6777b538SAndroid Build Coastguard Worker 	            xmlFree(currentNode);
4581*6777b538SAndroid Build Coastguard Worker 
4582*6777b538SAndroid Build Coastguard Worker                 if (ctxt->name == NULL) {
4583*6777b538SAndroid Build Coastguard Worker                     currentNode = NULL;
4584*6777b538SAndroid Build Coastguard Worker                 } else {
4585*6777b538SAndroid Build Coastguard Worker                     currentNode = xmlStrdup(ctxt->name);
4586*6777b538SAndroid Build Coastguard Worker                     if (currentNode == NULL) {
4587*6777b538SAndroid Build Coastguard Worker                         htmlErrMemory(ctxt);
4588*6777b538SAndroid Build Coastguard Worker                         break;
4589*6777b538SAndroid Build Coastguard Worker                     }
4590*6777b538SAndroid Build Coastguard Worker                 }
4591*6777b538SAndroid Build Coastguard Worker 	        depth = ctxt->nameNr;
4592*6777b538SAndroid Build Coastguard Worker 	        continue;
4593*6777b538SAndroid Build Coastguard Worker 	    }
4594*6777b538SAndroid Build Coastguard Worker 
4595*6777b538SAndroid Build Coastguard Worker 	    if (ctxt->name != NULL) {
4596*6777b538SAndroid Build Coastguard Worker 	        if (htmlCheckAutoClose(name, ctxt->name) == 1) {
4597*6777b538SAndroid Build Coastguard Worker 	            htmlAutoClose(ctxt, name);
4598*6777b538SAndroid Build Coastguard Worker 	            continue;
4599*6777b538SAndroid Build Coastguard Worker 	        }
4600*6777b538SAndroid Build Coastguard Worker 	    }
4601*6777b538SAndroid Build Coastguard Worker 	}
4602*6777b538SAndroid Build Coastguard Worker 
4603*6777b538SAndroid Build Coastguard Worker 	/*
4604*6777b538SAndroid Build Coastguard Worker 	 * Has this node been popped out during parsing of
4605*6777b538SAndroid Build Coastguard Worker 	 * the next element
4606*6777b538SAndroid Build Coastguard Worker 	 */
4607*6777b538SAndroid Build Coastguard Worker         if ((ctxt->nameNr > 0) && (depth >= ctxt->nameNr) &&
4608*6777b538SAndroid Build Coastguard Worker 	    (!xmlStrEqual(currentNode, ctxt->name)))
4609*6777b538SAndroid Build Coastguard Worker 	     {
4610*6777b538SAndroid Build Coastguard Worker 	    htmlParserFinishElementParsing(ctxt);
4611*6777b538SAndroid Build Coastguard Worker 	    if (currentNode != NULL) xmlFree(currentNode);
4612*6777b538SAndroid Build Coastguard Worker 
4613*6777b538SAndroid Build Coastguard Worker             if (ctxt->name == NULL) {
4614*6777b538SAndroid Build Coastguard Worker                 currentNode = NULL;
4615*6777b538SAndroid Build Coastguard Worker             } else {
4616*6777b538SAndroid Build Coastguard Worker                 currentNode = xmlStrdup(ctxt->name);
4617*6777b538SAndroid Build Coastguard Worker                 if (currentNode == NULL) {
4618*6777b538SAndroid Build Coastguard Worker                     htmlErrMemory(ctxt);
4619*6777b538SAndroid Build Coastguard Worker                     break;
4620*6777b538SAndroid Build Coastguard Worker                 }
4621*6777b538SAndroid Build Coastguard Worker             }
4622*6777b538SAndroid Build Coastguard Worker 	    depth = ctxt->nameNr;
4623*6777b538SAndroid Build Coastguard Worker 	    continue;
4624*6777b538SAndroid Build Coastguard Worker 	}
4625*6777b538SAndroid Build Coastguard Worker 
4626*6777b538SAndroid Build Coastguard Worker 	if ((CUR != 0) && ((xmlStrEqual(currentNode, BAD_CAST"script")) ||
4627*6777b538SAndroid Build Coastguard Worker 	    (xmlStrEqual(currentNode, BAD_CAST"style")))) {
4628*6777b538SAndroid Build Coastguard Worker 	    /*
4629*6777b538SAndroid Build Coastguard Worker 	     * Handle SCRIPT/STYLE separately
4630*6777b538SAndroid Build Coastguard Worker 	     */
4631*6777b538SAndroid Build Coastguard Worker 	    htmlParseScript(ctxt);
4632*6777b538SAndroid Build Coastguard Worker 	}
4633*6777b538SAndroid Build Coastguard Worker 
4634*6777b538SAndroid Build Coastguard Worker         else if ((CUR == '<') && (NXT(1) == '!')) {
4635*6777b538SAndroid Build Coastguard Worker             /*
4636*6777b538SAndroid Build Coastguard Worker              * Sometimes DOCTYPE arrives in the middle of the document
4637*6777b538SAndroid Build Coastguard Worker              */
4638*6777b538SAndroid Build Coastguard Worker             if ((UPP(2) == 'D') && (UPP(3) == 'O') &&
4639*6777b538SAndroid Build Coastguard Worker                 (UPP(4) == 'C') && (UPP(5) == 'T') &&
4640*6777b538SAndroid Build Coastguard Worker                 (UPP(6) == 'Y') && (UPP(7) == 'P') &&
4641*6777b538SAndroid Build Coastguard Worker                 (UPP(8) == 'E')) {
4642*6777b538SAndroid Build Coastguard Worker                 htmlParseErr(ctxt, XML_HTML_STRUCURE_ERROR,
4643*6777b538SAndroid Build Coastguard Worker                              "Misplaced DOCTYPE declaration\n",
4644*6777b538SAndroid Build Coastguard Worker                              BAD_CAST "DOCTYPE" , NULL);
4645*6777b538SAndroid Build Coastguard Worker                 htmlParseDocTypeDecl(ctxt);
4646*6777b538SAndroid Build Coastguard Worker             }
4647*6777b538SAndroid Build Coastguard Worker             /*
4648*6777b538SAndroid Build Coastguard Worker              * First case :  a comment
4649*6777b538SAndroid Build Coastguard Worker              */
4650*6777b538SAndroid Build Coastguard Worker             else if ((NXT(2) == '-') && (NXT(3) == '-')) {
4651*6777b538SAndroid Build Coastguard Worker                 htmlParseComment(ctxt);
4652*6777b538SAndroid Build Coastguard Worker             }
4653*6777b538SAndroid Build Coastguard Worker             else {
4654*6777b538SAndroid Build Coastguard Worker                 htmlSkipBogusComment(ctxt);
4655*6777b538SAndroid Build Coastguard Worker             }
4656*6777b538SAndroid Build Coastguard Worker         }
4657*6777b538SAndroid Build Coastguard Worker 
4658*6777b538SAndroid Build Coastguard Worker         /*
4659*6777b538SAndroid Build Coastguard Worker          * Second case : a Processing Instruction.
4660*6777b538SAndroid Build Coastguard Worker          */
4661*6777b538SAndroid Build Coastguard Worker         else if ((CUR == '<') && (NXT(1) == '?')) {
4662*6777b538SAndroid Build Coastguard Worker             htmlParsePI(ctxt);
4663*6777b538SAndroid Build Coastguard Worker         }
4664*6777b538SAndroid Build Coastguard Worker 
4665*6777b538SAndroid Build Coastguard Worker         /*
4666*6777b538SAndroid Build Coastguard Worker          * Third case :  a sub-element.
4667*6777b538SAndroid Build Coastguard Worker          */
4668*6777b538SAndroid Build Coastguard Worker         else if ((CUR == '<') && IS_ASCII_LETTER(NXT(1))) {
4669*6777b538SAndroid Build Coastguard Worker             htmlParseElementInternal(ctxt);
4670*6777b538SAndroid Build Coastguard Worker             if (currentNode != NULL) xmlFree(currentNode);
4671*6777b538SAndroid Build Coastguard Worker 
4672*6777b538SAndroid Build Coastguard Worker             if (ctxt->name == NULL) {
4673*6777b538SAndroid Build Coastguard Worker                 currentNode = NULL;
4674*6777b538SAndroid Build Coastguard Worker             } else {
4675*6777b538SAndroid Build Coastguard Worker                 currentNode = xmlStrdup(ctxt->name);
4676*6777b538SAndroid Build Coastguard Worker                 if (currentNode == NULL) {
4677*6777b538SAndroid Build Coastguard Worker                     htmlErrMemory(ctxt);
4678*6777b538SAndroid Build Coastguard Worker                     break;
4679*6777b538SAndroid Build Coastguard Worker                 }
4680*6777b538SAndroid Build Coastguard Worker             }
4681*6777b538SAndroid Build Coastguard Worker             depth = ctxt->nameNr;
4682*6777b538SAndroid Build Coastguard Worker         }
4683*6777b538SAndroid Build Coastguard Worker         else if (CUR == '<') {
4684*6777b538SAndroid Build Coastguard Worker             if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
4685*6777b538SAndroid Build Coastguard Worker                 (ctxt->sax->characters != NULL))
4686*6777b538SAndroid Build Coastguard Worker                 ctxt->sax->characters(ctxt->userData, BAD_CAST "<", 1);
4687*6777b538SAndroid Build Coastguard Worker             NEXT;
4688*6777b538SAndroid Build Coastguard Worker         }
4689*6777b538SAndroid Build Coastguard Worker 
4690*6777b538SAndroid Build Coastguard Worker         /*
4691*6777b538SAndroid Build Coastguard Worker          * Fourth case : a reference. If if has not been resolved,
4692*6777b538SAndroid Build Coastguard Worker          *    parsing returns it's Name, create the node
4693*6777b538SAndroid Build Coastguard Worker          */
4694*6777b538SAndroid Build Coastguard Worker         else if (CUR == '&') {
4695*6777b538SAndroid Build Coastguard Worker             htmlParseReference(ctxt);
4696*6777b538SAndroid Build Coastguard Worker         }
4697*6777b538SAndroid Build Coastguard Worker 
4698*6777b538SAndroid Build Coastguard Worker         /*
4699*6777b538SAndroid Build Coastguard Worker          * Fifth case : end of the resource
4700*6777b538SAndroid Build Coastguard Worker          */
4701*6777b538SAndroid Build Coastguard Worker         else if (CUR == 0) {
4702*6777b538SAndroid Build Coastguard Worker             htmlAutoCloseOnEnd(ctxt);
4703*6777b538SAndroid Build Coastguard Worker             break;
4704*6777b538SAndroid Build Coastguard Worker         }
4705*6777b538SAndroid Build Coastguard Worker 
4706*6777b538SAndroid Build Coastguard Worker         /*
4707*6777b538SAndroid Build Coastguard Worker          * Last case, text. Note that References are handled directly.
4708*6777b538SAndroid Build Coastguard Worker          */
4709*6777b538SAndroid Build Coastguard Worker         else {
4710*6777b538SAndroid Build Coastguard Worker             htmlParseCharData(ctxt);
4711*6777b538SAndroid Build Coastguard Worker         }
4712*6777b538SAndroid Build Coastguard Worker 
4713*6777b538SAndroid Build Coastguard Worker         SHRINK;
4714*6777b538SAndroid Build Coastguard Worker         GROW;
4715*6777b538SAndroid Build Coastguard Worker     }
4716*6777b538SAndroid Build Coastguard Worker     if (currentNode != NULL) xmlFree(currentNode);
4717*6777b538SAndroid Build Coastguard Worker }
4718*6777b538SAndroid Build Coastguard Worker 
4719*6777b538SAndroid Build Coastguard Worker /**
4720*6777b538SAndroid Build Coastguard Worker  * htmlParseContent:
4721*6777b538SAndroid Build Coastguard Worker  * @ctxt:  an HTML parser context
4722*6777b538SAndroid Build Coastguard Worker  *
4723*6777b538SAndroid Build Coastguard Worker  * Parse a content: comment, sub-element, reference or text.
4724*6777b538SAndroid Build Coastguard Worker  * This is the entry point when called from parser.c
4725*6777b538SAndroid Build Coastguard Worker  */
4726*6777b538SAndroid Build Coastguard Worker 
4727*6777b538SAndroid Build Coastguard Worker void
__htmlParseContent(void * ctxt)4728*6777b538SAndroid Build Coastguard Worker __htmlParseContent(void *ctxt) {
4729*6777b538SAndroid Build Coastguard Worker     if (ctxt != NULL)
4730*6777b538SAndroid Build Coastguard Worker 	htmlParseContentInternal((htmlParserCtxtPtr) ctxt);
4731*6777b538SAndroid Build Coastguard Worker }
4732*6777b538SAndroid Build Coastguard Worker 
4733*6777b538SAndroid Build Coastguard Worker /**
4734*6777b538SAndroid Build Coastguard Worker  * htmlParseDocument:
4735*6777b538SAndroid Build Coastguard Worker  * @ctxt:  an HTML parser context
4736*6777b538SAndroid Build Coastguard Worker  *
4737*6777b538SAndroid Build Coastguard Worker  * Parse an HTML document and invoke the SAX handlers. This is useful
4738*6777b538SAndroid Build Coastguard Worker  * if you're only interested in custom SAX callbacks. If you want a
4739*6777b538SAndroid Build Coastguard Worker  * document tree, use htmlCtxtParseDocument.
4740*6777b538SAndroid Build Coastguard Worker  *
4741*6777b538SAndroid Build Coastguard Worker  * Returns 0, -1 in case of error.
4742*6777b538SAndroid Build Coastguard Worker  */
4743*6777b538SAndroid Build Coastguard Worker 
4744*6777b538SAndroid Build Coastguard Worker int
htmlParseDocument(htmlParserCtxtPtr ctxt)4745*6777b538SAndroid Build Coastguard Worker htmlParseDocument(htmlParserCtxtPtr ctxt) {
4746*6777b538SAndroid Build Coastguard Worker     xmlDtdPtr dtd;
4747*6777b538SAndroid Build Coastguard Worker 
4748*6777b538SAndroid Build Coastguard Worker     if ((ctxt == NULL) || (ctxt->input == NULL))
4749*6777b538SAndroid Build Coastguard Worker 	return(-1);
4750*6777b538SAndroid Build Coastguard Worker 
4751*6777b538SAndroid Build Coastguard Worker     /*
4752*6777b538SAndroid Build Coastguard Worker      * Document locator is unused. Only for backward compatibility.
4753*6777b538SAndroid Build Coastguard Worker      */
4754*6777b538SAndroid Build Coastguard Worker     if ((ctxt->sax) && (ctxt->sax->setDocumentLocator)) {
4755*6777b538SAndroid Build Coastguard Worker         xmlSAXLocator copy = xmlDefaultSAXLocator;
4756*6777b538SAndroid Build Coastguard Worker         ctxt->sax->setDocumentLocator(ctxt->userData, &copy);
4757*6777b538SAndroid Build Coastguard Worker     }
4758*6777b538SAndroid Build Coastguard Worker 
4759*6777b538SAndroid Build Coastguard Worker     xmlDetectEncoding(ctxt);
4760*6777b538SAndroid Build Coastguard Worker 
4761*6777b538SAndroid Build Coastguard Worker     /*
4762*6777b538SAndroid Build Coastguard Worker      * This is wrong but matches long-standing behavior. In most cases,
4763*6777b538SAndroid Build Coastguard Worker      * a document starting with an XML declaration will specify UTF-8.
4764*6777b538SAndroid Build Coastguard Worker      */
4765*6777b538SAndroid Build Coastguard Worker     if (((ctxt->input->flags & XML_INPUT_HAS_ENCODING) == 0) &&
4766*6777b538SAndroid Build Coastguard Worker         (xmlStrncmp(ctxt->input->cur, BAD_CAST "<?xm", 4) == 0))
4767*6777b538SAndroid Build Coastguard Worker         xmlSwitchEncoding(ctxt, XML_CHAR_ENCODING_UTF8);
4768*6777b538SAndroid Build Coastguard Worker 
4769*6777b538SAndroid Build Coastguard Worker     /*
4770*6777b538SAndroid Build Coastguard Worker      * Wipe out everything which is before the first '<'
4771*6777b538SAndroid Build Coastguard Worker      */
4772*6777b538SAndroid Build Coastguard Worker     SKIP_BLANKS;
4773*6777b538SAndroid Build Coastguard Worker     if (CUR == 0) {
4774*6777b538SAndroid Build Coastguard Worker 	htmlParseErr(ctxt, XML_ERR_DOCUMENT_EMPTY,
4775*6777b538SAndroid Build Coastguard Worker 	             "Document is empty\n", NULL, NULL);
4776*6777b538SAndroid Build Coastguard Worker     }
4777*6777b538SAndroid Build Coastguard Worker 
4778*6777b538SAndroid Build Coastguard Worker     if ((ctxt->sax) && (ctxt->sax->startDocument) && (!ctxt->disableSAX))
4779*6777b538SAndroid Build Coastguard Worker 	ctxt->sax->startDocument(ctxt->userData);
4780*6777b538SAndroid Build Coastguard Worker 
4781*6777b538SAndroid Build Coastguard Worker     /*
4782*6777b538SAndroid Build Coastguard Worker      * Parse possible comments and PIs before any content
4783*6777b538SAndroid Build Coastguard Worker      */
4784*6777b538SAndroid Build Coastguard Worker     while (((CUR == '<') && (NXT(1) == '!') &&
4785*6777b538SAndroid Build Coastguard Worker             (NXT(2) == '-') && (NXT(3) == '-')) ||
4786*6777b538SAndroid Build Coastguard Worker 	   ((CUR == '<') && (NXT(1) == '?'))) {
4787*6777b538SAndroid Build Coastguard Worker         htmlParseComment(ctxt);
4788*6777b538SAndroid Build Coastguard Worker         htmlParsePI(ctxt);
4789*6777b538SAndroid Build Coastguard Worker 	SKIP_BLANKS;
4790*6777b538SAndroid Build Coastguard Worker     }
4791*6777b538SAndroid Build Coastguard Worker 
4792*6777b538SAndroid Build Coastguard Worker 
4793*6777b538SAndroid Build Coastguard Worker     /*
4794*6777b538SAndroid Build Coastguard Worker      * Then possibly doc type declaration(s) and more Misc
4795*6777b538SAndroid Build Coastguard Worker      * (doctypedecl Misc*)?
4796*6777b538SAndroid Build Coastguard Worker      */
4797*6777b538SAndroid Build Coastguard Worker     if ((CUR == '<') && (NXT(1) == '!') &&
4798*6777b538SAndroid Build Coastguard Worker 	(UPP(2) == 'D') && (UPP(3) == 'O') &&
4799*6777b538SAndroid Build Coastguard Worker 	(UPP(4) == 'C') && (UPP(5) == 'T') &&
4800*6777b538SAndroid Build Coastguard Worker 	(UPP(6) == 'Y') && (UPP(7) == 'P') &&
4801*6777b538SAndroid Build Coastguard Worker 	(UPP(8) == 'E')) {
4802*6777b538SAndroid Build Coastguard Worker 	htmlParseDocTypeDecl(ctxt);
4803*6777b538SAndroid Build Coastguard Worker     }
4804*6777b538SAndroid Build Coastguard Worker     SKIP_BLANKS;
4805*6777b538SAndroid Build Coastguard Worker 
4806*6777b538SAndroid Build Coastguard Worker     /*
4807*6777b538SAndroid Build Coastguard Worker      * Parse possible comments and PIs before any content
4808*6777b538SAndroid Build Coastguard Worker      */
4809*6777b538SAndroid Build Coastguard Worker     while ((PARSER_STOPPED(ctxt) == 0) &&
4810*6777b538SAndroid Build Coastguard Worker            (((CUR == '<') && (NXT(1) == '!') &&
4811*6777b538SAndroid Build Coastguard Worker              (NXT(2) == '-') && (NXT(3) == '-')) ||
4812*6777b538SAndroid Build Coastguard Worker 	    ((CUR == '<') && (NXT(1) == '?')))) {
4813*6777b538SAndroid Build Coastguard Worker         htmlParseComment(ctxt);
4814*6777b538SAndroid Build Coastguard Worker         htmlParsePI(ctxt);
4815*6777b538SAndroid Build Coastguard Worker 	SKIP_BLANKS;
4816*6777b538SAndroid Build Coastguard Worker     }
4817*6777b538SAndroid Build Coastguard Worker 
4818*6777b538SAndroid Build Coastguard Worker     /*
4819*6777b538SAndroid Build Coastguard Worker      * Time to start parsing the tree itself
4820*6777b538SAndroid Build Coastguard Worker      */
4821*6777b538SAndroid Build Coastguard Worker     htmlParseContentInternal(ctxt);
4822*6777b538SAndroid Build Coastguard Worker 
4823*6777b538SAndroid Build Coastguard Worker     /*
4824*6777b538SAndroid Build Coastguard Worker      * autoclose
4825*6777b538SAndroid Build Coastguard Worker      */
4826*6777b538SAndroid Build Coastguard Worker     if (CUR == 0)
4827*6777b538SAndroid Build Coastguard Worker 	htmlAutoCloseOnEnd(ctxt);
4828*6777b538SAndroid Build Coastguard Worker 
4829*6777b538SAndroid Build Coastguard Worker 
4830*6777b538SAndroid Build Coastguard Worker     /*
4831*6777b538SAndroid Build Coastguard Worker      * SAX: end of the document processing.
4832*6777b538SAndroid Build Coastguard Worker      */
4833*6777b538SAndroid Build Coastguard Worker     if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
4834*6777b538SAndroid Build Coastguard Worker         ctxt->sax->endDocument(ctxt->userData);
4835*6777b538SAndroid Build Coastguard Worker 
4836*6777b538SAndroid Build Coastguard Worker     if ((!(ctxt->options & HTML_PARSE_NODEFDTD)) && (ctxt->myDoc != NULL)) {
4837*6777b538SAndroid Build Coastguard Worker 	dtd = xmlGetIntSubset(ctxt->myDoc);
4838*6777b538SAndroid Build Coastguard Worker 	if (dtd == NULL) {
4839*6777b538SAndroid Build Coastguard Worker 	    ctxt->myDoc->intSubset =
4840*6777b538SAndroid Build Coastguard Worker 		xmlCreateIntSubset(ctxt->myDoc, BAD_CAST "html",
4841*6777b538SAndroid Build Coastguard Worker 		    BAD_CAST "-//W3C//DTD HTML 4.0 Transitional//EN",
4842*6777b538SAndroid Build Coastguard Worker 		    BAD_CAST "http://www.w3.org/TR/REC-html40/loose.dtd");
4843*6777b538SAndroid Build Coastguard Worker             if (ctxt->myDoc->intSubset == NULL)
4844*6777b538SAndroid Build Coastguard Worker                 htmlErrMemory(ctxt);
4845*6777b538SAndroid Build Coastguard Worker         }
4846*6777b538SAndroid Build Coastguard Worker     }
4847*6777b538SAndroid Build Coastguard Worker     if (! ctxt->wellFormed) return(-1);
4848*6777b538SAndroid Build Coastguard Worker     return(0);
4849*6777b538SAndroid Build Coastguard Worker }
4850*6777b538SAndroid Build Coastguard Worker 
4851*6777b538SAndroid Build Coastguard Worker 
4852*6777b538SAndroid Build Coastguard Worker /************************************************************************
4853*6777b538SAndroid Build Coastguard Worker  *									*
4854*6777b538SAndroid Build Coastguard Worker  *			Parser contexts handling			*
4855*6777b538SAndroid Build Coastguard Worker  *									*
4856*6777b538SAndroid Build Coastguard Worker  ************************************************************************/
4857*6777b538SAndroid Build Coastguard Worker 
4858*6777b538SAndroid Build Coastguard Worker /**
4859*6777b538SAndroid Build Coastguard Worker  * htmlInitParserCtxt:
4860*6777b538SAndroid Build Coastguard Worker  * @ctxt:  an HTML parser context
4861*6777b538SAndroid Build Coastguard Worker  * @sax:  SAX handler
4862*6777b538SAndroid Build Coastguard Worker  * @userData:  user data
4863*6777b538SAndroid Build Coastguard Worker  *
4864*6777b538SAndroid Build Coastguard Worker  * Initialize a parser context
4865*6777b538SAndroid Build Coastguard Worker  *
4866*6777b538SAndroid Build Coastguard Worker  * Returns 0 in case of success and -1 in case of error
4867*6777b538SAndroid Build Coastguard Worker  */
4868*6777b538SAndroid Build Coastguard Worker 
4869*6777b538SAndroid Build Coastguard Worker static int
htmlInitParserCtxt(htmlParserCtxtPtr ctxt,const htmlSAXHandler * sax,void * userData)4870*6777b538SAndroid Build Coastguard Worker htmlInitParserCtxt(htmlParserCtxtPtr ctxt, const htmlSAXHandler *sax,
4871*6777b538SAndroid Build Coastguard Worker                    void *userData)
4872*6777b538SAndroid Build Coastguard Worker {
4873*6777b538SAndroid Build Coastguard Worker     if (ctxt == NULL) return(-1);
4874*6777b538SAndroid Build Coastguard Worker     memset(ctxt, 0, sizeof(htmlParserCtxt));
4875*6777b538SAndroid Build Coastguard Worker 
4876*6777b538SAndroid Build Coastguard Worker     ctxt->dict = xmlDictCreate();
4877*6777b538SAndroid Build Coastguard Worker     if (ctxt->dict == NULL)
4878*6777b538SAndroid Build Coastguard Worker 	return(-1);
4879*6777b538SAndroid Build Coastguard Worker 
4880*6777b538SAndroid Build Coastguard Worker     if (ctxt->sax == NULL)
4881*6777b538SAndroid Build Coastguard Worker         ctxt->sax = (htmlSAXHandler *) xmlMalloc(sizeof(htmlSAXHandler));
4882*6777b538SAndroid Build Coastguard Worker     if (ctxt->sax == NULL)
4883*6777b538SAndroid Build Coastguard Worker 	return(-1);
4884*6777b538SAndroid Build Coastguard Worker     if (sax == NULL) {
4885*6777b538SAndroid Build Coastguard Worker         memset(ctxt->sax, 0, sizeof(htmlSAXHandler));
4886*6777b538SAndroid Build Coastguard Worker         xmlSAX2InitHtmlDefaultSAXHandler(ctxt->sax);
4887*6777b538SAndroid Build Coastguard Worker         ctxt->userData = ctxt;
4888*6777b538SAndroid Build Coastguard Worker     } else {
4889*6777b538SAndroid Build Coastguard Worker         memcpy(ctxt->sax, sax, sizeof(htmlSAXHandler));
4890*6777b538SAndroid Build Coastguard Worker         ctxt->userData = userData ? userData : ctxt;
4891*6777b538SAndroid Build Coastguard Worker     }
4892*6777b538SAndroid Build Coastguard Worker 
4893*6777b538SAndroid Build Coastguard Worker     /* Allocate the Input stack */
4894*6777b538SAndroid Build Coastguard Worker     ctxt->inputTab = (htmlParserInputPtr *)
4895*6777b538SAndroid Build Coastguard Worker                       xmlMalloc(5 * sizeof(htmlParserInputPtr));
4896*6777b538SAndroid Build Coastguard Worker     if (ctxt->inputTab == NULL)
4897*6777b538SAndroid Build Coastguard Worker 	return(-1);
4898*6777b538SAndroid Build Coastguard Worker     ctxt->inputNr = 0;
4899*6777b538SAndroid Build Coastguard Worker     ctxt->inputMax = 5;
4900*6777b538SAndroid Build Coastguard Worker     ctxt->input = NULL;
4901*6777b538SAndroid Build Coastguard Worker     ctxt->version = NULL;
4902*6777b538SAndroid Build Coastguard Worker     ctxt->encoding = NULL;
4903*6777b538SAndroid Build Coastguard Worker     ctxt->standalone = -1;
4904*6777b538SAndroid Build Coastguard Worker     ctxt->instate = XML_PARSER_START;
4905*6777b538SAndroid Build Coastguard Worker 
4906*6777b538SAndroid Build Coastguard Worker     /* Allocate the Node stack */
4907*6777b538SAndroid Build Coastguard Worker     ctxt->nodeTab = (htmlNodePtr *) xmlMalloc(10 * sizeof(htmlNodePtr));
4908*6777b538SAndroid Build Coastguard Worker     if (ctxt->nodeTab == NULL)
4909*6777b538SAndroid Build Coastguard Worker 	return(-1);
4910*6777b538SAndroid Build Coastguard Worker     ctxt->nodeNr = 0;
4911*6777b538SAndroid Build Coastguard Worker     ctxt->nodeMax = 10;
4912*6777b538SAndroid Build Coastguard Worker     ctxt->node = NULL;
4913*6777b538SAndroid Build Coastguard Worker 
4914*6777b538SAndroid Build Coastguard Worker     /* Allocate the Name stack */
4915*6777b538SAndroid Build Coastguard Worker     ctxt->nameTab = (const xmlChar **) xmlMalloc(10 * sizeof(xmlChar *));
4916*6777b538SAndroid Build Coastguard Worker     if (ctxt->nameTab == NULL)
4917*6777b538SAndroid Build Coastguard Worker 	return(-1);
4918*6777b538SAndroid Build Coastguard Worker     ctxt->nameNr = 0;
4919*6777b538SAndroid Build Coastguard Worker     ctxt->nameMax = 10;
4920*6777b538SAndroid Build Coastguard Worker     ctxt->name = NULL;
4921*6777b538SAndroid Build Coastguard Worker 
4922*6777b538SAndroid Build Coastguard Worker     ctxt->nodeInfoTab = NULL;
4923*6777b538SAndroid Build Coastguard Worker     ctxt->nodeInfoNr  = 0;
4924*6777b538SAndroid Build Coastguard Worker     ctxt->nodeInfoMax = 0;
4925*6777b538SAndroid Build Coastguard Worker 
4926*6777b538SAndroid Build Coastguard Worker     ctxt->myDoc = NULL;
4927*6777b538SAndroid Build Coastguard Worker     ctxt->wellFormed = 1;
4928*6777b538SAndroid Build Coastguard Worker     ctxt->replaceEntities = 0;
4929*6777b538SAndroid Build Coastguard Worker     ctxt->linenumbers = xmlLineNumbersDefaultValue;
4930*6777b538SAndroid Build Coastguard Worker     ctxt->keepBlanks = xmlKeepBlanksDefaultValue;
4931*6777b538SAndroid Build Coastguard Worker     ctxt->html = 1;
4932*6777b538SAndroid Build Coastguard Worker     ctxt->vctxt.flags = XML_VCTXT_USE_PCTXT;
4933*6777b538SAndroid Build Coastguard Worker     ctxt->vctxt.userData = ctxt;
4934*6777b538SAndroid Build Coastguard Worker     ctxt->vctxt.error = xmlParserValidityError;
4935*6777b538SAndroid Build Coastguard Worker     ctxt->vctxt.warning = xmlParserValidityWarning;
4936*6777b538SAndroid Build Coastguard Worker     ctxt->record_info = 0;
4937*6777b538SAndroid Build Coastguard Worker     ctxt->validate = 0;
4938*6777b538SAndroid Build Coastguard Worker     ctxt->checkIndex = 0;
4939*6777b538SAndroid Build Coastguard Worker     ctxt->catalogs = NULL;
4940*6777b538SAndroid Build Coastguard Worker     xmlInitNodeInfoSeq(&ctxt->node_seq);
4941*6777b538SAndroid Build Coastguard Worker     return(0);
4942*6777b538SAndroid Build Coastguard Worker }
4943*6777b538SAndroid Build Coastguard Worker 
4944*6777b538SAndroid Build Coastguard Worker /**
4945*6777b538SAndroid Build Coastguard Worker  * htmlFreeParserCtxt:
4946*6777b538SAndroid Build Coastguard Worker  * @ctxt:  an HTML parser context
4947*6777b538SAndroid Build Coastguard Worker  *
4948*6777b538SAndroid Build Coastguard Worker  * Free all the memory used by a parser context. However the parsed
4949*6777b538SAndroid Build Coastguard Worker  * document in ctxt->myDoc is not freed.
4950*6777b538SAndroid Build Coastguard Worker  */
4951*6777b538SAndroid Build Coastguard Worker 
4952*6777b538SAndroid Build Coastguard Worker void
htmlFreeParserCtxt(htmlParserCtxtPtr ctxt)4953*6777b538SAndroid Build Coastguard Worker htmlFreeParserCtxt(htmlParserCtxtPtr ctxt)
4954*6777b538SAndroid Build Coastguard Worker {
4955*6777b538SAndroid Build Coastguard Worker     xmlFreeParserCtxt(ctxt);
4956*6777b538SAndroid Build Coastguard Worker }
4957*6777b538SAndroid Build Coastguard Worker 
4958*6777b538SAndroid Build Coastguard Worker /**
4959*6777b538SAndroid Build Coastguard Worker  * htmlNewParserCtxt:
4960*6777b538SAndroid Build Coastguard Worker  *
4961*6777b538SAndroid Build Coastguard Worker  * Allocate and initialize a new HTML parser context.
4962*6777b538SAndroid Build Coastguard Worker  *
4963*6777b538SAndroid Build Coastguard Worker  * This can be used to parse HTML documents into DOM trees with
4964*6777b538SAndroid Build Coastguard Worker  * functions like xmlCtxtReadFile or xmlCtxtReadMemory.
4965*6777b538SAndroid Build Coastguard Worker  *
4966*6777b538SAndroid Build Coastguard Worker  * See htmlCtxtUseOptions for parser options.
4967*6777b538SAndroid Build Coastguard Worker  *
4968*6777b538SAndroid Build Coastguard Worker  * See xmlCtxtSetErrorHandler for advanced error handling.
4969*6777b538SAndroid Build Coastguard Worker  *
4970*6777b538SAndroid Build Coastguard Worker  * See xmlNewInputURL, xmlNewInputMemory, xmlNewInputIO and similar
4971*6777b538SAndroid Build Coastguard Worker  * functions for advanced input control.
4972*6777b538SAndroid Build Coastguard Worker  *
4973*6777b538SAndroid Build Coastguard Worker  * See htmlNewSAXParserCtxt for custom SAX parsers.
4974*6777b538SAndroid Build Coastguard Worker  *
4975*6777b538SAndroid Build Coastguard Worker  * Returns the htmlParserCtxtPtr or NULL in case of allocation error
4976*6777b538SAndroid Build Coastguard Worker  */
4977*6777b538SAndroid Build Coastguard Worker 
4978*6777b538SAndroid Build Coastguard Worker htmlParserCtxtPtr
htmlNewParserCtxt(void)4979*6777b538SAndroid Build Coastguard Worker htmlNewParserCtxt(void)
4980*6777b538SAndroid Build Coastguard Worker {
4981*6777b538SAndroid Build Coastguard Worker     return(htmlNewSAXParserCtxt(NULL, NULL));
4982*6777b538SAndroid Build Coastguard Worker }
4983*6777b538SAndroid Build Coastguard Worker 
4984*6777b538SAndroid Build Coastguard Worker /**
4985*6777b538SAndroid Build Coastguard Worker  * htmlNewSAXParserCtxt:
4986*6777b538SAndroid Build Coastguard Worker  * @sax:  SAX handler
4987*6777b538SAndroid Build Coastguard Worker  * @userData:  user data
4988*6777b538SAndroid Build Coastguard Worker  *
4989*6777b538SAndroid Build Coastguard Worker  * Allocate and initialize a new HTML SAX parser context. If userData
4990*6777b538SAndroid Build Coastguard Worker  * is NULL, the parser context will be passed as user data.
4991*6777b538SAndroid Build Coastguard Worker  *
4992*6777b538SAndroid Build Coastguard Worker  * Available since 2.11.0. If you want support older versions,
4993*6777b538SAndroid Build Coastguard Worker  * it's best to invoke htmlNewParserCtxt and set ctxt->sax with
4994*6777b538SAndroid Build Coastguard Worker  * struct assignment.
4995*6777b538SAndroid Build Coastguard Worker  *
4996*6777b538SAndroid Build Coastguard Worker  * Also see htmlNewParserCtxt.
4997*6777b538SAndroid Build Coastguard Worker  *
4998*6777b538SAndroid Build Coastguard Worker  * Returns the htmlParserCtxtPtr or NULL in case of allocation error
4999*6777b538SAndroid Build Coastguard Worker  */
5000*6777b538SAndroid Build Coastguard Worker 
5001*6777b538SAndroid Build Coastguard Worker htmlParserCtxtPtr
htmlNewSAXParserCtxt(const htmlSAXHandler * sax,void * userData)5002*6777b538SAndroid Build Coastguard Worker htmlNewSAXParserCtxt(const htmlSAXHandler *sax, void *userData)
5003*6777b538SAndroid Build Coastguard Worker {
5004*6777b538SAndroid Build Coastguard Worker     xmlParserCtxtPtr ctxt;
5005*6777b538SAndroid Build Coastguard Worker 
5006*6777b538SAndroid Build Coastguard Worker     xmlInitParser();
5007*6777b538SAndroid Build Coastguard Worker 
5008*6777b538SAndroid Build Coastguard Worker     ctxt = (xmlParserCtxtPtr) xmlMalloc(sizeof(xmlParserCtxt));
5009*6777b538SAndroid Build Coastguard Worker     if (ctxt == NULL)
5010*6777b538SAndroid Build Coastguard Worker 	return(NULL);
5011*6777b538SAndroid Build Coastguard Worker     memset(ctxt, 0, sizeof(xmlParserCtxt));
5012*6777b538SAndroid Build Coastguard Worker     if (htmlInitParserCtxt(ctxt, sax, userData) < 0) {
5013*6777b538SAndroid Build Coastguard Worker         htmlFreeParserCtxt(ctxt);
5014*6777b538SAndroid Build Coastguard Worker 	return(NULL);
5015*6777b538SAndroid Build Coastguard Worker     }
5016*6777b538SAndroid Build Coastguard Worker     return(ctxt);
5017*6777b538SAndroid Build Coastguard Worker }
5018*6777b538SAndroid Build Coastguard Worker 
5019*6777b538SAndroid Build Coastguard Worker static htmlParserCtxtPtr
htmlCreateMemoryParserCtxtInternal(const char * url,const char * buffer,size_t size,const char * encoding)5020*6777b538SAndroid Build Coastguard Worker htmlCreateMemoryParserCtxtInternal(const char *url,
5021*6777b538SAndroid Build Coastguard Worker                                    const char *buffer, size_t size,
5022*6777b538SAndroid Build Coastguard Worker                                    const char *encoding) {
5023*6777b538SAndroid Build Coastguard Worker     xmlParserCtxtPtr ctxt;
5024*6777b538SAndroid Build Coastguard Worker     xmlParserInputPtr input;
5025*6777b538SAndroid Build Coastguard Worker 
5026*6777b538SAndroid Build Coastguard Worker     if (buffer == NULL)
5027*6777b538SAndroid Build Coastguard Worker 	return(NULL);
5028*6777b538SAndroid Build Coastguard Worker 
5029*6777b538SAndroid Build Coastguard Worker     ctxt = htmlNewParserCtxt();
5030*6777b538SAndroid Build Coastguard Worker     if (ctxt == NULL)
5031*6777b538SAndroid Build Coastguard Worker 	return(NULL);
5032*6777b538SAndroid Build Coastguard Worker 
5033*6777b538SAndroid Build Coastguard Worker     input = xmlNewInputMemory(ctxt, url, buffer, size, encoding, 0);
5034*6777b538SAndroid Build Coastguard Worker     if (input == NULL) {
5035*6777b538SAndroid Build Coastguard Worker 	xmlFreeParserCtxt(ctxt);
5036*6777b538SAndroid Build Coastguard Worker         return(NULL);
5037*6777b538SAndroid Build Coastguard Worker     }
5038*6777b538SAndroid Build Coastguard Worker 
5039*6777b538SAndroid Build Coastguard Worker     inputPush(ctxt, input);
5040*6777b538SAndroid Build Coastguard Worker 
5041*6777b538SAndroid Build Coastguard Worker     return(ctxt);
5042*6777b538SAndroid Build Coastguard Worker }
5043*6777b538SAndroid Build Coastguard Worker 
5044*6777b538SAndroid Build Coastguard Worker /**
5045*6777b538SAndroid Build Coastguard Worker  * htmlCreateMemoryParserCtxt:
5046*6777b538SAndroid Build Coastguard Worker  * @buffer:  a pointer to a char array
5047*6777b538SAndroid Build Coastguard Worker  * @size:  the size of the array
5048*6777b538SAndroid Build Coastguard Worker  *
5049*6777b538SAndroid Build Coastguard Worker  * DEPRECATED: Use htmlNewParserCtxt and htmlCtxtReadMemory.
5050*6777b538SAndroid Build Coastguard Worker  *
5051*6777b538SAndroid Build Coastguard Worker  * Create a parser context for an HTML in-memory document. The input
5052*6777b538SAndroid Build Coastguard Worker  * buffer must not contain any terminating null bytes.
5053*6777b538SAndroid Build Coastguard Worker  *
5054*6777b538SAndroid Build Coastguard Worker  * Returns the new parser context or NULL
5055*6777b538SAndroid Build Coastguard Worker  */
5056*6777b538SAndroid Build Coastguard Worker htmlParserCtxtPtr
htmlCreateMemoryParserCtxt(const char * buffer,int size)5057*6777b538SAndroid Build Coastguard Worker htmlCreateMemoryParserCtxt(const char *buffer, int size) {
5058*6777b538SAndroid Build Coastguard Worker     if (size <= 0)
5059*6777b538SAndroid Build Coastguard Worker 	return(NULL);
5060*6777b538SAndroid Build Coastguard Worker 
5061*6777b538SAndroid Build Coastguard Worker     return(htmlCreateMemoryParserCtxtInternal(NULL, buffer, size, NULL));
5062*6777b538SAndroid Build Coastguard Worker }
5063*6777b538SAndroid Build Coastguard Worker 
5064*6777b538SAndroid Build Coastguard Worker /**
5065*6777b538SAndroid Build Coastguard Worker  * htmlCreateDocParserCtxt:
5066*6777b538SAndroid Build Coastguard Worker  * @str:  a pointer to an array of xmlChar
5067*6777b538SAndroid Build Coastguard Worker  * @encoding:  encoding (optional)
5068*6777b538SAndroid Build Coastguard Worker  *
5069*6777b538SAndroid Build Coastguard Worker  * Create a parser context for a null-terminated string.
5070*6777b538SAndroid Build Coastguard Worker  *
5071*6777b538SAndroid Build Coastguard Worker  * Returns the new parser context or NULL if a memory allocation failed.
5072*6777b538SAndroid Build Coastguard Worker  */
5073*6777b538SAndroid Build Coastguard Worker static htmlParserCtxtPtr
htmlCreateDocParserCtxt(const xmlChar * str,const char * url,const char * encoding)5074*6777b538SAndroid Build Coastguard Worker htmlCreateDocParserCtxt(const xmlChar *str, const char *url,
5075*6777b538SAndroid Build Coastguard Worker                         const char *encoding) {
5076*6777b538SAndroid Build Coastguard Worker     xmlParserCtxtPtr ctxt;
5077*6777b538SAndroid Build Coastguard Worker     xmlParserInputPtr input;
5078*6777b538SAndroid Build Coastguard Worker 
5079*6777b538SAndroid Build Coastguard Worker     if (str == NULL)
5080*6777b538SAndroid Build Coastguard Worker 	return(NULL);
5081*6777b538SAndroid Build Coastguard Worker 
5082*6777b538SAndroid Build Coastguard Worker     ctxt = htmlNewParserCtxt();
5083*6777b538SAndroid Build Coastguard Worker     if (ctxt == NULL)
5084*6777b538SAndroid Build Coastguard Worker 	return(NULL);
5085*6777b538SAndroid Build Coastguard Worker 
5086*6777b538SAndroid Build Coastguard Worker     input = xmlNewInputString(ctxt, url, (const char *) str, encoding, 0);
5087*6777b538SAndroid Build Coastguard Worker     if (input == NULL) {
5088*6777b538SAndroid Build Coastguard Worker 	xmlFreeParserCtxt(ctxt);
5089*6777b538SAndroid Build Coastguard Worker 	return(NULL);
5090*6777b538SAndroid Build Coastguard Worker     }
5091*6777b538SAndroid Build Coastguard Worker 
5092*6777b538SAndroid Build Coastguard Worker     inputPush(ctxt, input);
5093*6777b538SAndroid Build Coastguard Worker 
5094*6777b538SAndroid Build Coastguard Worker     return(ctxt);
5095*6777b538SAndroid Build Coastguard Worker }
5096*6777b538SAndroid Build Coastguard Worker 
5097*6777b538SAndroid Build Coastguard Worker #ifdef LIBXML_PUSH_ENABLED
5098*6777b538SAndroid Build Coastguard Worker /************************************************************************
5099*6777b538SAndroid Build Coastguard Worker  *									*
5100*6777b538SAndroid Build Coastguard Worker  *	Progressive parsing interfaces				*
5101*6777b538SAndroid Build Coastguard Worker  *									*
5102*6777b538SAndroid Build Coastguard Worker  ************************************************************************/
5103*6777b538SAndroid Build Coastguard Worker 
5104*6777b538SAndroid Build Coastguard Worker /**
5105*6777b538SAndroid Build Coastguard Worker  * htmlParseLookupSequence:
5106*6777b538SAndroid Build Coastguard Worker  * @ctxt:  an HTML parser context
5107*6777b538SAndroid Build Coastguard Worker  * @first:  the first char to lookup
5108*6777b538SAndroid Build Coastguard Worker  * @next:  the next char to lookup or zero
5109*6777b538SAndroid Build Coastguard Worker  * @third:  the next char to lookup or zero
5110*6777b538SAndroid Build Coastguard Worker  * @ignoreattrval: skip over attribute values
5111*6777b538SAndroid Build Coastguard Worker  *
5112*6777b538SAndroid Build Coastguard Worker  * Try to find if a sequence (first, next, third) or  just (first next) or
5113*6777b538SAndroid Build Coastguard Worker  * (first) is available in the input stream.
5114*6777b538SAndroid Build Coastguard Worker  * This function has a side effect of (possibly) incrementing ctxt->checkIndex
5115*6777b538SAndroid Build Coastguard Worker  * to avoid rescanning sequences of bytes, it DOES change the state of the
5116*6777b538SAndroid Build Coastguard Worker  * parser, do not use liberally.
5117*6777b538SAndroid Build Coastguard Worker  * This is basically similar to xmlParseLookupSequence()
5118*6777b538SAndroid Build Coastguard Worker  *
5119*6777b538SAndroid Build Coastguard Worker  * Returns the index to the current parsing point if the full sequence
5120*6777b538SAndroid Build Coastguard Worker  *      is available, -1 otherwise.
5121*6777b538SAndroid Build Coastguard Worker  */
5122*6777b538SAndroid Build Coastguard Worker static int
htmlParseLookupSequence(htmlParserCtxtPtr ctxt,xmlChar first,xmlChar next,xmlChar third,int ignoreattrval)5123*6777b538SAndroid Build Coastguard Worker htmlParseLookupSequence(htmlParserCtxtPtr ctxt, xmlChar first,
5124*6777b538SAndroid Build Coastguard Worker                         xmlChar next, xmlChar third, int ignoreattrval)
5125*6777b538SAndroid Build Coastguard Worker {
5126*6777b538SAndroid Build Coastguard Worker     size_t base, len;
5127*6777b538SAndroid Build Coastguard Worker     htmlParserInputPtr in;
5128*6777b538SAndroid Build Coastguard Worker     const xmlChar *buf;
5129*6777b538SAndroid Build Coastguard Worker     int quote;
5130*6777b538SAndroid Build Coastguard Worker 
5131*6777b538SAndroid Build Coastguard Worker     in = ctxt->input;
5132*6777b538SAndroid Build Coastguard Worker     if (in == NULL)
5133*6777b538SAndroid Build Coastguard Worker         return (-1);
5134*6777b538SAndroid Build Coastguard Worker 
5135*6777b538SAndroid Build Coastguard Worker     base = ctxt->checkIndex;
5136*6777b538SAndroid Build Coastguard Worker     quote = ctxt->endCheckState;
5137*6777b538SAndroid Build Coastguard Worker 
5138*6777b538SAndroid Build Coastguard Worker     buf = in->cur;
5139*6777b538SAndroid Build Coastguard Worker     len = in->end - in->cur;
5140*6777b538SAndroid Build Coastguard Worker 
5141*6777b538SAndroid Build Coastguard Worker     /* take into account the sequence length */
5142*6777b538SAndroid Build Coastguard Worker     if (third)
5143*6777b538SAndroid Build Coastguard Worker         len -= 2;
5144*6777b538SAndroid Build Coastguard Worker     else if (next)
5145*6777b538SAndroid Build Coastguard Worker         len--;
5146*6777b538SAndroid Build Coastguard Worker     for (; base < len; base++) {
5147*6777b538SAndroid Build Coastguard Worker         if (base >= INT_MAX / 2) {
5148*6777b538SAndroid Build Coastguard Worker             ctxt->checkIndex = 0;
5149*6777b538SAndroid Build Coastguard Worker             ctxt->endCheckState = 0;
5150*6777b538SAndroid Build Coastguard Worker             return (base - 2);
5151*6777b538SAndroid Build Coastguard Worker         }
5152*6777b538SAndroid Build Coastguard Worker         if (ignoreattrval) {
5153*6777b538SAndroid Build Coastguard Worker             if (quote) {
5154*6777b538SAndroid Build Coastguard Worker                 if (buf[base] == quote)
5155*6777b538SAndroid Build Coastguard Worker                     quote = 0;
5156*6777b538SAndroid Build Coastguard Worker                 continue;
5157*6777b538SAndroid Build Coastguard Worker             }
5158*6777b538SAndroid Build Coastguard Worker             if (buf[base] == '"' || buf[base] == '\'') {
5159*6777b538SAndroid Build Coastguard Worker                 quote = buf[base];
5160*6777b538SAndroid Build Coastguard Worker                 continue;
5161*6777b538SAndroid Build Coastguard Worker             }
5162*6777b538SAndroid Build Coastguard Worker         }
5163*6777b538SAndroid Build Coastguard Worker         if (buf[base] == first) {
5164*6777b538SAndroid Build Coastguard Worker             if (third != 0) {
5165*6777b538SAndroid Build Coastguard Worker                 if ((buf[base + 1] != next) || (buf[base + 2] != third))
5166*6777b538SAndroid Build Coastguard Worker                     continue;
5167*6777b538SAndroid Build Coastguard Worker             } else if (next != 0) {
5168*6777b538SAndroid Build Coastguard Worker                 if (buf[base + 1] != next)
5169*6777b538SAndroid Build Coastguard Worker                     continue;
5170*6777b538SAndroid Build Coastguard Worker             }
5171*6777b538SAndroid Build Coastguard Worker             ctxt->checkIndex = 0;
5172*6777b538SAndroid Build Coastguard Worker             ctxt->endCheckState = 0;
5173*6777b538SAndroid Build Coastguard Worker             return (base);
5174*6777b538SAndroid Build Coastguard Worker         }
5175*6777b538SAndroid Build Coastguard Worker     }
5176*6777b538SAndroid Build Coastguard Worker     ctxt->checkIndex = base;
5177*6777b538SAndroid Build Coastguard Worker     ctxt->endCheckState = quote;
5178*6777b538SAndroid Build Coastguard Worker     return (-1);
5179*6777b538SAndroid Build Coastguard Worker }
5180*6777b538SAndroid Build Coastguard Worker 
5181*6777b538SAndroid Build Coastguard Worker /**
5182*6777b538SAndroid Build Coastguard Worker  * htmlParseLookupCommentEnd:
5183*6777b538SAndroid Build Coastguard Worker  * @ctxt: an HTML parser context
5184*6777b538SAndroid Build Coastguard Worker  *
5185*6777b538SAndroid Build Coastguard Worker  * Try to find a comment end tag in the input stream
5186*6777b538SAndroid Build Coastguard Worker  * The search includes "-->" as well as WHATWG-recommended incorrectly-closed tags.
5187*6777b538SAndroid Build Coastguard Worker  * (See https://html.spec.whatwg.org/multipage/parsing.html#parse-error-incorrectly-closed-comment)
5188*6777b538SAndroid Build Coastguard Worker  * This function has a side effect of (possibly) incrementing ctxt->checkIndex
5189*6777b538SAndroid Build Coastguard Worker  * to avoid rescanning sequences of bytes, it DOES change the state of the
5190*6777b538SAndroid Build Coastguard Worker  * parser, do not use liberally.
5191*6777b538SAndroid Build Coastguard Worker  * This wraps to htmlParseLookupSequence()
5192*6777b538SAndroid Build Coastguard Worker  *
5193*6777b538SAndroid Build Coastguard Worker  * Returns the index to the current parsing point if the full sequence is available, -1 otherwise.
5194*6777b538SAndroid Build Coastguard Worker  */
5195*6777b538SAndroid Build Coastguard Worker static int
htmlParseLookupCommentEnd(htmlParserCtxtPtr ctxt)5196*6777b538SAndroid Build Coastguard Worker htmlParseLookupCommentEnd(htmlParserCtxtPtr ctxt)
5197*6777b538SAndroid Build Coastguard Worker {
5198*6777b538SAndroid Build Coastguard Worker     int mark = 0;
5199*6777b538SAndroid Build Coastguard Worker     int offset;
5200*6777b538SAndroid Build Coastguard Worker 
5201*6777b538SAndroid Build Coastguard Worker     while (1) {
5202*6777b538SAndroid Build Coastguard Worker 	mark = htmlParseLookupSequence(ctxt, '-', '-', 0, 0);
5203*6777b538SAndroid Build Coastguard Worker 	if (mark < 0)
5204*6777b538SAndroid Build Coastguard Worker             break;
5205*6777b538SAndroid Build Coastguard Worker         if ((NXT(mark+2) == '>') ||
5206*6777b538SAndroid Build Coastguard Worker 	    ((NXT(mark+2) == '!') && (NXT(mark+3) == '>'))) {
5207*6777b538SAndroid Build Coastguard Worker             ctxt->checkIndex = 0;
5208*6777b538SAndroid Build Coastguard Worker 	    break;
5209*6777b538SAndroid Build Coastguard Worker 	}
5210*6777b538SAndroid Build Coastguard Worker         offset = (NXT(mark+2) == '!') ? 3 : 2;
5211*6777b538SAndroid Build Coastguard Worker         if (mark + offset >= ctxt->input->end - ctxt->input->cur) {
5212*6777b538SAndroid Build Coastguard Worker 	    ctxt->checkIndex = mark;
5213*6777b538SAndroid Build Coastguard Worker             return(-1);
5214*6777b538SAndroid Build Coastguard Worker         }
5215*6777b538SAndroid Build Coastguard Worker 	ctxt->checkIndex = mark + 1;
5216*6777b538SAndroid Build Coastguard Worker     }
5217*6777b538SAndroid Build Coastguard Worker     return mark;
5218*6777b538SAndroid Build Coastguard Worker }
5219*6777b538SAndroid Build Coastguard Worker 
5220*6777b538SAndroid Build Coastguard Worker 
5221*6777b538SAndroid Build Coastguard Worker /**
5222*6777b538SAndroid Build Coastguard Worker  * htmlParseTryOrFinish:
5223*6777b538SAndroid Build Coastguard Worker  * @ctxt:  an HTML parser context
5224*6777b538SAndroid Build Coastguard Worker  * @terminate:  last chunk indicator
5225*6777b538SAndroid Build Coastguard Worker  *
5226*6777b538SAndroid Build Coastguard Worker  * Try to progress on parsing
5227*6777b538SAndroid Build Coastguard Worker  *
5228*6777b538SAndroid Build Coastguard Worker  * Returns zero if no parsing was possible
5229*6777b538SAndroid Build Coastguard Worker  */
5230*6777b538SAndroid Build Coastguard Worker static int
htmlParseTryOrFinish(htmlParserCtxtPtr ctxt,int terminate)5231*6777b538SAndroid Build Coastguard Worker htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
5232*6777b538SAndroid Build Coastguard Worker     int ret = 0;
5233*6777b538SAndroid Build Coastguard Worker     htmlParserInputPtr in;
5234*6777b538SAndroid Build Coastguard Worker     ptrdiff_t avail = 0;
5235*6777b538SAndroid Build Coastguard Worker     xmlChar cur, next;
5236*6777b538SAndroid Build Coastguard Worker 
5237*6777b538SAndroid Build Coastguard Worker     htmlParserNodeInfo node_info;
5238*6777b538SAndroid Build Coastguard Worker 
5239*6777b538SAndroid Build Coastguard Worker     while (PARSER_STOPPED(ctxt) == 0) {
5240*6777b538SAndroid Build Coastguard Worker 
5241*6777b538SAndroid Build Coastguard Worker 	in = ctxt->input;
5242*6777b538SAndroid Build Coastguard Worker 	if (in == NULL) break;
5243*6777b538SAndroid Build Coastguard Worker 	avail = in->end - in->cur;
5244*6777b538SAndroid Build Coastguard Worker 	if ((avail == 0) && (terminate)) {
5245*6777b538SAndroid Build Coastguard Worker 	    htmlAutoCloseOnEnd(ctxt);
5246*6777b538SAndroid Build Coastguard Worker 	    if ((ctxt->nameNr == 0) && (ctxt->instate != XML_PARSER_EOF)) {
5247*6777b538SAndroid Build Coastguard Worker 		/*
5248*6777b538SAndroid Build Coastguard Worker 		 * SAX: end of the document processing.
5249*6777b538SAndroid Build Coastguard Worker 		 */
5250*6777b538SAndroid Build Coastguard Worker 		ctxt->instate = XML_PARSER_EOF;
5251*6777b538SAndroid Build Coastguard Worker 		if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
5252*6777b538SAndroid Build Coastguard Worker 		    ctxt->sax->endDocument(ctxt->userData);
5253*6777b538SAndroid Build Coastguard Worker 	    }
5254*6777b538SAndroid Build Coastguard Worker 	}
5255*6777b538SAndroid Build Coastguard Worker         if (avail < 1)
5256*6777b538SAndroid Build Coastguard Worker 	    goto done;
5257*6777b538SAndroid Build Coastguard Worker         /*
5258*6777b538SAndroid Build Coastguard Worker          * This is done to make progress and avoid an infinite loop
5259*6777b538SAndroid Build Coastguard Worker          * if a parsing attempt was aborted by hitting a NUL byte. After
5260*6777b538SAndroid Build Coastguard Worker          * changing htmlCurrentChar, this probably isn't necessary anymore.
5261*6777b538SAndroid Build Coastguard Worker          * We should consider removing this check.
5262*6777b538SAndroid Build Coastguard Worker          */
5263*6777b538SAndroid Build Coastguard Worker 	cur = in->cur[0];
5264*6777b538SAndroid Build Coastguard Worker 	if (cur == 0) {
5265*6777b538SAndroid Build Coastguard Worker 	    SKIP(1);
5266*6777b538SAndroid Build Coastguard Worker 	    continue;
5267*6777b538SAndroid Build Coastguard Worker 	}
5268*6777b538SAndroid Build Coastguard Worker 
5269*6777b538SAndroid Build Coastguard Worker         switch (ctxt->instate) {
5270*6777b538SAndroid Build Coastguard Worker             case XML_PARSER_EOF:
5271*6777b538SAndroid Build Coastguard Worker 	        /*
5272*6777b538SAndroid Build Coastguard Worker 		 * Document parsing is done !
5273*6777b538SAndroid Build Coastguard Worker 		 */
5274*6777b538SAndroid Build Coastguard Worker 	        goto done;
5275*6777b538SAndroid Build Coastguard Worker             case XML_PARSER_START:
5276*6777b538SAndroid Build Coastguard Worker                 /*
5277*6777b538SAndroid Build Coastguard Worker                  * This is wrong but matches long-standing behavior. In most
5278*6777b538SAndroid Build Coastguard Worker                  * cases, a document starting with an XML declaration will
5279*6777b538SAndroid Build Coastguard Worker                  * specify UTF-8.
5280*6777b538SAndroid Build Coastguard Worker                  */
5281*6777b538SAndroid Build Coastguard Worker                 if (((ctxt->input->flags & XML_INPUT_HAS_ENCODING) == 0) &&
5282*6777b538SAndroid Build Coastguard Worker                     (xmlStrncmp(ctxt->input->cur, BAD_CAST "<?xm", 4) == 0)) {
5283*6777b538SAndroid Build Coastguard Worker                     xmlSwitchEncoding(ctxt, XML_CHAR_ENCODING_UTF8);
5284*6777b538SAndroid Build Coastguard Worker                 }
5285*6777b538SAndroid Build Coastguard Worker 
5286*6777b538SAndroid Build Coastguard Worker 	        /*
5287*6777b538SAndroid Build Coastguard Worker 		 * Very first chars read from the document flow.
5288*6777b538SAndroid Build Coastguard Worker 		 */
5289*6777b538SAndroid Build Coastguard Worker 		cur = in->cur[0];
5290*6777b538SAndroid Build Coastguard Worker 		if (IS_BLANK_CH(cur)) {
5291*6777b538SAndroid Build Coastguard Worker 		    SKIP_BLANKS;
5292*6777b538SAndroid Build Coastguard Worker                     avail = in->end - in->cur;
5293*6777b538SAndroid Build Coastguard Worker 		}
5294*6777b538SAndroid Build Coastguard Worker                 if ((ctxt->sax) && (ctxt->sax->setDocumentLocator)) {
5295*6777b538SAndroid Build Coastguard Worker                     xmlSAXLocator copy = xmlDefaultSAXLocator;
5296*6777b538SAndroid Build Coastguard Worker                     ctxt->sax->setDocumentLocator(ctxt->userData, &copy);
5297*6777b538SAndroid Build Coastguard Worker                 }
5298*6777b538SAndroid Build Coastguard Worker 		if ((ctxt->sax) && (ctxt->sax->startDocument) &&
5299*6777b538SAndroid Build Coastguard Worker 	            (!ctxt->disableSAX))
5300*6777b538SAndroid Build Coastguard Worker 		    ctxt->sax->startDocument(ctxt->userData);
5301*6777b538SAndroid Build Coastguard Worker 
5302*6777b538SAndroid Build Coastguard Worker 		cur = in->cur[0];
5303*6777b538SAndroid Build Coastguard Worker 		next = in->cur[1];
5304*6777b538SAndroid Build Coastguard Worker 		if ((cur == '<') && (next == '!') &&
5305*6777b538SAndroid Build Coastguard Worker 		    (UPP(2) == 'D') && (UPP(3) == 'O') &&
5306*6777b538SAndroid Build Coastguard Worker 		    (UPP(4) == 'C') && (UPP(5) == 'T') &&
5307*6777b538SAndroid Build Coastguard Worker 		    (UPP(6) == 'Y') && (UPP(7) == 'P') &&
5308*6777b538SAndroid Build Coastguard Worker 		    (UPP(8) == 'E')) {
5309*6777b538SAndroid Build Coastguard Worker 		    if ((!terminate) &&
5310*6777b538SAndroid Build Coastguard Worker 		        (htmlParseLookupSequence(ctxt, '>', 0, 0, 1) < 0))
5311*6777b538SAndroid Build Coastguard Worker 			goto done;
5312*6777b538SAndroid Build Coastguard Worker 		    htmlParseDocTypeDecl(ctxt);
5313*6777b538SAndroid Build Coastguard Worker 		    ctxt->instate = XML_PARSER_PROLOG;
5314*6777b538SAndroid Build Coastguard Worker                 } else {
5315*6777b538SAndroid Build Coastguard Worker 		    ctxt->instate = XML_PARSER_MISC;
5316*6777b538SAndroid Build Coastguard Worker 		}
5317*6777b538SAndroid Build Coastguard Worker 		break;
5318*6777b538SAndroid Build Coastguard Worker             case XML_PARSER_MISC:
5319*6777b538SAndroid Build Coastguard Worker 		SKIP_BLANKS;
5320*6777b538SAndroid Build Coastguard Worker                 avail = in->end - in->cur;
5321*6777b538SAndroid Build Coastguard Worker 		/*
5322*6777b538SAndroid Build Coastguard Worker 		 * no chars in buffer
5323*6777b538SAndroid Build Coastguard Worker 		 */
5324*6777b538SAndroid Build Coastguard Worker 		if (avail < 1)
5325*6777b538SAndroid Build Coastguard Worker 		    goto done;
5326*6777b538SAndroid Build Coastguard Worker 		/*
5327*6777b538SAndroid Build Coastguard Worker 		 * not enough chars in buffer
5328*6777b538SAndroid Build Coastguard Worker 		 */
5329*6777b538SAndroid Build Coastguard Worker 		if (avail < 2) {
5330*6777b538SAndroid Build Coastguard Worker 		    if (!terminate)
5331*6777b538SAndroid Build Coastguard Worker 			goto done;
5332*6777b538SAndroid Build Coastguard Worker 		    else
5333*6777b538SAndroid Build Coastguard Worker 			next = ' ';
5334*6777b538SAndroid Build Coastguard Worker 		} else {
5335*6777b538SAndroid Build Coastguard Worker 		    next = in->cur[1];
5336*6777b538SAndroid Build Coastguard Worker 		}
5337*6777b538SAndroid Build Coastguard Worker 		cur = in->cur[0];
5338*6777b538SAndroid Build Coastguard Worker 	        if ((cur == '<') && (next == '!') &&
5339*6777b538SAndroid Build Coastguard Worker 		    (in->cur[2] == '-') && (in->cur[3] == '-')) {
5340*6777b538SAndroid Build Coastguard Worker 		    if ((!terminate) && (htmlParseLookupCommentEnd(ctxt) < 0))
5341*6777b538SAndroid Build Coastguard Worker 			goto done;
5342*6777b538SAndroid Build Coastguard Worker 		    htmlParseComment(ctxt);
5343*6777b538SAndroid Build Coastguard Worker 		    ctxt->instate = XML_PARSER_MISC;
5344*6777b538SAndroid Build Coastguard Worker 	        } else if ((cur == '<') && (next == '?')) {
5345*6777b538SAndroid Build Coastguard Worker 		    if ((!terminate) &&
5346*6777b538SAndroid Build Coastguard Worker 		        (htmlParseLookupSequence(ctxt, '>', 0, 0, 0) < 0))
5347*6777b538SAndroid Build Coastguard Worker 			goto done;
5348*6777b538SAndroid Build Coastguard Worker 		    htmlParsePI(ctxt);
5349*6777b538SAndroid Build Coastguard Worker 		    ctxt->instate = XML_PARSER_MISC;
5350*6777b538SAndroid Build Coastguard Worker 		} else if ((cur == '<') && (next == '!') &&
5351*6777b538SAndroid Build Coastguard Worker 		    (UPP(2) == 'D') && (UPP(3) == 'O') &&
5352*6777b538SAndroid Build Coastguard Worker 		    (UPP(4) == 'C') && (UPP(5) == 'T') &&
5353*6777b538SAndroid Build Coastguard Worker 		    (UPP(6) == 'Y') && (UPP(7) == 'P') &&
5354*6777b538SAndroid Build Coastguard Worker 		    (UPP(8) == 'E')) {
5355*6777b538SAndroid Build Coastguard Worker 		    if ((!terminate) &&
5356*6777b538SAndroid Build Coastguard Worker 		        (htmlParseLookupSequence(ctxt, '>', 0, 0, 1) < 0))
5357*6777b538SAndroid Build Coastguard Worker 			goto done;
5358*6777b538SAndroid Build Coastguard Worker 		    htmlParseDocTypeDecl(ctxt);
5359*6777b538SAndroid Build Coastguard Worker 		    ctxt->instate = XML_PARSER_PROLOG;
5360*6777b538SAndroid Build Coastguard Worker 		} else if ((cur == '<') && (next == '!') &&
5361*6777b538SAndroid Build Coastguard Worker 		           (avail < 9)) {
5362*6777b538SAndroid Build Coastguard Worker 		    goto done;
5363*6777b538SAndroid Build Coastguard Worker 		} else {
5364*6777b538SAndroid Build Coastguard Worker 		    ctxt->instate = XML_PARSER_CONTENT;
5365*6777b538SAndroid Build Coastguard Worker 		}
5366*6777b538SAndroid Build Coastguard Worker 		break;
5367*6777b538SAndroid Build Coastguard Worker             case XML_PARSER_PROLOG:
5368*6777b538SAndroid Build Coastguard Worker 		SKIP_BLANKS;
5369*6777b538SAndroid Build Coastguard Worker                 avail = in->end - in->cur;
5370*6777b538SAndroid Build Coastguard Worker 		if (avail < 2)
5371*6777b538SAndroid Build Coastguard Worker 		    goto done;
5372*6777b538SAndroid Build Coastguard Worker 		cur = in->cur[0];
5373*6777b538SAndroid Build Coastguard Worker 		next = in->cur[1];
5374*6777b538SAndroid Build Coastguard Worker 		if ((cur == '<') && (next == '!') &&
5375*6777b538SAndroid Build Coastguard Worker 		    (in->cur[2] == '-') && (in->cur[3] == '-')) {
5376*6777b538SAndroid Build Coastguard Worker 		    if ((!terminate) && (htmlParseLookupCommentEnd(ctxt) < 0))
5377*6777b538SAndroid Build Coastguard Worker 			goto done;
5378*6777b538SAndroid Build Coastguard Worker 		    htmlParseComment(ctxt);
5379*6777b538SAndroid Build Coastguard Worker 		    ctxt->instate = XML_PARSER_PROLOG;
5380*6777b538SAndroid Build Coastguard Worker 	        } else if ((cur == '<') && (next == '?')) {
5381*6777b538SAndroid Build Coastguard Worker 		    if ((!terminate) &&
5382*6777b538SAndroid Build Coastguard Worker 		        (htmlParseLookupSequence(ctxt, '>', 0, 0, 0) < 0))
5383*6777b538SAndroid Build Coastguard Worker 			goto done;
5384*6777b538SAndroid Build Coastguard Worker 		    htmlParsePI(ctxt);
5385*6777b538SAndroid Build Coastguard Worker 		    ctxt->instate = XML_PARSER_PROLOG;
5386*6777b538SAndroid Build Coastguard Worker 		} else if ((cur == '<') && (next == '!') &&
5387*6777b538SAndroid Build Coastguard Worker 		           (avail < 4)) {
5388*6777b538SAndroid Build Coastguard Worker 		    goto done;
5389*6777b538SAndroid Build Coastguard Worker 		} else {
5390*6777b538SAndroid Build Coastguard Worker 		    ctxt->instate = XML_PARSER_CONTENT;
5391*6777b538SAndroid Build Coastguard Worker 		}
5392*6777b538SAndroid Build Coastguard Worker 		break;
5393*6777b538SAndroid Build Coastguard Worker             case XML_PARSER_EPILOG:
5394*6777b538SAndroid Build Coastguard Worker                 avail = in->end - in->cur;
5395*6777b538SAndroid Build Coastguard Worker 		if (avail < 1)
5396*6777b538SAndroid Build Coastguard Worker 		    goto done;
5397*6777b538SAndroid Build Coastguard Worker 		cur = in->cur[0];
5398*6777b538SAndroid Build Coastguard Worker 		if (IS_BLANK_CH(cur)) {
5399*6777b538SAndroid Build Coastguard Worker 		    htmlParseCharData(ctxt);
5400*6777b538SAndroid Build Coastguard Worker 		    goto done;
5401*6777b538SAndroid Build Coastguard Worker 		}
5402*6777b538SAndroid Build Coastguard Worker 		if (avail < 2)
5403*6777b538SAndroid Build Coastguard Worker 		    goto done;
5404*6777b538SAndroid Build Coastguard Worker 		next = in->cur[1];
5405*6777b538SAndroid Build Coastguard Worker 	        if ((cur == '<') && (next == '!') &&
5406*6777b538SAndroid Build Coastguard Worker 		    (in->cur[2] == '-') && (in->cur[3] == '-')) {
5407*6777b538SAndroid Build Coastguard Worker 		    if ((!terminate) && (htmlParseLookupCommentEnd(ctxt) < 0))
5408*6777b538SAndroid Build Coastguard Worker 			goto done;
5409*6777b538SAndroid Build Coastguard Worker 		    htmlParseComment(ctxt);
5410*6777b538SAndroid Build Coastguard Worker 		    ctxt->instate = XML_PARSER_EPILOG;
5411*6777b538SAndroid Build Coastguard Worker 	        } else if ((cur == '<') && (next == '?')) {
5412*6777b538SAndroid Build Coastguard Worker 		    if ((!terminate) &&
5413*6777b538SAndroid Build Coastguard Worker 		        (htmlParseLookupSequence(ctxt, '>', 0, 0, 0) < 0))
5414*6777b538SAndroid Build Coastguard Worker 			goto done;
5415*6777b538SAndroid Build Coastguard Worker 		    htmlParsePI(ctxt);
5416*6777b538SAndroid Build Coastguard Worker 		    ctxt->instate = XML_PARSER_EPILOG;
5417*6777b538SAndroid Build Coastguard Worker 		} else if ((cur == '<') && (next == '!') &&
5418*6777b538SAndroid Build Coastguard Worker 		           (avail < 4)) {
5419*6777b538SAndroid Build Coastguard Worker 		    goto done;
5420*6777b538SAndroid Build Coastguard Worker 		} else {
5421*6777b538SAndroid Build Coastguard Worker 		    ctxt->errNo = XML_ERR_DOCUMENT_END;
5422*6777b538SAndroid Build Coastguard Worker 		    ctxt->wellFormed = 0;
5423*6777b538SAndroid Build Coastguard Worker 		    ctxt->instate = XML_PARSER_EOF;
5424*6777b538SAndroid Build Coastguard Worker 		    if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
5425*6777b538SAndroid Build Coastguard Worker 			ctxt->sax->endDocument(ctxt->userData);
5426*6777b538SAndroid Build Coastguard Worker 		    goto done;
5427*6777b538SAndroid Build Coastguard Worker 		}
5428*6777b538SAndroid Build Coastguard Worker 		break;
5429*6777b538SAndroid Build Coastguard Worker             case XML_PARSER_START_TAG: {
5430*6777b538SAndroid Build Coastguard Worker 	        const xmlChar *name;
5431*6777b538SAndroid Build Coastguard Worker 		int failed;
5432*6777b538SAndroid Build Coastguard Worker 		const htmlElemDesc * info;
5433*6777b538SAndroid Build Coastguard Worker 
5434*6777b538SAndroid Build Coastguard Worker 		/*
5435*6777b538SAndroid Build Coastguard Worker 		 * no chars in buffer
5436*6777b538SAndroid Build Coastguard Worker 		 */
5437*6777b538SAndroid Build Coastguard Worker 		if (avail < 1)
5438*6777b538SAndroid Build Coastguard Worker 		    goto done;
5439*6777b538SAndroid Build Coastguard Worker 		/*
5440*6777b538SAndroid Build Coastguard Worker 		 * not enough chars in buffer
5441*6777b538SAndroid Build Coastguard Worker 		 */
5442*6777b538SAndroid Build Coastguard Worker 		if (avail < 2) {
5443*6777b538SAndroid Build Coastguard Worker 		    if (!terminate)
5444*6777b538SAndroid Build Coastguard Worker 			goto done;
5445*6777b538SAndroid Build Coastguard Worker 		    else
5446*6777b538SAndroid Build Coastguard Worker 			next = ' ';
5447*6777b538SAndroid Build Coastguard Worker 		} else {
5448*6777b538SAndroid Build Coastguard Worker 		    next = in->cur[1];
5449*6777b538SAndroid Build Coastguard Worker 		}
5450*6777b538SAndroid Build Coastguard Worker 		cur = in->cur[0];
5451*6777b538SAndroid Build Coastguard Worker 	        if (cur != '<') {
5452*6777b538SAndroid Build Coastguard Worker 		    ctxt->instate = XML_PARSER_CONTENT;
5453*6777b538SAndroid Build Coastguard Worker 		    break;
5454*6777b538SAndroid Build Coastguard Worker 		}
5455*6777b538SAndroid Build Coastguard Worker 		if (next == '/') {
5456*6777b538SAndroid Build Coastguard Worker 		    ctxt->instate = XML_PARSER_END_TAG;
5457*6777b538SAndroid Build Coastguard Worker 		    ctxt->checkIndex = 0;
5458*6777b538SAndroid Build Coastguard Worker 		    break;
5459*6777b538SAndroid Build Coastguard Worker 		}
5460*6777b538SAndroid Build Coastguard Worker 		if ((!terminate) &&
5461*6777b538SAndroid Build Coastguard Worker 		    (htmlParseLookupSequence(ctxt, '>', 0, 0, 1) < 0))
5462*6777b538SAndroid Build Coastguard Worker 		    goto done;
5463*6777b538SAndroid Build Coastguard Worker 
5464*6777b538SAndroid Build Coastguard Worker                 /* Capture start position */
5465*6777b538SAndroid Build Coastguard Worker 	        if (ctxt->record_info) {
5466*6777b538SAndroid Build Coastguard Worker 	             node_info.begin_pos = ctxt->input->consumed +
5467*6777b538SAndroid Build Coastguard Worker 	                                (CUR_PTR - ctxt->input->base);
5468*6777b538SAndroid Build Coastguard Worker 	             node_info.begin_line = ctxt->input->line;
5469*6777b538SAndroid Build Coastguard Worker 	        }
5470*6777b538SAndroid Build Coastguard Worker 
5471*6777b538SAndroid Build Coastguard Worker 
5472*6777b538SAndroid Build Coastguard Worker 		failed = htmlParseStartTag(ctxt);
5473*6777b538SAndroid Build Coastguard Worker 		name = ctxt->name;
5474*6777b538SAndroid Build Coastguard Worker 		if ((failed == -1) ||
5475*6777b538SAndroid Build Coastguard Worker 		    (name == NULL)) {
5476*6777b538SAndroid Build Coastguard Worker 		    if (CUR == '>')
5477*6777b538SAndroid Build Coastguard Worker 			NEXT;
5478*6777b538SAndroid Build Coastguard Worker 		    break;
5479*6777b538SAndroid Build Coastguard Worker 		}
5480*6777b538SAndroid Build Coastguard Worker 
5481*6777b538SAndroid Build Coastguard Worker 		/*
5482*6777b538SAndroid Build Coastguard Worker 		 * Lookup the info for that element.
5483*6777b538SAndroid Build Coastguard Worker 		 */
5484*6777b538SAndroid Build Coastguard Worker 		info = htmlTagLookup(name);
5485*6777b538SAndroid Build Coastguard Worker 		if (info == NULL) {
5486*6777b538SAndroid Build Coastguard Worker 		    htmlParseErr(ctxt, XML_HTML_UNKNOWN_TAG,
5487*6777b538SAndroid Build Coastguard Worker 		                 "Tag %s invalid\n", name, NULL);
5488*6777b538SAndroid Build Coastguard Worker 		}
5489*6777b538SAndroid Build Coastguard Worker 
5490*6777b538SAndroid Build Coastguard Worker 		/*
5491*6777b538SAndroid Build Coastguard Worker 		 * Check for an Empty Element labeled the XML/SGML way
5492*6777b538SAndroid Build Coastguard Worker 		 */
5493*6777b538SAndroid Build Coastguard Worker 		if ((CUR == '/') && (NXT(1) == '>')) {
5494*6777b538SAndroid Build Coastguard Worker 		    SKIP(2);
5495*6777b538SAndroid Build Coastguard Worker 		    if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
5496*6777b538SAndroid Build Coastguard Worker 			ctxt->sax->endElement(ctxt->userData, name);
5497*6777b538SAndroid Build Coastguard Worker 		    htmlnamePop(ctxt);
5498*6777b538SAndroid Build Coastguard Worker 		    ctxt->instate = XML_PARSER_CONTENT;
5499*6777b538SAndroid Build Coastguard Worker 		    break;
5500*6777b538SAndroid Build Coastguard Worker 		}
5501*6777b538SAndroid Build Coastguard Worker 
5502*6777b538SAndroid Build Coastguard Worker 		if (CUR == '>') {
5503*6777b538SAndroid Build Coastguard Worker 		    NEXT;
5504*6777b538SAndroid Build Coastguard Worker 		} else {
5505*6777b538SAndroid Build Coastguard Worker 		    htmlParseErr(ctxt, XML_ERR_GT_REQUIRED,
5506*6777b538SAndroid Build Coastguard Worker 		                 "Couldn't find end of Start Tag %s\n",
5507*6777b538SAndroid Build Coastguard Worker 				 name, NULL);
5508*6777b538SAndroid Build Coastguard Worker 
5509*6777b538SAndroid Build Coastguard Worker 		    /*
5510*6777b538SAndroid Build Coastguard Worker 		     * end of parsing of this node.
5511*6777b538SAndroid Build Coastguard Worker 		     */
5512*6777b538SAndroid Build Coastguard Worker 		    if (xmlStrEqual(name, ctxt->name)) {
5513*6777b538SAndroid Build Coastguard Worker 			nodePop(ctxt);
5514*6777b538SAndroid Build Coastguard Worker 			htmlnamePop(ctxt);
5515*6777b538SAndroid Build Coastguard Worker 		    }
5516*6777b538SAndroid Build Coastguard Worker 
5517*6777b538SAndroid Build Coastguard Worker 		    if (ctxt->record_info)
5518*6777b538SAndroid Build Coastguard Worker 		        htmlNodeInfoPush(ctxt, &node_info);
5519*6777b538SAndroid Build Coastguard Worker 
5520*6777b538SAndroid Build Coastguard Worker 		    ctxt->instate = XML_PARSER_CONTENT;
5521*6777b538SAndroid Build Coastguard Worker 		    break;
5522*6777b538SAndroid Build Coastguard Worker 		}
5523*6777b538SAndroid Build Coastguard Worker 
5524*6777b538SAndroid Build Coastguard Worker 		/*
5525*6777b538SAndroid Build Coastguard Worker 		 * Check for an Empty Element from DTD definition
5526*6777b538SAndroid Build Coastguard Worker 		 */
5527*6777b538SAndroid Build Coastguard Worker 		if ((info != NULL) && (info->empty)) {
5528*6777b538SAndroid Build Coastguard Worker 		    if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
5529*6777b538SAndroid Build Coastguard Worker 			ctxt->sax->endElement(ctxt->userData, name);
5530*6777b538SAndroid Build Coastguard Worker 		    htmlnamePop(ctxt);
5531*6777b538SAndroid Build Coastguard Worker 		}
5532*6777b538SAndroid Build Coastguard Worker 
5533*6777b538SAndroid Build Coastguard Worker                 if (ctxt->record_info)
5534*6777b538SAndroid Build Coastguard Worker 	            htmlNodeInfoPush(ctxt, &node_info);
5535*6777b538SAndroid Build Coastguard Worker 
5536*6777b538SAndroid Build Coastguard Worker 		ctxt->instate = XML_PARSER_CONTENT;
5537*6777b538SAndroid Build Coastguard Worker                 break;
5538*6777b538SAndroid Build Coastguard Worker 	    }
5539*6777b538SAndroid Build Coastguard Worker             case XML_PARSER_CONTENT: {
5540*6777b538SAndroid Build Coastguard Worker 		xmlChar chr[2] = { 0, 0 };
5541*6777b538SAndroid Build Coastguard Worker 
5542*6777b538SAndroid Build Coastguard Worker                 /*
5543*6777b538SAndroid Build Coastguard Worker 		 * Handle preparsed entities and charRef
5544*6777b538SAndroid Build Coastguard Worker 		 */
5545*6777b538SAndroid Build Coastguard Worker 		if ((avail == 1) && (terminate)) {
5546*6777b538SAndroid Build Coastguard Worker 		    cur = in->cur[0];
5547*6777b538SAndroid Build Coastguard Worker 		    if ((cur != '<') && (cur != '&')) {
5548*6777b538SAndroid Build Coastguard Worker 			if (ctxt->sax != NULL) {
5549*6777b538SAndroid Build Coastguard Worker                             chr[0] = cur;
5550*6777b538SAndroid Build Coastguard Worker 			    if (IS_BLANK_CH(cur)) {
5551*6777b538SAndroid Build Coastguard Worker 				if (ctxt->keepBlanks) {
5552*6777b538SAndroid Build Coastguard Worker 				    if (ctxt->sax->characters != NULL)
5553*6777b538SAndroid Build Coastguard Worker 					ctxt->sax->characters(
5554*6777b538SAndroid Build Coastguard Worker 						ctxt->userData, chr, 1);
5555*6777b538SAndroid Build Coastguard Worker 				} else {
5556*6777b538SAndroid Build Coastguard Worker 				    if (ctxt->sax->ignorableWhitespace != NULL)
5557*6777b538SAndroid Build Coastguard Worker 					ctxt->sax->ignorableWhitespace(
5558*6777b538SAndroid Build Coastguard Worker 						ctxt->userData, chr, 1);
5559*6777b538SAndroid Build Coastguard Worker 				}
5560*6777b538SAndroid Build Coastguard Worker 			    } else {
5561*6777b538SAndroid Build Coastguard Worker 				htmlCheckParagraph(ctxt);
5562*6777b538SAndroid Build Coastguard Worker 				if (ctxt->sax->characters != NULL)
5563*6777b538SAndroid Build Coastguard Worker 				    ctxt->sax->characters(
5564*6777b538SAndroid Build Coastguard Worker 					    ctxt->userData, chr, 1);
5565*6777b538SAndroid Build Coastguard Worker 			    }
5566*6777b538SAndroid Build Coastguard Worker 			}
5567*6777b538SAndroid Build Coastguard Worker 			ctxt->checkIndex = 0;
5568*6777b538SAndroid Build Coastguard Worker 			in->cur++;
5569*6777b538SAndroid Build Coastguard Worker 			break;
5570*6777b538SAndroid Build Coastguard Worker 		    }
5571*6777b538SAndroid Build Coastguard Worker 		}
5572*6777b538SAndroid Build Coastguard Worker 		if (avail < 2)
5573*6777b538SAndroid Build Coastguard Worker 		    goto done;
5574*6777b538SAndroid Build Coastguard Worker 		cur = in->cur[0];
5575*6777b538SAndroid Build Coastguard Worker 		next = in->cur[1];
5576*6777b538SAndroid Build Coastguard Worker 		if ((xmlStrEqual(ctxt->name, BAD_CAST"script")) ||
5577*6777b538SAndroid Build Coastguard Worker 		    (xmlStrEqual(ctxt->name, BAD_CAST"style"))) {
5578*6777b538SAndroid Build Coastguard Worker 		    /*
5579*6777b538SAndroid Build Coastguard Worker 		     * Handle SCRIPT/STYLE separately
5580*6777b538SAndroid Build Coastguard Worker 		     */
5581*6777b538SAndroid Build Coastguard Worker 		    if (!terminate) {
5582*6777b538SAndroid Build Coastguard Worker 		        int idx;
5583*6777b538SAndroid Build Coastguard Worker 			xmlChar val;
5584*6777b538SAndroid Build Coastguard Worker 
5585*6777b538SAndroid Build Coastguard Worker 			idx = htmlParseLookupSequence(ctxt, '<', '/', 0, 0);
5586*6777b538SAndroid Build Coastguard Worker 			if (idx < 0)
5587*6777b538SAndroid Build Coastguard Worker 			    goto done;
5588*6777b538SAndroid Build Coastguard Worker 		        val = in->cur[idx + 2];
5589*6777b538SAndroid Build Coastguard Worker 			if (val == 0) { /* bad cut of input */
5590*6777b538SAndroid Build Coastguard Worker                             /*
5591*6777b538SAndroid Build Coastguard Worker                              * FIXME: htmlParseScript checks for additional
5592*6777b538SAndroid Build Coastguard Worker                              * characters after '</'.
5593*6777b538SAndroid Build Coastguard Worker                              */
5594*6777b538SAndroid Build Coastguard Worker                             ctxt->checkIndex = idx;
5595*6777b538SAndroid Build Coastguard Worker 			    goto done;
5596*6777b538SAndroid Build Coastguard Worker                         }
5597*6777b538SAndroid Build Coastguard Worker 		    }
5598*6777b538SAndroid Build Coastguard Worker 		    htmlParseScript(ctxt);
5599*6777b538SAndroid Build Coastguard Worker 		    if ((cur == '<') && (next == '/')) {
5600*6777b538SAndroid Build Coastguard Worker 			ctxt->instate = XML_PARSER_END_TAG;
5601*6777b538SAndroid Build Coastguard Worker 			ctxt->checkIndex = 0;
5602*6777b538SAndroid Build Coastguard Worker 			break;
5603*6777b538SAndroid Build Coastguard Worker 		    }
5604*6777b538SAndroid Build Coastguard Worker 		} else if ((cur == '<') && (next == '!')) {
5605*6777b538SAndroid Build Coastguard Worker                     if (avail < 4)
5606*6777b538SAndroid Build Coastguard Worker                         goto done;
5607*6777b538SAndroid Build Coastguard Worker                     /*
5608*6777b538SAndroid Build Coastguard Worker                      * Sometimes DOCTYPE arrives in the middle of the document
5609*6777b538SAndroid Build Coastguard Worker                      */
5610*6777b538SAndroid Build Coastguard Worker                     if ((UPP(2) == 'D') && (UPP(3) == 'O') &&
5611*6777b538SAndroid Build Coastguard Worker                         (UPP(4) == 'C') && (UPP(5) == 'T') &&
5612*6777b538SAndroid Build Coastguard Worker                         (UPP(6) == 'Y') && (UPP(7) == 'P') &&
5613*6777b538SAndroid Build Coastguard Worker                         (UPP(8) == 'E')) {
5614*6777b538SAndroid Build Coastguard Worker                         if ((!terminate) &&
5615*6777b538SAndroid Build Coastguard Worker                             (htmlParseLookupSequence(ctxt, '>', 0, 0, 1) < 0))
5616*6777b538SAndroid Build Coastguard Worker                             goto done;
5617*6777b538SAndroid Build Coastguard Worker                         htmlParseErr(ctxt, XML_HTML_STRUCURE_ERROR,
5618*6777b538SAndroid Build Coastguard Worker                                      "Misplaced DOCTYPE declaration\n",
5619*6777b538SAndroid Build Coastguard Worker                                      BAD_CAST "DOCTYPE" , NULL);
5620*6777b538SAndroid Build Coastguard Worker                         htmlParseDocTypeDecl(ctxt);
5621*6777b538SAndroid Build Coastguard Worker                     } else if ((in->cur[2] == '-') && (in->cur[3] == '-')) {
5622*6777b538SAndroid Build Coastguard Worker                         if ((!terminate) &&
5623*6777b538SAndroid Build Coastguard Worker                             (htmlParseLookupCommentEnd(ctxt) < 0))
5624*6777b538SAndroid Build Coastguard Worker                             goto done;
5625*6777b538SAndroid Build Coastguard Worker                         htmlParseComment(ctxt);
5626*6777b538SAndroid Build Coastguard Worker                         ctxt->instate = XML_PARSER_CONTENT;
5627*6777b538SAndroid Build Coastguard Worker                     } else {
5628*6777b538SAndroid Build Coastguard Worker                         if ((!terminate) &&
5629*6777b538SAndroid Build Coastguard Worker                             (htmlParseLookupSequence(ctxt, '>', 0, 0, 0) < 0))
5630*6777b538SAndroid Build Coastguard Worker                             goto done;
5631*6777b538SAndroid Build Coastguard Worker                         htmlSkipBogusComment(ctxt);
5632*6777b538SAndroid Build Coastguard Worker                     }
5633*6777b538SAndroid Build Coastguard Worker                 } else if ((cur == '<') && (next == '?')) {
5634*6777b538SAndroid Build Coastguard Worker                     if ((!terminate) &&
5635*6777b538SAndroid Build Coastguard Worker                         (htmlParseLookupSequence(ctxt, '>', 0, 0, 0) < 0))
5636*6777b538SAndroid Build Coastguard Worker                         goto done;
5637*6777b538SAndroid Build Coastguard Worker                     htmlParsePI(ctxt);
5638*6777b538SAndroid Build Coastguard Worker                     ctxt->instate = XML_PARSER_CONTENT;
5639*6777b538SAndroid Build Coastguard Worker                 } else if ((cur == '<') && (next == '/')) {
5640*6777b538SAndroid Build Coastguard Worker                     ctxt->instate = XML_PARSER_END_TAG;
5641*6777b538SAndroid Build Coastguard Worker                     ctxt->checkIndex = 0;
5642*6777b538SAndroid Build Coastguard Worker                     break;
5643*6777b538SAndroid Build Coastguard Worker                 } else if ((cur == '<') && IS_ASCII_LETTER(next)) {
5644*6777b538SAndroid Build Coastguard Worker                     if ((!terminate) && (next == 0))
5645*6777b538SAndroid Build Coastguard Worker                         goto done;
5646*6777b538SAndroid Build Coastguard Worker                     ctxt->instate = XML_PARSER_START_TAG;
5647*6777b538SAndroid Build Coastguard Worker                     ctxt->checkIndex = 0;
5648*6777b538SAndroid Build Coastguard Worker                     break;
5649*6777b538SAndroid Build Coastguard Worker                 } else if (cur == '<') {
5650*6777b538SAndroid Build Coastguard Worker                     if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
5651*6777b538SAndroid Build Coastguard Worker                         (ctxt->sax->characters != NULL))
5652*6777b538SAndroid Build Coastguard Worker                         ctxt->sax->characters(ctxt->userData,
5653*6777b538SAndroid Build Coastguard Worker                                               BAD_CAST "<", 1);
5654*6777b538SAndroid Build Coastguard Worker                     NEXT;
5655*6777b538SAndroid Build Coastguard Worker                 } else {
5656*6777b538SAndroid Build Coastguard Worker                     /*
5657*6777b538SAndroid Build Coastguard Worker                      * check that the text sequence is complete
5658*6777b538SAndroid Build Coastguard Worker                      * before handing out the data to the parser
5659*6777b538SAndroid Build Coastguard Worker                      * to avoid problems with erroneous end of
5660*6777b538SAndroid Build Coastguard Worker                      * data detection.
5661*6777b538SAndroid Build Coastguard Worker                      */
5662*6777b538SAndroid Build Coastguard Worker                     if ((!terminate) &&
5663*6777b538SAndroid Build Coastguard Worker                         (htmlParseLookupSequence(ctxt, '<', 0, 0, 0) < 0))
5664*6777b538SAndroid Build Coastguard Worker                         goto done;
5665*6777b538SAndroid Build Coastguard Worker                     ctxt->checkIndex = 0;
5666*6777b538SAndroid Build Coastguard Worker                     while ((PARSER_STOPPED(ctxt) == 0) &&
5667*6777b538SAndroid Build Coastguard Worker                            (cur != '<') && (in->cur < in->end)) {
5668*6777b538SAndroid Build Coastguard Worker                         if (cur == '&') {
5669*6777b538SAndroid Build Coastguard Worker                             htmlParseReference(ctxt);
5670*6777b538SAndroid Build Coastguard Worker                         } else {
5671*6777b538SAndroid Build Coastguard Worker                             htmlParseCharData(ctxt);
5672*6777b538SAndroid Build Coastguard Worker                         }
5673*6777b538SAndroid Build Coastguard Worker                         cur = in->cur[0];
5674*6777b538SAndroid Build Coastguard Worker                     }
5675*6777b538SAndroid Build Coastguard Worker 		}
5676*6777b538SAndroid Build Coastguard Worker 
5677*6777b538SAndroid Build Coastguard Worker 		break;
5678*6777b538SAndroid Build Coastguard Worker 	    }
5679*6777b538SAndroid Build Coastguard Worker             case XML_PARSER_END_TAG:
5680*6777b538SAndroid Build Coastguard Worker 		if (avail < 2)
5681*6777b538SAndroid Build Coastguard Worker 		    goto done;
5682*6777b538SAndroid Build Coastguard Worker 		if ((!terminate) &&
5683*6777b538SAndroid Build Coastguard Worker 		    (htmlParseLookupSequence(ctxt, '>', 0, 0, 0) < 0))
5684*6777b538SAndroid Build Coastguard Worker 		    goto done;
5685*6777b538SAndroid Build Coastguard Worker 		htmlParseEndTag(ctxt);
5686*6777b538SAndroid Build Coastguard Worker 		if (ctxt->nameNr == 0) {
5687*6777b538SAndroid Build Coastguard Worker 		    ctxt->instate = XML_PARSER_EPILOG;
5688*6777b538SAndroid Build Coastguard Worker 		} else {
5689*6777b538SAndroid Build Coastguard Worker 		    ctxt->instate = XML_PARSER_CONTENT;
5690*6777b538SAndroid Build Coastguard Worker 		}
5691*6777b538SAndroid Build Coastguard Worker 		ctxt->checkIndex = 0;
5692*6777b538SAndroid Build Coastguard Worker 	        break;
5693*6777b538SAndroid Build Coastguard Worker 	    default:
5694*6777b538SAndroid Build Coastguard Worker 		htmlParseErr(ctxt, XML_ERR_INTERNAL_ERROR,
5695*6777b538SAndroid Build Coastguard Worker 			     "HPP: internal error\n", NULL, NULL);
5696*6777b538SAndroid Build Coastguard Worker 		ctxt->instate = XML_PARSER_EOF;
5697*6777b538SAndroid Build Coastguard Worker 		break;
5698*6777b538SAndroid Build Coastguard Worker 	}
5699*6777b538SAndroid Build Coastguard Worker     }
5700*6777b538SAndroid Build Coastguard Worker done:
5701*6777b538SAndroid Build Coastguard Worker     if ((avail == 0) && (terminate)) {
5702*6777b538SAndroid Build Coastguard Worker 	htmlAutoCloseOnEnd(ctxt);
5703*6777b538SAndroid Build Coastguard Worker 	if ((ctxt->nameNr == 0) && (ctxt->instate != XML_PARSER_EOF)) {
5704*6777b538SAndroid Build Coastguard Worker 	    /*
5705*6777b538SAndroid Build Coastguard Worker 	     * SAX: end of the document processing.
5706*6777b538SAndroid Build Coastguard Worker 	     */
5707*6777b538SAndroid Build Coastguard Worker 	    ctxt->instate = XML_PARSER_EOF;
5708*6777b538SAndroid Build Coastguard Worker 	    if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
5709*6777b538SAndroid Build Coastguard Worker 		ctxt->sax->endDocument(ctxt->userData);
5710*6777b538SAndroid Build Coastguard Worker 	}
5711*6777b538SAndroid Build Coastguard Worker     }
5712*6777b538SAndroid Build Coastguard Worker     if ((!(ctxt->options & HTML_PARSE_NODEFDTD)) && (ctxt->myDoc != NULL) &&
5713*6777b538SAndroid Build Coastguard Worker 	((terminate) || (ctxt->instate == XML_PARSER_EOF) ||
5714*6777b538SAndroid Build Coastguard Worker 	 (ctxt->instate == XML_PARSER_EPILOG))) {
5715*6777b538SAndroid Build Coastguard Worker 	xmlDtdPtr dtd;
5716*6777b538SAndroid Build Coastguard Worker 	dtd = xmlGetIntSubset(ctxt->myDoc);
5717*6777b538SAndroid Build Coastguard Worker 	if (dtd == NULL) {
5718*6777b538SAndroid Build Coastguard Worker 	    ctxt->myDoc->intSubset =
5719*6777b538SAndroid Build Coastguard Worker 		xmlCreateIntSubset(ctxt->myDoc, BAD_CAST "html",
5720*6777b538SAndroid Build Coastguard Worker 		    BAD_CAST "-//W3C//DTD HTML 4.0 Transitional//EN",
5721*6777b538SAndroid Build Coastguard Worker 		    BAD_CAST "http://www.w3.org/TR/REC-html40/loose.dtd");
5722*6777b538SAndroid Build Coastguard Worker             if (ctxt->myDoc->intSubset == NULL)
5723*6777b538SAndroid Build Coastguard Worker                 htmlErrMemory(ctxt);
5724*6777b538SAndroid Build Coastguard Worker         }
5725*6777b538SAndroid Build Coastguard Worker     }
5726*6777b538SAndroid Build Coastguard Worker     return(ret);
5727*6777b538SAndroid Build Coastguard Worker }
5728*6777b538SAndroid Build Coastguard Worker 
5729*6777b538SAndroid Build Coastguard Worker /**
5730*6777b538SAndroid Build Coastguard Worker  * htmlParseChunk:
5731*6777b538SAndroid Build Coastguard Worker  * @ctxt:  an HTML parser context
5732*6777b538SAndroid Build Coastguard Worker  * @chunk:  chunk of memory
5733*6777b538SAndroid Build Coastguard Worker  * @size:  size of chunk in bytes
5734*6777b538SAndroid Build Coastguard Worker  * @terminate:  last chunk indicator
5735*6777b538SAndroid Build Coastguard Worker  *
5736*6777b538SAndroid Build Coastguard Worker  * Parse a chunk of memory in push parser mode.
5737*6777b538SAndroid Build Coastguard Worker  *
5738*6777b538SAndroid Build Coastguard Worker  * Assumes that the parser context was initialized with
5739*6777b538SAndroid Build Coastguard Worker  * htmlCreatePushParserCtxt.
5740*6777b538SAndroid Build Coastguard Worker  *
5741*6777b538SAndroid Build Coastguard Worker  * The last chunk, which will often be empty, must be marked with
5742*6777b538SAndroid Build Coastguard Worker  * the @terminate flag. With the default SAX callbacks, the resulting
5743*6777b538SAndroid Build Coastguard Worker  * document will be available in ctxt->myDoc. This pointer will not
5744*6777b538SAndroid Build Coastguard Worker  * be freed by the library.
5745*6777b538SAndroid Build Coastguard Worker  *
5746*6777b538SAndroid Build Coastguard Worker  * If the document isn't well-formed, ctxt->myDoc is set to NULL.
5747*6777b538SAndroid Build Coastguard Worker  *
5748*6777b538SAndroid Build Coastguard Worker  * Returns an xmlParserErrors code (0 on success).
5749*6777b538SAndroid Build Coastguard Worker  */
5750*6777b538SAndroid Build Coastguard Worker int
htmlParseChunk(htmlParserCtxtPtr ctxt,const char * chunk,int size,int terminate)5751*6777b538SAndroid Build Coastguard Worker htmlParseChunk(htmlParserCtxtPtr ctxt, const char *chunk, int size,
5752*6777b538SAndroid Build Coastguard Worker               int terminate) {
5753*6777b538SAndroid Build Coastguard Worker     if ((ctxt == NULL) || (ctxt->input == NULL))
5754*6777b538SAndroid Build Coastguard Worker 	return(XML_ERR_ARGUMENT);
5755*6777b538SAndroid Build Coastguard Worker     if (PARSER_STOPPED(ctxt) != 0)
5756*6777b538SAndroid Build Coastguard Worker         return(ctxt->errNo);
5757*6777b538SAndroid Build Coastguard Worker     if ((size > 0) && (chunk != NULL) && (ctxt->input != NULL) &&
5758*6777b538SAndroid Build Coastguard Worker         (ctxt->input->buf != NULL))  {
5759*6777b538SAndroid Build Coastguard Worker 	size_t pos = ctxt->input->cur - ctxt->input->base;
5760*6777b538SAndroid Build Coastguard Worker 	int res;
5761*6777b538SAndroid Build Coastguard Worker 
5762*6777b538SAndroid Build Coastguard Worker 	res = xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
5763*6777b538SAndroid Build Coastguard Worker         xmlBufUpdateInput(ctxt->input->buf->buffer, ctxt->input, pos);
5764*6777b538SAndroid Build Coastguard Worker 	if (res < 0) {
5765*6777b538SAndroid Build Coastguard Worker             htmlParseErr(ctxt, ctxt->input->buf->error,
5766*6777b538SAndroid Build Coastguard Worker                          "xmlParserInputBufferPush failed", NULL, NULL);
5767*6777b538SAndroid Build Coastguard Worker             xmlHaltParser(ctxt);
5768*6777b538SAndroid Build Coastguard Worker 	    return (ctxt->errNo);
5769*6777b538SAndroid Build Coastguard Worker 	}
5770*6777b538SAndroid Build Coastguard Worker     }
5771*6777b538SAndroid Build Coastguard Worker     htmlParseTryOrFinish(ctxt, terminate);
5772*6777b538SAndroid Build Coastguard Worker     if (terminate) {
5773*6777b538SAndroid Build Coastguard Worker 	if (ctxt->instate != XML_PARSER_EOF) {
5774*6777b538SAndroid Build Coastguard Worker 	    if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
5775*6777b538SAndroid Build Coastguard Worker 		ctxt->sax->endDocument(ctxt->userData);
5776*6777b538SAndroid Build Coastguard Worker 	}
5777*6777b538SAndroid Build Coastguard Worker 	ctxt->instate = XML_PARSER_EOF;
5778*6777b538SAndroid Build Coastguard Worker     }
5779*6777b538SAndroid Build Coastguard Worker     return((xmlParserErrors) ctxt->errNo);
5780*6777b538SAndroid Build Coastguard Worker }
5781*6777b538SAndroid Build Coastguard Worker 
5782*6777b538SAndroid Build Coastguard Worker /************************************************************************
5783*6777b538SAndroid Build Coastguard Worker  *									*
5784*6777b538SAndroid Build Coastguard Worker  *			User entry points				*
5785*6777b538SAndroid Build Coastguard Worker  *									*
5786*6777b538SAndroid Build Coastguard Worker  ************************************************************************/
5787*6777b538SAndroid Build Coastguard Worker 
5788*6777b538SAndroid Build Coastguard Worker /**
5789*6777b538SAndroid Build Coastguard Worker  * htmlCreatePushParserCtxt:
5790*6777b538SAndroid Build Coastguard Worker  * @sax:  a SAX handler (optional)
5791*6777b538SAndroid Build Coastguard Worker  * @user_data:  The user data returned on SAX callbacks (optional)
5792*6777b538SAndroid Build Coastguard Worker  * @chunk:  a pointer to an array of chars (optional)
5793*6777b538SAndroid Build Coastguard Worker  * @size:  number of chars in the array
5794*6777b538SAndroid Build Coastguard Worker  * @filename:  only used for error reporting (optional)
5795*6777b538SAndroid Build Coastguard Worker  * @enc:  encoding (deprecated, pass XML_CHAR_ENCODING_NONE)
5796*6777b538SAndroid Build Coastguard Worker  *
5797*6777b538SAndroid Build Coastguard Worker  * Create a parser context for using the HTML parser in push mode.
5798*6777b538SAndroid Build Coastguard Worker  *
5799*6777b538SAndroid Build Coastguard Worker  * Returns the new parser context or NULL if a memory allocation
5800*6777b538SAndroid Build Coastguard Worker  * failed.
5801*6777b538SAndroid Build Coastguard Worker  */
5802*6777b538SAndroid Build Coastguard Worker htmlParserCtxtPtr
htmlCreatePushParserCtxt(htmlSAXHandlerPtr sax,void * user_data,const char * chunk,int size,const char * filename,xmlCharEncoding enc)5803*6777b538SAndroid Build Coastguard Worker htmlCreatePushParserCtxt(htmlSAXHandlerPtr sax, void *user_data,
5804*6777b538SAndroid Build Coastguard Worker                          const char *chunk, int size, const char *filename,
5805*6777b538SAndroid Build Coastguard Worker 			 xmlCharEncoding enc) {
5806*6777b538SAndroid Build Coastguard Worker     htmlParserCtxtPtr ctxt;
5807*6777b538SAndroid Build Coastguard Worker     htmlParserInputPtr input;
5808*6777b538SAndroid Build Coastguard Worker     const char *encoding;
5809*6777b538SAndroid Build Coastguard Worker 
5810*6777b538SAndroid Build Coastguard Worker     ctxt = htmlNewSAXParserCtxt(sax, user_data);
5811*6777b538SAndroid Build Coastguard Worker     if (ctxt == NULL)
5812*6777b538SAndroid Build Coastguard Worker 	return(NULL);
5813*6777b538SAndroid Build Coastguard Worker 
5814*6777b538SAndroid Build Coastguard Worker     encoding = xmlGetCharEncodingName(enc);
5815*6777b538SAndroid Build Coastguard Worker     input = xmlNewInputPush(ctxt, filename, chunk, size, encoding);
5816*6777b538SAndroid Build Coastguard Worker     if (input == NULL) {
5817*6777b538SAndroid Build Coastguard Worker 	htmlFreeParserCtxt(ctxt);
5818*6777b538SAndroid Build Coastguard Worker 	return(NULL);
5819*6777b538SAndroid Build Coastguard Worker     }
5820*6777b538SAndroid Build Coastguard Worker     inputPush(ctxt, input);
5821*6777b538SAndroid Build Coastguard Worker 
5822*6777b538SAndroid Build Coastguard Worker     return(ctxt);
5823*6777b538SAndroid Build Coastguard Worker }
5824*6777b538SAndroid Build Coastguard Worker #endif /* LIBXML_PUSH_ENABLED */
5825*6777b538SAndroid Build Coastguard Worker 
5826*6777b538SAndroid Build Coastguard Worker /**
5827*6777b538SAndroid Build Coastguard Worker  * htmlSAXParseDoc:
5828*6777b538SAndroid Build Coastguard Worker  * @cur:  a pointer to an array of xmlChar
5829*6777b538SAndroid Build Coastguard Worker  * @encoding:  a free form C string describing the HTML document encoding, or NULL
5830*6777b538SAndroid Build Coastguard Worker  * @sax:  the SAX handler block
5831*6777b538SAndroid Build Coastguard Worker  * @userData: if using SAX, this pointer will be provided on callbacks.
5832*6777b538SAndroid Build Coastguard Worker  *
5833*6777b538SAndroid Build Coastguard Worker  * DEPRECATED: Use htmlNewSAXParserCtxt and htmlCtxtReadDoc.
5834*6777b538SAndroid Build Coastguard Worker  *
5835*6777b538SAndroid Build Coastguard Worker  * Parse an HTML in-memory document. If sax is not NULL, use the SAX callbacks
5836*6777b538SAndroid Build Coastguard Worker  * to handle parse events. If sax is NULL, fallback to the default DOM
5837*6777b538SAndroid Build Coastguard Worker  * behavior and return a tree.
5838*6777b538SAndroid Build Coastguard Worker  *
5839*6777b538SAndroid Build Coastguard Worker  * Returns the resulting document tree unless SAX is NULL or the document is
5840*6777b538SAndroid Build Coastguard Worker  *     not well formed.
5841*6777b538SAndroid Build Coastguard Worker  */
5842*6777b538SAndroid Build Coastguard Worker 
5843*6777b538SAndroid Build Coastguard Worker htmlDocPtr
htmlSAXParseDoc(const xmlChar * cur,const char * encoding,htmlSAXHandlerPtr sax,void * userData)5844*6777b538SAndroid Build Coastguard Worker htmlSAXParseDoc(const xmlChar *cur, const char *encoding,
5845*6777b538SAndroid Build Coastguard Worker                 htmlSAXHandlerPtr sax, void *userData) {
5846*6777b538SAndroid Build Coastguard Worker     htmlDocPtr ret;
5847*6777b538SAndroid Build Coastguard Worker     htmlParserCtxtPtr ctxt;
5848*6777b538SAndroid Build Coastguard Worker 
5849*6777b538SAndroid Build Coastguard Worker     if (cur == NULL)
5850*6777b538SAndroid Build Coastguard Worker         return(NULL);
5851*6777b538SAndroid Build Coastguard Worker 
5852*6777b538SAndroid Build Coastguard Worker     ctxt = htmlCreateDocParserCtxt(cur, NULL, encoding);
5853*6777b538SAndroid Build Coastguard Worker     if (ctxt == NULL)
5854*6777b538SAndroid Build Coastguard Worker         return(NULL);
5855*6777b538SAndroid Build Coastguard Worker 
5856*6777b538SAndroid Build Coastguard Worker     if (sax != NULL) {
5857*6777b538SAndroid Build Coastguard Worker         *ctxt->sax = *sax;
5858*6777b538SAndroid Build Coastguard Worker         ctxt->userData = userData;
5859*6777b538SAndroid Build Coastguard Worker     }
5860*6777b538SAndroid Build Coastguard Worker 
5861*6777b538SAndroid Build Coastguard Worker     htmlParseDocument(ctxt);
5862*6777b538SAndroid Build Coastguard Worker     ret = ctxt->myDoc;
5863*6777b538SAndroid Build Coastguard Worker     htmlFreeParserCtxt(ctxt);
5864*6777b538SAndroid Build Coastguard Worker 
5865*6777b538SAndroid Build Coastguard Worker     return(ret);
5866*6777b538SAndroid Build Coastguard Worker }
5867*6777b538SAndroid Build Coastguard Worker 
5868*6777b538SAndroid Build Coastguard Worker /**
5869*6777b538SAndroid Build Coastguard Worker  * htmlParseDoc:
5870*6777b538SAndroid Build Coastguard Worker  * @cur:  a pointer to an array of xmlChar
5871*6777b538SAndroid Build Coastguard Worker  * @encoding:  the encoding (optional)
5872*6777b538SAndroid Build Coastguard Worker  *
5873*6777b538SAndroid Build Coastguard Worker  * DEPRECATED: Use htmlReadDoc.
5874*6777b538SAndroid Build Coastguard Worker  *
5875*6777b538SAndroid Build Coastguard Worker  * Parse an HTML in-memory document and build a tree.
5876*6777b538SAndroid Build Coastguard Worker  *
5877*6777b538SAndroid Build Coastguard Worker  * This function uses deprecated global parser options.
5878*6777b538SAndroid Build Coastguard Worker  *
5879*6777b538SAndroid Build Coastguard Worker  * Returns the resulting document tree
5880*6777b538SAndroid Build Coastguard Worker  */
5881*6777b538SAndroid Build Coastguard Worker 
5882*6777b538SAndroid Build Coastguard Worker htmlDocPtr
htmlParseDoc(const xmlChar * cur,const char * encoding)5883*6777b538SAndroid Build Coastguard Worker htmlParseDoc(const xmlChar *cur, const char *encoding) {
5884*6777b538SAndroid Build Coastguard Worker     return(htmlSAXParseDoc(cur, encoding, NULL, NULL));
5885*6777b538SAndroid Build Coastguard Worker }
5886*6777b538SAndroid Build Coastguard Worker 
5887*6777b538SAndroid Build Coastguard Worker 
5888*6777b538SAndroid Build Coastguard Worker /**
5889*6777b538SAndroid Build Coastguard Worker  * htmlCreateFileParserCtxt:
5890*6777b538SAndroid Build Coastguard Worker  * @filename:  the filename
5891*6777b538SAndroid Build Coastguard Worker  * @encoding:  optional encoding
5892*6777b538SAndroid Build Coastguard Worker  *
5893*6777b538SAndroid Build Coastguard Worker  * DEPRECATED: Use htmlNewParserCtxt and htmlCtxtReadFile.
5894*6777b538SAndroid Build Coastguard Worker  *
5895*6777b538SAndroid Build Coastguard Worker  * Create a parser context to read from a file.
5896*6777b538SAndroid Build Coastguard Worker  *
5897*6777b538SAndroid Build Coastguard Worker  * A non-NULL encoding overrides encoding declarations in the document.
5898*6777b538SAndroid Build Coastguard Worker  *
5899*6777b538SAndroid Build Coastguard Worker  * Automatic support for ZLIB/Compress compressed document is provided
5900*6777b538SAndroid Build Coastguard Worker  * by default if found at compile-time.
5901*6777b538SAndroid Build Coastguard Worker  *
5902*6777b538SAndroid Build Coastguard Worker  * Returns the new parser context or NULL if a memory allocation failed.
5903*6777b538SAndroid Build Coastguard Worker  */
5904*6777b538SAndroid Build Coastguard Worker htmlParserCtxtPtr
htmlCreateFileParserCtxt(const char * filename,const char * encoding)5905*6777b538SAndroid Build Coastguard Worker htmlCreateFileParserCtxt(const char *filename, const char *encoding)
5906*6777b538SAndroid Build Coastguard Worker {
5907*6777b538SAndroid Build Coastguard Worker     htmlParserCtxtPtr ctxt;
5908*6777b538SAndroid Build Coastguard Worker     htmlParserInputPtr input;
5909*6777b538SAndroid Build Coastguard Worker 
5910*6777b538SAndroid Build Coastguard Worker     if (filename == NULL)
5911*6777b538SAndroid Build Coastguard Worker         return(NULL);
5912*6777b538SAndroid Build Coastguard Worker 
5913*6777b538SAndroid Build Coastguard Worker     ctxt = htmlNewParserCtxt();
5914*6777b538SAndroid Build Coastguard Worker     if (ctxt == NULL) {
5915*6777b538SAndroid Build Coastguard Worker 	return(NULL);
5916*6777b538SAndroid Build Coastguard Worker     }
5917*6777b538SAndroid Build Coastguard Worker 
5918*6777b538SAndroid Build Coastguard Worker     input = xmlNewInputURL(ctxt, filename, NULL, encoding, 0);
5919*6777b538SAndroid Build Coastguard Worker     if (input == NULL) {
5920*6777b538SAndroid Build Coastguard Worker 	xmlFreeParserCtxt(ctxt);
5921*6777b538SAndroid Build Coastguard Worker 	return(NULL);
5922*6777b538SAndroid Build Coastguard Worker     }
5923*6777b538SAndroid Build Coastguard Worker     inputPush(ctxt, input);
5924*6777b538SAndroid Build Coastguard Worker 
5925*6777b538SAndroid Build Coastguard Worker     return(ctxt);
5926*6777b538SAndroid Build Coastguard Worker }
5927*6777b538SAndroid Build Coastguard Worker 
5928*6777b538SAndroid Build Coastguard Worker /**
5929*6777b538SAndroid Build Coastguard Worker  * htmlSAXParseFile:
5930*6777b538SAndroid Build Coastguard Worker  * @filename:  the filename
5931*6777b538SAndroid Build Coastguard Worker  * @encoding:  encoding (optional)
5932*6777b538SAndroid Build Coastguard Worker  * @sax:  the SAX handler block
5933*6777b538SAndroid Build Coastguard Worker  * @userData: if using SAX, this pointer will be provided on callbacks.
5934*6777b538SAndroid Build Coastguard Worker  *
5935*6777b538SAndroid Build Coastguard Worker  * DEPRECATED: Use htmlNewSAXParserCtxt and htmlCtxtReadFile.
5936*6777b538SAndroid Build Coastguard Worker  *
5937*6777b538SAndroid Build Coastguard Worker  * parse an HTML file and build a tree. Automatic support for ZLIB/Compress
5938*6777b538SAndroid Build Coastguard Worker  * compressed document is provided by default if found at compile-time.
5939*6777b538SAndroid Build Coastguard Worker  * It use the given SAX function block to handle the parsing callback.
5940*6777b538SAndroid Build Coastguard Worker  * If sax is NULL, fallback to the default DOM tree building routines.
5941*6777b538SAndroid Build Coastguard Worker  *
5942*6777b538SAndroid Build Coastguard Worker  * Returns the resulting document tree unless SAX is NULL or the document is
5943*6777b538SAndroid Build Coastguard Worker  *     not well formed.
5944*6777b538SAndroid Build Coastguard Worker  */
5945*6777b538SAndroid Build Coastguard Worker 
5946*6777b538SAndroid Build Coastguard Worker htmlDocPtr
htmlSAXParseFile(const char * filename,const char * encoding,htmlSAXHandlerPtr sax,void * userData)5947*6777b538SAndroid Build Coastguard Worker htmlSAXParseFile(const char *filename, const char *encoding, htmlSAXHandlerPtr sax,
5948*6777b538SAndroid Build Coastguard Worker                  void *userData) {
5949*6777b538SAndroid Build Coastguard Worker     htmlDocPtr ret;
5950*6777b538SAndroid Build Coastguard Worker     htmlParserCtxtPtr ctxt;
5951*6777b538SAndroid Build Coastguard Worker     htmlSAXHandlerPtr oldsax = NULL;
5952*6777b538SAndroid Build Coastguard Worker 
5953*6777b538SAndroid Build Coastguard Worker     ctxt = htmlCreateFileParserCtxt(filename, encoding);
5954*6777b538SAndroid Build Coastguard Worker     if (ctxt == NULL) return(NULL);
5955*6777b538SAndroid Build Coastguard Worker     if (sax != NULL) {
5956*6777b538SAndroid Build Coastguard Worker 	oldsax = ctxt->sax;
5957*6777b538SAndroid Build Coastguard Worker         ctxt->sax = sax;
5958*6777b538SAndroid Build Coastguard Worker         ctxt->userData = userData;
5959*6777b538SAndroid Build Coastguard Worker     }
5960*6777b538SAndroid Build Coastguard Worker 
5961*6777b538SAndroid Build Coastguard Worker     htmlParseDocument(ctxt);
5962*6777b538SAndroid Build Coastguard Worker 
5963*6777b538SAndroid Build Coastguard Worker     ret = ctxt->myDoc;
5964*6777b538SAndroid Build Coastguard Worker     if (sax != NULL) {
5965*6777b538SAndroid Build Coastguard Worker         ctxt->sax = oldsax;
5966*6777b538SAndroid Build Coastguard Worker         ctxt->userData = NULL;
5967*6777b538SAndroid Build Coastguard Worker     }
5968*6777b538SAndroid Build Coastguard Worker     htmlFreeParserCtxt(ctxt);
5969*6777b538SAndroid Build Coastguard Worker 
5970*6777b538SAndroid Build Coastguard Worker     return(ret);
5971*6777b538SAndroid Build Coastguard Worker }
5972*6777b538SAndroid Build Coastguard Worker 
5973*6777b538SAndroid Build Coastguard Worker /**
5974*6777b538SAndroid Build Coastguard Worker  * htmlParseFile:
5975*6777b538SAndroid Build Coastguard Worker  * @filename:  the filename
5976*6777b538SAndroid Build Coastguard Worker  * @encoding:  encoding (optional)
5977*6777b538SAndroid Build Coastguard Worker  *
5978*6777b538SAndroid Build Coastguard Worker  * Parse an HTML file and build a tree.
5979*6777b538SAndroid Build Coastguard Worker  *
5980*6777b538SAndroid Build Coastguard Worker  * See xmlNewInputURL for details.
5981*6777b538SAndroid Build Coastguard Worker  *
5982*6777b538SAndroid Build Coastguard Worker  * Returns the resulting document tree
5983*6777b538SAndroid Build Coastguard Worker  */
5984*6777b538SAndroid Build Coastguard Worker 
5985*6777b538SAndroid Build Coastguard Worker htmlDocPtr
htmlParseFile(const char * filename,const char * encoding)5986*6777b538SAndroid Build Coastguard Worker htmlParseFile(const char *filename, const char *encoding) {
5987*6777b538SAndroid Build Coastguard Worker     return(htmlSAXParseFile(filename, encoding, NULL, NULL));
5988*6777b538SAndroid Build Coastguard Worker }
5989*6777b538SAndroid Build Coastguard Worker 
5990*6777b538SAndroid Build Coastguard Worker /**
5991*6777b538SAndroid Build Coastguard Worker  * htmlHandleOmittedElem:
5992*6777b538SAndroid Build Coastguard Worker  * @val:  int 0 or 1
5993*6777b538SAndroid Build Coastguard Worker  *
5994*6777b538SAndroid Build Coastguard Worker  * Set and return the previous value for handling HTML omitted tags.
5995*6777b538SAndroid Build Coastguard Worker  *
5996*6777b538SAndroid Build Coastguard Worker  * Returns the last value for 0 for no handling, 1 for auto insertion.
5997*6777b538SAndroid Build Coastguard Worker  */
5998*6777b538SAndroid Build Coastguard Worker 
5999*6777b538SAndroid Build Coastguard Worker int
htmlHandleOmittedElem(int val)6000*6777b538SAndroid Build Coastguard Worker htmlHandleOmittedElem(int val) {
6001*6777b538SAndroid Build Coastguard Worker     int old = htmlOmittedDefaultValue;
6002*6777b538SAndroid Build Coastguard Worker 
6003*6777b538SAndroid Build Coastguard Worker     htmlOmittedDefaultValue = val;
6004*6777b538SAndroid Build Coastguard Worker     return(old);
6005*6777b538SAndroid Build Coastguard Worker }
6006*6777b538SAndroid Build Coastguard Worker 
6007*6777b538SAndroid Build Coastguard Worker /**
6008*6777b538SAndroid Build Coastguard Worker  * htmlElementAllowedHere:
6009*6777b538SAndroid Build Coastguard Worker  * @parent: HTML parent element
6010*6777b538SAndroid Build Coastguard Worker  * @elt: HTML element
6011*6777b538SAndroid Build Coastguard Worker  *
6012*6777b538SAndroid Build Coastguard Worker  * Checks whether an HTML element may be a direct child of a parent element.
6013*6777b538SAndroid Build Coastguard Worker  * Note - doesn't check for deprecated elements
6014*6777b538SAndroid Build Coastguard Worker  *
6015*6777b538SAndroid Build Coastguard Worker  * Returns 1 if allowed; 0 otherwise.
6016*6777b538SAndroid Build Coastguard Worker  */
6017*6777b538SAndroid Build Coastguard Worker int
htmlElementAllowedHere(const htmlElemDesc * parent,const xmlChar * elt)6018*6777b538SAndroid Build Coastguard Worker htmlElementAllowedHere(const htmlElemDesc* parent, const xmlChar* elt) {
6019*6777b538SAndroid Build Coastguard Worker   const char** p ;
6020*6777b538SAndroid Build Coastguard Worker 
6021*6777b538SAndroid Build Coastguard Worker   if ( ! elt || ! parent || ! parent->subelts )
6022*6777b538SAndroid Build Coastguard Worker 	return 0 ;
6023*6777b538SAndroid Build Coastguard Worker 
6024*6777b538SAndroid Build Coastguard Worker   for ( p = parent->subelts; *p; ++p )
6025*6777b538SAndroid Build Coastguard Worker     if ( !xmlStrcmp((const xmlChar *)*p, elt) )
6026*6777b538SAndroid Build Coastguard Worker       return 1 ;
6027*6777b538SAndroid Build Coastguard Worker 
6028*6777b538SAndroid Build Coastguard Worker   return 0 ;
6029*6777b538SAndroid Build Coastguard Worker }
6030*6777b538SAndroid Build Coastguard Worker /**
6031*6777b538SAndroid Build Coastguard Worker  * htmlElementStatusHere:
6032*6777b538SAndroid Build Coastguard Worker  * @parent: HTML parent element
6033*6777b538SAndroid Build Coastguard Worker  * @elt: HTML element
6034*6777b538SAndroid Build Coastguard Worker  *
6035*6777b538SAndroid Build Coastguard Worker  * Checks whether an HTML element may be a direct child of a parent element.
6036*6777b538SAndroid Build Coastguard Worker  * and if so whether it is valid or deprecated.
6037*6777b538SAndroid Build Coastguard Worker  *
6038*6777b538SAndroid Build Coastguard Worker  * Returns one of HTML_VALID, HTML_DEPRECATED, HTML_INVALID
6039*6777b538SAndroid Build Coastguard Worker  */
6040*6777b538SAndroid Build Coastguard Worker htmlStatus
htmlElementStatusHere(const htmlElemDesc * parent,const htmlElemDesc * elt)6041*6777b538SAndroid Build Coastguard Worker htmlElementStatusHere(const htmlElemDesc* parent, const htmlElemDesc* elt) {
6042*6777b538SAndroid Build Coastguard Worker   if ( ! parent || ! elt )
6043*6777b538SAndroid Build Coastguard Worker     return HTML_INVALID ;
6044*6777b538SAndroid Build Coastguard Worker   if ( ! htmlElementAllowedHere(parent, (const xmlChar*) elt->name ) )
6045*6777b538SAndroid Build Coastguard Worker     return HTML_INVALID ;
6046*6777b538SAndroid Build Coastguard Worker 
6047*6777b538SAndroid Build Coastguard Worker   return ( elt->dtd == 0 ) ? HTML_VALID : HTML_DEPRECATED ;
6048*6777b538SAndroid Build Coastguard Worker }
6049*6777b538SAndroid Build Coastguard Worker /**
6050*6777b538SAndroid Build Coastguard Worker  * htmlAttrAllowed:
6051*6777b538SAndroid Build Coastguard Worker  * @elt: HTML element
6052*6777b538SAndroid Build Coastguard Worker  * @attr: HTML attribute
6053*6777b538SAndroid Build Coastguard Worker  * @legacy: whether to allow deprecated attributes
6054*6777b538SAndroid Build Coastguard Worker  *
6055*6777b538SAndroid Build Coastguard Worker  * Checks whether an attribute is valid for an element
6056*6777b538SAndroid Build Coastguard Worker  * Has full knowledge of Required and Deprecated attributes
6057*6777b538SAndroid Build Coastguard Worker  *
6058*6777b538SAndroid Build Coastguard Worker  * Returns one of HTML_REQUIRED, HTML_VALID, HTML_DEPRECATED, HTML_INVALID
6059*6777b538SAndroid Build Coastguard Worker  */
6060*6777b538SAndroid Build Coastguard Worker htmlStatus
htmlAttrAllowed(const htmlElemDesc * elt,const xmlChar * attr,int legacy)6061*6777b538SAndroid Build Coastguard Worker htmlAttrAllowed(const htmlElemDesc* elt, const xmlChar* attr, int legacy) {
6062*6777b538SAndroid Build Coastguard Worker   const char** p ;
6063*6777b538SAndroid Build Coastguard Worker 
6064*6777b538SAndroid Build Coastguard Worker   if ( !elt || ! attr )
6065*6777b538SAndroid Build Coastguard Worker 	return HTML_INVALID ;
6066*6777b538SAndroid Build Coastguard Worker 
6067*6777b538SAndroid Build Coastguard Worker   if ( elt->attrs_req )
6068*6777b538SAndroid Build Coastguard Worker     for ( p = elt->attrs_req; *p; ++p)
6069*6777b538SAndroid Build Coastguard Worker       if ( !xmlStrcmp((const xmlChar*)*p, attr) )
6070*6777b538SAndroid Build Coastguard Worker         return HTML_REQUIRED ;
6071*6777b538SAndroid Build Coastguard Worker 
6072*6777b538SAndroid Build Coastguard Worker   if ( elt->attrs_opt )
6073*6777b538SAndroid Build Coastguard Worker     for ( p = elt->attrs_opt; *p; ++p)
6074*6777b538SAndroid Build Coastguard Worker       if ( !xmlStrcmp((const xmlChar*)*p, attr) )
6075*6777b538SAndroid Build Coastguard Worker         return HTML_VALID ;
6076*6777b538SAndroid Build Coastguard Worker 
6077*6777b538SAndroid Build Coastguard Worker   if ( legacy && elt->attrs_depr )
6078*6777b538SAndroid Build Coastguard Worker     for ( p = elt->attrs_depr; *p; ++p)
6079*6777b538SAndroid Build Coastguard Worker       if ( !xmlStrcmp((const xmlChar*)*p, attr) )
6080*6777b538SAndroid Build Coastguard Worker         return HTML_DEPRECATED ;
6081*6777b538SAndroid Build Coastguard Worker 
6082*6777b538SAndroid Build Coastguard Worker   return HTML_INVALID ;
6083*6777b538SAndroid Build Coastguard Worker }
6084*6777b538SAndroid Build Coastguard Worker /**
6085*6777b538SAndroid Build Coastguard Worker  * htmlNodeStatus:
6086*6777b538SAndroid Build Coastguard Worker  * @node: an htmlNodePtr in a tree
6087*6777b538SAndroid Build Coastguard Worker  * @legacy: whether to allow deprecated elements (YES is faster here
6088*6777b538SAndroid Build Coastguard Worker  *	for Element nodes)
6089*6777b538SAndroid Build Coastguard Worker  *
6090*6777b538SAndroid Build Coastguard Worker  * Checks whether the tree node is valid.  Experimental (the author
6091*6777b538SAndroid Build Coastguard Worker  *     only uses the HTML enhancements in a SAX parser)
6092*6777b538SAndroid Build Coastguard Worker  *
6093*6777b538SAndroid Build Coastguard Worker  * Return: for Element nodes, a return from htmlElementAllowedHere (if
6094*6777b538SAndroid Build Coastguard Worker  *	legacy allowed) or htmlElementStatusHere (otherwise).
6095*6777b538SAndroid Build Coastguard Worker  *	for Attribute nodes, a return from htmlAttrAllowed
6096*6777b538SAndroid Build Coastguard Worker  *	for other nodes, HTML_NA (no checks performed)
6097*6777b538SAndroid Build Coastguard Worker  */
6098*6777b538SAndroid Build Coastguard Worker htmlStatus
htmlNodeStatus(htmlNodePtr node,int legacy)6099*6777b538SAndroid Build Coastguard Worker htmlNodeStatus(htmlNodePtr node, int legacy) {
6100*6777b538SAndroid Build Coastguard Worker   if ( ! node )
6101*6777b538SAndroid Build Coastguard Worker     return HTML_INVALID ;
6102*6777b538SAndroid Build Coastguard Worker 
6103*6777b538SAndroid Build Coastguard Worker   switch ( node->type ) {
6104*6777b538SAndroid Build Coastguard Worker     case XML_ELEMENT_NODE:
6105*6777b538SAndroid Build Coastguard Worker       return legacy
6106*6777b538SAndroid Build Coastguard Worker 	? ( htmlElementAllowedHere (
6107*6777b538SAndroid Build Coastguard Worker 		htmlTagLookup(node->parent->name) , node->name
6108*6777b538SAndroid Build Coastguard Worker 		) ? HTML_VALID : HTML_INVALID )
6109*6777b538SAndroid Build Coastguard Worker 	: htmlElementStatusHere(
6110*6777b538SAndroid Build Coastguard Worker 		htmlTagLookup(node->parent->name) ,
6111*6777b538SAndroid Build Coastguard Worker 		htmlTagLookup(node->name) )
6112*6777b538SAndroid Build Coastguard Worker 	;
6113*6777b538SAndroid Build Coastguard Worker     case XML_ATTRIBUTE_NODE:
6114*6777b538SAndroid Build Coastguard Worker       return htmlAttrAllowed(
6115*6777b538SAndroid Build Coastguard Worker 	htmlTagLookup(node->parent->name) , node->name, legacy) ;
6116*6777b538SAndroid Build Coastguard Worker     default: return HTML_NA ;
6117*6777b538SAndroid Build Coastguard Worker   }
6118*6777b538SAndroid Build Coastguard Worker }
6119*6777b538SAndroid Build Coastguard Worker /************************************************************************
6120*6777b538SAndroid Build Coastguard Worker  *									*
6121*6777b538SAndroid Build Coastguard Worker  *	New set (2.6.0) of simpler and more flexible APIs		*
6122*6777b538SAndroid Build Coastguard Worker  *									*
6123*6777b538SAndroid Build Coastguard Worker  ************************************************************************/
6124*6777b538SAndroid Build Coastguard Worker /**
6125*6777b538SAndroid Build Coastguard Worker  * DICT_FREE:
6126*6777b538SAndroid Build Coastguard Worker  * @str:  a string
6127*6777b538SAndroid Build Coastguard Worker  *
6128*6777b538SAndroid Build Coastguard Worker  * Free a string if it is not owned by the "dict" dictionary in the
6129*6777b538SAndroid Build Coastguard Worker  * current scope
6130*6777b538SAndroid Build Coastguard Worker  */
6131*6777b538SAndroid Build Coastguard Worker #define DICT_FREE(str)						\
6132*6777b538SAndroid Build Coastguard Worker 	if ((str) && ((!dict) ||				\
6133*6777b538SAndroid Build Coastguard Worker 	    (xmlDictOwns(dict, (const xmlChar *)(str)) == 0)))	\
6134*6777b538SAndroid Build Coastguard Worker 	    xmlFree((char *)(str));
6135*6777b538SAndroid Build Coastguard Worker 
6136*6777b538SAndroid Build Coastguard Worker /**
6137*6777b538SAndroid Build Coastguard Worker  * htmlCtxtReset:
6138*6777b538SAndroid Build Coastguard Worker  * @ctxt: an HTML parser context
6139*6777b538SAndroid Build Coastguard Worker  *
6140*6777b538SAndroid Build Coastguard Worker  * Reset a parser context
6141*6777b538SAndroid Build Coastguard Worker  */
6142*6777b538SAndroid Build Coastguard Worker void
htmlCtxtReset(htmlParserCtxtPtr ctxt)6143*6777b538SAndroid Build Coastguard Worker htmlCtxtReset(htmlParserCtxtPtr ctxt)
6144*6777b538SAndroid Build Coastguard Worker {
6145*6777b538SAndroid Build Coastguard Worker     xmlParserInputPtr input;
6146*6777b538SAndroid Build Coastguard Worker     xmlDictPtr dict;
6147*6777b538SAndroid Build Coastguard Worker 
6148*6777b538SAndroid Build Coastguard Worker     if (ctxt == NULL)
6149*6777b538SAndroid Build Coastguard Worker         return;
6150*6777b538SAndroid Build Coastguard Worker 
6151*6777b538SAndroid Build Coastguard Worker     dict = ctxt->dict;
6152*6777b538SAndroid Build Coastguard Worker 
6153*6777b538SAndroid Build Coastguard Worker     while ((input = inputPop(ctxt)) != NULL) { /* Non consuming */
6154*6777b538SAndroid Build Coastguard Worker         xmlFreeInputStream(input);
6155*6777b538SAndroid Build Coastguard Worker     }
6156*6777b538SAndroid Build Coastguard Worker     ctxt->inputNr = 0;
6157*6777b538SAndroid Build Coastguard Worker     ctxt->input = NULL;
6158*6777b538SAndroid Build Coastguard Worker 
6159*6777b538SAndroid Build Coastguard Worker     ctxt->spaceNr = 0;
6160*6777b538SAndroid Build Coastguard Worker     if (ctxt->spaceTab != NULL) {
6161*6777b538SAndroid Build Coastguard Worker 	ctxt->spaceTab[0] = -1;
6162*6777b538SAndroid Build Coastguard Worker 	ctxt->space = &ctxt->spaceTab[0];
6163*6777b538SAndroid Build Coastguard Worker     } else {
6164*6777b538SAndroid Build Coastguard Worker 	ctxt->space = NULL;
6165*6777b538SAndroid Build Coastguard Worker     }
6166*6777b538SAndroid Build Coastguard Worker 
6167*6777b538SAndroid Build Coastguard Worker 
6168*6777b538SAndroid Build Coastguard Worker     ctxt->nodeNr = 0;
6169*6777b538SAndroid Build Coastguard Worker     ctxt->node = NULL;
6170*6777b538SAndroid Build Coastguard Worker 
6171*6777b538SAndroid Build Coastguard Worker     ctxt->nameNr = 0;
6172*6777b538SAndroid Build Coastguard Worker     ctxt->name = NULL;
6173*6777b538SAndroid Build Coastguard Worker 
6174*6777b538SAndroid Build Coastguard Worker     ctxt->nsNr = 0;
6175*6777b538SAndroid Build Coastguard Worker 
6176*6777b538SAndroid Build Coastguard Worker     DICT_FREE(ctxt->version);
6177*6777b538SAndroid Build Coastguard Worker     ctxt->version = NULL;
6178*6777b538SAndroid Build Coastguard Worker     DICT_FREE(ctxt->encoding);
6179*6777b538SAndroid Build Coastguard Worker     ctxt->encoding = NULL;
6180*6777b538SAndroid Build Coastguard Worker     DICT_FREE(ctxt->extSubURI);
6181*6777b538SAndroid Build Coastguard Worker     ctxt->extSubURI = NULL;
6182*6777b538SAndroid Build Coastguard Worker     DICT_FREE(ctxt->extSubSystem);
6183*6777b538SAndroid Build Coastguard Worker     ctxt->extSubSystem = NULL;
6184*6777b538SAndroid Build Coastguard Worker     if (ctxt->myDoc != NULL)
6185*6777b538SAndroid Build Coastguard Worker         xmlFreeDoc(ctxt->myDoc);
6186*6777b538SAndroid Build Coastguard Worker     ctxt->myDoc = NULL;
6187*6777b538SAndroid Build Coastguard Worker 
6188*6777b538SAndroid Build Coastguard Worker     ctxt->standalone = -1;
6189*6777b538SAndroid Build Coastguard Worker     ctxt->hasExternalSubset = 0;
6190*6777b538SAndroid Build Coastguard Worker     ctxt->hasPErefs = 0;
6191*6777b538SAndroid Build Coastguard Worker     ctxt->html = 1;
6192*6777b538SAndroid Build Coastguard Worker     ctxt->instate = XML_PARSER_START;
6193*6777b538SAndroid Build Coastguard Worker 
6194*6777b538SAndroid Build Coastguard Worker     ctxt->wellFormed = 1;
6195*6777b538SAndroid Build Coastguard Worker     ctxt->nsWellFormed = 1;
6196*6777b538SAndroid Build Coastguard Worker     ctxt->disableSAX = 0;
6197*6777b538SAndroid Build Coastguard Worker     ctxt->valid = 1;
6198*6777b538SAndroid Build Coastguard Worker     ctxt->vctxt.userData = ctxt;
6199*6777b538SAndroid Build Coastguard Worker     ctxt->vctxt.flags = XML_VCTXT_USE_PCTXT;
6200*6777b538SAndroid Build Coastguard Worker     ctxt->vctxt.error = xmlParserValidityError;
6201*6777b538SAndroid Build Coastguard Worker     ctxt->vctxt.warning = xmlParserValidityWarning;
6202*6777b538SAndroid Build Coastguard Worker     ctxt->record_info = 0;
6203*6777b538SAndroid Build Coastguard Worker     ctxt->checkIndex = 0;
6204*6777b538SAndroid Build Coastguard Worker     ctxt->endCheckState = 0;
6205*6777b538SAndroid Build Coastguard Worker     ctxt->inSubset = 0;
6206*6777b538SAndroid Build Coastguard Worker     ctxt->errNo = XML_ERR_OK;
6207*6777b538SAndroid Build Coastguard Worker     ctxt->depth = 0;
6208*6777b538SAndroid Build Coastguard Worker     ctxt->catalogs = NULL;
6209*6777b538SAndroid Build Coastguard Worker     xmlInitNodeInfoSeq(&ctxt->node_seq);
6210*6777b538SAndroid Build Coastguard Worker 
6211*6777b538SAndroid Build Coastguard Worker     if (ctxt->attsDefault != NULL) {
6212*6777b538SAndroid Build Coastguard Worker         xmlHashFree(ctxt->attsDefault, xmlHashDefaultDeallocator);
6213*6777b538SAndroid Build Coastguard Worker         ctxt->attsDefault = NULL;
6214*6777b538SAndroid Build Coastguard Worker     }
6215*6777b538SAndroid Build Coastguard Worker     if (ctxt->attsSpecial != NULL) {
6216*6777b538SAndroid Build Coastguard Worker         xmlHashFree(ctxt->attsSpecial, NULL);
6217*6777b538SAndroid Build Coastguard Worker         ctxt->attsSpecial = NULL;
6218*6777b538SAndroid Build Coastguard Worker     }
6219*6777b538SAndroid Build Coastguard Worker 
6220*6777b538SAndroid Build Coastguard Worker     ctxt->nbErrors = 0;
6221*6777b538SAndroid Build Coastguard Worker     ctxt->nbWarnings = 0;
6222*6777b538SAndroid Build Coastguard Worker     if (ctxt->lastError.code != XML_ERR_OK)
6223*6777b538SAndroid Build Coastguard Worker         xmlResetError(&ctxt->lastError);
6224*6777b538SAndroid Build Coastguard Worker }
6225*6777b538SAndroid Build Coastguard Worker 
6226*6777b538SAndroid Build Coastguard Worker /**
6227*6777b538SAndroid Build Coastguard Worker  * htmlCtxtUseOptions:
6228*6777b538SAndroid Build Coastguard Worker  * @ctxt: an HTML parser context
6229*6777b538SAndroid Build Coastguard Worker  * @options:  a combination of htmlParserOption(s)
6230*6777b538SAndroid Build Coastguard Worker  *
6231*6777b538SAndroid Build Coastguard Worker  * Applies the options to the parser context
6232*6777b538SAndroid Build Coastguard Worker  *
6233*6777b538SAndroid Build Coastguard Worker  * Returns 0 in case of success, the set of unknown or unimplemented options
6234*6777b538SAndroid Build Coastguard Worker  *         in case of error.
6235*6777b538SAndroid Build Coastguard Worker  */
6236*6777b538SAndroid Build Coastguard Worker int
htmlCtxtUseOptions(htmlParserCtxtPtr ctxt,int options)6237*6777b538SAndroid Build Coastguard Worker htmlCtxtUseOptions(htmlParserCtxtPtr ctxt, int options)
6238*6777b538SAndroid Build Coastguard Worker {
6239*6777b538SAndroid Build Coastguard Worker     if (ctxt == NULL)
6240*6777b538SAndroid Build Coastguard Worker         return(-1);
6241*6777b538SAndroid Build Coastguard Worker 
6242*6777b538SAndroid Build Coastguard Worker     if (options & HTML_PARSE_NOWARNING) {
6243*6777b538SAndroid Build Coastguard Worker         ctxt->sax->warning = NULL;
6244*6777b538SAndroid Build Coastguard Worker         ctxt->vctxt.warning = NULL;
6245*6777b538SAndroid Build Coastguard Worker         options -= XML_PARSE_NOWARNING;
6246*6777b538SAndroid Build Coastguard Worker 	ctxt->options |= XML_PARSE_NOWARNING;
6247*6777b538SAndroid Build Coastguard Worker     }
6248*6777b538SAndroid Build Coastguard Worker     if (options & HTML_PARSE_NOERROR) {
6249*6777b538SAndroid Build Coastguard Worker         ctxt->sax->error = NULL;
6250*6777b538SAndroid Build Coastguard Worker         ctxt->vctxt.error = NULL;
6251*6777b538SAndroid Build Coastguard Worker         ctxt->sax->fatalError = NULL;
6252*6777b538SAndroid Build Coastguard Worker         options -= XML_PARSE_NOERROR;
6253*6777b538SAndroid Build Coastguard Worker 	ctxt->options |= XML_PARSE_NOERROR;
6254*6777b538SAndroid Build Coastguard Worker     }
6255*6777b538SAndroid Build Coastguard Worker     if (options & HTML_PARSE_PEDANTIC) {
6256*6777b538SAndroid Build Coastguard Worker         ctxt->pedantic = 1;
6257*6777b538SAndroid Build Coastguard Worker         options -= XML_PARSE_PEDANTIC;
6258*6777b538SAndroid Build Coastguard Worker 	ctxt->options |= XML_PARSE_PEDANTIC;
6259*6777b538SAndroid Build Coastguard Worker     } else
6260*6777b538SAndroid Build Coastguard Worker         ctxt->pedantic = 0;
6261*6777b538SAndroid Build Coastguard Worker     if (options & XML_PARSE_NOBLANKS) {
6262*6777b538SAndroid Build Coastguard Worker         ctxt->keepBlanks = 0;
6263*6777b538SAndroid Build Coastguard Worker         ctxt->sax->ignorableWhitespace = xmlSAX2IgnorableWhitespace;
6264*6777b538SAndroid Build Coastguard Worker         options -= XML_PARSE_NOBLANKS;
6265*6777b538SAndroid Build Coastguard Worker 	ctxt->options |= XML_PARSE_NOBLANKS;
6266*6777b538SAndroid Build Coastguard Worker     } else
6267*6777b538SAndroid Build Coastguard Worker         ctxt->keepBlanks = 1;
6268*6777b538SAndroid Build Coastguard Worker     if (options & HTML_PARSE_RECOVER) {
6269*6777b538SAndroid Build Coastguard Worker         ctxt->recovery = 1;
6270*6777b538SAndroid Build Coastguard Worker 	options -= HTML_PARSE_RECOVER;
6271*6777b538SAndroid Build Coastguard Worker     } else
6272*6777b538SAndroid Build Coastguard Worker         ctxt->recovery = 0;
6273*6777b538SAndroid Build Coastguard Worker     if (options & HTML_PARSE_COMPACT) {
6274*6777b538SAndroid Build Coastguard Worker 	ctxt->options |= HTML_PARSE_COMPACT;
6275*6777b538SAndroid Build Coastguard Worker         options -= HTML_PARSE_COMPACT;
6276*6777b538SAndroid Build Coastguard Worker     }
6277*6777b538SAndroid Build Coastguard Worker     if (options & XML_PARSE_HUGE) {
6278*6777b538SAndroid Build Coastguard Worker 	ctxt->options |= XML_PARSE_HUGE;
6279*6777b538SAndroid Build Coastguard Worker         options -= XML_PARSE_HUGE;
6280*6777b538SAndroid Build Coastguard Worker     }
6281*6777b538SAndroid Build Coastguard Worker     if (options & HTML_PARSE_NODEFDTD) {
6282*6777b538SAndroid Build Coastguard Worker 	ctxt->options |= HTML_PARSE_NODEFDTD;
6283*6777b538SAndroid Build Coastguard Worker         options -= HTML_PARSE_NODEFDTD;
6284*6777b538SAndroid Build Coastguard Worker     }
6285*6777b538SAndroid Build Coastguard Worker     if (options & HTML_PARSE_IGNORE_ENC) {
6286*6777b538SAndroid Build Coastguard Worker 	ctxt->options |= HTML_PARSE_IGNORE_ENC;
6287*6777b538SAndroid Build Coastguard Worker         options -= HTML_PARSE_IGNORE_ENC;
6288*6777b538SAndroid Build Coastguard Worker     }
6289*6777b538SAndroid Build Coastguard Worker     if (options & HTML_PARSE_NOIMPLIED) {
6290*6777b538SAndroid Build Coastguard Worker         ctxt->options |= HTML_PARSE_NOIMPLIED;
6291*6777b538SAndroid Build Coastguard Worker         options -= HTML_PARSE_NOIMPLIED;
6292*6777b538SAndroid Build Coastguard Worker     }
6293*6777b538SAndroid Build Coastguard Worker     ctxt->dictNames = 0;
6294*6777b538SAndroid Build Coastguard Worker     ctxt->linenumbers = 1;
6295*6777b538SAndroid Build Coastguard Worker     return (options);
6296*6777b538SAndroid Build Coastguard Worker }
6297*6777b538SAndroid Build Coastguard Worker 
6298*6777b538SAndroid Build Coastguard Worker /**
6299*6777b538SAndroid Build Coastguard Worker  * htmlCtxtParseDocument:
6300*6777b538SAndroid Build Coastguard Worker  * @ctxt:  an HTML parser context
6301*6777b538SAndroid Build Coastguard Worker  *
6302*6777b538SAndroid Build Coastguard Worker  * Parse an HTML document and return the resulting document tree.
6303*6777b538SAndroid Build Coastguard Worker  *
6304*6777b538SAndroid Build Coastguard Worker  * Returns the resulting document tree or NULL
6305*6777b538SAndroid Build Coastguard Worker  */
6306*6777b538SAndroid Build Coastguard Worker htmlDocPtr
htmlCtxtParseDocument(htmlParserCtxtPtr ctxt,xmlParserInputPtr input)6307*6777b538SAndroid Build Coastguard Worker htmlCtxtParseDocument(htmlParserCtxtPtr ctxt, xmlParserInputPtr input)
6308*6777b538SAndroid Build Coastguard Worker {
6309*6777b538SAndroid Build Coastguard Worker     htmlDocPtr ret;
6310*6777b538SAndroid Build Coastguard Worker 
6311*6777b538SAndroid Build Coastguard Worker     if ((ctxt == NULL) || (input == NULL))
6312*6777b538SAndroid Build Coastguard Worker         return(NULL);
6313*6777b538SAndroid Build Coastguard Worker 
6314*6777b538SAndroid Build Coastguard Worker     /* assert(ctxt->inputNr == 0); */
6315*6777b538SAndroid Build Coastguard Worker     while (ctxt->inputNr > 0)
6316*6777b538SAndroid Build Coastguard Worker         xmlFreeInputStream(inputPop(ctxt));
6317*6777b538SAndroid Build Coastguard Worker 
6318*6777b538SAndroid Build Coastguard Worker     if (inputPush(ctxt, input) < 0) {
6319*6777b538SAndroid Build Coastguard Worker         xmlFreeInputStream(input);
6320*6777b538SAndroid Build Coastguard Worker         return(NULL);
6321*6777b538SAndroid Build Coastguard Worker     }
6322*6777b538SAndroid Build Coastguard Worker 
6323*6777b538SAndroid Build Coastguard Worker     ctxt->html = 1;
6324*6777b538SAndroid Build Coastguard Worker     htmlParseDocument(ctxt);
6325*6777b538SAndroid Build Coastguard Worker 
6326*6777b538SAndroid Build Coastguard Worker     if (ctxt->errNo != XML_ERR_NO_MEMORY) {
6327*6777b538SAndroid Build Coastguard Worker         ret = ctxt->myDoc;
6328*6777b538SAndroid Build Coastguard Worker     } else {
6329*6777b538SAndroid Build Coastguard Worker         ret = NULL;
6330*6777b538SAndroid Build Coastguard Worker         xmlFreeDoc(ctxt->myDoc);
6331*6777b538SAndroid Build Coastguard Worker     }
6332*6777b538SAndroid Build Coastguard Worker     ctxt->myDoc = NULL;
6333*6777b538SAndroid Build Coastguard Worker 
6334*6777b538SAndroid Build Coastguard Worker     /* assert(ctxt->inputNr == 1); */
6335*6777b538SAndroid Build Coastguard Worker     while (ctxt->inputNr > 0)
6336*6777b538SAndroid Build Coastguard Worker         xmlFreeInputStream(inputPop(ctxt));
6337*6777b538SAndroid Build Coastguard Worker 
6338*6777b538SAndroid Build Coastguard Worker     return(ret);
6339*6777b538SAndroid Build Coastguard Worker }
6340*6777b538SAndroid Build Coastguard Worker 
6341*6777b538SAndroid Build Coastguard Worker /**
6342*6777b538SAndroid Build Coastguard Worker  * htmlReadDoc:
6343*6777b538SAndroid Build Coastguard Worker  * @str:  a pointer to a zero terminated string
6344*6777b538SAndroid Build Coastguard Worker  * @url:  only used for error reporting (optoinal)
6345*6777b538SAndroid Build Coastguard Worker  * @encoding:  the document encoding (optional)
6346*6777b538SAndroid Build Coastguard Worker  * @options:  a combination of htmlParserOptions
6347*6777b538SAndroid Build Coastguard Worker  *
6348*6777b538SAndroid Build Coastguard Worker  * Convenience function to parse an HTML document from a zero-terminated
6349*6777b538SAndroid Build Coastguard Worker  * string.
6350*6777b538SAndroid Build Coastguard Worker  *
6351*6777b538SAndroid Build Coastguard Worker  * See htmlCtxtReadDoc for details.
6352*6777b538SAndroid Build Coastguard Worker  *
6353*6777b538SAndroid Build Coastguard Worker  * Returns the resulting document tree.
6354*6777b538SAndroid Build Coastguard Worker  */
6355*6777b538SAndroid Build Coastguard Worker htmlDocPtr
htmlReadDoc(const xmlChar * str,const char * url,const char * encoding,int options)6356*6777b538SAndroid Build Coastguard Worker htmlReadDoc(const xmlChar *str, const char *url, const char *encoding,
6357*6777b538SAndroid Build Coastguard Worker             int options)
6358*6777b538SAndroid Build Coastguard Worker {
6359*6777b538SAndroid Build Coastguard Worker     htmlParserCtxtPtr ctxt;
6360*6777b538SAndroid Build Coastguard Worker     xmlParserInputPtr input;
6361*6777b538SAndroid Build Coastguard Worker     htmlDocPtr doc;
6362*6777b538SAndroid Build Coastguard Worker 
6363*6777b538SAndroid Build Coastguard Worker     ctxt = htmlNewParserCtxt();
6364*6777b538SAndroid Build Coastguard Worker     if (ctxt == NULL)
6365*6777b538SAndroid Build Coastguard Worker         return(NULL);
6366*6777b538SAndroid Build Coastguard Worker 
6367*6777b538SAndroid Build Coastguard Worker     htmlCtxtUseOptions(ctxt, options);
6368*6777b538SAndroid Build Coastguard Worker 
6369*6777b538SAndroid Build Coastguard Worker     input = xmlNewInputString(ctxt, url, (const char *) str, encoding,
6370*6777b538SAndroid Build Coastguard Worker                               XML_INPUT_BUF_STATIC);
6371*6777b538SAndroid Build Coastguard Worker 
6372*6777b538SAndroid Build Coastguard Worker     doc = htmlCtxtParseDocument(ctxt, input);
6373*6777b538SAndroid Build Coastguard Worker 
6374*6777b538SAndroid Build Coastguard Worker     htmlFreeParserCtxt(ctxt);
6375*6777b538SAndroid Build Coastguard Worker     return(doc);
6376*6777b538SAndroid Build Coastguard Worker }
6377*6777b538SAndroid Build Coastguard Worker 
6378*6777b538SAndroid Build Coastguard Worker /**
6379*6777b538SAndroid Build Coastguard Worker  * htmlReadFile:
6380*6777b538SAndroid Build Coastguard Worker  * @filename:  a file or URL
6381*6777b538SAndroid Build Coastguard Worker  * @encoding:  the document encoding (optional)
6382*6777b538SAndroid Build Coastguard Worker  * @options:  a combination of htmlParserOptions
6383*6777b538SAndroid Build Coastguard Worker  *
6384*6777b538SAndroid Build Coastguard Worker  * Convenience function to parse an HTML file from the filesystem,
6385*6777b538SAndroid Build Coastguard Worker  * the network or a global user-defined resource loader.
6386*6777b538SAndroid Build Coastguard Worker  *
6387*6777b538SAndroid Build Coastguard Worker  * See htmlCtxtReadFile for details.
6388*6777b538SAndroid Build Coastguard Worker  *
6389*6777b538SAndroid Build Coastguard Worker  * Returns the resulting document tree.
6390*6777b538SAndroid Build Coastguard Worker  */
6391*6777b538SAndroid Build Coastguard Worker htmlDocPtr
htmlReadFile(const char * filename,const char * encoding,int options)6392*6777b538SAndroid Build Coastguard Worker htmlReadFile(const char *filename, const char *encoding, int options)
6393*6777b538SAndroid Build Coastguard Worker {
6394*6777b538SAndroid Build Coastguard Worker     htmlParserCtxtPtr ctxt;
6395*6777b538SAndroid Build Coastguard Worker     xmlParserInputPtr input;
6396*6777b538SAndroid Build Coastguard Worker     htmlDocPtr doc;
6397*6777b538SAndroid Build Coastguard Worker 
6398*6777b538SAndroid Build Coastguard Worker     ctxt = htmlNewParserCtxt();
6399*6777b538SAndroid Build Coastguard Worker     if (ctxt == NULL)
6400*6777b538SAndroid Build Coastguard Worker         return(NULL);
6401*6777b538SAndroid Build Coastguard Worker 
6402*6777b538SAndroid Build Coastguard Worker     htmlCtxtUseOptions(ctxt, options);
6403*6777b538SAndroid Build Coastguard Worker 
6404*6777b538SAndroid Build Coastguard Worker     input = xmlNewInputURL(ctxt, filename, NULL, encoding, 0);
6405*6777b538SAndroid Build Coastguard Worker 
6406*6777b538SAndroid Build Coastguard Worker     doc = htmlCtxtParseDocument(ctxt, input);
6407*6777b538SAndroid Build Coastguard Worker 
6408*6777b538SAndroid Build Coastguard Worker     htmlFreeParserCtxt(ctxt);
6409*6777b538SAndroid Build Coastguard Worker     return(doc);
6410*6777b538SAndroid Build Coastguard Worker }
6411*6777b538SAndroid Build Coastguard Worker 
6412*6777b538SAndroid Build Coastguard Worker /**
6413*6777b538SAndroid Build Coastguard Worker  * htmlReadMemory:
6414*6777b538SAndroid Build Coastguard Worker  * @buffer:  a pointer to a char array
6415*6777b538SAndroid Build Coastguard Worker  * @size:  the size of the array
6416*6777b538SAndroid Build Coastguard Worker  * @url:  only used for error reporting (optional)
6417*6777b538SAndroid Build Coastguard Worker  * @encoding:  the document encoding, or NULL
6418*6777b538SAndroid Build Coastguard Worker  * @options:  a combination of htmlParserOption(s)
6419*6777b538SAndroid Build Coastguard Worker  *
6420*6777b538SAndroid Build Coastguard Worker  * Convenience function to parse an HTML document from memory.
6421*6777b538SAndroid Build Coastguard Worker  * The input buffer must not contain any terminating null bytes.
6422*6777b538SAndroid Build Coastguard Worker  *
6423*6777b538SAndroid Build Coastguard Worker  * See htmlCtxtReadMemory for details.
6424*6777b538SAndroid Build Coastguard Worker  *
6425*6777b538SAndroid Build Coastguard Worker  * Returns the resulting document tree
6426*6777b538SAndroid Build Coastguard Worker  */
6427*6777b538SAndroid Build Coastguard Worker htmlDocPtr
htmlReadMemory(const char * buffer,int size,const char * url,const char * encoding,int options)6428*6777b538SAndroid Build Coastguard Worker htmlReadMemory(const char *buffer, int size, const char *url,
6429*6777b538SAndroid Build Coastguard Worker                const char *encoding, int options)
6430*6777b538SAndroid Build Coastguard Worker {
6431*6777b538SAndroid Build Coastguard Worker     htmlParserCtxtPtr ctxt;
6432*6777b538SAndroid Build Coastguard Worker     xmlParserInputPtr input;
6433*6777b538SAndroid Build Coastguard Worker     htmlDocPtr doc;
6434*6777b538SAndroid Build Coastguard Worker 
6435*6777b538SAndroid Build Coastguard Worker     if (size < 0)
6436*6777b538SAndroid Build Coastguard Worker 	return(NULL);
6437*6777b538SAndroid Build Coastguard Worker 
6438*6777b538SAndroid Build Coastguard Worker     ctxt = htmlNewParserCtxt();
6439*6777b538SAndroid Build Coastguard Worker     if (ctxt == NULL)
6440*6777b538SAndroid Build Coastguard Worker         return(NULL);
6441*6777b538SAndroid Build Coastguard Worker 
6442*6777b538SAndroid Build Coastguard Worker     htmlCtxtUseOptions(ctxt, options);
6443*6777b538SAndroid Build Coastguard Worker 
6444*6777b538SAndroid Build Coastguard Worker     input = xmlNewInputMemory(ctxt, url, buffer, size, encoding,
6445*6777b538SAndroid Build Coastguard Worker                               XML_INPUT_BUF_STATIC);
6446*6777b538SAndroid Build Coastguard Worker 
6447*6777b538SAndroid Build Coastguard Worker     doc = htmlCtxtParseDocument(ctxt, input);
6448*6777b538SAndroid Build Coastguard Worker 
6449*6777b538SAndroid Build Coastguard Worker     htmlFreeParserCtxt(ctxt);
6450*6777b538SAndroid Build Coastguard Worker     return(doc);
6451*6777b538SAndroid Build Coastguard Worker }
6452*6777b538SAndroid Build Coastguard Worker 
6453*6777b538SAndroid Build Coastguard Worker /**
6454*6777b538SAndroid Build Coastguard Worker  * htmlReadFd:
6455*6777b538SAndroid Build Coastguard Worker  * @fd:  an open file descriptor
6456*6777b538SAndroid Build Coastguard Worker  * @url:  only used for error reporting (optional)
6457*6777b538SAndroid Build Coastguard Worker  * @encoding:  the document encoding, or NULL
6458*6777b538SAndroid Build Coastguard Worker  * @options:  a combination of htmlParserOptions
6459*6777b538SAndroid Build Coastguard Worker  *
6460*6777b538SAndroid Build Coastguard Worker  * Convenience function to parse an HTML document from a
6461*6777b538SAndroid Build Coastguard Worker  * file descriptor.
6462*6777b538SAndroid Build Coastguard Worker  *
6463*6777b538SAndroid Build Coastguard Worker  * NOTE that the file descriptor will not be closed when the
6464*6777b538SAndroid Build Coastguard Worker  * context is freed or reset.
6465*6777b538SAndroid Build Coastguard Worker  *
6466*6777b538SAndroid Build Coastguard Worker  * See htmlCtxtReadFd for details.
6467*6777b538SAndroid Build Coastguard Worker  *
6468*6777b538SAndroid Build Coastguard Worker  * Returns the resulting document tree
6469*6777b538SAndroid Build Coastguard Worker  */
6470*6777b538SAndroid Build Coastguard Worker htmlDocPtr
htmlReadFd(int fd,const char * url,const char * encoding,int options)6471*6777b538SAndroid Build Coastguard Worker htmlReadFd(int fd, const char *url, const char *encoding, int options)
6472*6777b538SAndroid Build Coastguard Worker {
6473*6777b538SAndroid Build Coastguard Worker     htmlParserCtxtPtr ctxt;
6474*6777b538SAndroid Build Coastguard Worker     xmlParserInputPtr input;
6475*6777b538SAndroid Build Coastguard Worker     htmlDocPtr doc;
6476*6777b538SAndroid Build Coastguard Worker 
6477*6777b538SAndroid Build Coastguard Worker     ctxt = htmlNewParserCtxt();
6478*6777b538SAndroid Build Coastguard Worker     if (ctxt == NULL)
6479*6777b538SAndroid Build Coastguard Worker         return(NULL);
6480*6777b538SAndroid Build Coastguard Worker 
6481*6777b538SAndroid Build Coastguard Worker     htmlCtxtUseOptions(ctxt, options);
6482*6777b538SAndroid Build Coastguard Worker 
6483*6777b538SAndroid Build Coastguard Worker     input = xmlNewInputFd(ctxt, url, fd, encoding, 0);
6484*6777b538SAndroid Build Coastguard Worker     input->buf->closecallback = NULL;
6485*6777b538SAndroid Build Coastguard Worker 
6486*6777b538SAndroid Build Coastguard Worker     doc = htmlCtxtParseDocument(ctxt, input);
6487*6777b538SAndroid Build Coastguard Worker 
6488*6777b538SAndroid Build Coastguard Worker     htmlFreeParserCtxt(ctxt);
6489*6777b538SAndroid Build Coastguard Worker     return(doc);
6490*6777b538SAndroid Build Coastguard Worker }
6491*6777b538SAndroid Build Coastguard Worker 
6492*6777b538SAndroid Build Coastguard Worker /**
6493*6777b538SAndroid Build Coastguard Worker  * htmlReadIO:
6494*6777b538SAndroid Build Coastguard Worker  * @ioread:  an I/O read function
6495*6777b538SAndroid Build Coastguard Worker  * @ioclose:  an I/O close function (optional)
6496*6777b538SAndroid Build Coastguard Worker  * @ioctx:  an I/O handler
6497*6777b538SAndroid Build Coastguard Worker  * @url:  only used for error reporting (optional)
6498*6777b538SAndroid Build Coastguard Worker  * @encoding:  the document encoding (optional)
6499*6777b538SAndroid Build Coastguard Worker  * @options:  a combination of htmlParserOption(s)
6500*6777b538SAndroid Build Coastguard Worker  *
6501*6777b538SAndroid Build Coastguard Worker  * Convenience function to parse an HTML document from I/O functions
6502*6777b538SAndroid Build Coastguard Worker  * and context.
6503*6777b538SAndroid Build Coastguard Worker  *
6504*6777b538SAndroid Build Coastguard Worker  * See htmlCtxtReadIO for details.
6505*6777b538SAndroid Build Coastguard Worker  *
6506*6777b538SAndroid Build Coastguard Worker  * Returns the resulting document tree
6507*6777b538SAndroid Build Coastguard Worker  */
6508*6777b538SAndroid Build Coastguard Worker htmlDocPtr
htmlReadIO(xmlInputReadCallback ioread,xmlInputCloseCallback ioclose,void * ioctx,const char * url,const char * encoding,int options)6509*6777b538SAndroid Build Coastguard Worker htmlReadIO(xmlInputReadCallback ioread, xmlInputCloseCallback ioclose,
6510*6777b538SAndroid Build Coastguard Worker           void *ioctx, const char *url, const char *encoding, int options)
6511*6777b538SAndroid Build Coastguard Worker {
6512*6777b538SAndroid Build Coastguard Worker     htmlParserCtxtPtr ctxt;
6513*6777b538SAndroid Build Coastguard Worker     xmlParserInputPtr input;
6514*6777b538SAndroid Build Coastguard Worker     htmlDocPtr doc;
6515*6777b538SAndroid Build Coastguard Worker 
6516*6777b538SAndroid Build Coastguard Worker     ctxt = htmlNewParserCtxt();
6517*6777b538SAndroid Build Coastguard Worker     if (ctxt == NULL)
6518*6777b538SAndroid Build Coastguard Worker         return (NULL);
6519*6777b538SAndroid Build Coastguard Worker 
6520*6777b538SAndroid Build Coastguard Worker     htmlCtxtUseOptions(ctxt, options);
6521*6777b538SAndroid Build Coastguard Worker 
6522*6777b538SAndroid Build Coastguard Worker     input = xmlNewInputIO(ctxt, url, ioread, ioclose, ioctx, encoding, 0);
6523*6777b538SAndroid Build Coastguard Worker 
6524*6777b538SAndroid Build Coastguard Worker     doc = htmlCtxtParseDocument(ctxt, input);
6525*6777b538SAndroid Build Coastguard Worker 
6526*6777b538SAndroid Build Coastguard Worker     htmlFreeParserCtxt(ctxt);
6527*6777b538SAndroid Build Coastguard Worker     return(doc);
6528*6777b538SAndroid Build Coastguard Worker }
6529*6777b538SAndroid Build Coastguard Worker 
6530*6777b538SAndroid Build Coastguard Worker /**
6531*6777b538SAndroid Build Coastguard Worker  * htmlCtxtReadDoc:
6532*6777b538SAndroid Build Coastguard Worker  * @ctxt:  an HTML parser context
6533*6777b538SAndroid Build Coastguard Worker  * @str:  a pointer to a zero terminated string
6534*6777b538SAndroid Build Coastguard Worker  * @URL:  only used for error reporting (optional)
6535*6777b538SAndroid Build Coastguard Worker  * @encoding:  the document encoding (optional)
6536*6777b538SAndroid Build Coastguard Worker  * @options:  a combination of htmlParserOptions
6537*6777b538SAndroid Build Coastguard Worker  *
6538*6777b538SAndroid Build Coastguard Worker  * Parse an HTML in-memory document and build a tree.
6539*6777b538SAndroid Build Coastguard Worker  *
6540*6777b538SAndroid Build Coastguard Worker  * See htmlCtxtUseOptions for details.
6541*6777b538SAndroid Build Coastguard Worker  *
6542*6777b538SAndroid Build Coastguard Worker  * Returns the resulting document tree
6543*6777b538SAndroid Build Coastguard Worker  */
6544*6777b538SAndroid Build Coastguard Worker htmlDocPtr
htmlCtxtReadDoc(htmlParserCtxtPtr ctxt,const xmlChar * str,const char * URL,const char * encoding,int options)6545*6777b538SAndroid Build Coastguard Worker htmlCtxtReadDoc(htmlParserCtxtPtr ctxt, const xmlChar *str,
6546*6777b538SAndroid Build Coastguard Worker                 const char *URL, const char *encoding, int options)
6547*6777b538SAndroid Build Coastguard Worker {
6548*6777b538SAndroid Build Coastguard Worker     xmlParserInputPtr input;
6549*6777b538SAndroid Build Coastguard Worker 
6550*6777b538SAndroid Build Coastguard Worker     if (ctxt == NULL)
6551*6777b538SAndroid Build Coastguard Worker         return (NULL);
6552*6777b538SAndroid Build Coastguard Worker 
6553*6777b538SAndroid Build Coastguard Worker     htmlCtxtReset(ctxt);
6554*6777b538SAndroid Build Coastguard Worker     htmlCtxtUseOptions(ctxt, options);
6555*6777b538SAndroid Build Coastguard Worker 
6556*6777b538SAndroid Build Coastguard Worker     input = xmlNewInputString(ctxt, URL, (const char *) str, encoding, 0);
6557*6777b538SAndroid Build Coastguard Worker 
6558*6777b538SAndroid Build Coastguard Worker     return(htmlCtxtParseDocument(ctxt, input));
6559*6777b538SAndroid Build Coastguard Worker }
6560*6777b538SAndroid Build Coastguard Worker 
6561*6777b538SAndroid Build Coastguard Worker /**
6562*6777b538SAndroid Build Coastguard Worker  * htmlCtxtReadFile:
6563*6777b538SAndroid Build Coastguard Worker  * @ctxt:  an HTML parser context
6564*6777b538SAndroid Build Coastguard Worker  * @filename:  a file or URL
6565*6777b538SAndroid Build Coastguard Worker  * @encoding:  the document encoding (optional)
6566*6777b538SAndroid Build Coastguard Worker  * @options:  a combination of htmlParserOptions
6567*6777b538SAndroid Build Coastguard Worker  *
6568*6777b538SAndroid Build Coastguard Worker  * Parse an HTML file from the filesystem, the network or a
6569*6777b538SAndroid Build Coastguard Worker  * user-defined resource loader.
6570*6777b538SAndroid Build Coastguard Worker  *
6571*6777b538SAndroid Build Coastguard Worker  * See xmlNewInputURL and htmlCtxtUseOptions for details.
6572*6777b538SAndroid Build Coastguard Worker  *
6573*6777b538SAndroid Build Coastguard Worker  * Returns the resulting document tree
6574*6777b538SAndroid Build Coastguard Worker  */
6575*6777b538SAndroid Build Coastguard Worker htmlDocPtr
htmlCtxtReadFile(htmlParserCtxtPtr ctxt,const char * filename,const char * encoding,int options)6576*6777b538SAndroid Build Coastguard Worker htmlCtxtReadFile(htmlParserCtxtPtr ctxt, const char *filename,
6577*6777b538SAndroid Build Coastguard Worker                 const char *encoding, int options)
6578*6777b538SAndroid Build Coastguard Worker {
6579*6777b538SAndroid Build Coastguard Worker     xmlParserInputPtr input;
6580*6777b538SAndroid Build Coastguard Worker 
6581*6777b538SAndroid Build Coastguard Worker     if (ctxt == NULL)
6582*6777b538SAndroid Build Coastguard Worker         return (NULL);
6583*6777b538SAndroid Build Coastguard Worker 
6584*6777b538SAndroid Build Coastguard Worker     htmlCtxtReset(ctxt);
6585*6777b538SAndroid Build Coastguard Worker     htmlCtxtUseOptions(ctxt, options);
6586*6777b538SAndroid Build Coastguard Worker 
6587*6777b538SAndroid Build Coastguard Worker     input = xmlNewInputURL(ctxt, filename, NULL, encoding, 0);
6588*6777b538SAndroid Build Coastguard Worker 
6589*6777b538SAndroid Build Coastguard Worker     return(htmlCtxtParseDocument(ctxt, input));
6590*6777b538SAndroid Build Coastguard Worker }
6591*6777b538SAndroid Build Coastguard Worker 
6592*6777b538SAndroid Build Coastguard Worker /**
6593*6777b538SAndroid Build Coastguard Worker  * htmlCtxtReadMemory:
6594*6777b538SAndroid Build Coastguard Worker  * @ctxt:  an HTML parser context
6595*6777b538SAndroid Build Coastguard Worker  * @buffer:  a pointer to a char array
6596*6777b538SAndroid Build Coastguard Worker  * @size:  the size of the array
6597*6777b538SAndroid Build Coastguard Worker  * @URL:  only used for error reporting (optional)
6598*6777b538SAndroid Build Coastguard Worker  * @encoding:  the document encoding (optinal)
6599*6777b538SAndroid Build Coastguard Worker  * @options:  a combination of htmlParserOptions
6600*6777b538SAndroid Build Coastguard Worker  *
6601*6777b538SAndroid Build Coastguard Worker  * Parse an HTML in-memory document and build a tree. The input buffer must
6602*6777b538SAndroid Build Coastguard Worker  * not contain any terminating null bytes.
6603*6777b538SAndroid Build Coastguard Worker  *
6604*6777b538SAndroid Build Coastguard Worker  * See htmlCtxtUseOptions for details.
6605*6777b538SAndroid Build Coastguard Worker  *
6606*6777b538SAndroid Build Coastguard Worker  * Returns the resulting document tree
6607*6777b538SAndroid Build Coastguard Worker  */
6608*6777b538SAndroid Build Coastguard Worker htmlDocPtr
htmlCtxtReadMemory(htmlParserCtxtPtr ctxt,const char * buffer,int size,const char * URL,const char * encoding,int options)6609*6777b538SAndroid Build Coastguard Worker htmlCtxtReadMemory(htmlParserCtxtPtr ctxt, const char *buffer, int size,
6610*6777b538SAndroid Build Coastguard Worker                   const char *URL, const char *encoding, int options)
6611*6777b538SAndroid Build Coastguard Worker {
6612*6777b538SAndroid Build Coastguard Worker     xmlParserInputPtr input;
6613*6777b538SAndroid Build Coastguard Worker 
6614*6777b538SAndroid Build Coastguard Worker     if ((ctxt == NULL) || (size < 0))
6615*6777b538SAndroid Build Coastguard Worker         return (NULL);
6616*6777b538SAndroid Build Coastguard Worker 
6617*6777b538SAndroid Build Coastguard Worker     htmlCtxtReset(ctxt);
6618*6777b538SAndroid Build Coastguard Worker     htmlCtxtUseOptions(ctxt, options);
6619*6777b538SAndroid Build Coastguard Worker 
6620*6777b538SAndroid Build Coastguard Worker     input = xmlNewInputMemory(ctxt, URL, buffer, size, encoding,
6621*6777b538SAndroid Build Coastguard Worker                               XML_INPUT_BUF_STATIC);
6622*6777b538SAndroid Build Coastguard Worker 
6623*6777b538SAndroid Build Coastguard Worker     return(htmlCtxtParseDocument(ctxt, input));
6624*6777b538SAndroid Build Coastguard Worker }
6625*6777b538SAndroid Build Coastguard Worker 
6626*6777b538SAndroid Build Coastguard Worker /**
6627*6777b538SAndroid Build Coastguard Worker  * htmlCtxtReadFd:
6628*6777b538SAndroid Build Coastguard Worker  * @ctxt:  an HTML parser context
6629*6777b538SAndroid Build Coastguard Worker  * @fd:  an open file descriptor
6630*6777b538SAndroid Build Coastguard Worker  * @URL:  only used for error reporting (optional)
6631*6777b538SAndroid Build Coastguard Worker  * @encoding:  the document encoding (optinal)
6632*6777b538SAndroid Build Coastguard Worker  * @options:  a combination of htmlParserOptions
6633*6777b538SAndroid Build Coastguard Worker  *
6634*6777b538SAndroid Build Coastguard Worker  * Parse an HTML from a file descriptor and build a tree.
6635*6777b538SAndroid Build Coastguard Worker  *
6636*6777b538SAndroid Build Coastguard Worker  * See htmlCtxtUseOptions for details.
6637*6777b538SAndroid Build Coastguard Worker  *
6638*6777b538SAndroid Build Coastguard Worker  * NOTE that the file descriptor will not be closed when the
6639*6777b538SAndroid Build Coastguard Worker  * context is freed or reset.
6640*6777b538SAndroid Build Coastguard Worker  *
6641*6777b538SAndroid Build Coastguard Worker  * Returns the resulting document tree
6642*6777b538SAndroid Build Coastguard Worker  */
6643*6777b538SAndroid Build Coastguard Worker htmlDocPtr
htmlCtxtReadFd(htmlParserCtxtPtr ctxt,int fd,const char * URL,const char * encoding,int options)6644*6777b538SAndroid Build Coastguard Worker htmlCtxtReadFd(htmlParserCtxtPtr ctxt, int fd,
6645*6777b538SAndroid Build Coastguard Worker               const char *URL, const char *encoding, int options)
6646*6777b538SAndroid Build Coastguard Worker {
6647*6777b538SAndroid Build Coastguard Worker     xmlParserInputPtr input;
6648*6777b538SAndroid Build Coastguard Worker 
6649*6777b538SAndroid Build Coastguard Worker     if (ctxt == NULL)
6650*6777b538SAndroid Build Coastguard Worker         return(NULL);
6651*6777b538SAndroid Build Coastguard Worker 
6652*6777b538SAndroid Build Coastguard Worker     htmlCtxtReset(ctxt);
6653*6777b538SAndroid Build Coastguard Worker     htmlCtxtUseOptions(ctxt, options);
6654*6777b538SAndroid Build Coastguard Worker 
6655*6777b538SAndroid Build Coastguard Worker     input = xmlNewInputFd(ctxt, URL, fd, encoding, 0);
6656*6777b538SAndroid Build Coastguard Worker     input->buf->closecallback = NULL;
6657*6777b538SAndroid Build Coastguard Worker 
6658*6777b538SAndroid Build Coastguard Worker     return(htmlCtxtParseDocument(ctxt, input));
6659*6777b538SAndroid Build Coastguard Worker }
6660*6777b538SAndroid Build Coastguard Worker 
6661*6777b538SAndroid Build Coastguard Worker /**
6662*6777b538SAndroid Build Coastguard Worker  * htmlCtxtReadIO:
6663*6777b538SAndroid Build Coastguard Worker  * @ctxt:  an HTML parser context
6664*6777b538SAndroid Build Coastguard Worker  * @ioread:  an I/O read function
6665*6777b538SAndroid Build Coastguard Worker  * @ioclose:  an I/O close function
6666*6777b538SAndroid Build Coastguard Worker  * @ioctx:  an I/O handler
6667*6777b538SAndroid Build Coastguard Worker  * @URL:  the base URL to use for the document
6668*6777b538SAndroid Build Coastguard Worker  * @encoding:  the document encoding, or NULL
6669*6777b538SAndroid Build Coastguard Worker  * @options:  a combination of htmlParserOption(s)
6670*6777b538SAndroid Build Coastguard Worker  *
6671*6777b538SAndroid Build Coastguard Worker  * Parse an HTML document from I/O functions and source and build a tree.
6672*6777b538SAndroid Build Coastguard Worker  *
6673*6777b538SAndroid Build Coastguard Worker  * See xmlNewInputIO and htmlCtxtUseOptions for details.
6674*6777b538SAndroid Build Coastguard Worker  *
6675*6777b538SAndroid Build Coastguard Worker  * Returns the resulting document tree
6676*6777b538SAndroid Build Coastguard Worker  */
6677*6777b538SAndroid Build Coastguard Worker htmlDocPtr
htmlCtxtReadIO(htmlParserCtxtPtr ctxt,xmlInputReadCallback ioread,xmlInputCloseCallback ioclose,void * ioctx,const char * URL,const char * encoding,int options)6678*6777b538SAndroid Build Coastguard Worker htmlCtxtReadIO(htmlParserCtxtPtr ctxt, xmlInputReadCallback ioread,
6679*6777b538SAndroid Build Coastguard Worker               xmlInputCloseCallback ioclose, void *ioctx,
6680*6777b538SAndroid Build Coastguard Worker 	      const char *URL,
6681*6777b538SAndroid Build Coastguard Worker               const char *encoding, int options)
6682*6777b538SAndroid Build Coastguard Worker {
6683*6777b538SAndroid Build Coastguard Worker     xmlParserInputPtr input;
6684*6777b538SAndroid Build Coastguard Worker 
6685*6777b538SAndroid Build Coastguard Worker     if (ctxt == NULL)
6686*6777b538SAndroid Build Coastguard Worker         return (NULL);
6687*6777b538SAndroid Build Coastguard Worker 
6688*6777b538SAndroid Build Coastguard Worker     htmlCtxtReset(ctxt);
6689*6777b538SAndroid Build Coastguard Worker     htmlCtxtUseOptions(ctxt, options);
6690*6777b538SAndroid Build Coastguard Worker 
6691*6777b538SAndroid Build Coastguard Worker     input = xmlNewInputIO(ctxt, URL, ioread, ioclose, ioctx, encoding, 0);
6692*6777b538SAndroid Build Coastguard Worker 
6693*6777b538SAndroid Build Coastguard Worker     return(htmlCtxtParseDocument(ctxt, input));
6694*6777b538SAndroid Build Coastguard Worker }
6695*6777b538SAndroid Build Coastguard Worker 
6696*6777b538SAndroid Build Coastguard Worker #endif /* LIBXML_HTML_ENABLED */
6697