1*2bc180efSBaptiste Daroussin /*
2*2bc180efSBaptiste Daroussin * parser.c, libyaml parser binding for Lua
3*2bc180efSBaptiste Daroussin * Written by Gary V. Vaughan, 2013
4*2bc180efSBaptiste Daroussin *
5*2bc180efSBaptiste Daroussin * Copyright (C) 2013-2022 Gary V. Vaughan
6*2bc180efSBaptiste Daroussin *
7*2bc180efSBaptiste Daroussin * Permission is hereby granted, free of charge, to any person obtaining a copy
8*2bc180efSBaptiste Daroussin * of this software and associated documentation files (the "Software"), to deal
9*2bc180efSBaptiste Daroussin * in the Software without restriction, including without limitation the rights
10*2bc180efSBaptiste Daroussin * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11*2bc180efSBaptiste Daroussin * copies of the Software, and to permit persons to whom the Software is
12*2bc180efSBaptiste Daroussin * furnished to do so, subject to the following conditions:
13*2bc180efSBaptiste Daroussin *
14*2bc180efSBaptiste Daroussin * The above copyright notice and this permission notice shall be included in
15*2bc180efSBaptiste Daroussin * all copies or substantial portions of the Software.
16*2bc180efSBaptiste Daroussin *
17*2bc180efSBaptiste Daroussin * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18*2bc180efSBaptiste Daroussin * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19*2bc180efSBaptiste Daroussin * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20*2bc180efSBaptiste Daroussin * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21*2bc180efSBaptiste Daroussin * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22*2bc180efSBaptiste Daroussin * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23*2bc180efSBaptiste Daroussin * THE SOFTWARE.
24*2bc180efSBaptiste Daroussin */
25*2bc180efSBaptiste Daroussin
26*2bc180efSBaptiste Daroussin #include "lyaml.h"
27*2bc180efSBaptiste Daroussin
28*2bc180efSBaptiste Daroussin typedef struct {
29*2bc180efSBaptiste Daroussin lua_State *L;
30*2bc180efSBaptiste Daroussin yaml_parser_t parser;
31*2bc180efSBaptiste Daroussin yaml_event_t event;
32*2bc180efSBaptiste Daroussin char validevent;
33*2bc180efSBaptiste Daroussin int document_count;
34*2bc180efSBaptiste Daroussin } lyaml_parser;
35*2bc180efSBaptiste Daroussin
36*2bc180efSBaptiste Daroussin
37*2bc180efSBaptiste Daroussin static void
parser_delete_event(lyaml_parser * parser)38*2bc180efSBaptiste Daroussin parser_delete_event (lyaml_parser *parser)
39*2bc180efSBaptiste Daroussin {
40*2bc180efSBaptiste Daroussin if (parser->validevent)
41*2bc180efSBaptiste Daroussin {
42*2bc180efSBaptiste Daroussin yaml_event_delete (&parser->event);
43*2bc180efSBaptiste Daroussin parser->validevent = 0;
44*2bc180efSBaptiste Daroussin }
45*2bc180efSBaptiste Daroussin }
46*2bc180efSBaptiste Daroussin
47*2bc180efSBaptiste Daroussin /* With the event result table on the top of the stack, insert
48*2bc180efSBaptiste Daroussin a mark entry. */
49*2bc180efSBaptiste Daroussin static void
parser_set_mark(lua_State * L,const char * k,yaml_mark_t mark)50*2bc180efSBaptiste Daroussin parser_set_mark (lua_State *L, const char *k, yaml_mark_t mark)
51*2bc180efSBaptiste Daroussin {
52*2bc180efSBaptiste Daroussin lua_pushstring (L, k);
53*2bc180efSBaptiste Daroussin lua_createtable (L, 0, 3);
54*2bc180efSBaptiste Daroussin #define MENTRY(_s) RAWSET_INTEGER(#_s, mark._s)
55*2bc180efSBaptiste Daroussin MENTRY( index );
56*2bc180efSBaptiste Daroussin MENTRY( line );
57*2bc180efSBaptiste Daroussin MENTRY( column );
58*2bc180efSBaptiste Daroussin #undef MENTRY
59*2bc180efSBaptiste Daroussin lua_rawset (L, -3);
60*2bc180efSBaptiste Daroussin }
61*2bc180efSBaptiste Daroussin
62*2bc180efSBaptiste Daroussin /* Push a new event table, pre-populated with shared elements. */
63*2bc180efSBaptiste Daroussin static void
parser_push_eventtable(lyaml_parser * parser,const char * v,int n)64*2bc180efSBaptiste Daroussin parser_push_eventtable (lyaml_parser *parser, const char *v, int n)
65*2bc180efSBaptiste Daroussin {
66*2bc180efSBaptiste Daroussin lua_State *L = parser->L;
67*2bc180efSBaptiste Daroussin
68*2bc180efSBaptiste Daroussin lua_createtable (L, 0, n + 3);
69*2bc180efSBaptiste Daroussin RAWSET_STRING ("type", v);
70*2bc180efSBaptiste Daroussin #define MENTRY(_s) parser_set_mark (L, #_s, parser->event._s)
71*2bc180efSBaptiste Daroussin MENTRY( start_mark );
72*2bc180efSBaptiste Daroussin MENTRY( end_mark );
73*2bc180efSBaptiste Daroussin #undef MENTRY
74*2bc180efSBaptiste Daroussin }
75*2bc180efSBaptiste Daroussin
76*2bc180efSBaptiste Daroussin static void
parse_STREAM_START(lyaml_parser * parser)77*2bc180efSBaptiste Daroussin parse_STREAM_START (lyaml_parser *parser)
78*2bc180efSBaptiste Daroussin {
79*2bc180efSBaptiste Daroussin #define EVENTF(_f) (parser->event.data.stream_start._f)
80*2bc180efSBaptiste Daroussin lua_State *L = parser->L;
81*2bc180efSBaptiste Daroussin const char *encoding;
82*2bc180efSBaptiste Daroussin
83*2bc180efSBaptiste Daroussin switch (EVENTF (encoding))
84*2bc180efSBaptiste Daroussin {
85*2bc180efSBaptiste Daroussin #define MENTRY(_s) \
86*2bc180efSBaptiste Daroussin case YAML_##_s##_ENCODING: encoding = #_s; break
87*2bc180efSBaptiste Daroussin
88*2bc180efSBaptiste Daroussin MENTRY( ANY );
89*2bc180efSBaptiste Daroussin MENTRY( UTF8 );
90*2bc180efSBaptiste Daroussin MENTRY( UTF16LE );
91*2bc180efSBaptiste Daroussin MENTRY( UTF16BE );
92*2bc180efSBaptiste Daroussin #undef MENTRY
93*2bc180efSBaptiste Daroussin
94*2bc180efSBaptiste Daroussin default:
95*2bc180efSBaptiste Daroussin lua_pushfstring (L, "invalid encoding %d", EVENTF (encoding));
96*2bc180efSBaptiste Daroussin lua_error (L);
97*2bc180efSBaptiste Daroussin }
98*2bc180efSBaptiste Daroussin
99*2bc180efSBaptiste Daroussin parser_push_eventtable (parser, "STREAM_START", 1);
100*2bc180efSBaptiste Daroussin RAWSET_STRING ("encoding", encoding);
101*2bc180efSBaptiste Daroussin #undef EVENTF
102*2bc180efSBaptiste Daroussin }
103*2bc180efSBaptiste Daroussin
104*2bc180efSBaptiste Daroussin /* With the tag list on the top of the stack, append TAG. */
105*2bc180efSBaptiste Daroussin static void
parser_append_tag(lua_State * L,yaml_tag_directive_t tag)106*2bc180efSBaptiste Daroussin parser_append_tag (lua_State *L, yaml_tag_directive_t tag)
107*2bc180efSBaptiste Daroussin {
108*2bc180efSBaptiste Daroussin lua_createtable (L, 0, 2);
109*2bc180efSBaptiste Daroussin #define MENTRY(_s) RAWSET_STRING(#_s, tag._s)
110*2bc180efSBaptiste Daroussin MENTRY( handle );
111*2bc180efSBaptiste Daroussin MENTRY( prefix );
112*2bc180efSBaptiste Daroussin #undef MENTRY
113*2bc180efSBaptiste Daroussin lua_rawseti (L, -2, lua_objlen (L, -2) + 1);
114*2bc180efSBaptiste Daroussin }
115*2bc180efSBaptiste Daroussin
116*2bc180efSBaptiste Daroussin static void
parse_DOCUMENT_START(lyaml_parser * parser)117*2bc180efSBaptiste Daroussin parse_DOCUMENT_START (lyaml_parser *parser)
118*2bc180efSBaptiste Daroussin {
119*2bc180efSBaptiste Daroussin #define EVENTF(_f) (parser->event.data.document_start._f)
120*2bc180efSBaptiste Daroussin lua_State *L = parser->L;
121*2bc180efSBaptiste Daroussin
122*2bc180efSBaptiste Daroussin /* increment document count */
123*2bc180efSBaptiste Daroussin parser->document_count++;
124*2bc180efSBaptiste Daroussin
125*2bc180efSBaptiste Daroussin parser_push_eventtable (parser, "DOCUMENT_START", 1);
126*2bc180efSBaptiste Daroussin RAWSET_BOOLEAN ("implicit", EVENTF (implicit));
127*2bc180efSBaptiste Daroussin
128*2bc180efSBaptiste Daroussin /* version_directive = { major = M, minor = N } */
129*2bc180efSBaptiste Daroussin if (EVENTF (version_directive))
130*2bc180efSBaptiste Daroussin {
131*2bc180efSBaptiste Daroussin lua_pushliteral (L, "version_directive");
132*2bc180efSBaptiste Daroussin lua_createtable (L, 0, 2);
133*2bc180efSBaptiste Daroussin #define MENTRY(_s) RAWSET_INTEGER(#_s, EVENTF (version_directive->_s))
134*2bc180efSBaptiste Daroussin MENTRY( major );
135*2bc180efSBaptiste Daroussin MENTRY( minor );
136*2bc180efSBaptiste Daroussin #undef MENTRY
137*2bc180efSBaptiste Daroussin lua_rawset (L, -3);
138*2bc180efSBaptiste Daroussin }
139*2bc180efSBaptiste Daroussin
140*2bc180efSBaptiste Daroussin /* tag_directives = { {handle = H1, prefix = P1}, ... } */
141*2bc180efSBaptiste Daroussin if (EVENTF (tag_directives.start) &&
142*2bc180efSBaptiste Daroussin EVENTF (tag_directives.end)) {
143*2bc180efSBaptiste Daroussin yaml_tag_directive_t *cur;
144*2bc180efSBaptiste Daroussin
145*2bc180efSBaptiste Daroussin lua_pushliteral (L, "tag_directives");
146*2bc180efSBaptiste Daroussin lua_newtable (L);
147*2bc180efSBaptiste Daroussin for (cur = EVENTF (tag_directives.start);
148*2bc180efSBaptiste Daroussin cur != EVENTF (tag_directives.end);
149*2bc180efSBaptiste Daroussin cur = cur + 1)
150*2bc180efSBaptiste Daroussin {
151*2bc180efSBaptiste Daroussin parser_append_tag (L, *cur);
152*2bc180efSBaptiste Daroussin }
153*2bc180efSBaptiste Daroussin lua_rawset (L, -3);
154*2bc180efSBaptiste Daroussin }
155*2bc180efSBaptiste Daroussin #undef EVENTF
156*2bc180efSBaptiste Daroussin }
157*2bc180efSBaptiste Daroussin
158*2bc180efSBaptiste Daroussin static void
parse_DOCUMENT_END(lyaml_parser * parser)159*2bc180efSBaptiste Daroussin parse_DOCUMENT_END (lyaml_parser *parser)
160*2bc180efSBaptiste Daroussin {
161*2bc180efSBaptiste Daroussin #define EVENTF(_f) (parser->event.data.document_end._f)
162*2bc180efSBaptiste Daroussin lua_State *L = parser->L;
163*2bc180efSBaptiste Daroussin
164*2bc180efSBaptiste Daroussin parser_push_eventtable (parser, "DOCUMENT_END", 1);
165*2bc180efSBaptiste Daroussin RAWSET_BOOLEAN ("implicit", EVENTF (implicit));
166*2bc180efSBaptiste Daroussin #undef EVENTF
167*2bc180efSBaptiste Daroussin }
168*2bc180efSBaptiste Daroussin
169*2bc180efSBaptiste Daroussin static void
parse_ALIAS(lyaml_parser * parser)170*2bc180efSBaptiste Daroussin parse_ALIAS (lyaml_parser *parser)
171*2bc180efSBaptiste Daroussin {
172*2bc180efSBaptiste Daroussin #define EVENTF(_f) (parser->event.data.alias._f)
173*2bc180efSBaptiste Daroussin lua_State *L = parser->L;
174*2bc180efSBaptiste Daroussin
175*2bc180efSBaptiste Daroussin parser_push_eventtable (parser, "ALIAS", 1);
176*2bc180efSBaptiste Daroussin RAWSET_EVENTF (anchor);
177*2bc180efSBaptiste Daroussin #undef EVENTF
178*2bc180efSBaptiste Daroussin }
179*2bc180efSBaptiste Daroussin
180*2bc180efSBaptiste Daroussin static void
parse_SCALAR(lyaml_parser * parser)181*2bc180efSBaptiste Daroussin parse_SCALAR (lyaml_parser *parser)
182*2bc180efSBaptiste Daroussin {
183*2bc180efSBaptiste Daroussin #define EVENTF(_f) (parser->event.data.scalar._f)
184*2bc180efSBaptiste Daroussin lua_State *L = parser->L;
185*2bc180efSBaptiste Daroussin const char *style;
186*2bc180efSBaptiste Daroussin
187*2bc180efSBaptiste Daroussin switch (EVENTF (style))
188*2bc180efSBaptiste Daroussin {
189*2bc180efSBaptiste Daroussin #define MENTRY(_s) \
190*2bc180efSBaptiste Daroussin case YAML_##_s##_SCALAR_STYLE: style = #_s; break
191*2bc180efSBaptiste Daroussin
192*2bc180efSBaptiste Daroussin MENTRY( ANY );
193*2bc180efSBaptiste Daroussin MENTRY( PLAIN );
194*2bc180efSBaptiste Daroussin MENTRY( SINGLE_QUOTED );
195*2bc180efSBaptiste Daroussin MENTRY( DOUBLE_QUOTED );
196*2bc180efSBaptiste Daroussin MENTRY( LITERAL );
197*2bc180efSBaptiste Daroussin MENTRY( FOLDED );
198*2bc180efSBaptiste Daroussin #undef MENTRY
199*2bc180efSBaptiste Daroussin
200*2bc180efSBaptiste Daroussin default:
201*2bc180efSBaptiste Daroussin lua_pushfstring (L, "invalid sequence style %d", EVENTF (style));
202*2bc180efSBaptiste Daroussin lua_error (L);
203*2bc180efSBaptiste Daroussin }
204*2bc180efSBaptiste Daroussin
205*2bc180efSBaptiste Daroussin
206*2bc180efSBaptiste Daroussin parser_push_eventtable (parser, "SCALAR", 6);
207*2bc180efSBaptiste Daroussin RAWSET_EVENTF (anchor);
208*2bc180efSBaptiste Daroussin RAWSET_EVENTF (tag);
209*2bc180efSBaptiste Daroussin RAWSET_EVENTF (value);
210*2bc180efSBaptiste Daroussin
211*2bc180efSBaptiste Daroussin RAWSET_BOOLEAN ("plain_implicit", EVENTF (plain_implicit));
212*2bc180efSBaptiste Daroussin RAWSET_BOOLEAN ("quoted_implicit", EVENTF (quoted_implicit));
213*2bc180efSBaptiste Daroussin RAWSET_STRING ("style", style);
214*2bc180efSBaptiste Daroussin #undef EVENTF
215*2bc180efSBaptiste Daroussin }
216*2bc180efSBaptiste Daroussin
217*2bc180efSBaptiste Daroussin static void
parse_SEQUENCE_START(lyaml_parser * parser)218*2bc180efSBaptiste Daroussin parse_SEQUENCE_START (lyaml_parser *parser)
219*2bc180efSBaptiste Daroussin {
220*2bc180efSBaptiste Daroussin #define EVENTF(_f) (parser->event.data.sequence_start._f)
221*2bc180efSBaptiste Daroussin lua_State *L = parser->L;
222*2bc180efSBaptiste Daroussin const char *style;
223*2bc180efSBaptiste Daroussin
224*2bc180efSBaptiste Daroussin switch (EVENTF (style))
225*2bc180efSBaptiste Daroussin {
226*2bc180efSBaptiste Daroussin #define MENTRY(_s) \
227*2bc180efSBaptiste Daroussin case YAML_##_s##_SEQUENCE_STYLE: style = #_s; break
228*2bc180efSBaptiste Daroussin
229*2bc180efSBaptiste Daroussin MENTRY( ANY );
230*2bc180efSBaptiste Daroussin MENTRY( BLOCK );
231*2bc180efSBaptiste Daroussin MENTRY( FLOW );
232*2bc180efSBaptiste Daroussin #undef MENTRY
233*2bc180efSBaptiste Daroussin
234*2bc180efSBaptiste Daroussin default:
235*2bc180efSBaptiste Daroussin lua_pushfstring (L, "invalid sequence style %d", EVENTF (style));
236*2bc180efSBaptiste Daroussin lua_error (L);
237*2bc180efSBaptiste Daroussin }
238*2bc180efSBaptiste Daroussin
239*2bc180efSBaptiste Daroussin parser_push_eventtable (parser, "SEQUENCE_START", 4);
240*2bc180efSBaptiste Daroussin RAWSET_EVENTF (anchor);
241*2bc180efSBaptiste Daroussin RAWSET_EVENTF (tag);
242*2bc180efSBaptiste Daroussin RAWSET_BOOLEAN ("implicit", EVENTF (implicit));
243*2bc180efSBaptiste Daroussin RAWSET_STRING ("style", style);
244*2bc180efSBaptiste Daroussin #undef EVENTF
245*2bc180efSBaptiste Daroussin }
246*2bc180efSBaptiste Daroussin
247*2bc180efSBaptiste Daroussin static void
parse_MAPPING_START(lyaml_parser * parser)248*2bc180efSBaptiste Daroussin parse_MAPPING_START (lyaml_parser *parser)
249*2bc180efSBaptiste Daroussin {
250*2bc180efSBaptiste Daroussin #define EVENTF(_f) (parser->event.data.mapping_start._f)
251*2bc180efSBaptiste Daroussin lua_State *L = parser->L;
252*2bc180efSBaptiste Daroussin const char *style;
253*2bc180efSBaptiste Daroussin
254*2bc180efSBaptiste Daroussin switch (EVENTF (style))
255*2bc180efSBaptiste Daroussin {
256*2bc180efSBaptiste Daroussin #define MENTRY(_s) \
257*2bc180efSBaptiste Daroussin case YAML_##_s##_MAPPING_STYLE: style = #_s; break
258*2bc180efSBaptiste Daroussin
259*2bc180efSBaptiste Daroussin MENTRY( ANY );
260*2bc180efSBaptiste Daroussin MENTRY( BLOCK );
261*2bc180efSBaptiste Daroussin MENTRY( FLOW );
262*2bc180efSBaptiste Daroussin #undef MENTRY
263*2bc180efSBaptiste Daroussin
264*2bc180efSBaptiste Daroussin default:
265*2bc180efSBaptiste Daroussin lua_pushfstring (L, "invalid mapping style %d", EVENTF (style));
266*2bc180efSBaptiste Daroussin lua_error (L);
267*2bc180efSBaptiste Daroussin }
268*2bc180efSBaptiste Daroussin
269*2bc180efSBaptiste Daroussin parser_push_eventtable (parser, "MAPPING_START", 4);
270*2bc180efSBaptiste Daroussin RAWSET_EVENTF (anchor);
271*2bc180efSBaptiste Daroussin RAWSET_EVENTF (tag);
272*2bc180efSBaptiste Daroussin RAWSET_BOOLEAN ("implicit", EVENTF (implicit));
273*2bc180efSBaptiste Daroussin RAWSET_STRING ("style", style);
274*2bc180efSBaptiste Daroussin #undef EVENTF
275*2bc180efSBaptiste Daroussin }
276*2bc180efSBaptiste Daroussin
277*2bc180efSBaptiste Daroussin static void
parser_generate_error_message(lyaml_parser * parser)278*2bc180efSBaptiste Daroussin parser_generate_error_message (lyaml_parser *parser)
279*2bc180efSBaptiste Daroussin {
280*2bc180efSBaptiste Daroussin yaml_parser_t *P = &parser->parser;
281*2bc180efSBaptiste Daroussin char buf[256];
282*2bc180efSBaptiste Daroussin luaL_Buffer b;
283*2bc180efSBaptiste Daroussin
284*2bc180efSBaptiste Daroussin luaL_buffinit (parser->L, &b);
285*2bc180efSBaptiste Daroussin luaL_addstring (&b, P->problem ? P->problem : "A problem");
286*2bc180efSBaptiste Daroussin snprintf (buf, sizeof (buf), " at document: %d", parser->document_count);
287*2bc180efSBaptiste Daroussin luaL_addstring (&b, buf);
288*2bc180efSBaptiste Daroussin
289*2bc180efSBaptiste Daroussin if (P->problem_mark.line || P->problem_mark.column)
290*2bc180efSBaptiste Daroussin {
291*2bc180efSBaptiste Daroussin snprintf (buf, sizeof (buf), ", line: %lu, column: %lu",
292*2bc180efSBaptiste Daroussin (unsigned long) P->problem_mark.line + 1,
293*2bc180efSBaptiste Daroussin (unsigned long) P->problem_mark.column + 1);
294*2bc180efSBaptiste Daroussin luaL_addstring (&b, buf);
295*2bc180efSBaptiste Daroussin }
296*2bc180efSBaptiste Daroussin luaL_addstring (&b, "\n");
297*2bc180efSBaptiste Daroussin
298*2bc180efSBaptiste Daroussin if (P->context)
299*2bc180efSBaptiste Daroussin {
300*2bc180efSBaptiste Daroussin snprintf (buf, sizeof (buf), "%s at line: %lu, column: %lu\n",
301*2bc180efSBaptiste Daroussin P->context,
302*2bc180efSBaptiste Daroussin (unsigned long) P->context_mark.line + 1,
303*2bc180efSBaptiste Daroussin (unsigned long) P->context_mark.column + 1);
304*2bc180efSBaptiste Daroussin luaL_addstring (&b, buf);
305*2bc180efSBaptiste Daroussin }
306*2bc180efSBaptiste Daroussin
307*2bc180efSBaptiste Daroussin luaL_pushresult (&b);
308*2bc180efSBaptiste Daroussin }
309*2bc180efSBaptiste Daroussin
310*2bc180efSBaptiste Daroussin static int
event_iter(lua_State * L)311*2bc180efSBaptiste Daroussin event_iter (lua_State *L)
312*2bc180efSBaptiste Daroussin {
313*2bc180efSBaptiste Daroussin lyaml_parser *parser = (lyaml_parser *)lua_touserdata(L, lua_upvalueindex(1));
314*2bc180efSBaptiste Daroussin char *str;
315*2bc180efSBaptiste Daroussin
316*2bc180efSBaptiste Daroussin parser_delete_event (parser);
317*2bc180efSBaptiste Daroussin if (yaml_parser_parse (&parser->parser, &parser->event) != 1)
318*2bc180efSBaptiste Daroussin {
319*2bc180efSBaptiste Daroussin parser_generate_error_message (parser);
320*2bc180efSBaptiste Daroussin return lua_error (L);
321*2bc180efSBaptiste Daroussin }
322*2bc180efSBaptiste Daroussin
323*2bc180efSBaptiste Daroussin parser->validevent = 1;
324*2bc180efSBaptiste Daroussin
325*2bc180efSBaptiste Daroussin lua_newtable (L);
326*2bc180efSBaptiste Daroussin lua_pushliteral (L, "type");
327*2bc180efSBaptiste Daroussin
328*2bc180efSBaptiste Daroussin switch (parser->event.type)
329*2bc180efSBaptiste Daroussin {
330*2bc180efSBaptiste Daroussin /* First the simple events, generated right here... */
331*2bc180efSBaptiste Daroussin #define MENTRY(_s) \
332*2bc180efSBaptiste Daroussin case YAML_##_s##_EVENT: parser_push_eventtable (parser, #_s, 0); break
333*2bc180efSBaptiste Daroussin MENTRY( STREAM_END );
334*2bc180efSBaptiste Daroussin MENTRY( SEQUENCE_END );
335*2bc180efSBaptiste Daroussin MENTRY( MAPPING_END );
336*2bc180efSBaptiste Daroussin #undef MENTRY
337*2bc180efSBaptiste Daroussin
338*2bc180efSBaptiste Daroussin /* ...then the complex events, generated by a function call. */
339*2bc180efSBaptiste Daroussin #define MENTRY(_s) \
340*2bc180efSBaptiste Daroussin case YAML_##_s##_EVENT: parse_##_s (parser); break
341*2bc180efSBaptiste Daroussin MENTRY( STREAM_START );
342*2bc180efSBaptiste Daroussin MENTRY( DOCUMENT_START );
343*2bc180efSBaptiste Daroussin MENTRY( DOCUMENT_END );
344*2bc180efSBaptiste Daroussin MENTRY( ALIAS );
345*2bc180efSBaptiste Daroussin MENTRY( SCALAR );
346*2bc180efSBaptiste Daroussin MENTRY( SEQUENCE_START );
347*2bc180efSBaptiste Daroussin MENTRY( MAPPING_START );
348*2bc180efSBaptiste Daroussin #undef MENTRY
349*2bc180efSBaptiste Daroussin
350*2bc180efSBaptiste Daroussin case YAML_NO_EVENT:
351*2bc180efSBaptiste Daroussin lua_pushnil (L);
352*2bc180efSBaptiste Daroussin break;
353*2bc180efSBaptiste Daroussin default:
354*2bc180efSBaptiste Daroussin lua_pushfstring (L, "invalid event %d", parser->event.type);
355*2bc180efSBaptiste Daroussin return lua_error (L);
356*2bc180efSBaptiste Daroussin }
357*2bc180efSBaptiste Daroussin
358*2bc180efSBaptiste Daroussin return 1;
359*2bc180efSBaptiste Daroussin }
360*2bc180efSBaptiste Daroussin
361*2bc180efSBaptiste Daroussin static int
parser_gc(lua_State * L)362*2bc180efSBaptiste Daroussin parser_gc (lua_State *L)
363*2bc180efSBaptiste Daroussin {
364*2bc180efSBaptiste Daroussin lyaml_parser *parser = (lyaml_parser *) lua_touserdata (L, 1);
365*2bc180efSBaptiste Daroussin
366*2bc180efSBaptiste Daroussin if (parser)
367*2bc180efSBaptiste Daroussin {
368*2bc180efSBaptiste Daroussin parser_delete_event (parser);
369*2bc180efSBaptiste Daroussin yaml_parser_delete (&parser->parser);
370*2bc180efSBaptiste Daroussin }
371*2bc180efSBaptiste Daroussin return 0;
372*2bc180efSBaptiste Daroussin }
373*2bc180efSBaptiste Daroussin
374*2bc180efSBaptiste Daroussin void
parser_init(lua_State * L)375*2bc180efSBaptiste Daroussin parser_init (lua_State *L)
376*2bc180efSBaptiste Daroussin {
377*2bc180efSBaptiste Daroussin luaL_newmetatable(L, "lyaml.parser");
378*2bc180efSBaptiste Daroussin lua_pushcfunction(L, parser_gc);
379*2bc180efSBaptiste Daroussin lua_setfield(L, -2, "__gc");
380*2bc180efSBaptiste Daroussin }
381*2bc180efSBaptiste Daroussin
382*2bc180efSBaptiste Daroussin int
Pparser(lua_State * L)383*2bc180efSBaptiste Daroussin Pparser (lua_State *L)
384*2bc180efSBaptiste Daroussin {
385*2bc180efSBaptiste Daroussin lyaml_parser *parser;
386*2bc180efSBaptiste Daroussin const unsigned char *str;
387*2bc180efSBaptiste Daroussin
388*2bc180efSBaptiste Daroussin /* requires a single string type argument */
389*2bc180efSBaptiste Daroussin luaL_argcheck (L, lua_isstring (L, 1), 1, "must provide a string argument");
390*2bc180efSBaptiste Daroussin str = (const unsigned char *) lua_tostring (L, 1);
391*2bc180efSBaptiste Daroussin
392*2bc180efSBaptiste Daroussin /* create a user datum to store the parser */
393*2bc180efSBaptiste Daroussin parser = (lyaml_parser *) lua_newuserdata (L, sizeof (*parser));
394*2bc180efSBaptiste Daroussin memset ((void *) parser, 0, sizeof (*parser));
395*2bc180efSBaptiste Daroussin parser->L = L;
396*2bc180efSBaptiste Daroussin
397*2bc180efSBaptiste Daroussin /* set its metatable */
398*2bc180efSBaptiste Daroussin luaL_getmetatable (L, "lyaml.parser");
399*2bc180efSBaptiste Daroussin lua_setmetatable (L, -2);
400*2bc180efSBaptiste Daroussin
401*2bc180efSBaptiste Daroussin /* try to initialize the parser */
402*2bc180efSBaptiste Daroussin if (yaml_parser_initialize (&parser->parser) == 0)
403*2bc180efSBaptiste Daroussin luaL_error (L, "cannot initialize parser for %s", str);
404*2bc180efSBaptiste Daroussin yaml_parser_set_input_string (&parser->parser, str, lua_strlen (L, 1));
405*2bc180efSBaptiste Daroussin
406*2bc180efSBaptiste Daroussin /* create and return the iterator function, with the loader userdatum as
407*2bc180efSBaptiste Daroussin its sole upvalue */
408*2bc180efSBaptiste Daroussin lua_pushcclosure (L, event_iter, 1);
409*2bc180efSBaptiste Daroussin return 1;
410*2bc180efSBaptiste Daroussin }
411