aboutsummaryrefslogtreecommitdiff
path: root/ltests.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2009-12-01 14:49:48 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2009-12-01 14:49:48 -0200
commitdf1dc3f1f54a75174cea7298d5c40bc7b99e60ea (patch)
tree934555beb62ec4f4c00ec0fe6ba55eb6c7c2a3cb /ltests.c
parent513d0258d9d6ec5b52efc612ebc52aa5161c23fa (diff)
downloadlua-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.c92
1 files changed, 76 insertions, 16 deletions
diff --git a/ltests.c b/ltests.c
index 196c86c3..8410e08e 100644
--- a/ltests.c
+++ b/ltests.c
@@ -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
814static void sethookaux (lua_State *L, int mask, int count, const char *code);
815
813static const char *const delimits = " \t\n,;"; 816static const char *const delimits = " \t\n,;";
814 817
815static void skip (const char **pc) { 818static 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
845static const char *getname_aux (char *buff, const char **pc) { 848static 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);
874static int Cfunck (lua_State *L); 887static int Cfunck (lua_State *L);
875 888
876static int runC (lua_State *L, lua_State *L1, const char *pc) { 889static 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)
1110static struct X { int x; } x; 1133static 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
1170static 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*/
1196static 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*/
1213static 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
1175static int setyhook (lua_State *L) { 1231
1232static 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},