1*2bc180efSBaptiste Daroussin /*
2*2bc180efSBaptiste Daroussin * scanner.c, libyaml scanner 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
29*2bc180efSBaptiste Daroussin typedef struct {
30*2bc180efSBaptiste Daroussin lua_State *L;
31*2bc180efSBaptiste Daroussin yaml_parser_t parser;
32*2bc180efSBaptiste Daroussin yaml_token_t token;
33*2bc180efSBaptiste Daroussin char validtoken;
34*2bc180efSBaptiste Daroussin int document_count;
35*2bc180efSBaptiste Daroussin } lyaml_scanner;
36*2bc180efSBaptiste Daroussin
37*2bc180efSBaptiste Daroussin
38*2bc180efSBaptiste Daroussin static void
scanner_delete_token(lyaml_scanner * scanner)39*2bc180efSBaptiste Daroussin scanner_delete_token (lyaml_scanner *scanner)
40*2bc180efSBaptiste Daroussin {
41*2bc180efSBaptiste Daroussin if (scanner->validtoken)
42*2bc180efSBaptiste Daroussin {
43*2bc180efSBaptiste Daroussin yaml_token_delete (&scanner->token);
44*2bc180efSBaptiste Daroussin scanner->validtoken = 0;
45*2bc180efSBaptiste Daroussin }
46*2bc180efSBaptiste Daroussin }
47*2bc180efSBaptiste Daroussin
48*2bc180efSBaptiste Daroussin /* With the token result table on the top of the stack, insert
49*2bc180efSBaptiste Daroussin a mark entry. */
50*2bc180efSBaptiste Daroussin static void
scanner_set_mark(lua_State * L,const char * k,yaml_mark_t mark)51*2bc180efSBaptiste Daroussin scanner_set_mark (lua_State *L, const char *k, yaml_mark_t mark)
52*2bc180efSBaptiste Daroussin {
53*2bc180efSBaptiste Daroussin lua_pushstring (L, k);
54*2bc180efSBaptiste Daroussin lua_createtable (L, 0, 3);
55*2bc180efSBaptiste Daroussin #define MENTRY(_s) RAWSET_INTEGER (#_s, mark._s)
56*2bc180efSBaptiste Daroussin MENTRY( index );
57*2bc180efSBaptiste Daroussin MENTRY( line );
58*2bc180efSBaptiste Daroussin MENTRY( column );
59*2bc180efSBaptiste Daroussin #undef MENTRY
60*2bc180efSBaptiste Daroussin lua_rawset (L, -3);
61*2bc180efSBaptiste Daroussin }
62*2bc180efSBaptiste Daroussin
63*2bc180efSBaptiste Daroussin /* Push a new token table, pre-populated with shared elements. */
64*2bc180efSBaptiste Daroussin static void
scanner_push_tokentable(lyaml_scanner * scanner,const char * v,int n)65*2bc180efSBaptiste Daroussin scanner_push_tokentable (lyaml_scanner *scanner, const char *v, int n)
66*2bc180efSBaptiste Daroussin {
67*2bc180efSBaptiste Daroussin lua_State *L = scanner->L;
68*2bc180efSBaptiste Daroussin
69*2bc180efSBaptiste Daroussin lua_createtable (L, 0, n + 3);
70*2bc180efSBaptiste Daroussin RAWSET_STRING ("type", v);
71*2bc180efSBaptiste Daroussin
72*2bc180efSBaptiste Daroussin #define MENTRY(_s) scanner_set_mark (L, #_s, scanner->token._s)
73*2bc180efSBaptiste Daroussin MENTRY( start_mark );
74*2bc180efSBaptiste Daroussin MENTRY( end_mark );
75*2bc180efSBaptiste Daroussin #undef MENTRY
76*2bc180efSBaptiste Daroussin }
77*2bc180efSBaptiste Daroussin
78*2bc180efSBaptiste Daroussin static void
scan_STREAM_START(lyaml_scanner * scanner)79*2bc180efSBaptiste Daroussin scan_STREAM_START (lyaml_scanner *scanner)
80*2bc180efSBaptiste Daroussin {
81*2bc180efSBaptiste Daroussin #define EVENTF(_f) (scanner->token.data.stream_start._f)
82*2bc180efSBaptiste Daroussin lua_State *L = scanner->L;
83*2bc180efSBaptiste Daroussin const char *encoding;
84*2bc180efSBaptiste Daroussin
85*2bc180efSBaptiste Daroussin switch (EVENTF (encoding))
86*2bc180efSBaptiste Daroussin {
87*2bc180efSBaptiste Daroussin #define MENTRY(_s) \
88*2bc180efSBaptiste Daroussin case YAML_##_s##_ENCODING: encoding = #_s; break
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 scanner_push_tokentable (scanner, "STREAM_START", 1);
100*2bc180efSBaptiste Daroussin RAWSET_STRING ("encoding", encoding);
101*2bc180efSBaptiste Daroussin #undef EVENTF
102*2bc180efSBaptiste Daroussin }
103*2bc180efSBaptiste Daroussin
104*2bc180efSBaptiste Daroussin static void
scan_VERSION_DIRECTIVE(lyaml_scanner * scanner)105*2bc180efSBaptiste Daroussin scan_VERSION_DIRECTIVE (lyaml_scanner *scanner)
106*2bc180efSBaptiste Daroussin {
107*2bc180efSBaptiste Daroussin #define EVENTF(_f) (scanner->token.data.version_directive._f)
108*2bc180efSBaptiste Daroussin lua_State *L = scanner->L;
109*2bc180efSBaptiste Daroussin
110*2bc180efSBaptiste Daroussin scanner_push_tokentable (scanner, "VERSION_DIRECTIVE", 2);
111*2bc180efSBaptiste Daroussin
112*2bc180efSBaptiste Daroussin #define MENTRY(_s) RAWSET_INTEGER (#_s, EVENTF (_s))
113*2bc180efSBaptiste Daroussin MENTRY( major );
114*2bc180efSBaptiste Daroussin MENTRY( minor );
115*2bc180efSBaptiste Daroussin #undef MENTRY
116*2bc180efSBaptiste Daroussin #undef EVENTF
117*2bc180efSBaptiste Daroussin }
118*2bc180efSBaptiste Daroussin
119*2bc180efSBaptiste Daroussin static void
scan_TAG_DIRECTIVE(lyaml_scanner * scanner)120*2bc180efSBaptiste Daroussin scan_TAG_DIRECTIVE (lyaml_scanner *scanner)
121*2bc180efSBaptiste Daroussin {
122*2bc180efSBaptiste Daroussin #define EVENTF(_f) (scanner->token.data.tag_directive._f)
123*2bc180efSBaptiste Daroussin lua_State *L = scanner->L;
124*2bc180efSBaptiste Daroussin
125*2bc180efSBaptiste Daroussin scanner_push_tokentable (scanner, "TAG_DIRECTIVE", 2);
126*2bc180efSBaptiste Daroussin RAWSET_EVENTF( handle );
127*2bc180efSBaptiste Daroussin RAWSET_EVENTF( prefix );
128*2bc180efSBaptiste Daroussin #undef EVENTF
129*2bc180efSBaptiste Daroussin }
130*2bc180efSBaptiste Daroussin
131*2bc180efSBaptiste Daroussin static void
scan_ALIAS(lyaml_scanner * scanner)132*2bc180efSBaptiste Daroussin scan_ALIAS (lyaml_scanner *scanner)
133*2bc180efSBaptiste Daroussin {
134*2bc180efSBaptiste Daroussin #define EVENTF(_f) (scanner->token.data.alias._f)
135*2bc180efSBaptiste Daroussin lua_State *L = scanner->L;
136*2bc180efSBaptiste Daroussin
137*2bc180efSBaptiste Daroussin scanner_push_tokentable (scanner, "ALIAS", 1);
138*2bc180efSBaptiste Daroussin RAWSET_EVENTF (value);
139*2bc180efSBaptiste Daroussin #undef EVENTF
140*2bc180efSBaptiste Daroussin }
141*2bc180efSBaptiste Daroussin
142*2bc180efSBaptiste Daroussin static void
scan_ANCHOR(lyaml_scanner * scanner)143*2bc180efSBaptiste Daroussin scan_ANCHOR (lyaml_scanner *scanner)
144*2bc180efSBaptiste Daroussin {
145*2bc180efSBaptiste Daroussin #define EVENTF(_f) (scanner->token.data.anchor._f)
146*2bc180efSBaptiste Daroussin lua_State *L = scanner->L;
147*2bc180efSBaptiste Daroussin
148*2bc180efSBaptiste Daroussin scanner_push_tokentable (scanner, "ANCHOR", 1);
149*2bc180efSBaptiste Daroussin RAWSET_EVENTF (value);
150*2bc180efSBaptiste Daroussin #undef EVENTF
151*2bc180efSBaptiste Daroussin }
152*2bc180efSBaptiste Daroussin
153*2bc180efSBaptiste Daroussin static void
scan_TAG(lyaml_scanner * scanner)154*2bc180efSBaptiste Daroussin scan_TAG(lyaml_scanner *scanner)
155*2bc180efSBaptiste Daroussin {
156*2bc180efSBaptiste Daroussin #define EVENTF(_f) (scanner->token.data.tag._f)
157*2bc180efSBaptiste Daroussin lua_State *L = scanner->L;
158*2bc180efSBaptiste Daroussin
159*2bc180efSBaptiste Daroussin scanner_push_tokentable (scanner, "TAG", 2);
160*2bc180efSBaptiste Daroussin RAWSET_EVENTF( handle );
161*2bc180efSBaptiste Daroussin RAWSET_EVENTF( suffix );
162*2bc180efSBaptiste Daroussin #undef EVENTF
163*2bc180efSBaptiste Daroussin }
164*2bc180efSBaptiste Daroussin
165*2bc180efSBaptiste Daroussin static void
scan_SCALAR(lyaml_scanner * scanner)166*2bc180efSBaptiste Daroussin scan_SCALAR (lyaml_scanner *scanner)
167*2bc180efSBaptiste Daroussin {
168*2bc180efSBaptiste Daroussin #define EVENTF(_f) (scanner->token.data.scalar._f)
169*2bc180efSBaptiste Daroussin lua_State *L = scanner->L;
170*2bc180efSBaptiste Daroussin const char *style;
171*2bc180efSBaptiste Daroussin
172*2bc180efSBaptiste Daroussin switch (EVENTF (style))
173*2bc180efSBaptiste Daroussin {
174*2bc180efSBaptiste Daroussin #define MENTRY(_s) \
175*2bc180efSBaptiste Daroussin case YAML_##_s##_SCALAR_STYLE: style = #_s; break
176*2bc180efSBaptiste Daroussin
177*2bc180efSBaptiste Daroussin MENTRY( PLAIN );
178*2bc180efSBaptiste Daroussin MENTRY( SINGLE_QUOTED );
179*2bc180efSBaptiste Daroussin MENTRY( DOUBLE_QUOTED );
180*2bc180efSBaptiste Daroussin MENTRY( LITERAL );
181*2bc180efSBaptiste Daroussin MENTRY( FOLDED );
182*2bc180efSBaptiste Daroussin #undef MENTRY
183*2bc180efSBaptiste Daroussin
184*2bc180efSBaptiste Daroussin default:
185*2bc180efSBaptiste Daroussin lua_pushfstring (L, "invalid scalar style %d", EVENTF (style));
186*2bc180efSBaptiste Daroussin lua_error (L);
187*2bc180efSBaptiste Daroussin }
188*2bc180efSBaptiste Daroussin
189*2bc180efSBaptiste Daroussin scanner_push_tokentable (scanner, "SCALAR", 3);
190*2bc180efSBaptiste Daroussin RAWSET_EVENTF (value);
191*2bc180efSBaptiste Daroussin RAWSET_INTEGER ("length", EVENTF (length));
192*2bc180efSBaptiste Daroussin RAWSET_STRING ("style", style);
193*2bc180efSBaptiste Daroussin #undef EVENTF
194*2bc180efSBaptiste Daroussin }
195*2bc180efSBaptiste Daroussin
196*2bc180efSBaptiste Daroussin static void
scanner_generate_error_message(lyaml_scanner * scanner)197*2bc180efSBaptiste Daroussin scanner_generate_error_message (lyaml_scanner *scanner)
198*2bc180efSBaptiste Daroussin {
199*2bc180efSBaptiste Daroussin yaml_parser_t *P = &scanner->parser;
200*2bc180efSBaptiste Daroussin char buf[256];
201*2bc180efSBaptiste Daroussin luaL_Buffer b;
202*2bc180efSBaptiste Daroussin
203*2bc180efSBaptiste Daroussin luaL_buffinit (scanner->L, &b);
204*2bc180efSBaptiste Daroussin luaL_addstring (&b, P->problem ? P->problem : "A problem");
205*2bc180efSBaptiste Daroussin snprintf (buf, sizeof (buf), " at document: %d", scanner->document_count);
206*2bc180efSBaptiste Daroussin luaL_addstring (&b, buf);
207*2bc180efSBaptiste Daroussin
208*2bc180efSBaptiste Daroussin if (P->problem_mark.line || P->problem_mark.column)
209*2bc180efSBaptiste Daroussin {
210*2bc180efSBaptiste Daroussin snprintf (buf, sizeof (buf), ", line: %lu, column: %lu",
211*2bc180efSBaptiste Daroussin (unsigned long) P->problem_mark.line + 1,
212*2bc180efSBaptiste Daroussin (unsigned long) P->problem_mark.column + 1);
213*2bc180efSBaptiste Daroussin luaL_addstring (&b, buf);
214*2bc180efSBaptiste Daroussin }
215*2bc180efSBaptiste Daroussin luaL_addstring (&b, "\n");
216*2bc180efSBaptiste Daroussin
217*2bc180efSBaptiste Daroussin if (P->context)
218*2bc180efSBaptiste Daroussin {
219*2bc180efSBaptiste Daroussin snprintf (buf, sizeof (buf), "%s at line: %lu, column: %lu\n",
220*2bc180efSBaptiste Daroussin P->context,
221*2bc180efSBaptiste Daroussin (unsigned long) P->context_mark.line + 1,
222*2bc180efSBaptiste Daroussin (unsigned long) P->context_mark.column + 1);
223*2bc180efSBaptiste Daroussin luaL_addstring (&b, buf);
224*2bc180efSBaptiste Daroussin }
225*2bc180efSBaptiste Daroussin
226*2bc180efSBaptiste Daroussin luaL_pushresult (&b);
227*2bc180efSBaptiste Daroussin }
228*2bc180efSBaptiste Daroussin
229*2bc180efSBaptiste Daroussin static int
token_iter(lua_State * L)230*2bc180efSBaptiste Daroussin token_iter (lua_State *L)
231*2bc180efSBaptiste Daroussin {
232*2bc180efSBaptiste Daroussin lyaml_scanner *scanner = (lyaml_scanner *)lua_touserdata(L, lua_upvalueindex(1));
233*2bc180efSBaptiste Daroussin char *str;
234*2bc180efSBaptiste Daroussin
235*2bc180efSBaptiste Daroussin scanner_delete_token (scanner);
236*2bc180efSBaptiste Daroussin if (yaml_parser_scan (&scanner->parser, &scanner->token) != 1)
237*2bc180efSBaptiste Daroussin {
238*2bc180efSBaptiste Daroussin scanner_generate_error_message (scanner);
239*2bc180efSBaptiste Daroussin return lua_error (L);
240*2bc180efSBaptiste Daroussin }
241*2bc180efSBaptiste Daroussin
242*2bc180efSBaptiste Daroussin scanner->validtoken = 1;
243*2bc180efSBaptiste Daroussin
244*2bc180efSBaptiste Daroussin lua_newtable (L);
245*2bc180efSBaptiste Daroussin lua_pushliteral (L, "type");
246*2bc180efSBaptiste Daroussin
247*2bc180efSBaptiste Daroussin switch (scanner->token.type)
248*2bc180efSBaptiste Daroussin {
249*2bc180efSBaptiste Daroussin /* First the simple tokens, generated right here... */
250*2bc180efSBaptiste Daroussin #define MENTRY(_s) \
251*2bc180efSBaptiste Daroussin case YAML_##_s##_TOKEN: scanner_push_tokentable (scanner, #_s, 0); break
252*2bc180efSBaptiste Daroussin MENTRY( STREAM_END );
253*2bc180efSBaptiste Daroussin MENTRY( DOCUMENT_START );
254*2bc180efSBaptiste Daroussin MENTRY( DOCUMENT_END );
255*2bc180efSBaptiste Daroussin MENTRY( BLOCK_SEQUENCE_START );
256*2bc180efSBaptiste Daroussin MENTRY( BLOCK_MAPPING_START );
257*2bc180efSBaptiste Daroussin MENTRY( BLOCK_END );
258*2bc180efSBaptiste Daroussin MENTRY( FLOW_SEQUENCE_START );
259*2bc180efSBaptiste Daroussin MENTRY( FLOW_SEQUENCE_END );
260*2bc180efSBaptiste Daroussin MENTRY( FLOW_MAPPING_START );
261*2bc180efSBaptiste Daroussin MENTRY( FLOW_MAPPING_END );
262*2bc180efSBaptiste Daroussin MENTRY( BLOCK_ENTRY );
263*2bc180efSBaptiste Daroussin MENTRY( FLOW_ENTRY );
264*2bc180efSBaptiste Daroussin MENTRY( KEY );
265*2bc180efSBaptiste Daroussin MENTRY( VALUE );
266*2bc180efSBaptiste Daroussin #undef MENTRY
267*2bc180efSBaptiste Daroussin
268*2bc180efSBaptiste Daroussin /* ...then the complex tokens, generated by a function call. */
269*2bc180efSBaptiste Daroussin #define MENTRY(_s) \
270*2bc180efSBaptiste Daroussin case YAML_##_s##_TOKEN: scan_##_s (scanner); break
271*2bc180efSBaptiste Daroussin MENTRY( STREAM_START );
272*2bc180efSBaptiste Daroussin MENTRY( VERSION_DIRECTIVE );
273*2bc180efSBaptiste Daroussin MENTRY( TAG_DIRECTIVE );
274*2bc180efSBaptiste Daroussin MENTRY( ALIAS );
275*2bc180efSBaptiste Daroussin MENTRY( ANCHOR );
276*2bc180efSBaptiste Daroussin MENTRY( TAG );
277*2bc180efSBaptiste Daroussin MENTRY( SCALAR );
278*2bc180efSBaptiste Daroussin #undef MENTRY
279*2bc180efSBaptiste Daroussin
280*2bc180efSBaptiste Daroussin case YAML_NO_TOKEN:
281*2bc180efSBaptiste Daroussin lua_pushnil (L);
282*2bc180efSBaptiste Daroussin break;
283*2bc180efSBaptiste Daroussin default:
284*2bc180efSBaptiste Daroussin lua_pushfstring (L, "invalid token %d", scanner->token.type);
285*2bc180efSBaptiste Daroussin return lua_error (L);
286*2bc180efSBaptiste Daroussin }
287*2bc180efSBaptiste Daroussin
288*2bc180efSBaptiste Daroussin return 1;
289*2bc180efSBaptiste Daroussin }
290*2bc180efSBaptiste Daroussin
291*2bc180efSBaptiste Daroussin static int
scanner_gc(lua_State * L)292*2bc180efSBaptiste Daroussin scanner_gc (lua_State *L)
293*2bc180efSBaptiste Daroussin {
294*2bc180efSBaptiste Daroussin lyaml_scanner *scanner = (lyaml_scanner *) lua_touserdata (L, 1);
295*2bc180efSBaptiste Daroussin
296*2bc180efSBaptiste Daroussin if (scanner)
297*2bc180efSBaptiste Daroussin {
298*2bc180efSBaptiste Daroussin scanner_delete_token (scanner);
299*2bc180efSBaptiste Daroussin yaml_parser_delete (&scanner->parser);
300*2bc180efSBaptiste Daroussin }
301*2bc180efSBaptiste Daroussin return 0;
302*2bc180efSBaptiste Daroussin }
303*2bc180efSBaptiste Daroussin
304*2bc180efSBaptiste Daroussin void
scanner_init(lua_State * L)305*2bc180efSBaptiste Daroussin scanner_init (lua_State *L)
306*2bc180efSBaptiste Daroussin {
307*2bc180efSBaptiste Daroussin luaL_newmetatable (L, "lyaml.scanner");
308*2bc180efSBaptiste Daroussin lua_pushcfunction (L, scanner_gc);
309*2bc180efSBaptiste Daroussin lua_setfield (L, -2, "__gc");
310*2bc180efSBaptiste Daroussin }
311*2bc180efSBaptiste Daroussin
312*2bc180efSBaptiste Daroussin int
Pscanner(lua_State * L)313*2bc180efSBaptiste Daroussin Pscanner (lua_State *L)
314*2bc180efSBaptiste Daroussin {
315*2bc180efSBaptiste Daroussin lyaml_scanner *scanner;
316*2bc180efSBaptiste Daroussin const unsigned char *str;
317*2bc180efSBaptiste Daroussin
318*2bc180efSBaptiste Daroussin /* requires a single string type argument */
319*2bc180efSBaptiste Daroussin luaL_argcheck (L, lua_isstring (L, 1), 1, "must provide a string argument");
320*2bc180efSBaptiste Daroussin str = (const unsigned char *) lua_tostring (L, 1);
321*2bc180efSBaptiste Daroussin
322*2bc180efSBaptiste Daroussin /* create a user datum to store the scanner */
323*2bc180efSBaptiste Daroussin scanner = (lyaml_scanner *) lua_newuserdata (L, sizeof (*scanner));
324*2bc180efSBaptiste Daroussin memset ((void *) scanner, 0, sizeof (*scanner));
325*2bc180efSBaptiste Daroussin scanner->L = L;
326*2bc180efSBaptiste Daroussin
327*2bc180efSBaptiste Daroussin /* set its metatable */
328*2bc180efSBaptiste Daroussin luaL_getmetatable (L, "lyaml.scanner");
329*2bc180efSBaptiste Daroussin lua_setmetatable (L, -2);
330*2bc180efSBaptiste Daroussin
331*2bc180efSBaptiste Daroussin /* try to initialize the scanner */
332*2bc180efSBaptiste Daroussin if (yaml_parser_initialize (&scanner->parser) == 0)
333*2bc180efSBaptiste Daroussin luaL_error (L, "cannot initialize parser for %s", str);
334*2bc180efSBaptiste Daroussin yaml_parser_set_input_string (&scanner->parser, str, lua_strlen (L, 1));
335*2bc180efSBaptiste Daroussin
336*2bc180efSBaptiste Daroussin /* create and return the iterator function, with the loader userdatum as
337*2bc180efSBaptiste Daroussin its sole upvalue */
338*2bc180efSBaptiste Daroussin lua_pushcclosure (L, token_iter, 1);
339*2bc180efSBaptiste Daroussin return 1;
340*2bc180efSBaptiste Daroussin }
341