diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2009-12-01 14:49:48 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2009-12-01 14:49:48 -0200 |
commit | df1dc3f1f54a75174cea7298d5c40bc7b99e60ea (patch) | |
tree | 934555beb62ec4f4c00ec0fe6ba55eb6c7c2a3cb /ltests.c | |
parent | 513d0258d9d6ec5b52efc612ebc52aa5161c23fa (diff) | |
download | lua-df1dc3f1f54a75174cea7298d5c40bc7b99e60ea.tar.gz lua-df1dc3f1f54a75174cea7298d5c40bc7b99e60ea.tar.bz2 lua-df1dc3f1f54a75174cea7298d5c40bc7b99e60ea.zip |
strings in C scripts may be delimited by quotes + new functionality to
set C scripts as C hooks
Diffstat (limited to 'ltests.c')
-rw-r--r-- | ltests.c | 92 |
1 files changed, 76 insertions, 16 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ltests.c,v 2.79 2009/11/06 17:08:43 roberto Exp roberto $ | 2 | ** $Id: ltests.c,v 2.80 2009/11/27 15:39:31 roberto Exp roberto $ |
3 | ** Internal Module for Debugging of the Lua Implementation | 3 | ** Internal Module for Debugging of the Lua Implementation |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -810,6 +810,9 @@ static int int2fb_aux (lua_State *L) { | |||
810 | ** ======================================================= | 810 | ** ======================================================= |
811 | */ | 811 | */ |
812 | 812 | ||
813 | |||
814 | static void sethookaux (lua_State *L, int mask, int count, const char *code); | ||
815 | |||
813 | static const char *const delimits = " \t\n,;"; | 816 | static const char *const delimits = " \t\n,;"; |
814 | 817 | ||
815 | static void skip (const char **pc) { | 818 | static void skip (const char **pc) { |
@@ -842,11 +845,21 @@ static int getnum_aux (lua_State *L, const char **pc) { | |||
842 | return sig*res; | 845 | return sig*res; |
843 | } | 846 | } |
844 | 847 | ||
845 | static const char *getname_aux (char *buff, const char **pc) { | 848 | static const char *getname_aux (lua_State *L, char *buff, const char **pc) { |
846 | int i = 0; | 849 | int i = 0; |
847 | skip(pc); | 850 | skip(pc); |
848 | while (**pc != '\0' && !strchr(delimits, **pc)) | 851 | if (**pc == '"' || **pc == '\'') { /* quoted string? */ |
849 | buff[i++] = *(*pc)++; | 852 | int quote = *(*pc)++; |
853 | while (**pc != quote) { | ||
854 | if (**pc == '\0') luaL_error(L, "unfinished string in C script"); | ||
855 | buff[i++] = *(*pc)++; | ||
856 | } | ||
857 | (*pc)++; | ||
858 | } | ||
859 | else { | ||
860 | while (**pc != '\0' && !strchr(delimits, **pc)) | ||
861 | buff[i++] = *(*pc)++; | ||
862 | } | ||
850 | buff[i] = '\0'; | 863 | buff[i] = '\0'; |
851 | return buff; | 864 | return buff; |
852 | } | 865 | } |
@@ -866,7 +879,7 @@ static int getindex_aux (lua_State *L, const char **pc) { | |||
866 | #define EQ(s1) (strcmp(s1, inst) == 0) | 879 | #define EQ(s1) (strcmp(s1, inst) == 0) |
867 | 880 | ||
868 | #define getnum (getnum_aux(L, &pc)) | 881 | #define getnum (getnum_aux(L, &pc)) |
869 | #define getname (getname_aux(buff, &pc)) | 882 | #define getname (getname_aux(L, buff, &pc)) |
870 | #define getindex (getindex_aux(L, &pc)) | 883 | #define getindex (getindex_aux(L, &pc)) |
871 | 884 | ||
872 | 885 | ||
@@ -874,8 +887,8 @@ static int testC (lua_State *L); | |||
874 | static int Cfunck (lua_State *L); | 887 | static int Cfunck (lua_State *L); |
875 | 888 | ||
876 | static int runC (lua_State *L, lua_State *L1, const char *pc) { | 889 | static int runC (lua_State *L, lua_State *L1, const char *pc) { |
877 | char buff[30]; | 890 | char buff[300]; |
878 | if (pc == NULL) return luaL_error(L, "attempt to runC null code"); | 891 | if (pc == NULL) return luaL_error(L, "attempt to runC null script"); |
879 | for (;;) { | 892 | for (;;) { |
880 | const char *inst = getname; | 893 | const char *inst = getname; |
881 | if EQ("") return 0; | 894 | if EQ("") return 0; |
@@ -1079,6 +1092,11 @@ static int runC (lua_State *L, lua_State *L1, const char *pc) { | |||
1079 | int i = getindex; | 1092 | int i = getindex; |
1080 | lua_pushinteger(L1, lua_objlen(L1, i)); | 1093 | lua_pushinteger(L1, lua_objlen(L1, i)); |
1081 | } | 1094 | } |
1095 | else if EQ("append") { | ||
1096 | int t = getindex; | ||
1097 | int i = lua_objlen(L1, t); | ||
1098 | lua_rawseti(L1, t, i + 1); | ||
1099 | } | ||
1082 | else if EQ("getctx") { | 1100 | else if EQ("getctx") { |
1083 | static const char *const codes[] = {"OK", "YIELD", "ERRRUN", | 1101 | static const char *const codes[] = {"OK", "YIELD", "ERRRUN", |
1084 | "ERRSYNTAX", "ERRMEM", "ERRGCMM", "ERRERR"}; | 1102 | "ERRSYNTAX", "ERRMEM", "ERRGCMM", "ERRERR"}; |
@@ -1105,6 +1123,11 @@ static int runC (lua_State *L, lua_State *L1, const char *pc) { | |||
1105 | lua_tostring(L, b), | 1123 | lua_tostring(L, b), |
1106 | lua_tostring(L, c)); | 1124 | lua_tostring(L, c)); |
1107 | } | 1125 | } |
1126 | else if EQ("sethook") { | ||
1127 | int mask = getnum; | ||
1128 | int count = getnum; | ||
1129 | sethookaux(L1, mask, count, getname); | ||
1130 | } | ||
1108 | else if EQ("throw") { | 1131 | else if EQ("throw") { |
1109 | #if defined(__cplusplus) | 1132 | #if defined(__cplusplus) |
1110 | static struct X { int x; } x; | 1133 | static struct X { int x; } x; |
@@ -1163,25 +1186,62 @@ static int makeCfunc (lua_State *L) { | |||
1163 | 1186 | ||
1164 | /* | 1187 | /* |
1165 | ** {====================================================== | 1188 | ** {====================================================== |
1166 | ** tests for yield inside hooks | 1189 | ** tests for C hooks |
1167 | ** ======================================================= | 1190 | ** ======================================================= |
1168 | */ | 1191 | */ |
1169 | 1192 | ||
1170 | static void yieldf (lua_State *L, lua_Debug *ar) { | 1193 | /* |
1171 | UNUSED(ar); | 1194 | ** C hook that runs the C script stored in registry.C_HOOK[L] |
1172 | lua_yield(L, 0); | 1195 | */ |
1196 | static void Chook (lua_State *L, lua_Debug *ar) { | ||
1197 | const char *scpt; | ||
1198 | const char *const events [] = {"call", "ret", "line", "count", "tailcall"}; | ||
1199 | lua_getfield(L, LUA_REGISTRYINDEX, "C_HOOK"); | ||
1200 | lua_pushlightuserdata(L, L); | ||
1201 | lua_gettable(L, -2); /* get C_HOOK[L] (script saved by sethookaux) */ | ||
1202 | scpt = lua_tostring(L, -1); /* not very religious (string will be popped) */ | ||
1203 | lua_pop(L, 2); /* remove C_HOOK and script */ | ||
1204 | lua_pushstring(L, events[ar->event]); /* may be used by script */ | ||
1205 | lua_pushinteger(L, ar->currentline); /* may be used by script */ | ||
1206 | runC(L, L, scpt); /* run script from C_HOOK[L] */ | ||
1207 | } | ||
1208 | |||
1209 | |||
1210 | /* | ||
1211 | ** sets registry.C_HOOK[L] = scpt and sets Chook as a hook | ||
1212 | */ | ||
1213 | static void sethookaux (lua_State *L, int mask, int count, const char *scpt) { | ||
1214 | if (*scpt == '\0') { /* no script? */ | ||
1215 | lua_sethook(L, NULL, 0, 0); /* turn off hooks */ | ||
1216 | return; | ||
1217 | } | ||
1218 | lua_getfield(L, LUA_REGISTRYINDEX, "C_HOOK"); /* get C_HOOK table */ | ||
1219 | if (!lua_istable(L, -1)) { /* no hook table? */ | ||
1220 | lua_pop(L, 1); /* remove previous value */ | ||
1221 | lua_newtable(L); /* create new C_HOOK table */ | ||
1222 | lua_pushvalue(L, -1); | ||
1223 | lua_setfield(L, LUA_REGISTRYINDEX, "C_HOOK"); /* register it */ | ||
1224 | } | ||
1225 | lua_pushlightuserdata(L, L); | ||
1226 | lua_pushstring(L, scpt); | ||
1227 | lua_settable(L, -3); /* C_HOOK[L] = script */ | ||
1228 | lua_sethook(L, Chook, mask, count); | ||
1173 | } | 1229 | } |
1174 | 1230 | ||
1175 | static int setyhook (lua_State *L) { | 1231 | |
1232 | static int sethook (lua_State *L) { | ||
1176 | if (lua_isnoneornil(L, 1)) | 1233 | if (lua_isnoneornil(L, 1)) |
1177 | lua_sethook(L, NULL, 0, 0); /* turn off hooks */ | 1234 | lua_sethook(L, NULL, 0, 0); /* turn off hooks */ |
1178 | else { | 1235 | else { |
1179 | const char *smask = luaL_checkstring(L, 1); | 1236 | const char *scpt = luaL_checkstring(L, 1); |
1180 | int count = luaL_optint(L, 2, 0); | 1237 | const char *smask = luaL_checkstring(L, 2); |
1238 | int count = luaL_optint(L, 3, 0); | ||
1181 | int mask = 0; | 1239 | int mask = 0; |
1240 | if (strchr(smask, 'c')) mask |= LUA_MASKCALL; | ||
1241 | if (strchr(smask, 'r')) mask |= LUA_MASKRET; | ||
1182 | if (strchr(smask, 'l')) mask |= LUA_MASKLINE; | 1242 | if (strchr(smask, 'l')) mask |= LUA_MASKLINE; |
1183 | if (count > 0) mask |= LUA_MASKCOUNT; | 1243 | if (count > 0) mask |= LUA_MASKCOUNT; |
1184 | lua_sethook(L, yieldf, mask, count); | 1244 | sethookaux(L, mask, count, scpt); |
1185 | } | 1245 | } |
1186 | return 0; | 1246 | return 0; |
1187 | } | 1247 | } |
@@ -1232,7 +1292,7 @@ static const struct luaL_Reg tests_funcs[] = { | |||
1232 | {"ref", tref}, | 1292 | {"ref", tref}, |
1233 | {"resume", coresume}, | 1293 | {"resume", coresume}, |
1234 | {"s2d", s2d}, | 1294 | {"s2d", s2d}, |
1235 | {"setyhook", setyhook}, | 1295 | {"sethook", sethook}, |
1236 | {"stacklevel", stacklevel}, | 1296 | {"stacklevel", stacklevel}, |
1237 | {"testC", testC}, | 1297 | {"testC", testC}, |
1238 | {"makeCfunc", makeCfunc}, | 1298 | {"makeCfunc", makeCfunc}, |