1 /* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */
2 /* vi: set ts=4 sw=4 expandtab: (add to ~/.vimrc: set modeline modelines=5) */
3 /* ***** BEGIN LICENSE BLOCK *****
4 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6 * The contents of this file are subject to the Mozilla Public License Version
7 * 1.1 (the "License"); you may not use this file except in compliance with
8 * the License. You may obtain a copy of the License at
9 * http://www.mozilla.org/MPL/
11 * Software distributed under the License is distributed on an "AS IS" basis,
12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 * for the specific language governing rights and limitations under the
16 * The Original Code is [Open Source Virtual Machine.].
18 * The Initial Developer of the Original Code is
19 * Adobe System Incorporated.
20 * Portions created by the Initial Developer are Copyright (C) 2008
21 * the Initial Developer. All Rights Reserved.
26 * Alternatively, the contents of this file may be used under the terms of
27 * either the GNU General Public License Version 2 or later (the "GPL"), or
28 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 * in which case the provisions of the GPL or the LGPL are applicable instead
30 * of those above. If you wish to allow use of your version of this file only
31 * under the terms of either the GPL or the LGPL, and not to allow others to
32 * use your version of this file under the terms of the MPL, indicate your
33 * decision by deleting the provisions above and replace them with the notice
34 * and other provisions required by the GPL or the LGPL. If you do not delete
35 * the provisions above, a recipient may use your version of this file under
36 * the terms of any one of the MPL, the GPL or the LGPL.
38 * ***** END LICENSE BLOCK ***** */
50 // xmlInitializer is the only entry point.
54 XmlContext(Compiler
* compiler
)
55 : allocator(compiler
->allocator
)
62 void addExpr(Expr
* e
);
64 void addText(const char* s
);
65 void addText(wchar c
);
71 Allocator
* const allocator
;
72 SeqBuilder
<Expr
*> exprs
;
77 void XmlContext::addExpr(Expr
* e
)
83 void XmlContext::addText(Str
* s
)
88 void XmlContext::addText(const char* s
)
94 void XmlContext::addText(wchar c
)
99 Seq
<Expr
*>* XmlContext::get()
105 void XmlContext::flush() {
106 if (text
.length() > 0) {
107 exprs
.addAtEnd(ALLOC(LiteralString
, (text
.str(), text_start
)));
110 getn(buf, text.str(), 500);
117 Expr
* Parser::xmlInitializer()
119 AvmAssert( T0
== T_BreakLeftAngle
&& T1
== T_LAST
);
121 XmlContext
ctx(compiler
);
122 bool is_list
= false;
123 uint32_t pos
= position();
130 case T_XmlProcessingInstruction
:
137 if (T0
== T_XmlRightAngle
) {
139 xmlListInitializer(&ctx
);
146 compiler
->internalError(position(), "error state in xml handling");
151 next(); // Re-synchronize the lexer for normal lexing
152 return ALLOC(XmlInitializer
, (ctx
.get(), is_list
, pos
));
158 void Parser::xmlListInitializer(XmlContext
* ctx
)
160 xmlAssert(ctx
, T_XmlRightAngle
);
161 xmlElementContent(ctx
);
162 xmlAssert(ctx
, T_XmlLeftAngleSlash
);
164 xmlAssert(ctx
, T_XmlRightAngle
);
167 // IN: T0 is first non-space token of tag name
168 // OUT: T0 is ">" or "/>"
170 void Parser::xmlElement(XmlContext
* ctx
)
173 if (T0
!= T_XmlRightAngle
&& T0
!= T_XmlSlashRightAngle
) {
177 if (T0
== T_XmlRightAngle
) {
179 xmlElementContent(ctx
);
180 xmlAssert(ctx
, T_XmlLeftAngleSlash
);
183 xmlAssert(ctx
, T_XmlRightAngle
);
186 xmlAssert(ctx
, T_XmlSlashRightAngle
);
189 // IN: T0 is first non-space token of name
190 // OUT: T0 is first non-space token following name
192 void Parser::xmlTagName(XmlContext
* ctx
)
194 if (T0
== T_XmlLeftBrace
)
195 xmlExpression(ctx
, ESC_none
);
197 xmlAssert(ctx
, T_XmlName
);
201 // IN: T0 is first non-space token of first attribute (or /> or >)
202 // OUT: T0 is /> or >
204 void Parser::xmlAttributes(XmlContext
* ctx
)
207 while (T0
!= T_XmlRightAngle
&& T0
!= T_XmlSlashRightAngle
) {
212 if (T0
== T_XmlLeftBrace
) {
213 xmlExpression(ctx
, ESC_attributeValue
);
215 // {E} = V is an extension required by the test suite, not in Ecma-357
216 if (T0
== T_XmlEquals
)
220 xmlAssert(ctx
, T_XmlName
);
223 xmlAssert(ctx
, T_XmlEquals
);
225 if (T0
== T_XmlLeftBrace
) {
227 xmlExpression(ctx
, ESC_attributeValue
);
231 xmlAssert(ctx
, T_XmlString
, ESC_attributeValue
);
240 void Parser::xmlElementContent(XmlContext
* ctx
)
245 case T_XmlProcessingInstruction
:
249 case T_XmlWhitespace
:
252 case T_XmlRightBrace
:
253 case T_XmlRightAngle
:
254 case T_XmlSlashRightAngle
:
259 xmlExpression(ctx
, ESC_elementValue
);
266 case T_XmlLeftAngleSlash
:
269 compiler
->internalError(position(), "Unexpected state in XML parsing");
277 void Parser::xmlExpression(XmlContext
* ctx
, Escapement esc
)
279 AvmAssert( T0
== T_XmlLeftBrace
);
280 next(); // re-enter normal lexing
281 Expr
* expr
= commaExpression(0);
283 expr
= ALLOC(EscapeExpr
, (expr
, esc
));
285 AvmAssert( T0
== T_RightBrace
&& T1
== T_LAST
);
288 xmlAssert(ctx
, T_XmlRightBrace
);
291 void Parser::xmlEscape(XmlContext
* ctx
, const wchar
* cs
, const wchar
* limit
, bool is_attr
)
293 while ( cs
< limit
) {
297 ctx
->addText("<");
300 ctx
->addText("&");
304 ctx
->addText(""");
308 ctx
->addText(">");
311 // This is weird but apparently according to spec
313 if (cs
+ 5 <= limit
&&
321 ctx
->addText("
");
325 ctx
->addText("
");
329 ctx
->addText("	");
342 void Parser::xmlAssert(XmlContext
* ctx
, Token t
, Escapement esc
)
345 compiler
->syntaxError(position(), SYNTAXERR_XML_UNEXPECTED_TOKEN
);
347 case T_XmlProcessingInstruction
:
352 case T_XmlWhitespace
:
358 case ESC_attributeValue
:
359 case ESC_elementValue
:
362 ctx->addText(V0.s->s[0]);
363 xmlEscape(ctx, V0.s->s + 1, V0.s->s + V0.s->length - 1, esc == ESC_attributeValue);
364 ctx->addText(V0.s->s[0]);
372 case T_XmlRightBrace
:
375 case T_XmlRightAngle
:
378 case T_XmlSlashRightAngle
:
387 case T_XmlLeftAngleSlash
:
391 compiler
->internalError(position(), "Unexpected token in XML parsing");
395 void Parser::xmlAtomSkipSpace()
399 } while (T0
== T_XmlWhitespace
);