浏览代码

new auxiliary functions to implement new package system

Roberto Ierusalimschy 21 年之前
父节点
当前提交
6acfb91c8d
共有 3 个文件被更改,包括 95 次插入5 次删除
  1. 46 3
      lauxlib.c
  2. 7 1
      lauxlib.h
  3. 42 1
      ltests.c

+ 46 - 3
lauxlib.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lauxlib.c,v 1.123 2004/08/30 18:35:14 roberto Exp roberto $
+** $Id: lauxlib.c,v 1.124 2004/09/03 13:17:14 roberto Exp roberto $
 ** Auxiliary functions for building Lua libraries
 ** See Copyright Notice in lua.h
 */
@@ -352,8 +352,8 @@ static const char *pushnexttemplate (lua_State *L, const char *path) {
 }
 
 
-static const char *luaL_gsub (lua_State *L, const char *s,
-                              const char *p, const char *r) {
+LUALIB_API const char *luaL_gsub (lua_State *L, const char *s, const char *p,
+                                                               const char *r) {
   const char *wild;
   int l = strlen(p);
   luaL_Buffer b;
@@ -391,6 +391,49 @@ LUALIB_API const char *luaL_searchpath (lua_State *L, const char *name,
 }
 
 
+LUALIB_API const char *luaL_getfield (lua_State *L, const char *fname) {
+  const char *e;
+  while ((e = strchr(fname, '.')) != NULL) {
+    lua_pushlstring(L, fname, e - fname);
+    lua_gettable(L, -2);
+    lua_remove(L, -2);  /* remove previous table */
+    fname = e + 1;
+    if (!lua_istable(L, -1)) return fname;
+  }
+  lua_getfield(L, -1, fname);  /* get last field */
+  lua_remove(L, -2);  /* remove previous table */
+  return NULL;
+}
+
+
+LUALIB_API const char *luaL_setfield (lua_State *L, const char *fname) {
+  const char *e;
+  lua_insert(L, -2);  /* move value to below table */
+  while ((e = strchr(fname, '.')) != NULL) {
+    lua_pushlstring(L, fname, e - fname);
+    lua_gettable(L, -2);
+    if (lua_isnil(L, -1)) {  /* no such field? */
+      lua_pop(L, 1);  /* remove this nil */
+      lua_newtable(L);  /* create a new table for field */
+      lua_pushlstring(L, fname, e - fname);
+      lua_pushvalue(L, -2);
+      lua_settable(L, -4);  /* set new table into field */
+    }
+    lua_remove(L, -2);  /* remove previous table */
+    fname = e + 1;
+    if (!lua_istable(L, -1)) {
+      lua_pop(L, 2);  /* remove table and value */
+      return fname;
+    }
+  }
+  lua_insert(L, -2);  /* move table to below value */
+  lua_setfield(L, -2, fname);  /* set last field */
+  lua_remove(L, -2);  /* remove table */
+  return NULL;
+}
+
+
+
 /*
 ** {======================================================
 ** Generic Buffer manipulation

+ 7 - 1
lauxlib.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lauxlib.h,v 1.69 2004/06/30 12:58:44 roberto Exp roberto $
+** $Id: lauxlib.h,v 1.70 2004/07/09 18:23:17 roberto Exp roberto $
 ** Auxiliary functions for building Lua libraries
 ** See Copyright Notice in lua.h
 */
@@ -70,6 +70,12 @@ LUALIB_API int luaL_loadbuffer (lua_State *L, const char *buff, size_t sz,
 LUALIB_API lua_State *(luaL_newstate) (void);
 
 
+LUALIB_API const char *luaL_gsub (lua_State *L, const char *s, const char *p,
+                                     const char *r);
+LUALIB_API const char *luaL_getfield (lua_State *L, const char *fname);
+LUALIB_API const char *luaL_setfield (lua_State *L, const char *fname);
+
+
 
 /*
 ** ===============================================================

+ 42 - 1
ltests.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ltests.c,v 2.10 2004/07/09 18:23:17 roberto Exp roberto $
+** $Id: ltests.c,v 2.11 2004/08/24 20:12:06 roberto Exp roberto $
 ** Internal Module for Debugging of the Lua Implementation
 ** See Copyright Notice in lua.h
 */
@@ -1029,6 +1029,44 @@ static int coresume (lua_State *L) {
 
 
 
+/*
+** {======================================================
+** tests auxlib functions
+** =======================================================
+*/
+
+static int auxgsub (lua_State *L) {
+  const char *s1 = luaL_checkstring(L, 1);
+  const char *s2 = luaL_checkstring(L, 2);
+  const char *s3 = luaL_checkstring(L, 3);
+  lua_settop(L, 3);
+  luaL_gsub(L, s1, s2, s3);
+  lua_assert(lua_gettop(L) == 4);
+  return 1;
+}
+
+
+static int auxgetf (lua_State *L) {
+  const char *s = luaL_checkstring(L, 1);
+  lua_settop(L, 2);
+  lua_pushstring(L, luaL_getfield(L, s));
+  lua_assert(lua_gettop(L) == 3);
+  return 2;
+}
+
+
+static int auxsetf (lua_State *L) {
+  const char *s = luaL_checkstring(L, 1);
+  lua_settop(L, 3);
+  lua_pushstring(L, luaL_setfield(L, s));
+  lua_assert(lua_gettop(L) == 2);
+  return 1;
+}
+
+/* }====================================================== */
+
+
+
 static const struct luaL_reg tests_funcs[] = {
   {"hash", hash_query},
   {"limits", get_limits},
@@ -1063,6 +1101,9 @@ static const struct luaL_reg tests_funcs[] = {
   {"totalmem", mem_query},
   {"resume", coresume},
   {"setyhook", setyhook},
+  {"gsub", auxgsub},
+  {"getfield", auxgetf},
+  {"setfield", auxsetf},
   {NULL, NULL}
 };