src/lxplib.c

changeset 26
a8caec6c5429
parent 19
10c30b63873a
child 31
ebb63b55bcc1
equal deleted inserted replaced
25:8c3a5b827e48 26:a8caec6c5429
15 #include "lauxlib.h" 15 #include "lauxlib.h"
16 16
17 17
18 #include "lxplib.h" 18 #include "lxplib.h"
19 19
20 #if (LUA_VERSION_NUM == 501)
21 #define lua_getuservalue(L, i) lua_getfenv(L, i)
22 #define lua_setuservalue(L, i) lua_setfenv(L, i)
23 #endif
20 24
21 #if !defined(lua_pushliteral) 25 #if !defined(lua_pushliteral)
22 #define lua_pushliteral(L, s) \ 26 #define lua_pushliteral(L, s) \
23 lua_pushstring(L, "" s, (sizeof(s)/sizeof(char))-1) 27 lua_pushstring(L, "" s, (sizeof(s)/sizeof(char))-1)
24 #endif 28 #endif
33 }; 37 };
34 38
35 struct lxp_userdata { 39 struct lxp_userdata {
36 lua_State *L; 40 lua_State *L;
37 XML_Parser parser; /* associated expat parser */ 41 XML_Parser parser; /* associated expat parser */
38 int tableref; /* table with callbacks for this parser */ 42 int errorref; /* reference to error message if state is XPSerror */
39 enum XPState state; 43 enum XPState state;
40 luaL_Buffer *b; /* to concatenate sequences of cdata pieces */ 44 luaL_Buffer *b; /* to concatenate sequences of cdata pieces */
41 int bufferCharData; /* whether to buffer cdata pieces */ 45 int bufferCharData; /* whether to buffer cdata pieces */
42 }; 46 };
43 47
56 } 60 }
57 61
58 62
59 static lxp_userdata *createlxp (lua_State *L) { 63 static lxp_userdata *createlxp (lua_State *L) {
60 lxp_userdata *xpu = (lxp_userdata *)lua_newuserdata(L, sizeof(lxp_userdata)); 64 lxp_userdata *xpu = (lxp_userdata *)lua_newuserdata(L, sizeof(lxp_userdata));
61 xpu->tableref = LUA_REFNIL; /* in case of errors... */ 65 xpu->errorref = LUA_REFNIL;
62 xpu->parser = NULL; 66 xpu->parser = NULL;
63 xpu->L = NULL; 67 xpu->L = NULL;
64 xpu->state = XPSpre; 68 xpu->state = XPSpre;
65 luaL_getmetatable(L, ParserType); 69 luaL_getmetatable(L, ParserType);
66 lua_setmetatable(L, -2); 70 lua_setmetatable(L, -2);
67 return xpu; 71 return xpu;
68 } 72 }
69 73
70 74
71 static void lxpclose (lua_State *L, lxp_userdata *xpu) { 75 static void lxpclose (lua_State *L, lxp_userdata *xpu) {
72 luaL_unref(L, LUA_REGISTRYINDEX, xpu->tableref); 76 luaL_unref(L, LUA_REGISTRYINDEX, xpu->errorref);
73 xpu->tableref = LUA_REFNIL; 77 xpu->errorref = LUA_REFNIL;
74 if (xpu->parser) 78 if (xpu->parser)
75 XML_ParserFree(xpu->parser); 79 XML_ParserFree(xpu->parser);
76 xpu->parser = NULL; 80 xpu->parser = NULL;
77 } 81 }
78 82
85 static void docall (lxp_userdata *xpu, int nargs, int nres) { 89 static void docall (lxp_userdata *xpu, int nargs, int nres) {
86 lua_State *L = xpu->L; 90 lua_State *L = xpu->L;
87 assert(xpu->state == XPSok); 91 assert(xpu->state == XPSok);
88 if (lua_pcall(L, nargs + 1, nres, 0) != 0) { 92 if (lua_pcall(L, nargs + 1, nres, 0) != 0) {
89 xpu->state = XPSerror; 93 xpu->state = XPSerror;
90 luaL_unref(L, LUA_REGISTRYINDEX, xpu->tableref); 94 xpu->errorref = luaL_ref(L, LUA_REGISTRYINDEX); /* error message */
91 xpu->tableref = luaL_ref(L, LUA_REGISTRYINDEX); /* error message */
92 } 95 }
93 } 96 }
94 97
95 98
96 /* 99 /*
231 if (getHandle(xpu, ExternalEntityKey) == 0) return 1; /* no handle */ 234 if (getHandle(xpu, ExternalEntityKey) == 0) return 1; /* no handle */
232 child = createlxp(L); 235 child = createlxp(L);
233 child->parser = XML_ExternalEntityParserCreate(p, context, NULL); 236 child->parser = XML_ExternalEntityParserCreate(p, context, NULL);
234 if (!child->parser) 237 if (!child->parser)
235 luaL_error(L, "XML_ParserCreate failed"); 238 luaL_error(L, "XML_ParserCreate failed");
236 lua_rawgeti(L, LUA_REGISTRYINDEX, xpu->tableref); /*lua_getref(L, xpu->tableref); */ /* child uses the same table of its father */ 239 lua_getuservalue(L, 1);
237 child->tableref = luaL_ref(L, LUA_REGISTRYINDEX); 240 lua_setuservalue(L, -2); /* child uses the same table of its father */
238 lua_pushstring(L, base); 241 lua_pushstring(L, base);
239 lua_pushstring(L, systemId); 242 lua_pushstring(L, systemId);
240 lua_pushstring(L, publicId); 243 lua_pushstring(L, publicId);
241 docall(xpu, 4, 1); 244 docall(xpu, 4, 1);
242 status = lua_toboolean(L, -1); 245 status = lua_toboolean(L, -1);
389 if (!p) 392 if (!p)
390 luaL_error(L, "XML_ParserCreate failed"); 393 luaL_error(L, "XML_ParserCreate failed");
391 luaL_checktype(L, 1, LUA_TTABLE); 394 luaL_checktype(L, 1, LUA_TTABLE);
392 checkcallbacks(L); 395 checkcallbacks(L);
393 lua_pushvalue(L, 1); 396 lua_pushvalue(L, 1);
394 xpu->tableref = luaL_ref(L, LUA_REGISTRYINDEX); 397 lua_setuservalue(L, -2);
395 XML_SetUserData(p, xpu); 398 XML_SetUserData(p, xpu);
396 if (hasfield(L, StartCdataKey) || hasfield(L, EndCdataKey)) 399 if (hasfield(L, StartCdataKey) || hasfield(L, EndCdataKey))
397 XML_SetCdataSectionHandler(p, f_StartCdata, f_EndCdataKey); 400 XML_SetCdataSectionHandler(p, f_StartCdata, f_EndCdataKey);
398 if (hasfield(L, CharDataKey)) 401 if (hasfield(L, CharDataKey))
399 XML_SetCharacterDataHandler(p, f_CharData); 402 XML_SetCharacterDataHandler(p, f_CharData);
455 return 1; 458 return 1;
456 } 459 }
457 460
458 461
459 static int getcallbacks (lua_State *L) { 462 static int getcallbacks (lua_State *L) {
460 lxp_userdata *xpu = checkparser(L, 1); 463 checkparser(L, 1);
461 lua_rawgeti(L, LUA_REGISTRYINDEX, xpu->tableref); 464 lua_getuservalue(L, 1);
462 return 1; 465 return 1;
463 } 466 }
464 467
465 468
466 static int parse_aux (lua_State *L, lxp_userdata *xpu, const char *s, 469 static int parse_aux (lua_State *L, lxp_userdata *xpu, const char *s,
469 int status; 472 int status;
470 xpu->L = L; 473 xpu->L = L;
471 xpu->state = XPSok; 474 xpu->state = XPSok;
472 xpu->b = &b; 475 xpu->b = &b;
473 lua_settop(L, 2); 476 lua_settop(L, 2);
474 lua_rawgeti(L, LUA_REGISTRYINDEX, xpu->tableref); /*lua_getref(L, xpu->tableref);*/ /* to be used by handlers */ 477 getcallbacks(L);
475 status = XML_Parse(xpu->parser, s, (int)len, s == NULL); 478 status = XML_Parse(xpu->parser, s, (int)len, s == NULL);
476 if (xpu->state == XPSstring) dischargestring(xpu); 479 if (xpu->state == XPSstring) dischargestring(xpu);
477 if (xpu->state == XPSerror) { /* callback error? */ 480 if (xpu->state == XPSerror) { /* callback error? */
478 lua_rawgeti(L, LUA_REGISTRYINDEX, xpu->tableref); /* get original msg. */ 481 lua_rawgeti(L, LUA_REGISTRYINDEX, xpu->errorref); /* get original msg. */
479 lua_error(L); 482 lua_error(L);
480 } 483 }
481 if (s == NULL) xpu->state = XPSfinished; 484 if (s == NULL) xpu->state = XPSfinished;
482 if (status) { 485 if (status) {
483 lua_pushboolean(L, 1); 486 lua_pushboolean(L, 1);

mercurial