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 |
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); |