Beispiel #1
1
int WINAPI WinMain(HINSTANCE hInstance,  HINSTANCE hPrevInstance,  LPSTR lpCmdLine, int nCmdShow)
{
  int argc;
  char ** argv = CommandLineToArgvA(GetCommandLineA(),&argc);

#else
int main (int argc, char *argv[])
{
#endif
  HINSTANCE hinstLib;

  char buffer[MAX_PATH],*file;

  if (!GetFullPathName(argv[0],MAX_PATH,buffer,&file)) {
    MessageBox(NULL,
      TEXT("Couldn't find the correct working directory"),
      TEXT("Failed to start editor"),
      MB_OK|MB_ICONERROR);
    return 0;
  }
  if (file!=NULL) *file = 0; // finish the string, don't need the appname

  SetCurrentDirectory(buffer);

  // set the application as DPI aware
  typedef enum _Process_DPI_Awareness {
    Process_DPI_Unaware            = 0,
    Process_System_DPI_Aware       = 1,
    Process_Per_Monitor_DPI_Aware  = 2
  } Process_DPI_Awareness;
  typedef BOOL (WINAPI *SetProcessDPIAwareness_t)(Process_DPI_Awareness);
  SetProcessDPIAwareness_t pfnSetProcessDPIAwareness = (SetProcessDPIAwareness_t)
    GetProcAddress(GetModuleHandle(TEXT("user32.dll")), "SetProcessDPIAware");
  if (NULL != pfnSetProcessDPIAwareness) pfnSetProcessDPIAwareness(Process_System_DPI_Aware);

  hinstLib = LoadLibrary(".\\bin\\lua51.dll");
  if (hinstLib != NULL)
  {
    luaL_newstate = (voidfunc*) GetProcAddress(hinstLib, "luaL_newstate");
    luaL_loadbuffer = (varfunc*) GetProcAddress(hinstLib, "luaL_loadbuffer");
    luaL_openlibs = (varfunc*) GetProcAddress(hinstLib, "luaL_openlibs");
    lua_pcall = (varfunc*)GetProcAddress(hinstLib, "lua_pcall");
    lua_tolstring = (varfunc*)GetProcAddress(hinstLib, "lua_tolstring");
    lua_setfield = (varfunc*)GetProcAddress(hinstLib, "lua_setfield");
    lua_pushcclosure = (varfunc*)GetProcAddress(hinstLib, "lua_pushcclosure");
    lua_createtable = (varfuncvoid*)GetProcAddress(hinstLib, "lua_createtable");
    lua_pushstring = (varfuncvoid*)GetProcAddress(hinstLib, "lua_pushstring");
    lua_rawseti = (varfuncvoid*)GetProcAddress(hinstLib, "lua_rawseti");
    // If the function address is valid, call the function.

    if (luaL_newstate && luaL_loadbuffer && luaL_openlibs && lua_pcall &&
      lua_pushcclosure && lua_setfield && lua_tolstring &&
      lua_createtable && lua_pushstring && lua_rawseti)
    {
      // OK, I don't do any error checking here, which COULD
      // lead to bugs that are hard to find, but considered the simplicity
      // of the whole process, it SHOULD be pretty unlikely to fail here
      // but don't come back on me if it does...
      void *L = luaL_newstate();
      int i;

      if (L!=NULL) {
        lua_createtable(L,argc,0);
        for (i=0;i<argc;i++) {
          lua_pushstring(L,argv[i]);
          lua_rawseti(L,-2,i+1);
        }
        lua_setfield(L,LUA_GLOBALSINDEX,"_ARG");
        luaL_openlibs(L);
        lua_pushcclosure(L,luafunc_mbox,0);
        lua_setfield(L,LUA_GLOBALSINDEX,"_ERRMSG");
        if (luaL_loadbuffer(L,luacode,strlen(luacode),"Initializer") == 0)
          lua_pcall(L,0,0,0);
        else
          MessageBox(NULL,
          TEXT("An unexpected error occured while loading the lua chunk."),
          TEXT("Failed to start editor"),
          MB_OK|MB_ICONERROR);
      } else
        MessageBox(NULL,
        TEXT("Couldn't initialize a luastate"),
        TEXT("Failed to start editor"),
        MB_OK|MB_ICONERROR);
    } else {
      MessageBox(NULL,
        TEXT("Could not load all functions that are supposed to be located in the lua51.dll\n"
        "This is not supposed to be happening..."),
        TEXT("Failed to start editor"),
        MB_OK|MB_ICONERROR);
    }

    // Free the DLL module.
    FreeLibrary(hinstLib);
  } else {
    MessageBox(NULL,
      TEXT("The lua51.dll could not be found or loaded, please check the working directory of the application.\n"),
      TEXT("Failed to initialize editor"),
      MB_OK|MB_ICONERROR);
  }

  return 0;
}
static int
ngx_http_lua_shdict_get_keys(lua_State *L)
{
    ngx_queue_t                 *q, *prev;
    ngx_http_lua_shdict_node_t  *sd;
    ngx_http_lua_shdict_ctx_t   *ctx;
    ngx_shm_zone_t              *zone;
    ngx_time_t                  *tp;
    int                          total = 0;
    int                          attempts = 1024;
    uint64_t                     now;
    int                          n;

    n = lua_gettop(L);

    if (n != 1 && n != 2) {
        return luaL_error(L, "expecting 1 or 2 argument(s), "
                          "but saw %d", n);
    }

    luaL_checktype(L, 1, LUA_TLIGHTUSERDATA);

    zone = lua_touserdata(L, 1);
    if (zone == NULL) {
        return luaL_error(L, "bad user data for the ngx_shm_zone_t pointer");
    }

    if (n == 2) {
        attempts = luaL_checkint(L, 2);
    }

    ctx = zone->data;

    ngx_shmtx_lock(&ctx->shpool->mutex);

    if (ngx_queue_empty(&ctx->sh->queue)) {
        ngx_shmtx_unlock(&ctx->shpool->mutex);
        lua_createtable(L, 0, 0);
        return 1;
    }

    tp = ngx_timeofday();

    now = (uint64_t) tp->sec * 1000 + tp->msec;

    /* first run through: get total number of elements we need to allocate */

    q = ngx_queue_last(&ctx->sh->queue);

    while (q != ngx_queue_sentinel(&ctx->sh->queue)) {
        prev = ngx_queue_prev(q);

        sd = ngx_queue_data(q, ngx_http_lua_shdict_node_t, queue);

        if (sd->expires == 0 || sd->expires > now) {
            total++;
            if (attempts && total == attempts) {
                break;
            }
        }

        q = prev;
    }

    lua_createtable(L, total, 0);

    /* second run through: add keys to table */

    total = 0;
    q = ngx_queue_last(&ctx->sh->queue);

    while (q != ngx_queue_sentinel(&ctx->sh->queue)) {
        prev = ngx_queue_prev(q);

        sd = ngx_queue_data(q, ngx_http_lua_shdict_node_t, queue);

        if (sd->expires == 0 || sd->expires > now) {
            lua_pushlstring(L, (char *) sd->data, sd->key_len);
            lua_rawseti(L, -2, ++total);
            if (attempts && total == attempts) {
                break;
            }
        }

        q = prev;
    }

    ngx_shmtx_unlock(&ctx->shpool->mutex);

    /* table is at top of stack */
    return 1;
}
Beispiel #3
0
//////////////////////////////
//
// Now push all these functions into the Lua state!
//
//
int LUA_InfoLib(lua_State *L)
{
	// index of A_Lua actions to run for each state
	lua_newtable(L);
	lua_setfield(L, LUA_REGISTRYINDEX, LREG_STATEACTION);

	// index of globally available Lua actions by function name
	lua_newtable(L);
	lua_setfield(L, LUA_REGISTRYINDEX, LREG_ACTIONS);

	luaL_newmetatable(L, META_STATE);
		lua_pushcfunction(L, state_get);
		lua_setfield(L, -2, "__index");

		lua_pushcfunction(L, state_set);
		lua_setfield(L, -2, "__newindex");

		lua_pushcfunction(L, state_num);
		lua_setfield(L, -2, "__len");
	lua_pop(L, 1);

	luaL_newmetatable(L, META_MOBJINFO);
		lua_pushcfunction(L, mobjinfo_get);
		lua_setfield(L, -2, "__index");

		lua_pushcfunction(L, mobjinfo_set);
		lua_setfield(L, -2, "__newindex");

		lua_pushcfunction(L, mobjinfo_num);
		lua_setfield(L, -2, "__len");
	lua_pop(L, 1);

	luaL_newmetatable(L, META_SFXINFO);
		lua_pushcfunction(L, sfxinfo_get);
		lua_setfield(L, -2, "__index");

		lua_pushcfunction(L, sfxinfo_set);
		lua_setfield(L, -2, "__newindex");

		lua_pushcfunction(L, sfxinfo_num);
		lua_setfield(L, -2, "__len");
	lua_pop(L, 1);

	lua_newuserdata(L, 0);
		lua_createtable(L, 0, 2);
			lua_pushcfunction(L, lib_getSprname);
			lua_setfield(L, -2, "__index");

			lua_pushcfunction(L, lib_sprnamelen);
			lua_setfield(L, -2, "__len");
		lua_setmetatable(L, -2);
	lua_setglobal(L, "sprnames");

	lua_newuserdata(L, 0);
		lua_createtable(L, 0, 2);
			lua_pushcfunction(L, lib_getState);
			lua_setfield(L, -2, "__index");

			lua_pushcfunction(L, lib_setState);
			lua_setfield(L, -2, "__newindex");

			lua_pushcfunction(L, lib_statelen);
			lua_setfield(L, -2, "__len");
		lua_setmetatable(L, -2);
	lua_setglobal(L, "states");

	lua_newuserdata(L, 0);
		lua_createtable(L, 0, 2);
			lua_pushcfunction(L, lib_getMobjInfo);
			lua_setfield(L, -2, "__index");

			lua_pushcfunction(L, lib_setMobjInfo);
			lua_setfield(L, -2, "__newindex");

			lua_pushcfunction(L, lib_mobjinfolen);
			lua_setfield(L, -2, "__len");
		lua_setmetatable(L, -2);
	lua_setglobal(L, "mobjinfo");

	lua_newuserdata(L, 0);
		lua_createtable(L, 0, 2);
			lua_pushcfunction(L, lib_getSfxInfo);
			lua_setfield(L, -2, "__index");

			lua_pushcfunction(L, lib_setSfxInfo);
			lua_setfield(L, -2, "__newindex");

			lua_pushcfunction(L, lib_sfxlen);
			lua_setfield(L, -2, "__len");
		lua_setmetatable(L, -2);
	lua_pushvalue(L, -1);
	lua_setglobal(L, "S_sfx");
	lua_setglobal(L, "sfxinfo");
	return 0;
}
Beispiel #4
0
int LUA_MapLib(lua_State *L)
{
	luaL_newmetatable(L, META_SECTORLINES);
		lua_pushcfunction(L, sectorlines_get);
		lua_setfield(L, -2, "__index");

		lua_pushcfunction(L, sectorlines_num);
		lua_setfield(L, -2, "__len");
	lua_pop(L, 1);

	luaL_newmetatable(L, META_SECTOR);
		lua_pushcfunction(L, sector_get);
		lua_setfield(L, -2, "__index");

		lua_pushcfunction(L, sector_set);
		lua_setfield(L, -2, "__newindex");

		lua_pushcfunction(L, sector_num);
		lua_setfield(L, -2, "__len");
	lua_pop(L, 1);

	luaL_newmetatable(L, META_SUBSECTOR);
		lua_pushcfunction(L, subsector_get);
		lua_setfield(L, -2, "__index");

		lua_pushcfunction(L, subsector_num);
		lua_setfield(L, -2, "__len");
	lua_pop(L, 1);

	luaL_newmetatable(L, META_LINE);
		lua_pushcfunction(L, line_get);
		lua_setfield(L, -2, "__index");

		lua_pushcfunction(L, line_num);
		lua_setfield(L, -2, "__len");
	lua_pop(L, 1);

	luaL_newmetatable(L, META_SIDENUM);
		lua_pushcfunction(L, sidenum_get);
		lua_setfield(L, -2, "__index");
	lua_pop(L, 1);

	luaL_newmetatable(L, META_SIDE);
		lua_pushcfunction(L, side_get);
		lua_setfield(L, -2, "__index");

		lua_pushcfunction(L, side_set);
		lua_setfield(L, -2, "__newindex");

		lua_pushcfunction(L, side_num);
		lua_setfield(L, -2, "__len");
	lua_pop(L, 1);

	luaL_newmetatable(L, META_VERTEX);
		lua_pushcfunction(L, vertex_get);
		lua_setfield(L, -2, "__index");

		lua_pushcfunction(L, vertex_num);
		lua_setfield(L, -2, "__len");
	lua_pop(L, 1);

	luaL_newmetatable(L, META_FFLOOR);
		lua_pushcfunction(L, ffloor_get);
		lua_setfield(L, -2, "__index");

		lua_pushcfunction(L, ffloor_set);
		lua_setfield(L, -2, "__newindex");
	lua_pop(L, 1);

	luaL_newmetatable(L, META_MAPHEADER);
		lua_pushcfunction(L, mapheaderinfo_get);
		lua_setfield(L, -2, "__index");

		//lua_pushcfunction(L, mapheaderinfo_num);
		//lua_setfield(L, -2, "__len");
	lua_pop(L, 1);

	lua_newuserdata(L, 0);
		lua_createtable(L, 0, 2);
			lua_pushcfunction(L, lib_getSector);
			lua_setfield(L, -2, "__index");

			lua_pushcfunction(L, lib_numsectors);
			lua_setfield(L, -2, "__len");
		lua_setmetatable(L, -2);
	lua_setglobal(L, "sectors");

	lua_newuserdata(L, 0);
		lua_createtable(L, 0, 2);
			lua_pushcfunction(L, lib_getSubsector);
			lua_setfield(L, -2, "__index");

			lua_pushcfunction(L, lib_numsubsectors);
			lua_setfield(L, -2, "__len");
		lua_setmetatable(L, -2);
	lua_setglobal(L, "subsectors");

	lua_newuserdata(L, 0);
		lua_createtable(L, 0, 2);
			lua_pushcfunction(L, lib_getLine);
			lua_setfield(L, -2, "__index");

			lua_pushcfunction(L, lib_numlines);
			lua_setfield(L, -2, "__len");
		lua_setmetatable(L, -2);
	lua_setglobal(L, "lines");

	lua_newuserdata(L, 0);
		lua_createtable(L, 0, 2);
			lua_pushcfunction(L, lib_getSide);
			lua_setfield(L, -2, "__index");

			lua_pushcfunction(L, lib_numsides);
			lua_setfield(L, -2, "__len");
		lua_setmetatable(L, -2);
	lua_setglobal(L, "sides");

	lua_newuserdata(L, 0);
		lua_createtable(L, 0, 2);
			lua_pushcfunction(L, lib_getVertex);
			lua_setfield(L, -2, "__index");

			lua_pushcfunction(L, lib_numvertexes);
			lua_setfield(L, -2, "__len");
		lua_setmetatable(L, -2);
	lua_setglobal(L, "vertexes");

	lua_newuserdata(L, 0);
		lua_createtable(L, 0, 2);
			lua_pushcfunction(L, lib_getMapheaderinfo);
			lua_setfield(L, -2, "__index");

			lua_pushcfunction(L, lib_nummapheaders);
			lua_setfield(L, -2, "__len");
		lua_setmetatable(L, -2);
	lua_setglobal(L, "mapheaderinfo");
	return 0;
}
Beispiel #5
0
static void *
_push_value(lua_State *L, char * ptr, char type) {
	switch(type) {
		case 'u': {
			uint64_t v = *(uint64_t*)ptr;
			ptr += 8;
			lua_pushnumber(L,(lua_Number)v);
			break;
		}
		case 'i': {
			int32_t v = *(int32_t*)ptr;
			ptr += 4;
			lua_pushinteger(L,v);
			break;
		}
		case 'b': {
			int32_t v = *(int32_t*)ptr;
			ptr += 4;
			lua_pushboolean(L,v);
			break;
		}
		case 'p': {
			uint32_t v = *(uint32_t*)ptr;
			ptr += 4;
			lua_pushlightuserdata(L,(void *)(intptr_t)v);
			break;
		}
		case 'x': {
			lua_pushlstring(L,ptr,8);
			ptr += 8;
			break;
		}
		case 'd': {
			int64_t v = *(int64_t*)ptr;
			ptr += 8;
			lua_pushnumber(L,(lua_Number)v);
			break;
		}
		case 'r': {
			double v = *(double *)ptr;
			ptr += 8;
			lua_pushnumber(L,v);
			break;
		}
		case 's': {
			struct pbc_slice * slice = (struct pbc_slice *)ptr;
			lua_pushlstring(L,(const char *)slice->buffer, slice->len);
			ptr += sizeof(struct pbc_slice);
			break;
		}
		case 'm': {
			struct pbc_slice * slice = (struct pbc_slice *)ptr;
			lua_createtable(L,2,0);
			lua_pushlightuserdata(L, slice->buffer);
			lua_rawseti(L,-2,1);
			lua_pushinteger(L,slice->len);
			lua_rawseti(L,-2,2);
			ptr += sizeof(struct pbc_slice);
			break;			
		}
	}
	return ptr;
}
Beispiel #6
0
static void newfenv (lua_State *L, lua_CFunction cls) {
  lua_createtable(L, 0, 1);
  lua_pushcfunction(L, cls);
  lua_setfield(L, -2, "__close");
}
Beispiel #7
0
static int db_getinfo (lua_State *L) {
  lua_Debug ar;
  int arg;
  //add by cuiwei 07.8.30
  int i;
  char aparms[1024] = {0};
  //add end
  lua_State *L1 = getthread(L, &arg);
  const char *options = luaL_optstring(L, arg+2, "flnSu");
  if (lua_isnumber(L, arg+1)) {
    if (!lua_getstack(L1, (int)lua_tointeger(L, arg+1), &ar)) {
      lua_pushnil(L);  /* level out of range */
      return 1;
    }
  }
  else if (lua_isfunction(L, arg+1)) {
    lua_pushfstring(L, ">%s", options);
    options = lua_tostring(L, -1);
    lua_pushvalue(L, arg+1);
    lua_xmove(L, L1, 1);
  }
  else
    return luaL_argerror(L, arg+1, "function or level expected");
  if (!lua_getinfo(L1, options, &ar))
    return luaL_argerror(L, arg+2, "invalid option");
  lua_createtable(L, 0, 2);
  if (strchr(options, 'S')) {
    settabss(L, "source", ar.source);
    settabss(L, "short_src", ar.short_src);
    settabsi(L, "linedefined", ar.linedefined);
    settabsi(L, "lastlinedefined", ar.lastlinedefined);
    settabss(L, "what", ar.what);
  }
  if (strchr(options, 'l'))
    settabsi(L, "currentline", ar.currentline);
  if (strchr(options, 'u'))
  {
    settabsi(L, "nups", ar.nups);
	//add by cuiwei 07.8.30
	if (ar.what != "C" )
	{
		settabsi(L, "npars", ar.npars);
		settabsi(L, "has3dot", ar.has3dot?1:0);
		for ( i = 1; i <= ar.npars; i++ )
		{
			strcat(aparms, ar.parms[i-1]);
			if ( i != ar.npars || ar.has3dot)
			{
				strcat(aparms, ",");
			}
		}
		if ( ar.has3dot )
		{
			strcat(aparms, "...");
		}	settabss(L, "strparms", aparms);
	}
	//add end
  }
  if (strchr(options, 'n')) {
    settabss(L, "name", ar.name);
    settabss(L, "namewhat", ar.namewhat);
  }
  if (strchr(options, 'L'))
    treatstackoption(L, L1, "activelines");
  if (strchr(options, 'f'))
    treatstackoption(L, L1, "func");
  return 1;  /* return table */
}
Beispiel #8
0
	void LuaInstance::PushTable(std::size_t sequenceElementCount, std::size_t arrayElementCount) const
	{
		constexpr std::size_t maxInt = std::numeric_limits<int>::max();
		lua_createtable(m_state, static_cast<int>(std::min(sequenceElementCount, maxInt)), static_cast<int>(std::min(arrayElementCount, maxInt)));
	}
static int
ngx_http_lua_socket_udp_setpeername(lua_State *L)
{
    ngx_http_request_t          *r;
    ngx_http_lua_ctx_t          *ctx;
    ngx_str_t                    host;
    int                          port;
    ngx_resolver_ctx_t          *rctx, temp;
    ngx_http_core_loc_conf_t    *clcf;
    int                          saved_top;
    int                          n;
    u_char                      *p;
    size_t                       len;
    ngx_url_t                    url;
    ngx_int_t                    rc;
    ngx_http_lua_loc_conf_t     *llcf;
    ngx_udp_connection_t        *uc;
    int                          timeout;

    ngx_http_lua_socket_udp_upstream_t      *u;

    n = lua_gettop(L);
    if (n != 2 && n != 3) {
        return luaL_error(L, "ngx.socket.udp setpeername: expecting 2 or 3 "
                          "arguments (including the object), but seen %d", n);
    }

    lua_pushlightuserdata(L, &ngx_http_lua_request_key);
    lua_rawget(L, LUA_GLOBALSINDEX);
    r = lua_touserdata(L, -1);
    lua_pop(L, 1);

    if (r == NULL) {
        return luaL_error(L, "no request found");
    }

    ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module);
    if (ctx == NULL) {
        return luaL_error(L, "no ctx found");
    }

    ngx_http_lua_check_context(L, ctx, NGX_HTTP_LUA_CONTEXT_REWRITE
                               | NGX_HTTP_LUA_CONTEXT_ACCESS
                               | NGX_HTTP_LUA_CONTEXT_CONTENT);

    luaL_checktype(L, 1, LUA_TTABLE);

    p = (u_char *) luaL_checklstring(L, 2, &len);

    host.data = ngx_palloc(r->pool, len + 1);
    if (host.data == NULL) {
        return luaL_error(L, "out of memory");
    }

    host.len = len;

    ngx_memcpy(host.data, p, len);
    host.data[len] = '\0';

    if (n == 3) {
        port = luaL_checkinteger(L, 3);

        if (port < 0 || port > 65536) {
            lua_pushnil(L);
            lua_pushfstring(L, "bad port number: %d", port);
            return 2;
        }

    } else { /* n == 2 */
        port = 0;
    }

    lua_rawgeti(L, 1, SOCKET_CTX_INDEX);
    u = lua_touserdata(L, -1);
    lua_pop(L, 1);

    if (u) {
        if (u->waiting) {
            lua_pushnil(L);
            lua_pushliteral(L, "socket busy");
            return 2;
        }

        if (u->udp_connection.connection) {
            ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                           "lua udp socket reconnect without shutting down");

            ngx_http_lua_socket_udp_finalize(r, u);
        }

        ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                       "lua reuse socket upstream ctx");

    } else {
        u = lua_newuserdata(L, sizeof(ngx_http_lua_socket_udp_upstream_t));
        if (u == NULL) {
            return luaL_error(L, "out of memory");
        }

#if 1
        lua_createtable(L, 0 /* narr */, 1 /* nrec */); /* metatable */
        lua_pushcfunction(L, ngx_http_lua_socket_udp_upstream_destroy);
        lua_setfield(L, -2, "__gc");
        lua_setmetatable(L, -2);
#endif

        lua_rawseti(L, 1, SOCKET_CTX_INDEX);
    }

    ngx_memzero(u, sizeof(ngx_http_lua_socket_udp_upstream_t));

    u->request = r; /* set the controlling request */
    llcf = ngx_http_get_module_loc_conf(r, ngx_http_lua_module);

    u->conf = llcf;

    uc = &u->udp_connection;

    uc->log = *r->connection->log;

    dd("lua peer connection log: %p", &uc->log);

    lua_rawgeti(L, 1, SOCKET_TIMEOUT_INDEX);
    timeout = (ngx_int_t) lua_tointeger(L, -1);
    lua_pop(L, 1);

    if (timeout > 0) {
        u->read_timeout = (ngx_msec_t) timeout;

    } else {
        u->read_timeout = u->conf->read_timeout;
    }

    ngx_memzero(&url, sizeof(ngx_url_t));

    url.url.len = host.len;
    url.url.data = host.data;
    url.default_port = port;
    url.no_resolve = 1;

    if (ngx_parse_url(r->pool, &url) != NGX_OK) {
        lua_pushnil(L);

        if (url.err) {
            lua_pushfstring(L, "failed to parse host name \"%s\": %s",
                            host.data, url.err);

        } else {
            lua_pushfstring(L, "failed to parse host name \"%s\"", host.data);
        }

        return 2;
    }

    u->resolved = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_resolved_t));
    if (u->resolved == NULL) {
        return luaL_error(L, "out of memory");
    }

    if (url.addrs && url.addrs[0].sockaddr) {
        ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                       "lua udp socket network address given directly");

        u->resolved->sockaddr = url.addrs[0].sockaddr;
        u->resolved->socklen = url.addrs[0].socklen;
        u->resolved->naddrs = 1;
        u->resolved->host = url.addrs[0].name;

    } else {
        u->resolved->host = host;
        u->resolved->port = (in_port_t) port;
    }

    if (u->resolved->sockaddr) {
        rc = ngx_http_lua_socket_resolve_retval_handler(r, u, L);
        if (rc == NGX_AGAIN) {
            return lua_yield(L, 0);
        }

        return rc;
    }

    clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

    temp.name = host;
    rctx = ngx_resolve_start(clcf->resolver, &temp);
    if (rctx == NULL) {
        u->ft_type |= NGX_HTTP_LUA_SOCKET_FT_RESOLVER;
        lua_pushnil(L);
        lua_pushliteral(L, "failed to start the resolver");
        return 2;
    }

    if (rctx == NGX_NO_RESOLVER) {
        u->ft_type |= NGX_HTTP_LUA_SOCKET_FT_RESOLVER;
        lua_pushnil(L);
        lua_pushfstring(L, "no resolver defined to resolve \"%s\"", host.data);
        return 2;
    }

    rctx->name = host;
    rctx->type = NGX_RESOLVE_A;
    rctx->handler = ngx_http_lua_socket_resolve_handler;
    rctx->data = u;
    rctx->timeout = clcf->resolver_timeout;

    u->resolved->ctx = rctx;

    saved_top = lua_gettop(L);

    if (ngx_resolve_name(rctx) != NGX_OK) {
        ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                       "lua udp socket fail to run resolver immediately");

        u->ft_type |= NGX_HTTP_LUA_SOCKET_FT_RESOLVER;

        u->resolved->ctx = NULL;
        lua_pushnil(L);
        lua_pushfstring(L, "%s could not be resolved", host.data);

        return 2;
    }

    if (u->waiting == 1) {
        /* resolved and already connecting */
        return lua_yield(L, 0);
    }

    n = lua_gettop(L) - saved_top;
    if (n) {
        /* errors occurred during resolving or connecting
         * or already connected */
        return n;
    }

    /* still resolving */

    u->waiting = 1;
    u->prepare_retvals = ngx_http_lua_socket_resolve_retval_handler;

    ctx->data = u;
    ctx->udp_socket_busy = 1;
    ctx->udp_socket_ready = 0;

    if (ctx->entered_content_phase) {
        r->write_event_handler = ngx_http_lua_content_wev_handler;
    }

    return lua_yield(L, 0);
}
int
ngx_http_lua_ngx_req_get_post_args(lua_State *L)
{
    ngx_http_request_t          *r;
    u_char                      *buf;
    int                          retval;
    size_t                       len;
    ngx_chain_t                 *cl;
    u_char                      *p;
    u_char                      *last;

    if (lua_gettop(L) != 0) {
        return luaL_error(L, "expecting 0 arguments but seen %d",
                lua_gettop(L));
    }

    lua_getglobal(L, GLOBALS_SYMBOL_REQUEST);
    r = lua_touserdata(L, -1);
    lua_pop(L, 1);

    if (r == NULL) {
        return luaL_error(L, "no request object found");
    }

    if (r->discard_body) {
        lua_createtable(L, 0, 4);
        return 1;
    }

    if (r->request_body == NULL) {
        return luaL_error(L, "no request body found; "
                "maybe you should turn on lua_need_request_body?");
    }

    if (r->request_body->temp_file) {
        return luaL_error(L, "requesty body in temp file not supported");
    }

    lua_createtable(L, 0, 4);

    if (r->request_body->bufs == NULL) {
        return 1;
    }

    /* we copy r->request_body->bufs over to buf to simplify
     * unescaping query arg keys and values */

    len = 0;
    for (cl = r->request_body->bufs; cl; cl = cl->next) {
        len += cl->buf->last - cl->buf->pos;
    }

    dd("post body length: %d", (int) len);

    buf = ngx_palloc(r->pool, len);
    if (buf == NULL) {
        return luaL_error(L, "out of memory");
    }

    p = buf;
    for (cl = r->request_body->bufs; cl; cl = cl->next) {
        p = ngx_copy(p, cl->buf->pos, cl->buf->last - cl->buf->pos);
    }

    dd("post body: %.*s", (int) len, buf);

    last = buf + len;

    retval = ngx_http_lua_parse_args(r, L, buf, last);

    ngx_pfree(r->pool, buf);

    return retval;
}
Beispiel #11
0
int
luaopen_lem_sqlite3_core(lua_State *L)
{
	/* create module table */
	lua_createtable(L, 0, 11);

	/* create Statement metatable */
	lua_createtable(L, 0, 10);
	lua_pushvalue(L, -1);
	lua_setfield(L, -2, "__index");
	/* insert __gc method */
	lua_pushcfunction(L, stmt_finalize);
	lua_setfield(L, -2, "__gc");
	/* insert finalize method */
	lua_pushcfunction(L, stmt_finalize);
	lua_setfield(L, -2, "finalize");
	/* insert bind method */
	lua_pushcfunction(L, stmt_bind);
	lua_setfield(L, -2, "bind");
	/* insert column_names method */
	lua_pushcfunction(L, stmt_column_names);
	lua_setfield(L, -2, "column_names");
	/* insert step method */
	lua_pushcfunction(L, stmt_step);
	lua_setfield(L, -2, "step");
	/* insert reset method */
	lua_pushcfunction(L, stmt_reset);
	lua_setfield(L, -2, "reset");
	/* insert Statement metatable */
	lua_setfield(L, -2, "Statement");

	/* create Connection metatable */
	lua_createtable(L, 0, 10);
	lua_pushvalue(L, -1);
	lua_setfield(L, -2, "__index");
	/* insert __gc method */
	lua_pushcfunction(L, db_close);
	lua_setfield(L, -2, "__gc");
	/* insert close method */
	lua_pushcfunction(L, db_close);
	lua_setfield(L, -2, "close");
	/* insert last_insert_rowid method */
	lua_pushcfunction(L, db_last_insert_rowid);
	lua_setfield(L, -2, "last_insert_rowid");
	/* insert changes method */
	lua_pushcfunction(L, db_changes);
	lua_setfield(L, -2, "changes");
	/* insert autocommit method */
	lua_pushcfunction(L, db_autocommit);
	lua_setfield(L, -2, "autocommit");
	/* insert prepare method */
	lua_getfield(L, -2, "Statement"); /* upvalue 1: Statement metatable */
	lua_pushcclosure(L, db_prepare, 1);
	lua_setfield(L, -2, "prepare");
	/* insert exec method */
	lua_pushcfunction(L, db_exec);
	lua_setfield(L, -2, "exec");

	/* insert open function */
	lua_pushvalue(L, -1); /* upvalue 1: Connection metatable */
	lua_pushcclosure(L, db_open, 1);
	lua_setfield(L, -3, "open");

	/* insert Connection metatable */
	lua_setfield(L, -2, "Connection");

#if SQLITE_VERSION_NUMBER >= 3005000
	set_open_constant(L, NOMUTEX);
	set_open_constant(L, FULLMUTEX);
	set_open_constant(L, SHAREDCACHE);
	set_open_constant(L, PRIVATECACHE);
	set_open_constant(L, URI);

	set_open_constant(L, READONLY);
	set_open_constant(L, READWRITE);
	set_open_constant(L, CREATE);
#endif

	return 1;
}
static int
ngx_http_lua_ngx_re_match(lua_State *L)
{
    /* u_char                      *p; */
    ngx_http_request_t          *r;
    ngx_str_t                    subj;
    ngx_str_t                    pat;
    ngx_str_t                    opts;
    ngx_lua_regex_compile_t      re_comp;
    ngx_http_lua_regex_t        *re;
    const char                  *msg;
    ngx_int_t                    rc;
    ngx_uint_t                   n;
    int                          i;
    ngx_int_t                    pos = 0;
    int                          nargs;
    int                         *cap = NULL;
    int                          ovecsize;
    ngx_uint_t                   flags;
    ngx_pool_t                  *pool, *old_pool;
    ngx_http_lua_main_conf_t    *lmcf = NULL;
    u_char                       errstr[NGX_MAX_CONF_ERRSTR + 1];
    pcre_extra                  *sd = NULL;

    nargs = lua_gettop(L);

    if (nargs != 2 && nargs != 3 && nargs != 4) {
        return luaL_error(L, "expecting two or three or four arguments, "
                "but got %d", nargs);
    }

    lua_pushlightuserdata(L, &ngx_http_lua_request_key);
    lua_rawget(L, LUA_GLOBALSINDEX);
    r = lua_touserdata(L, -1);
    lua_pop(L, 1);

    if (r == NULL) {
        return luaL_error(L, "no request object found");
    }

    subj.data = (u_char *) luaL_checklstring(L, 1, &subj.len);
    pat.data = (u_char *) luaL_checklstring(L, 2, &pat.len);

    ngx_memzero(&re_comp, sizeof(ngx_lua_regex_compile_t));

    if (nargs >= 3) {
        opts.data = (u_char *) luaL_checklstring(L, 3, &opts.len);

        if (nargs == 4) {
            luaL_checktype(L, 4, LUA_TTABLE);
            lua_getfield(L, 4, "pos");
            if (lua_isnumber(L, -1)) {
                pos = (ngx_int_t) lua_tointeger(L, -1);
                if (pos < 0) {
                    pos = 0;
                }

            } else if (lua_isnil(L, -1)) {
                pos = 0;

            } else {
                msg = lua_pushfstring(L, "bad pos field type in the ctx table "
                        "argument: %s",
                        luaL_typename(L, -1));

                return luaL_argerror(L, 4, msg);
            }

            lua_pop(L, 1);
        }

    } else {
        opts.data = (u_char *) "";
        opts.len = 0;
    }

    re_comp.options = 0;

    flags = ngx_http_lua_ngx_re_parse_opts(L, &re_comp, &opts, 3);

    if (flags & NGX_LUA_RE_COMPILE_ONCE) {
        lmcf = ngx_http_get_module_main_conf(r, ngx_http_lua_module);
        pool = lmcf->pool;

        dd("server pool %p", lmcf->pool);

        lua_pushlightuserdata(L, &ngx_http_lua_regex_cache_key);
        lua_rawget(L, LUA_REGISTRYINDEX); /* table */

        lua_pushliteral(L, "m");
        lua_pushvalue(L, 2); /* table regex */

        dd("options size: %d", (int) sizeof(re_comp.options));

        lua_pushlstring(L, (char *) &re_comp.options, sizeof(re_comp.options));
                /* table regex opts */

        lua_concat(L, 3); /* table key */
        lua_pushvalue(L, -1); /* table key key */

        dd("regex cache key: %.*s", (int) (pat.len + sizeof(re_comp.options)),
                lua_tostring(L, -1));

        lua_rawget(L, -3); /* table key re */
        re = lua_touserdata(L, -1);

        lua_pop(L, 1); /* table key */

        if (re) {
            ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                    "lua regex cache hit for match regex \"%s\" with "
                    "options \"%s\"", pat.data, opts.data);

            lua_pop(L, 2);

            dd("restoring regex %p, ncaptures %d,  captures %p", re->regex,
                    re->ncaptures, re->captures);

            re_comp.regex = re->regex;
            sd = re->regex_sd;
            re_comp.captures = re->ncaptures;
            cap = re->captures;

            if (flags & NGX_LUA_RE_MODE_DFA) {
                ovecsize = 2;

            } else {
                ovecsize = (re->ncaptures + 1) * 3;
            }

            goto exec;
        }

        ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                "lua regex cache miss for match regex \"%s\" "
                "with options \"%s\"", pat.data, opts.data);

        if (lmcf->regex_cache_entries >= lmcf->regex_cache_max_entries) {

            if (lmcf->regex_cache_entries == lmcf->regex_cache_max_entries) {
                ngx_log_error(NGX_LOG_WARN, r->connection->log, 0,
                        "lua exceeding regex cache max entries (%i)",
                        lmcf->regex_cache_max_entries);

                lmcf->regex_cache_entries++;
            }

            pool = r->pool;
            flags &= ~NGX_LUA_RE_COMPILE_ONCE;
        }

    } else {
        pool = r->pool;
    }

    dd("pool %p, r pool %p", pool, r->pool);

    re_comp.pattern = pat;
    re_comp.err.len = NGX_MAX_CONF_ERRSTR;
    re_comp.err.data = errstr;
    re_comp.pool = pool;

    ngx_log_debug5(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
            "lua compiling match regex \"%s\" with options \"%s\" "
            "(compile once: %d) (dfa mode: %d) (jit mode: %d)",
            pat.data, opts.data,
            (flags & NGX_LUA_RE_COMPILE_ONCE) != 0,
            (flags & NGX_LUA_RE_MODE_DFA) != 0,
            (flags & NGX_LUA_RE_MODE_JIT) != 0);

    old_pool = ngx_http_lua_pcre_malloc_init(pool);

    rc = ngx_lua_regex_compile(&re_comp);

    ngx_http_lua_pcre_malloc_done(old_pool);

    if (rc != NGX_OK) {
        dd("compile failed");

        re_comp.err.data[re_comp.err.len] = '\0';
        msg = lua_pushfstring(L, "failed to compile regex \"%s\": %s",
                pat.data, re_comp.err.data);

        return luaL_argerror(L, 2, msg);
    }

#if LUA_HAVE_PCRE_JIT

    if (flags & NGX_LUA_RE_MODE_JIT) {

        old_pool = ngx_http_lua_pcre_malloc_init(pool);

        sd = pcre_study(re_comp.regex, PCRE_STUDY_JIT_COMPILE, &msg);

        ngx_http_lua_pcre_malloc_done(old_pool);

#   if (NGX_DEBUG)
        dd("sd = %p", sd);

        if (msg != NULL) {
            ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                "pcre study failed with PCRE_STUDY_JIT_COMPILE: %s (%p)",
                msg, sd);
        }

        if (sd != NULL) {
            int         jitted;

            old_pool = ngx_http_lua_pcre_malloc_init(pool);

            pcre_fullinfo(re_comp.regex, sd, PCRE_INFO_JIT, &jitted);

            ngx_http_lua_pcre_malloc_done(old_pool);

            ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                "pcre JIT compiling result: %d", jitted);
        }
#   endif /* NGX_DEBUG */

    } else {
        old_pool = ngx_http_lua_pcre_malloc_init(pool);

        sd = pcre_study(re_comp.regex, 0, &msg);

        ngx_http_lua_pcre_malloc_done(old_pool);

#   if (NGX_DEBUG)
        dd("sd = %p", sd);

        if (msg != NULL) {
            ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                "pcre_study failed with PCRE_STUDY_JIT_COMPILE: %s (%p)",
                msg, sd);
        }
#   endif /* NGX_DEBUG */
    }

#else  /* LUA_HAVE_PCRE_JIT */

    if (flags & NGX_LUA_RE_MODE_JIT) {
        ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                "your pcre build does not have JIT support and "
                "the \"j\" regex option is ignored");
    }

#endif /* LUA_HAVE_PCRE_JIT */

    dd("compile done, captures %d", (int) re_comp.captures);

    if (flags & NGX_LUA_RE_MODE_DFA) {
        ovecsize = 2;

    } else {
        ovecsize = (re_comp.captures + 1) * 3;
    }

    dd("allocating cap with size: %d", (int) ovecsize);

    cap = ngx_palloc(pool, ovecsize * sizeof(int));

    if (cap == NULL) {
        flags &= ~NGX_LUA_RE_COMPILE_ONCE;
        msg = "out of memory";
        goto error;
    }

    if (flags & NGX_LUA_RE_COMPILE_ONCE) {

        ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                "lua saving compiled regex (%d captures) into the cache "
                "(entries %i)", re_comp.captures,
                 lmcf ? lmcf->regex_cache_entries : 0);

        re = ngx_palloc(pool, sizeof(ngx_http_lua_regex_t));
        if (re == NULL) {
            return luaL_error(L, "out of memory");
        }

        dd("saving regex %p, ncaptures %d,  captures %p", re_comp.regex,
                re_comp.captures, cap);

        re->regex = re_comp.regex;
        re->regex_sd = sd;
        re->ncaptures = re_comp.captures;
        re->captures = cap;
        re->replace = NULL;

        lua_pushlightuserdata(L, re); /* table key value */
        lua_rawset(L, -3); /* table */
        lua_pop(L, 1);

        if (lmcf) {
            lmcf->regex_cache_entries++;
        }
    }

exec:
    if (flags & NGX_LUA_RE_MODE_DFA) {

#if LUA_HAVE_PCRE_DFA

        int ws[NGX_LUA_RE_DFA_MODE_WORKSPACE_COUNT];
        rc = ngx_http_lua_regex_dfa_exec(re_comp.regex, sd, &subj,
            (int) pos, cap, ovecsize, ws, NGX_LUA_RE_DFA_MODE_WORKSPACE_COUNT);

#else /* LUA_HAVE_PCRE_DFA */

        msg = "at least pcre 6.0 is required for the DFA mode";
        goto error;

#endif /* LUA_HAVE_PCRE_DFA */

    } else {
        rc = ngx_http_lua_regex_exec(re_comp.regex, sd, &subj, (int) pos, cap,
                ovecsize);
    }

    if (rc == NGX_REGEX_NO_MATCHED) {
        ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                "regex \"%s\" not matched on string \"%s\" starting from %z",
                pat.data, subj.data, pos);

        if (!(flags & NGX_LUA_RE_COMPILE_ONCE)) {
            if (sd) {
                ngx_http_lua_regex_free_study_data(pool, sd);
            }

            ngx_pfree(pool, re_comp.regex);
            ngx_pfree(pool, cap);
        }

        lua_pushnil(L);
        return 1;
    }

    if (rc < 0) {
        msg = lua_pushfstring(L, ngx_regex_exec_n " failed: %d on \"%s\" "
            "using \"%s\"", (int) rc, subj.data, pat.data);
        goto error;
    }

    if (rc == 0) {
        if (flags & NGX_LUA_RE_MODE_DFA) {
            rc = 1;

        } else {
            msg = "capture size too small";
            goto error;
        }
    }

    dd("rc = %d", (int) rc);

    lua_createtable(L, rc - 1 /* narr */, 1 /* nrec */);

    for (i = 0, n = 0; i < rc; i++, n += 2) {
        dd("capture %d: %d %d", i, cap[n], cap[n + 1]);
        if (cap[n] < 0) {
            lua_pushnil(L);

        } else {
            lua_pushlstring(L, (char *) &subj.data[cap[n]],
                    cap[n + 1] - cap[n]);

            dd("pushing capture %s at %d", lua_tostring(L, -1), (int) i);
        }

        lua_rawseti(L, -2, (int) i);
    }

    if (nargs == 4) { /* having ctx table */
        pos = cap[1];
        lua_pushinteger(L, (lua_Integer) pos);
        lua_setfield(L, 4, "pos");
    }

    if (!(flags & NGX_LUA_RE_COMPILE_ONCE)) {

        if (sd) {
            ngx_http_lua_regex_free_study_data(pool, sd);
        }

        ngx_pfree(pool, re_comp.regex);
        ngx_pfree(pool, cap);
    }

    return 1;

error:
    if (!(flags & NGX_LUA_RE_COMPILE_ONCE)) {
        if (sd) {
            ngx_http_lua_regex_free_study_data(pool, sd);
        }

        if (re_comp.regex) {
            ngx_pfree(pool, re_comp.regex);
        }

        if (cap) {
            ngx_pfree(pool, cap);
        }
    }

    return luaL_error(L, msg);
}
static int
ngx_http_lua_ngx_re_gmatch_iterator(lua_State *L)
{
    ngx_http_lua_regex_ctx_t    *ctx;
    ngx_http_request_t          *r;
    int                         *cap;
    ngx_int_t                    rc;
    ngx_uint_t                   n;
    int                          i;
    ngx_str_t                    subj;
    int                          offset;
    const char                  *msg = NULL;

    /* upvalues in order: subj ctx offset */

    subj.data = (u_char *) lua_tolstring(L, lua_upvalueindex(1), &subj.len);
    ctx = (ngx_http_lua_regex_ctx_t *) lua_touserdata(L, lua_upvalueindex(2));
    offset = (int) lua_tointeger(L, lua_upvalueindex(3));

    if (offset < 0) {
        lua_pushnil(L);
        return 1;
    }

    cap = ctx->captures;

    dd("offset %d, r %p, subj %s", (int) offset, ctx->request, subj.data);

    lua_pushlightuserdata(L, &ngx_http_lua_request_key);
    lua_rawget(L, LUA_GLOBALSINDEX);
    r = lua_touserdata(L, -1);
    lua_pop(L, 1);

    if (r == NULL) {
        return luaL_error(L, "no request object found");
    }

    if (r != ctx->request || r->pool != ctx->request->pool) {
        return luaL_error(L, "attempt to use ngx.re.gmatch iterator in a "
                "request that did not create it");
    }

    dd("regex exec...");

    if (ctx->flags & NGX_LUA_RE_MODE_DFA) {

#if LUA_HAVE_PCRE_DFA

        int ws[NGX_LUA_RE_DFA_MODE_WORKSPACE_COUNT];

        rc = ngx_http_lua_regex_dfa_exec(ctx->regex, ctx->regex_sd, &subj,
            offset, cap, ctx->captures_len, ws,
            NGX_LUA_RE_DFA_MODE_WORKSPACE_COUNT);

#else /* LUA_HAVE_PCRE_DFA */
        msg = "at least pcre 6.0 is required for the DFA mode";
        goto error;

#endif /* LUA_HAVE_PCRE_DFA */

    } else {
        rc = ngx_http_lua_regex_exec(ctx->regex, ctx->regex_sd, &subj,
                                     offset, cap, ctx->captures_len);
    }

    if (rc == NGX_REGEX_NO_MATCHED) {
        /* set upvalue "offset" to -1 */
        lua_pushinteger(L, -1);
        lua_replace(L, lua_upvalueindex(3));

        if (!(ctx->flags & NGX_LUA_RE_COMPILE_ONCE)) {
            if (ctx->regex_sd) {
                ngx_http_lua_regex_free_study_data(r->pool, ctx->regex_sd);
                ctx->regex_sd = NULL;
            }

            ngx_pfree(r->pool, cap);
        }

        lua_pushnil(L);
        return 1;
    }

    if (rc < 0) {
        msg = lua_pushfstring(L, ngx_regex_exec_n " failed: %d on \"%s\"",
                (int) rc, subj.data);
        goto error;
    }

    if (rc == 0) {
        if (ctx->flags & NGX_LUA_RE_MODE_DFA) {
            rc = 1;

        } else {
            goto error;
        }
    }

    dd("rc = %d", (int) rc);

    lua_createtable(L, rc - 1 /* narr */, 1 /* nrec */);

    for (i = 0, n = 0; i < rc; i++, n += 2) {
        dd("capture %d: %d %d", i, cap[n], cap[n + 1]);
        if (cap[n] < 0) {
            lua_pushnil(L);

        } else {
            lua_pushlstring(L, (char *) &subj.data[cap[n]],
                    cap[n + 1] - cap[n]);

            dd("pushing capture %s at %d", lua_tostring(L, -1), (int) i);
        }

        lua_rawseti(L, -2, (int) i);
    }

    offset = cap[1];
    if (offset == (ssize_t) subj.len) {
        offset = -1;

        if (!(ctx->flags & NGX_LUA_RE_COMPILE_ONCE)) {
            if (ctx->regex_sd) {
                ngx_http_lua_regex_free_study_data(r->pool, ctx->regex_sd);
                ctx->regex_sd = NULL;
            }

            ngx_pfree(r->pool, cap);
        }
    }

    lua_pushinteger(L, offset);
    lua_replace(L, lua_upvalueindex(3));

    return 1;

error:
    lua_pushinteger(L, -1);
    lua_replace(L, lua_upvalueindex(3));

    if (!(ctx->flags & NGX_LUA_RE_COMPILE_ONCE)) {
        if (ctx->regex_sd) {
            ngx_http_lua_regex_free_study_data(r->pool, ctx->regex_sd);
            ctx->regex_sd = NULL;
        }

        ngx_pfree(r->pool, cap);
    }

    return luaL_error(L, msg);
}
static int
ngx_http_lua_ngx_re_sub_helper(lua_State *L, unsigned global)
{
    ngx_http_lua_regex_t        *re;
    ngx_http_request_t          *r;
    ngx_str_t                    subj;
    ngx_str_t                    pat;
    ngx_str_t                    opts;
    ngx_str_t                    tpl;
    ngx_http_lua_main_conf_t    *lmcf = NULL;
    ngx_pool_t                  *pool, *old_pool;
    ngx_lua_regex_compile_t      re_comp;
    const char                  *msg;
    ngx_int_t                    rc;
    ngx_uint_t                   n;
    ngx_int_t                    i;
    int                          nargs;
    int                         *cap = NULL;
    int                          ovecsize;
    int                          type;
    unsigned                     func;
    int                          offset;
    size_t                       count;
    luaL_Buffer                  luabuf;
    ngx_int_t                    flags;
    u_char                      *p;
    u_char                       errstr[NGX_MAX_CONF_ERRSTR + 1];
    pcre_extra                  *sd = NULL;

    ngx_http_lua_complex_value_t              *ctpl = NULL;
    ngx_http_lua_compile_complex_value_t       ccv;

    nargs = lua_gettop(L);

    if (nargs != 3 && nargs != 4) {
        return luaL_error(L, "expecting three or four arguments, but got %d",
                nargs);
    }

    lua_pushlightuserdata(L, &ngx_http_lua_request_key);
    lua_rawget(L, LUA_GLOBALSINDEX);
    r = lua_touserdata(L, -1);
    lua_pop(L, 1);

    if (r == NULL) {
        return luaL_error(L, "no request object found");
    }

    subj.data = (u_char *) luaL_checklstring(L, 1, &subj.len);
    pat.data = (u_char *) luaL_checklstring(L, 2, &pat.len);

    func = 0;

    type = lua_type(L, 3);
    switch (type) {
        case LUA_TFUNCTION:
            func = 1;
            tpl.len = 0;
            tpl.data = (u_char *) "";
            break;

        case LUA_TNUMBER:
        case LUA_TSTRING:
            tpl.data = (u_char *) lua_tolstring(L, 3, &tpl.len);
            break;

        default:
            msg = lua_pushfstring(L, "string, number, or function expected, "
                    "got %s", lua_typename(L, type));
            return luaL_argerror(L, 3, msg);
    }

    ngx_memzero(&re_comp, sizeof(ngx_lua_regex_compile_t));

    if (nargs == 4) {
        opts.data = (u_char *) luaL_checklstring(L, 4, &opts.len);
        lua_pop(L, 1);

    } else { /* nargs == 3 */
        opts.data = (u_char *) "";
        opts.len = 0;
    }

    /* stack: subj regex repl */

    re_comp.options = 0;

    flags = ngx_http_lua_ngx_re_parse_opts(L, &re_comp, &opts, 4);

    if (flags & NGX_LUA_RE_COMPILE_ONCE) {
        lmcf = ngx_http_get_module_main_conf(r, ngx_http_lua_module);
        pool = lmcf->pool;

        dd("server pool %p", lmcf->pool);

        lua_pushlightuserdata(L, &ngx_http_lua_regex_cache_key);
        lua_rawget(L, LUA_REGISTRYINDEX); /* table */

        lua_pushliteral(L, "s");
        lua_pushinteger(L, tpl.len);
        lua_pushliteral(L, ":");
        lua_pushvalue(L, 2);

        if (tpl.len != 0) {
            lua_pushvalue(L, 3);
        }

        dd("options size: %d", (int) sizeof(re_comp.options));

        lua_pushlstring(L, (char *) &re_comp.options, sizeof(re_comp.options));
                /* table regex opts */

        if (tpl.len == 0) {
            lua_concat(L, 5); /* table key */

        } else {
            lua_concat(L, 6); /* table key */
        }

        lua_pushvalue(L, -1); /* table key key */

        dd("regex cache key: %.*s", (int) (pat.len + sizeof(re_comp.options)),
                lua_tostring(L, -1));

        lua_rawget(L, -3); /* table key re */
        re = lua_touserdata(L, -1);

        lua_pop(L, 1); /* table key */

        if (re) {
            ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                    "lua regex cache hit for sub regex \"%s\" with options "
                    "\"%s\" and replace \"%s\"", pat.data, opts.data,
                    func ? (u_char *) "<func>" : tpl.data);

            lua_pop(L, 2);

            dd("restoring regex %p, ncaptures %d,  captures %p", re->regex,
                    re->ncaptures, re->captures);

            re_comp.regex = re->regex;
            sd = re->regex_sd;
            re_comp.captures = re->ncaptures;
            cap = re->captures;
            ctpl = re->replace;

            if (flags & NGX_LUA_RE_MODE_DFA) {
                ovecsize = 2;

            } else {
                ovecsize = (re->ncaptures + 1) * 3;
            }

            goto exec;
        }

        ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                "lua regex cache miss for %ssub regex \"%s\" with options "
                "\"%s\" and replace \"%s\"",
                global ? "g" : "",
                pat.data, opts.data,
                func ? (u_char *) "<func>" : tpl.data);

        if (lmcf->regex_cache_entries >= lmcf->regex_cache_max_entries) {

            if (lmcf->regex_cache_entries == lmcf->regex_cache_max_entries) {
                ngx_log_error(NGX_LOG_WARN, r->connection->log, 0,
                        "lua exceeding regex cache max entries (%i)",
                        lmcf->regex_cache_max_entries);

                lmcf->regex_cache_entries++;
            }

            pool = r->pool;
            flags &= ~NGX_LUA_RE_COMPILE_ONCE;
        }

    } else {
        pool = r->pool;
    }

    re_comp.pattern = pat;
    re_comp.err.len = NGX_MAX_CONF_ERRSTR;
    re_comp.err.data = errstr;
    re_comp.pool = pool;

    dd("compiling regex");

    ngx_log_debug6(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
            "lua compiling %ssub regex \"%s\" with options \"%s\" "
            "(compile once: %d) (dfa mode: %d) (jit mode: %d)",
            global ? "g" : "", pat.data, opts.data,
            (flags & NGX_LUA_RE_COMPILE_ONCE) != 0,
            (flags & NGX_LUA_RE_MODE_DFA) != 0,
            (flags & NGX_LUA_RE_MODE_JIT) != 0);

    old_pool = ngx_http_lua_pcre_malloc_init(pool);

    rc = ngx_lua_regex_compile(&re_comp);

    ngx_http_lua_pcre_malloc_done(old_pool);

    if (rc != NGX_OK) {
        dd("compile failed");

        re_comp.err.data[re_comp.err.len] = '\0';
        msg = lua_pushfstring(L, "failed to compile regex \"%s\": %s",
                pat.data, re_comp.err.data);

        return luaL_argerror(L, 2, msg);
    }

#if LUA_HAVE_PCRE_JIT

    if (flags & NGX_LUA_RE_MODE_JIT) {

        old_pool = ngx_http_lua_pcre_malloc_init(pool);

        sd = pcre_study(re_comp.regex, PCRE_STUDY_JIT_COMPILE, &msg);

        ngx_http_lua_pcre_malloc_done(old_pool);

#   if (NGX_DEBUG)
        dd("sd = %p", sd);

        if (msg != NULL) {
            ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                "pcre study failed with PCRE_STUDY_JIT_COMPILE: %s (%p)",
                msg, sd);
        }

        if (sd != NULL) {
            int         jitted;

            old_pool = ngx_http_lua_pcre_malloc_init(pool);

            pcre_fullinfo(re_comp.regex, sd, PCRE_INFO_JIT, &jitted);

            ngx_http_lua_pcre_malloc_done(old_pool);

            ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                "pcre JIT compiling result: %d", jitted);
        }
#   endif /* NGX_DEBUG */

    } else {

        old_pool = ngx_http_lua_pcre_malloc_init(pool);

        sd = pcre_study(re_comp.regex, 0, &msg);

        ngx_http_lua_pcre_malloc_done(old_pool);

#   if (NGX_DEBUG)
        dd("sd = %p", sd);

        if (msg != NULL) {
            ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                "pcre_study failed with PCRE_STUDY_JIT_COMPILE: %s (%p)",
                msg, sd);
        }
#   endif /* NGX_DEBUG */
    }

#else  /* LUA_HAVE_PCRE_JIT */

    if (flags & NGX_LUA_RE_MODE_JIT) {
        ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                "your pcre build does not have JIT support and "
                "the \"j\" regex option is ignored");
    }

#endif /* LUA_HAVE_PCRE_JIT */

    dd("compile done, captures %d", re_comp.captures);

    if (flags & NGX_LUA_RE_MODE_DFA) {
        ovecsize = 2;

    } else {
        ovecsize = (re_comp.captures + 1) * 3;
    }

    cap = ngx_palloc(pool, ovecsize * sizeof(int));
    if (cap == NULL) {
        flags &= ~NGX_LUA_RE_COMPILE_ONCE;
        msg = "out of memory";
        goto error;
    }

    if (func) {
        ctpl = NULL;

    } else {
        ctpl = ngx_palloc(pool, sizeof(ngx_http_lua_complex_value_t));
        if (ctpl == NULL) {
            flags &= ~NGX_LUA_RE_COMPILE_ONCE;
            msg = "out of memory";
            goto error;
        }

        if ((flags & NGX_LUA_RE_COMPILE_ONCE) && tpl.len != 0) {
            /* copy the string buffer pointed to by tpl.data from Lua VM */
            p = ngx_palloc(pool, tpl.len + 1);
            if (p == NULL) {
                flags &= ~NGX_LUA_RE_COMPILE_ONCE;
                msg = "out of memory";
                goto error;
            }

            ngx_memcpy(p, tpl.data, tpl.len);
            p[tpl.len] = '\0';

            tpl.data = p;
        }

        ngx_memzero(&ccv, sizeof(ngx_http_lua_compile_complex_value_t));
        ccv.pool = pool;
        ccv.log = r->connection->log;
        ccv.value = &tpl;
        ccv.complex_value = ctpl;

        if (ngx_http_lua_compile_complex_value(&ccv) != NGX_OK) {
            ngx_pfree(pool, cap);
            ngx_pfree(pool, ctpl);

            if ((flags & NGX_LUA_RE_COMPILE_ONCE) && tpl.len != 0) {
                ngx_pfree(pool, tpl.data);
            }

            if (sd) {
                ngx_http_lua_regex_free_study_data(pool, sd);
            }

            ngx_pfree(pool, re_comp.regex);

            return luaL_error(L, "bad template for substitution: \"%s\"",
                    lua_tostring(L, 3));
        }
    }

    if (flags & NGX_LUA_RE_COMPILE_ONCE) {

        ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                "lua saving compiled sub regex (%d captures) into the cache "
                "(entries %i)", re_comp.captures,
                lmcf ? lmcf->regex_cache_entries : 0);

        re = ngx_palloc(pool, sizeof(ngx_http_lua_regex_t));
        if (re == NULL) {
            return luaL_error(L, "out of memory");
        }

        dd("saving regex %p, ncaptures %d,  captures %p", re_comp.regex,
                re_comp.captures, cap);

        re->regex = re_comp.regex;
        re->regex_sd = sd;
        re->ncaptures = re_comp.captures;
        re->captures = cap;
        re->replace = ctpl;

        lua_pushlightuserdata(L, re); /* table key value */
        lua_rawset(L, -3); /* table */
        lua_pop(L, 1);

        if (lmcf) {
            lmcf->regex_cache_entries++;
        }
    }

exec:
    count = 0;
    offset = 0;

    for (;;) {
        if (subj.len == 0) {
            break;
        }

        if (flags & NGX_LUA_RE_MODE_DFA) {

#if LUA_HAVE_PCRE_DFA

            int ws[NGX_LUA_RE_DFA_MODE_WORKSPACE_COUNT];
            rc = ngx_http_lua_regex_dfa_exec(re_comp.regex, sd, &subj,
                offset, cap, ovecsize, ws, NGX_LUA_RE_DFA_MODE_WORKSPACE_COUNT);

#else /* LUA_HAVE_PCRE_DFA */

        msg = "at least pcre 6.0 is required for the DFA mode";
        goto error;

#endif /* LUA_HAVE_PCRE_DFA */

        } else {
            rc = ngx_http_lua_regex_exec(re_comp.regex, sd, &subj, offset, cap,
                    ovecsize);
        }

        if (rc == NGX_REGEX_NO_MATCHED) {
            break;
        }

        if (rc < 0) {
            msg = lua_pushfstring(L, ngx_regex_exec_n " failed: %d on \"%s\" "
                "using \"%s\"", (int) rc, subj.data, pat.data);
            goto error;
        }

        if (rc == 0) {
            if (flags & NGX_LUA_RE_MODE_DFA) {
                rc = 1;

            } else {
                msg = "capture size too small";
                goto error;
            }
        }

        dd("rc = %d", (int) rc);

        count++;

        if (count == 1) {
            luaL_buffinit(L, &luabuf);
        }

        if (func) {
            lua_pushvalue(L, -1);

            lua_createtable(L, rc - 1 /* narr */, 1 /* nrec */);

            for (i = 0, n = 0; i < rc; i++, n += 2) {
                dd("capture %d: %d %d", (int) i, cap[n], cap[n + 1]);
                if (cap[n] < 0) {
                    lua_pushnil(L);

                } else {
                    lua_pushlstring(L, (char *) &subj.data[cap[n]],
                            cap[n + 1] - cap[n]);

                    dd("pushing capture %s at %d", lua_tostring(L, -1),
                            (int) i);
                }

                lua_rawseti(L, -2, (int) i);
            }

            dd("stack size at call: %d", lua_gettop(L));

            lua_call(L, 1 /* nargs */, 1 /* nresults */);
            type = lua_type(L, -1);
            switch (type) {
                case LUA_TNUMBER:
                case LUA_TSTRING:
                    tpl.data = (u_char *) lua_tolstring(L, -1, &tpl.len);
                    break;

                default:
                    msg = lua_pushfstring(L, "string or number expected to be "
                            "returned by the replace function, got %s",
                            lua_typename(L, type));
                    return luaL_argerror(L, 3, msg);
            }

            luaL_addlstring(&luabuf, (char *) &subj.data[offset],
                    cap[0] - offset);

            luaL_addlstring(&luabuf, (char *) tpl.data, tpl.len);

            lua_pop(L, 1);

            offset = cap[1];

            if (global) {
                continue;
            }

            break;
        }

        rc = ngx_http_lua_complex_value(r, &subj, offset, rc, cap, ctpl,
                &luabuf);

        if (rc != NGX_OK) {
            msg = lua_pushfstring(L, "failed to eval the template for "
                "replacement: \"%s\"", tpl.data);
            goto error;
        }

        offset = cap[1];

        if (global) {
            continue;
        }

        break;
    }

    if (count == 0) {
        dd("no match, just the original subject");
        lua_settop(L, 1);

    } else {
        if (offset != (int) subj.len) {
            dd("adding trailer: %s (len %d)", &subj.data[offset],
                    (int) (subj.len - offset));

            luaL_addlstring(&luabuf, (char *) &subj.data[offset],
                    subj.len - offset);
        }

        luaL_pushresult(&luabuf);

        dd("the dst string: %s", lua_tostring(L, -1));
    }

    if (!(flags & NGX_LUA_RE_COMPILE_ONCE)) {
        if (sd) {
            ngx_http_lua_regex_free_study_data(pool, sd);
        }

        if (re_comp.regex) {
            ngx_pfree(pool, re_comp.regex);
        }

        if (ctpl) {
            ngx_pfree(pool, ctpl);
        }

        if (cap) {
            ngx_pfree(pool, cap);
        }
    }

    lua_pushinteger(L, count);
    return 2;

error:
    if (!(flags & NGX_LUA_RE_COMPILE_ONCE)) {
        if (sd) {
            ngx_http_lua_regex_free_study_data(pool, sd);
        }

        if (re_comp.regex) {
            ngx_pfree(pool, re_comp.regex);
        }

        if (ctpl) {
            ngx_pfree(pool, ctpl);
        }

        if (cap) {
            ngx_pfree(pool, cap);
        }
    }

    return luaL_error(L, msg);
}
Beispiel #15
0
void
qlua_selftable(lua_State *L, const luaL_Reg *table, QLUA_Type t_id)
{
    lua_createtable(L, 0, 0);
    qlua_fillmeta(L, table, t_id);
}
Beispiel #16
0
void
qlua_init(lua_State *L, int argc, char *argv[])
{
    static const lua_CFunction qcd_inits[] = {
        init_qlua_io,
        init_complex,
        init_seqrandom,
        init_seqcolvec,
        init_seqcolmat,
        init_seqdirferm,
        init_seqdirprop,
        init_xml,
        init_vector,
#ifdef HAS_GSL
        init_matrix,
        init_root,
        init_min,
#endif
        init_lattice,
        init_latint,
        init_latreal,
        init_latrandom,
        init_latcomplex,
        init_latsubset,
        init_latmulti,
        init_latcolvec,
        init_latcolmat,
        init_latdirferm,
        init_latdirprop,
        init_scatter,
        init_gather,
        init_gamma,
#ifdef HAS_AFF
        init_aff_io,
#endif
#ifdef HAS_HDF5
        init_hdf5_io,
#endif
#ifdef HAS_HYPRE
        init_qhp,
#endif
        init_nersc_io,
        init_qdpc_io,
        init_ddpairs_io,
        init_qdpcc_io,
#ifdef HAS_CLOVER
        init_clover,
#endif
#ifdef HAS_MDWF
        init_mdwf,
#endif
#ifdef HAS_EXTRAS
        init_extras,
#endif
        /* ZZZ add other packages here */
        NULL };

    int i;

    lua_gc(L, LUA_GCSTOP, 0);  /* stop collector during initialization */
    qlua_openlibs(L);  /* open libraries */

#ifdef HAS_GSL
    luaL_register(L, gsllib, fEmpty);
#endif
    luaL_register(L, qcdlib, fQCD);
    for (i = 0; qcd_inits[i]; i++) {
        lua_pushcfunction(L, qcd_inits[i]);
        lua_call(L, 0, 0);
    }
    lua_getglobal(L, qcdlib);
    lua_pushnumber(L, QDP_Ns);
    lua_setfield(L, -2, "Ns");
    lua_newtable(L);
    for (i = 0; versions[i].name; i++) {
        lua_pushstring(L, versions[i].value);
        lua_setfield(L, -2, versions[i].name);
    }
    lua_setfield(L, -2, "version");
    lua_pop(L, 1);

    /* collect all script names */
    {
        int i;
        lua_createtable(L, argc - 1, 0);
        for (i = 1; i < argc; i++) {
            lua_pushstring(L, argv[i]);
            lua_rawseti(L, -2, i);
        }
        lua_setglobal(L, "scripts");
    }
    lua_gc(L, LUA_GCRESTART, 0);
}
Beispiel #17
0
Datei: fs.c Projekt: ifzz/LuaIO
static void LuaIO_fs_callback(uv_fs_t* req) {
  LuaIO_fs_req_t* fs_req = container_of(req, LuaIO_fs_req_t, req);
  lua_State* L = fs_req->current_thread;
  int result = req->result;

  switch (req->fs_type) {
    case UV_FS_ACCESS:
    case UV_FS_CLOSE:
    case UV_FS_RENAME:
    case UV_FS_UNLINK:
    case UV_FS_RMDIR:
    case UV_FS_MKDIR:
    case UV_FS_FTRUNCATE:
    case UV_FS_FSYNC:
    case UV_FS_FDATASYNC:
    case UV_FS_LINK:
    case UV_FS_SYMLINK:
    case UV_FS_CHMOD:
    case UV_FS_FCHMOD:
    case UV_FS_CHOWN:
    case UV_FS_FCHOWN:
    case UV_FS_UTIME:
    case UV_FS_FUTIME:
    case UV_FS_OPEN:
    case UV_FS_SENDFILE:
      lua_pushinteger(L, result);
      LuaIO_pfree(&LuaIO_fs_req_pool, fs_req);
      LuaIO_resume(L, 1);
      return;

    case UV_FS_READ:
      if (result > 0) {
        fs_req->read_buffer->write_pos += result;
      }

      lua_pushinteger(L, result);
      LuaIO_pfree(&LuaIO_fs_req_pool, fs_req);
      LuaIO_resume(L, 1);
      return;

    case UV_FS_WRITE:
      if (result < 0) {
        lua_pushinteger(L, result);
      } else {
        lua_pushinteger(L, fs_req->bytes);
      }

      luaL_unref(L, LUA_REGISTRYINDEX, fs_req->write_data_ref);
      LuaIO_pfree(&LuaIO_fs_req_pool, fs_req);
      LuaIO_resume(L, 1);
      return;

    case UV_FS_STAT:
    case UV_FS_LSTAT:
    case UV_FS_FSTAT:
      if (result < 0) {
        lua_pushnil(L);
        lua_pushinteger(L, result);
      } else {
        LuaIO_fs_create_stat(L, &req->statbuf);
        lua_pushinteger(L, 0);
      }

      LuaIO_pfree(&LuaIO_fs_req_pool, fs_req);
      LuaIO_resume(L, 2);
      return;

    case UV_FS_MKDTEMP:
      if (result < 0) {
        lua_pushnil(L);
        lua_pushinteger(L, result);
      } else {
        lua_pushstring(L, req->path);
        lua_pushinteger(L, 0);
      }

      LuaIO_pfree(&LuaIO_fs_req_pool, fs_req);
      LuaIO_resume(L, 2);
      return;

    case UV_FS_READLINK:
      if (result < 0) {
        lua_pushnil(L);
        lua_pushinteger(L, result);
      } else {
        lua_pushstring(L, (char*)req->ptr);
        lua_pushinteger(L, 0);
      }

      LuaIO_pfree(&LuaIO_fs_req_pool, fs_req);
      LuaIO_resume(L, 2);
      return;

    case UV_FS_SCANDIR:
      if (result < 0) {
        lua_pushnil(L);
        lua_pushinteger(L, result);
      } else {
        int ret;
        lua_createtable(L, 0, 0);

        for (int i = 1; ; i++) {
          uv_dirent_t ent;
          ret = uv_fs_scandir_next(req, &ent);
          if (ret) break;

          lua_pushstring(L, ent.name);
          lua_rawseti(L, -2, i);
        }

        if (ret && ret != UV_EOF) {
          lua_pop(L, 1);
          lua_pushnil(L);
          lua_pushinteger(L, ret);
        } else {
          lua_pushinteger(L, 0);
        }
      }

      LuaIO_pfree(&LuaIO_fs_req_pool, fs_req);
      LuaIO_resume(L, 2);
      return;

    default:
      luaL_error(L, "fs_native module error: unknown fs type(%d)", req->fs_type); 
  }
}
Beispiel #18
0
void pushLuaFsm(lua_State * lua, const Fsm<char>& fsm)
{
	const char* members[] = { "firstLinearState", "fsm" };
	const int nMembers = static_cast<int>(sizeof(members) / sizeof(members[0]));
	const char* transition[] = { "next", "tokens" };
	const int nTransEntries = static_cast<int>(sizeof(transition) / sizeof(transition[0]));
	lua_createtable(lua, fsm.getNumberOfStates(), nMembers);
	int top = lua_gettop(lua);
	for (Fsm<char>::State state = 0; state < fsm.getNumberOfStates(); ++state)
	{
		std::set<char> symbols;
		fsm.getAcceptedSymbols(state, symbols);
		// push as index into state table
		lua_pushinteger(lua, state + 1);
		// create transition table for state
		lua_createtable(lua, 0, static_cast<int>(symbols.size()));
		for (std::set<char>::const_iterator isym = symbols.begin(); isym != symbols.end(); ++isym)
		{
			lua_pushlstring(lua, &(*isym), 1);
			// create transition entry
			lua_createtable(lua, 0, nTransEntries);
			for (int t = 0; t < nTransEntries; ++t)
				lua_pushstring(lua, transition[t]);

			// create tokens list
			lua_newtable(lua);
			Fsm<char>::State next = state;
			BitSequence<int> tokens = fsm.next(next, *isym);
			for (int i = 0, iTok = tokens.begin(); iTok < tokens.end(); ++iTok)
				if (tokens.get(iTok))
				{
					// add token to tokens list
					lua_pushinteger(lua, ++i);
					lua_pushinteger(lua, iTok);
					lua_settable(lua, -3);
				}

			// assign tokens list to entry.tokens
			lua_settable(lua, -nTransEntries - 2);
			// assign next state to entry.next
			lua_pushinteger(lua, next + 1);
			lua_settable(lua, -nTransEntries - 1);
			// assign entry to transitiontable[*isym]
			lua_settable(lua, -3);
		}
		// assign transition table to state
		lua_settable(lua, -3);
	}

	for (int m = 0; m < nMembers; ++m)
		lua_pushstring(lua, members[m]);

	// assign fsm
	lua_pushlightuserdata(lua, const_cast<Fsm<char>*>(&fsm));
	lua_settable(lua, -2-nMembers);
	// assign firstLinearState
	lua_pushinteger(lua, fsm.getFirstLinearSequence(2));
	lua_settable(lua, -1-nMembers);

	assert(lua_gettop(lua) == top);
}
Beispiel #19
0
/*
 * Reads a row.
 */
static int read (lua_State *L) {
    mysql_rec *m;
    is_read_mode_t read_mode;
    const char *read_mode_options[] = IS_READ_MODE_OPTIONS;
    int i;

    m = (mysql_rec *) luaL_checkudata(L, 1, IS_MYSQL_METATABLE);
    if (!m->res) {
        lua_pushliteral(L, "no statement to read from");
        lua_error(L);
    }
    read_mode = luaL_checkoption(L, 2, read_mode_options[0],
                                 read_mode_options);

    switch (mysql_stmt_fetch(m->stmt)) {
    case 0:
    case MYSQL_DATA_TRUNCATED:
        switch (read_mode) {
        case IS_RNAME:
            lua_createtable(L, 0, m->field_count);
            break;

        case IS_RINDEX:
            lua_createtable(L, m->field_count, 0);
            break;
        }
        for (i = 0; i < m->field_count; i++) {
            /* ignore NULL */
            if (m->nulls[i]) {
                continue;
            }

            /* handle types */
            switch (m->bind[i].buffer_type) {
            case MYSQL_TYPE_NULL:
                lua_pushnil(L);
                break;

            case MYSQL_TYPE_DOUBLE:
                lua_pushnumber(L, m->doubles[i]);
                break;

            case MYSQL_TYPE_BIT:
                read_bit(L, m, i);
                break;

            case MYSQL_TYPE_STRING:
                read_string(L, m, i);
                break;

            default:
                /* not reached */
                lua_pushliteral(L, "internal error");
                lua_error(L);
            }

            /* store */
            switch (read_mode) {
            case IS_RNAME:
                lua_setfield(L, -2, m->fields[i].name);
                break;

            case IS_RINDEX:
                lua_rawseti(L, -2, i + 1);
                break;
            }
        }
        return 1;

    case 1:
        error(L, m);
    }

    /* done */
    if (m->res) {
        mysql_free_result(m->res);
        m->res = NULL;
    }
    if (m->stmt) {
        mysql_stmt_close(m->stmt);
        m->stmt = NULL;
    }

    return 0;
}
Beispiel #20
0
static void push_bindings(lua_State *l, const KeyBindings::BindingPrototype *protos) {
	LUA_DEBUG_START(l);

	lua_newtable(l); // [-1] bindings
	lua_pushnil(l); // [-2] bindings, [-1] group (no current group)

	assert(!protos[0].function); // first entry should be a group header

	int group_idx = 1;
	int binding_idx = 1;
	for (const KeyBindings::BindingPrototype *proto = protos; proto->label; ++proto) {
		if (! proto->function) {
			// start a new named binding group

			// [-2] bindings, [-1] group
			lua_pop(l, 1);
			// [-1] bindings
			lua_newtable(l);
			lua_pushstring(l, proto->label);
			lua_setfield(l, -2, "label");
			// [-2] bindings, [-1] group
			lua_pushvalue(l, -1);
			// [-3] bindings, [-2] group, [-1] group copy
			lua_rawseti(l, -3, group_idx);
			++group_idx;

			binding_idx = 1;
		} else {
			// key or axis binding prototype

			// [-2] bindings, [-1] group
			lua_createtable(l, 0, 5);
			// [-3] bindings, [-2] group, [-1] binding

			// fields: type ('KEY' or 'AXIS'), id ('BindIncreaseSpeed'), label ('Increase Speed'), binding ('Key13'), bindingDescription ('')
			lua_pushstring(l, (proto->kb ? "KEY" : "AXIS"));
			lua_setfield(l, -2, "type");
			lua_pushstring(l, proto->function);
			lua_setfield(l, -2, "id");
			lua_pushstring(l, proto->label);
			lua_setfield(l, -2, "label");
			if (proto->kb) {
				const KeyBindings::KeyBinding kb1 = proto->kb->binding1;
				if (kb1.Enabled()) {
					lua_pushstring(l, kb1.ToString().c_str());
					lua_setfield(l, -2, "binding1");
					lua_pushstring(l, kb1.Description().c_str());
					lua_setfield(l, -2, "bindingDescription1");
				}
				const KeyBindings::KeyBinding kb2 = proto->kb->binding2;
				if (kb2.Enabled()) {
					lua_pushstring(l, kb2.ToString().c_str());
					lua_setfield(l, -2, "binding2");
					lua_pushstring(l, kb2.Description().c_str());
					lua_setfield(l, -2, "bindingDescription2");
				}
			} else if (proto->ab) {
				const KeyBindings::AxisBinding &ab = *proto->ab;
				lua_pushstring(l, ab.ToString().c_str());
				lua_setfield(l, -2, "binding1");
				lua_pushstring(l, ab.Description().c_str());
				lua_setfield(l, -2, "bindingDescription1");
			} else {
				assert(0); // invalid prototype binding
			}

			// [-3] bindings, [-2] group, [-1] binding
			lua_rawseti(l, -2, binding_idx);
			++binding_idx;
		}

		LUA_DEBUG_CHECK(l, 2); // [-2] bindings, [-1] group
	}

	// pop the group table (which should already have been put in the bindings table)
	lua_pop(l, 1);

	LUA_DEBUG_END(l, 1);
}
Beispiel #21
0
/*
 * Retrieves metadata.
 */
static int metadata (lua_State *L) {
    mysql_rec *m;
    is_metadata_mode_t metadata_mode;
    const char *metadata_options[] = IS_METADATA_OPTIONS;
    int i;

    m = (mysql_rec *) luaL_checkudata(L, 1, IS_MYSQL_METATABLE);
    metadata_mode = luaL_checkoption(L, 2, metadata_options[0],
                                     metadata_options);
    if (m->res == NULL) {
        lua_pushliteral(L, "no statement to get metadata from");
        lua_error(L);
    }

    lua_createtable(L, m->field_count, 0);
    for (i = 0; i < m->field_count; i++) {
        switch (metadata_mode) {
        case IS_MNAME:
            lua_pushstring(L, m->fields[i].name);
            break;

        case IS_MTYPE:
            switch (m->fields[i].type) {
            case MYSQL_TYPE_TINY:
                lua_pushliteral(L, "TINYINT");
                break;

            case MYSQL_TYPE_SHORT:
                lua_pushliteral(L, "SMALLINT");
                break;

            case MYSQL_TYPE_LONG:
                lua_pushliteral(L, "INTEGER");
                break;

            case MYSQL_TYPE_INT24:
                lua_pushliteral(L, "MEDIUMINT");
                break;

            case MYSQL_TYPE_LONGLONG:
                lua_pushliteral(L, "BIGINT");
                break;

            case MYSQL_TYPE_DECIMAL:
                lua_pushliteral(L, "DECIMAL");
                break;

            case MYSQL_TYPE_NEWDECIMAL:
                lua_pushliteral(L, "DECIMAL");
                break;

            case MYSQL_TYPE_FLOAT:
                lua_pushliteral(L, "FLOAT");
                break;

            case MYSQL_TYPE_DOUBLE:
                lua_pushliteral(L, "DOUBLE");
                break;

            case MYSQL_TYPE_BIT:
                lua_pushliteral(L, "BIT");
                break;

            case MYSQL_TYPE_TIMESTAMP:
                lua_pushliteral(L, "TIMESTAMP");
                break;

            case MYSQL_TYPE_DATE:
                lua_pushliteral(L, "DATE");
                break;

            case MYSQL_TYPE_TIME:
                lua_pushliteral(L, "TIME");
                break;

            case MYSQL_TYPE_DATETIME:
                lua_pushliteral(L, "DATETIME");
                break;

            case MYSQL_TYPE_YEAR:
                lua_pushliteral(L, "YEAR");
                break;

            case MYSQL_TYPE_STRING:
                if (m->fields[i].flags & BINARY_FLAG) {
                    lua_pushliteral(L, "BINARY");
                } else {
                    lua_pushliteral(L, "CHAR");
                }
                break;

            case MYSQL_TYPE_VAR_STRING:
                if (m->fields[i].flags & BINARY_FLAG) {
                    lua_pushliteral(L, "VARBINARY");
                } else {
                    lua_pushliteral(L, "VARCHAR");
                }
                break;

            case MYSQL_TYPE_BLOB:
                if (m->fields[i].flags & BINARY_FLAG) {
                    lua_pushliteral(L, "BLOB");
                } else {
                    lua_pushliteral(L, "TEXT");
                }
                break;

            case MYSQL_TYPE_SET:
                lua_pushliteral(L, "SET");
                break;

            case MYSQL_TYPE_ENUM:
                lua_pushliteral(L, "ENUM");
                break;

            case MYSQL_TYPE_GEOMETRY:
                lua_pushliteral(L, "SPATIAL");
                break;

            case MYSQL_TYPE_NULL:
                lua_pushliteral(L, "NULL");
                break;

            default:
                lua_pushliteral(L, "UNKNOWN");
            }
            break;

        case IS_MLENGTH:
            lua_pushnumber(L, m->fields[i].length);
            break;

        case IS_MSCALE:
            lua_pushnumber(L, m->fields[i].decimals);
            break;

        case IS_MLUATYPE:
            switch (m->fields[i].type) {
            case MYSQL_TYPE_TINY:
            case MYSQL_TYPE_SHORT:
            case MYSQL_TYPE_LONG:
            case MYSQL_TYPE_INT24:
            case MYSQL_TYPE_LONGLONG:
            case MYSQL_TYPE_DECIMAL:
            case MYSQL_TYPE_NEWDECIMAL:
            case MYSQL_TYPE_FLOAT:
            case MYSQL_TYPE_DOUBLE:
                lua_pushliteral(L, "number");
                break;

            case MYSQL_TYPE_BIT:
                if (m->fields[i].length == 1) {
                    lua_pushliteral(L, "boolean");
                } else {
                    lua_pushliteral(L, "number");
                }
                break;

            case MYSQL_TYPE_TIMESTAMP:
            case MYSQL_TYPE_DATE:
            case MYSQL_TYPE_TIME:
            case MYSQL_TYPE_DATETIME:
            case MYSQL_TYPE_YEAR:
            case MYSQL_TYPE_STRING:
            case MYSQL_TYPE_VAR_STRING:
            case MYSQL_TYPE_BLOB:
            case MYSQL_TYPE_SET:
            case MYSQL_TYPE_ENUM:
            case MYSQL_TYPE_GEOMETRY:
                lua_pushliteral(L, "string");
                break;

            default:
                lua_pushliteral(L, "nil");
            }
            break;
        }
        lua_rawseti(L, -2, i + 1);
    }

    return 1;
}
Beispiel #22
0
static int
frootN(lua_State *L, int idx_x)
{
  const gsl_multiroot_fsolver_type *T = NULL;
  gsl_multiroot_fsolver *s = NULL;
  char *name = NULL;
  struct frootN_params params;
  gsl_multiroot_function func;
  int ndim = lua_objlen(L, idx_x);
  int max_iter;
  int logging;
  double rel_err;
  double abs_err;
  gsl_vector *x = NULL;
  int iter;
  int i;
  int status = 1;

  if (ndim < 1)
    luaL_error(L, "Dimension too small in solver");

  switch (luaL_checkint(L, lua_upvalueindex(QS_kind))) {
  case QROOT_dnewton:
    T = gsl_multiroot_fsolver_dnewton;
    name = "dnewton";
    break;
  case QROOT_broyden:
    T = gsl_multiroot_fsolver_broyden;
    name = "broyden";
    break;
  case QROOT_hybrid:
    T = gsl_multiroot_fsolver_hybrid;
    name = "hybrid";
    break;
  case QROOT_hybrids:
    T = gsl_multiroot_fsolver_hybrids;
    name = "hybrids";
    break;
  default:
    luaL_error(L, "internal error: unexpected solver");
    return 0;
  }
  x = new_gsl_vector(L, ndim);
  for (i = 0; i < ndim; i++) {
    double xi;
    lua_pushnumber(L, i + 1);
    lua_gettable(L, idx_x);
    xi = luaL_checknumber(L, -1);
    lua_pop(L, 1);
    gsl_vector_set(x, i, xi);
  }

  max_iter = luaL_optint(L, lua_upvalueindex(QS_max_iter), 100);
  rel_err = luaL_optnumber(L, lua_upvalueindex(QS_rel_err), 0.0);
  abs_err = luaL_optnumber(L, lua_upvalueindex(QS_abs_err), 0.0);
  logging = lua_toboolean(L, lua_upvalueindex(QS_logging));

  params.func = &params;
  params.ndim = ndim;
  params.L = L;
  lua_pushlightuserdata(L, &params);
  lua_pushvalue(L, 1);
  lua_settable(L, LUA_REGISTRYINDEX);
  func.params = &params;
  func.n = ndim;
  func.f = frootN_func;
  
  s = gsl_multiroot_fsolver_alloc (T, ndim);
  if (s == NULL) {
    lua_gc(L, LUA_GCCOLLECT, 0);
    s = gsl_multiroot_fsolver_alloc (T, ndim);
    if (s == NULL)
      luaL_error(L, "not enough memory");
  }
  gsl_multiroot_fsolver_set(s, &func, x);

  lua_pushnil(L);
  lua_createtable(L, 0, logging?4:3);
  lua_pushstring(L, name);
  lua_setfield(L, -2, "Name");
  if (logging) {
    lua_createtable(L, 0, 2); /* Logs */
    lua_createtable(L, max_iter, 0); /* X */
    lua_createtable(L, max_iter, 0); /* f */
  }

  for (iter = 1; iter < max_iter; iter++) {
    if (gsl_multiroot_fsolver_iterate(s) != 0) {
      iter --;
      status = 2;
      break;
    }
    if (logging) {
      lua_createtable(L, ndim, 0); /* x */
      lua_createtable(L, ndim, 0); /* f */
      for (i = 0; i < ndim; i++) {
        lua_pushnumber(L, gsl_vector_get(s->x, i));
        lua_rawseti(L, -3, i+1);
        lua_pushnumber(L, gsl_vector_get(s->f, i));
        lua_rawseti(L, -2, i+1);
      }
      lua_rawseti(L, -3, iter);
      lua_rawseti(L, -3, iter);
    }
    if (gsl_multiroot_test_delta(s->dx, s->x, abs_err, rel_err) == GSL_SUCCESS) {
      status = 0;
      break;
    }
  }

  if (logging) {
    lua_setfield(L, -3, "f");
    lua_setfield(L, -2, "x");
    lua_setfield(L, -2, "Logs");
  }

  lua_pushstring(L, status == 0? "OK": "FAILED");
  lua_setfield(L, -2, "Status");
  lua_pushinteger(L, iter);
  lua_setfield(L, -2, "Iterations");

  lua_createtable(L, ndim, 0);
  for (i = 0; i < ndim; i++) {
    lua_pushnumber(L, gsl_vector_get(s->x, i));
    lua_rawseti(L, -2, i+1);
  }
  lua_replace(L, -3);

  lua_pushlightuserdata(L, &params);
  lua_pushnil(L);
  lua_settable(L, LUA_REGISTRYINDEX);
  gsl_multiroot_fsolver_free(s);
  gsl_vector_free(x);

  return 2;
}
static int
ngx_http_lua_ngx_req_get_headers(lua_State *L)
{
    ngx_list_part_t              *part;
    ngx_table_elt_t              *header;
    ngx_http_request_t           *r;
    ngx_uint_t                    i;
    int                           n;
    int                           max;
    int                           raw = 0;
    int                           count = 0;

    n = lua_gettop(L);

    if (n >= 1) {
        if (lua_isnil(L, 1)) {
            max = NGX_HTTP_LUA_MAX_HEADERS;

        } else {
            max = luaL_checkinteger(L, 1);
        }

        if (n >= 2) {
            raw = lua_toboolean(L, 2);
        }

    } else {
        max = NGX_HTTP_LUA_MAX_HEADERS;
    }

    r = ngx_http_lua_get_req(L);
    if (r == NULL) {
        return luaL_error(L, "no request object found");
    }

    ngx_http_lua_check_fake_request(L, r);

    part = &r->headers_in.headers.part;
    count = part->nelts;
    while (part->next) {
        part = part->next;
        count += part->nelts;
    }

    if (max > 0 && count > max) {
        count = max;
        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                       "lua exceeding request header limit %d", max);
    }

    lua_createtable(L, 0, count);

    if (!raw) {
        lua_pushlightuserdata(L, &ngx_http_lua_headers_metatable_key);
        lua_rawget(L, LUA_REGISTRYINDEX);
        lua_setmetatable(L, -2);
    }

    part = &r->headers_in.headers.part;
    header = part->elts;

    for (i = 0; /* void */; i++) {

        dd("stack top: %d", lua_gettop(L));

        if (i >= part->nelts) {
            if (part->next == NULL) {
                break;
            }

            part = part->next;
            header = part->elts;
            i = 0;
        }

        if (raw) {
            lua_pushlstring(L, (char *) header[i].key.data, header[i].key.len);

        } else {
            lua_pushlstring(L, (char *) header[i].lowcase_key,
                            header[i].key.len);
        }

        /* stack: table key */

        lua_pushlstring(L, (char *) header[i].value.data,
                        header[i].value.len); /* stack: table key value */

        ngx_http_lua_set_multi_value_table(L, -3);

        ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                       "lua request header: \"%V: %V\"",
                       &header[i].key, &header[i].value);

        if (--count == 0) {
            return 1;
        }
    }

    return 1;
}
Beispiel #24
0
static void
_push_array(lua_State *L, pbc_array array, char type, int index) {
	switch (type) {
	case 'I': {
		int v = pbc_array_integer(array, index, NULL);
		lua_pushinteger(L, v);
		break;
	}
	case 'U': {
		uint32_t hi = 0;
		uint32_t low = pbc_array_integer(array, index, &hi);
		uint64_t v = (uint64_t)hi << 32 | (uint64_t)low;
		lua_pushnumber(L, (lua_Number)v);
		break;
	}
	case 'D': {
		uint32_t hi = 0;
		uint32_t low = pbc_array_integer(array, index, &hi);
		uint64_t v = (uint64_t)hi << 32 | (uint64_t)low;
		lua_pushnumber(L, (lua_Number)((int64_t)v));
		break;
	}
	case 'B': {
		int v = pbc_array_integer(array, index, NULL);
		lua_pushboolean(L, v);
		break;
	}
	case 'P': {
		uint32_t v = pbc_array_integer(array, index, NULL);
		lua_pushlightuserdata(L,(void *)(intptr_t)v);
		break;
	}
	case 'X': {
		uint32_t hi = 0;
		uint32_t low = pbc_array_integer(array, index, &hi);
		uint64_t v = (uint64_t)low | (uint64_t)hi << 32;
		lua_pushlstring(L, (char *)&v, 8);
		break;
	}
	case 'R': {
		double v = pbc_array_real(array, index);
		lua_pushnumber(L, v);
		break;
	}
	case 'S': {
		struct pbc_slice * slice = pbc_array_slice(array, index);
		lua_pushlstring(L, (const char *)slice->buffer,slice->len);
		break;
	}
	case 'M': {
		struct pbc_slice * slice = pbc_array_slice(array, index);
		lua_createtable(L,2,0);
		lua_pushlightuserdata(L,slice->buffer);
		lua_rawseti(L,-2,1);
		lua_pushinteger(L,slice->len);
		lua_rawseti(L,-2,2);
		break;
	}
	}
	lua_rawseti(L,-2,index+1);
}
static int
ngx_http_lua_ngx_resp_get_headers(lua_State *L)
{
    ngx_list_part_t    *part;
    ngx_table_elt_t    *header;
    ngx_http_request_t *r;
    u_char             *lowcase_key = NULL;
    size_t              lowcase_key_sz = 0;
    ngx_uint_t          i;
    int                 n;
    int                 max;
    int                 raw = 0;
    int                 count = 0;

    n = lua_gettop(L);

    if (n >= 1) {
        if (lua_isnil(L, 1)) {
            max = NGX_HTTP_LUA_MAX_HEADERS;

        } else {
            max = luaL_checkinteger(L, 1);
        }

        if (n >= 2) {
            raw = lua_toboolean(L, 2);
        }

    } else {
        max = NGX_HTTP_LUA_MAX_HEADERS;
    }

    r = ngx_http_lua_get_req(L);
    if (r == NULL) {
        return luaL_error(L, "no request object found");
    }

    ngx_http_lua_check_fake_request(L, r);

    part = &r->headers_out.headers.part;
    count = part->nelts;
    while (part->next) {
        part = part->next;
        count += part->nelts;
    }

    if (max > 0 && count > max) {
        count = max;
        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                       "lua exceeding request header limit %d", max);
    }

    lua_createtable(L, 0, count);

    if (!raw) {
        lua_pushlightuserdata(L, &ngx_http_lua_headers_metatable_key);
        lua_rawget(L, LUA_REGISTRYINDEX);
        lua_setmetatable(L, -2);
    }

#if 1
    if (r->headers_out.content_type.len) {
        lua_pushliteral(L, "content-type");
        lua_pushlstring(L, (char *) r->headers_out.content_type.data,
                        r->headers_out.content_type.len);
        lua_rawset(L, -3);
    }

    if (r->headers_out.content_length == NULL
        && r->headers_out.content_length_n >= 0)
    {
        lua_pushliteral(L, "content-length");
        lua_pushfstring(L, "%d", (int) r->headers_out.content_length_n);
        lua_rawset(L, -3);
    }

    lua_pushliteral(L, "connection");
    if (r->headers_out.status == NGX_HTTP_SWITCHING_PROTOCOLS) {
        lua_pushliteral(L, "upgrade");

    } else if (r->keepalive) {
        lua_pushliteral(L, "keep-alive");

    } else {
        lua_pushliteral(L, "close");
    }
    lua_rawset(L, -3);

    if (r->chunked) {
        lua_pushliteral(L, "transfer-encoding");
        lua_pushliteral(L, "chunked");
        lua_rawset(L, -3);
    }
#endif

    part = &r->headers_out.headers.part;
    header = part->elts;

    for (i = 0; /* void */; i++) {

        dd("stack top: %d", lua_gettop(L));

        if (i >= part->nelts) {
            if (part->next == NULL) {
                break;
            }

            part = part->next;
            header = part->elts;
            i = 0;
        }

        if (header[i].hash == 0) {
            continue;
        }

        if (raw) {
            lua_pushlstring(L, (char *) header[i].key.data, header[i].key.len);

        } else {
            /* nginx does not even bother initializing output header entry's
             * "lowcase_key" field. so we cannot count on that at all. */
            if (header[i].key.len > lowcase_key_sz) {
                lowcase_key_sz = header[i].key.len * 2;

                /* we allocate via Lua's GC to prevent in-request
                 * leaks in the nginx request memory pools */
                lowcase_key = lua_newuserdata(L, lowcase_key_sz);
                lua_insert(L, 1);
            }

            ngx_strlow(lowcase_key, header[i].key.data, header[i].key.len);
            lua_pushlstring(L, (char *) lowcase_key, header[i].key.len);
        }

        /* stack: [udata] table key */

        lua_pushlstring(L, (char *) header[i].value.data,
                        header[i].value.len); /* stack: [udata] table key
                                                 value */

        ngx_http_lua_set_multi_value_table(L, -3);

        ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                       "lua response header: \"%V: %V\"",
                       &header[i].key, &header[i].value);

        if (--count == 0) {
            return 1;
        }
    }

    return 1;
}
Beispiel #26
0
//////////////////////////////////////////////////////////////////////
// Constructor:
static int ar_write(lua_State *L) {
    struct archive** self_ref;

    static struct {
        const char *name;
        int (*setter)(struct archive *);
    } names[] = {
        /* Copied from archive_write_set_format_by_name.c */
        { "ar",         archive_write_set_format_ar_bsd },
        { "arbsd",      archive_write_set_format_ar_bsd },
        { "argnu",      archive_write_set_format_ar_svr4 },
        { "arsvr4",     archive_write_set_format_ar_svr4 },
        { "cpio",       archive_write_set_format_cpio },
        { "mtree",      archive_write_set_format_mtree },
        { "newc",       archive_write_set_format_cpio_newc },
        { "odc",        archive_write_set_format_cpio },
        { "pax",        archive_write_set_format_pax },
        { "posix",      archive_write_set_format_pax },
        { "shar",       archive_write_set_format_shar },
        { "shardump",   archive_write_set_format_shar_dump },
        { "ustar",      archive_write_set_format_ustar },
        /* New ones to more closely match the C API */
        { "ar_bsd",     archive_write_set_format_ar_bsd },
        { "ar_svr4",    archive_write_set_format_ar_svr4 },
        { "cpio_newc",  archive_write_set_format_cpio_newc },
        { "pax_restricted", archive_write_set_format_pax_restricted },
        { "shar_dump",  archive_write_set_format_shar_dump },
        { NULL,         NULL }
    };
    int idx = 0;
    const char* name;

    luaL_checktype(L, 1, LUA_TTABLE);
    self_ref = (struct archive**)
        lua_newuserdata(L, sizeof(struct archive*)); // {ud}
    luaL_getmetatable(L, AR_WRITE); // {ud}, [write]
    lua_setmetatable(L, -2); // {ud}
    __ref_count++;
    *self_ref = archive_write_new();

    // Register it in the weak metatable:
    ar_registry_set(L, *self_ref);

    // Create an environment to store a reference to the writer:
    lua_createtable(L, 1, 0); // {ud}, {}
    lua_pushliteral(L, "writer"); // {ud}, {}, "writer"
    lua_rawget(L, 1); // {ud}, {}, fn
    if ( ! lua_isfunction(L, -1) ) {
        err("MissingArgument: required parameter 'writer' must be a function");
    }
    lua_setfield(L, -2, "writer");
    lua_setfenv(L, -2); // {ud}

    // Extract various fields and prepare the archive:
    lua_getfield(L, 1, "bytes_per_block");
    if ( ! lua_isnil(L, -1) &&
         ARCHIVE_OK != archive_write_set_bytes_per_block(*self_ref, lua_tointeger(L, -1)) )
    {
        err("archive_write_set_bytes_per_block: %s", archive_error_string(*self_ref));
    }
    lua_pop(L, 1);

    lua_getfield(L, 1, "bytes_in_last_block");
    if ( ! lua_isnil(L, -1) &&
         ARCHIVE_OK != archive_write_set_bytes_in_last_block(*self_ref, lua_tointeger(L, -1)) )
    {
        err("archive_write_set_bytes_in_last_block: %s", archive_error_string(*self_ref));
    }
    lua_pop(L, 1);

    lua_getfield(L, 1, "skip_file");
    if ( ! lua_isnil(L, -1) ) {
        dev_t dev;
        ino_t ino;

        if ( LUA_TTABLE != lua_type(L, -1) ) {
            err("skip_file member must be a table object");
        }

        lua_getfield(L, -1, "dev");
        if ( ! lua_isnumber(L, -1) ) {
            err("skip_file.dev member must be a number");
        }
        dev = (dev_t)lua_tonumber(L, -1);
        lua_pop(L, 1);

        lua_getfield(L, -1, "ino");
        if ( ! lua_isnumber(L, -1) ) {
            err("skip_file.ino member must be a number");
        }
        ino = (ino_t)lua_tonumber(L, -1);
        lua_pop(L, 1);

        if ( ARCHIVE_OK != archive_write_set_skip_file(*self_ref, dev, ino) ) {
            err("archive_write_set_skip_file: %s", archive_error_string(*self_ref));
        }
    }
    lua_pop(L, 1);

    lua_getfield(L, 1, "format");
    if ( lua_isnil(L, -1) ) {
        lua_pop(L, 1);
        lua_pushliteral(L, "posix");
    }
    name = lua_tostring(L, -1);
    for ( ;; idx++ ) {
        if ( names[idx].name == NULL ) {
            err("archive_write_set_format_*: No such format '%s'", name);
        }
        if ( strcmp(name, names[idx].name) == 0 ) break;
    }
    if ( ARCHIVE_OK != (names[idx].setter)(*self_ref) ) {
        err("archive_write_set_format_%s: %s", name, archive_error_string(*self_ref));
    }
    lua_pop(L, 1);

    lua_getfield(L, 1, "compression");
    if ( ! lua_isnil(L, -1) ) {
        static struct {
            const char *name;
            int (*setter)(struct archive *);
        } names[] = {
            { "bzip2",    archive_write_add_filter_bzip2 },
            { "compress", archive_write_add_filter_compress },
            { "gzip",     archive_write_add_filter_gzip },
            { "lzma",     archive_write_add_filter_lzma },
            { "xz",       archive_write_add_filter_xz },
            { NULL,       NULL }
        };
        int idx = 0;
        const char* name = lua_tostring(L, -1);
        for ( ;; idx++ ) {
            if ( names[idx].name == NULL ) {
                err("archive_write_set_compression_*: No such compression '%s'", name);
            }
            if ( strcmp(name, names[idx].name) == 0 ) break;
        }
        if ( ARCHIVE_OK != (names[idx].setter)(*self_ref) ) {
            err("archive_write_set_compression_%s: %s", name, archive_error_string(*self_ref));
        }
    }
    lua_pop(L, 1);

    lua_getfield(L, 1, "options");
    if ( ! lua_isnil(L, -1) &&
         ARCHIVE_OK != archive_write_set_options(*self_ref, lua_tostring(L, -1)) )
    {
        err("archive_write_set_options: %s",  archive_error_string(*self_ref));
    }
    lua_pop(L, 1);


    if ( ARCHIVE_OK != archive_write_open(*self_ref, L, NULL, &ar_write_cb, NULL) ) {
        err("archive_write_open: %s", archive_error_string(*self_ref));
    }

    return 1;
}
Beispiel #27
0
static void mar_encode_value(lua_State *L, mar_Buffer *buf, int val, size_t *idx)
{
    size_t l;
    int val_type = lua_type(L, val);
    if (lua_isinteger(L, val))
        val_type = MAR_TINT;
    lua_pushvalue(L, val);

    buf_write(L, (const char*)&val_type, MAR_CHR, buf);
    switch (val_type) {
    case LUA_TBOOLEAN: {
        int int_val = lua_toboolean(L, -1);
        buf_write(L, (const char*)&int_val, MAR_CHR, buf);
        break;
    }
    case LUA_TSTRING: {
        const char *str_val = lua_tolstring(L, -1, &l);
        buf_write(L, (const char*)&l, MAR_I32, buf);
        buf_write(L, str_val, l, buf);
        break;
    }
    case LUA_TNUMBER: {
        lua_Number num_val = lua_tonumber(L, -1);
        buf_write(L, (const char*)&num_val, MAR_I64, buf);
        break;
    }
    case MAR_TINT: {
        lua_Integer num_val = lua_tointeger(L, -1);
        buf_write(L, (const char*)&num_val, MAR_I64, buf);
        break;
    }
    case LUA_TTABLE: {
        int tag, ref;
        lua_pushvalue(L, -1);
        lua_rawget(L, SEEN_IDX);
        if (!lua_isnil(L, -1)) {
            ref = lua_tointeger(L, -1);
            tag = MAR_TREF;
            buf_write(L, (const char*)&tag, MAR_CHR, buf);
            buf_write(L, (const char*)&ref, MAR_I32, buf);
            lua_pop(L, 1);
        }
        else {
            mar_Buffer rec_buf;
            lua_pop(L, 1); /* pop nil */
            if (luaL_getmetafield(L, -1, "__persist")) {
                tag = MAR_TUSR;

                lua_pushvalue(L, -2); /* self */
                lua_call(L, 1, 1);
                if (!lua_isfunction(L, -1)) {
                    luaL_error(L, "__persist must return a function");
                }

                lua_remove(L, -2); /* __persist */

                lua_newtable(L);
                lua_pushvalue(L, -2); /* callback */
                lua_rawseti(L, -2, 1);

                buf_init(L, &rec_buf);
                mar_encode_table(L, &rec_buf, idx);

                buf_write(L, (const char*)&tag, MAR_CHR, buf);
                buf_write(L, (const char*)&rec_buf.head, MAR_I32, buf);
                buf_write(L, rec_buf.data, rec_buf.head, buf);
                buf_done(L, &rec_buf);
                lua_pop(L, 1);
            }
            else {
                tag = MAR_TVAL;

                lua_pushvalue(L, -1);
                lua_pushinteger(L, (*idx)++);
                lua_rawset(L, SEEN_IDX);

                lua_pushvalue(L, -1);
                buf_init(L, &rec_buf);
                mar_encode_table(L, &rec_buf, idx);
                lua_pop(L, 1);

                buf_write(L, (const char*)&tag, MAR_CHR, buf);
                buf_write(L, (const char*)&rec_buf.head, MAR_I32, buf);
                buf_write(L, rec_buf.data,rec_buf.head, buf);
                buf_done(L, &rec_buf);
            }
        }
        break;
    }
    case LUA_TFUNCTION: {
        int tag, ref;
        lua_pushvalue(L, -1);
        lua_rawget(L, SEEN_IDX);
        if (!lua_isnil(L, -1)) {
            ref = lua_tointeger(L, -1);
            tag = MAR_TREF;
            buf_write(L, (const char*)&tag, MAR_CHR, buf);
            buf_write(L, (const char*)&ref, MAR_I32, buf);
            lua_pop(L, 1);
        }
        else {
            mar_Buffer rec_buf;
            unsigned int i;
            lua_Debug ar;
            lua_pop(L, 1); /* pop nil */

            lua_pushvalue(L, -1);
            lua_getinfo(L, ">nuS", &ar);
            if (ar.what[0] != 'L') {
                luaL_error(L, "attempt to persist a C function '%s'", ar.name);
            }
            tag = MAR_TVAL;
            lua_pushvalue(L, -1);
            lua_pushinteger(L, (*idx)++);
            lua_rawset(L, SEEN_IDX);

            lua_pushvalue(L, -1);
            buf_init(L, &rec_buf);
            lua_dump(L, (lua_Writer)buf_write, &rec_buf, true);

            buf_write(L, (const char*)&tag, MAR_CHR, buf);
            buf_write(L, (const char*)&rec_buf.head, MAR_I32, buf);
            buf_write(L, rec_buf.data, rec_buf.head, buf);
            buf_done(L, &rec_buf);
            lua_pop(L, 1);

            lua_createtable(L, ar.nups, 0);
            for (i = 1; i <= ar.nups; i++) {
                const char* upvalue_name = lua_getupvalue(L, -2, i);
                if (strcmp("_ENV", upvalue_name) == 0) {
                    lua_pop(L, 1);
                    // Mark where _ENV is expected.
                    lua_pushstring(L, MAR_ENV_IDX_KEY);
                    lua_pushinteger(L, i);
                    lua_rawset(L, -3);
                }
                else {
                    lua_rawseti(L, -2, i);
                }
            }
            lua_pushstring(L, MAR_NUPS_IDX_KEY);
            lua_pushnumber(L, ar.nups);
            lua_rawset(L, -3);

            buf_init(L, &rec_buf);
            mar_encode_table(L, &rec_buf, idx);

            buf_write(L, (const char*)&rec_buf.head, MAR_I32, buf);
            buf_write(L, rec_buf.data, rec_buf.head, buf);
            buf_done(L, &rec_buf);
            lua_pop(L, 1);
        }

        break;
    }
    case LUA_TUSERDATA: {
        int tag, ref;
        lua_pushvalue(L, -1);
        lua_rawget(L, SEEN_IDX);
        if (!lua_isnil(L, -1)) {
            ref = lua_tointeger(L, -1);
            tag = MAR_TREF;
            buf_write(L, (const char*)&tag, MAR_CHR, buf);
            buf_write(L, (const char*)&ref, MAR_I32, buf);
            lua_pop(L, 1);
        }
        else {
            mar_Buffer rec_buf;
            lua_pop(L, 1); /* pop nil */
            if (luaL_getmetafield(L, -1, "__persist")) {
                tag = MAR_TUSR;

                lua_pushvalue(L, -2);
                lua_pushinteger(L, (*idx)++);
                lua_rawset(L, SEEN_IDX);

                lua_pushvalue(L, -2);
                lua_call(L, 1, 1);
                if (!lua_isfunction(L, -1)) {
                    luaL_error(L, "__persist must return a function");
                }
                lua_newtable(L);
                lua_pushvalue(L, -2);
                lua_rawseti(L, -2, 1);
                lua_remove(L, -2);

                buf_init(L, &rec_buf);
                mar_encode_table(L, &rec_buf, idx);

                buf_write(L, (const char*)&tag, MAR_CHR, buf);
                buf_write(L, (const char*)&rec_buf.head, MAR_I32, buf);
		        buf_write(L, rec_buf.data, rec_buf.head, buf);
		        buf_done(L, &rec_buf);
            }
            else {
                luaL_error(L, "attempt to encode userdata (no __persist hook)");
            }
            lua_pop(L, 1);
        }
        break;
    }
    case LUA_TNIL: break;
    default:
        luaL_error(L, "invalid value type (%s)", lua_typename(L, val_type));
    }
    lua_pop(L, 1);
}
Beispiel #28
0
	static int step_tolua(lua_State *L)
	{
		SQLiteLuaStmt *ptr = (SQLiteLuaStmt *)checkudata(L, 1, &stmtmetakey, "sqlite.stmt");
		if (ptr->stmt == NULL)
		{
			lua_pushnil(L);
			lua_pushliteral(L, "closed database");
			return 2;
		}
		if (ptr->iseof)
		{
			lua_pushnil(L);
			lua_pushliteral(L, "attempt to step a halted statement");
			return 2;
		}
		int result = sqlite3_step(ptr->stmt);
		if (result == SQLITE_ROW)
		{
			int col = sqlite3_column_count(ptr->stmt);
			lua_createtable(L, col, 0);
			for (int i = 0; i < col; ++i)
			{
				switch (sqlite3_column_type(ptr->stmt, i))
				{
				case SQLITE_INTEGER:
					{
						i64 l = sqlite3_column_int64(ptr->stmt, i);
						if (l > UINT_MAX || l < INT_MIN)
						{
							char bytes[9];
							bytes[0] = 'L';
							for (int i = 1; i < 9; ++i)
							{
								bytes[9 - i] = (char)(l & 0xff);
								l >>= 8;
							}
							lua_pushlstring(L, bytes, 9);
						}
						else
						{
							lua_pushnumber(L, (double)l);
						}
					}
					break;
				case SQLITE_FLOAT:
					{
						double d = sqlite3_column_double(ptr->stmt, i);
						lua_pushnumber(L, d);
					}
					break;
				case SQLITE_TEXT:
					{
						const char *str = (const char *)sqlite3_column_text(ptr->stmt, i);
						if (str == NULL)
						{
							lua_pushnil(L);
						}
						else
						{
							lua_pushstring(L, str);
						}
					}
					break;
				case SQLITE_BLOB:
					{
						const char *blob = (const char *)sqlite3_column_blob(ptr->stmt, i);
						if (blob == NULL)
						{
							lua_pushnil(L);
						}
						else
						{
							int len = sqlite3_column_bytes(ptr->stmt, i);
							lua_pushlstring(L, blob, (size_t)len);
						}
					}
					break;
				default:
					lua_pushnil(L);
				}
void
ngx_http_lua_inject_shdict_api(ngx_http_lua_main_conf_t *lmcf, lua_State *L)
{
    ngx_http_lua_shdict_ctx_t   *ctx;
    ngx_uint_t                   i;
    ngx_shm_zone_t             **zone;

    if (lmcf->shm_zones != NULL) {
        lua_createtable(L, 0, lmcf->shm_zones->nelts /* nrec */);
                /* ngx.shared */

        lua_createtable(L, 0 /* narr */, 13 /* nrec */); /* shared mt */

        lua_pushcfunction(L, ngx_http_lua_shdict_get);
        lua_setfield(L, -2, "get");

        lua_pushcfunction(L, ngx_http_lua_shdict_get_stale);
        lua_setfield(L, -2, "get_stale");

        lua_pushcfunction(L, ngx_http_lua_shdict_set);
        lua_setfield(L, -2, "set");

        lua_pushcfunction(L, ngx_http_lua_shdict_safe_set);
        lua_setfield(L, -2, "safe_set");

        lua_pushcfunction(L, ngx_http_lua_shdict_add);
        lua_setfield(L, -2, "add");

        lua_pushcfunction(L, ngx_http_lua_shdict_safe_add);
        lua_setfield(L, -2, "safe_add");

        lua_pushcfunction(L, ngx_http_lua_shdict_replace);
        lua_setfield(L, -2, "replace");

        lua_pushcfunction(L, ngx_http_lua_shdict_incr);
        lua_setfield(L, -2, "incr");

        lua_pushcfunction(L, ngx_http_lua_shdict_delete);
        lua_setfield(L, -2, "delete");

        lua_pushcfunction(L, ngx_http_lua_shdict_flush_all);
        lua_setfield(L, -2, "flush_all");

        lua_pushcfunction(L, ngx_http_lua_shdict_flush_expired);
        lua_setfield(L, -2, "flush_expired");

        lua_pushcfunction(L, ngx_http_lua_shdict_get_keys);
        lua_setfield(L, -2, "get_keys");

        lua_pushvalue(L, -1); /* shared mt mt */
        lua_setfield(L, -2, "__index"); /* shared mt */

        zone = lmcf->shm_zones->elts;

        for (i = 0; i < lmcf->shm_zones->nelts; i++) {
            ctx = zone[i]->data;

            lua_pushlstring(L, (char *) ctx->name.data, ctx->name.len);
                /* shared mt key */

            lua_pushlightuserdata(L, zone[i]); /* shared mt key ud */
            lua_pushvalue(L, -3); /* shared mt key ud mt */
            lua_setmetatable(L, -2); /* shared mt key ud */
            lua_rawset(L, -4); /* shared mt */
        }

        lua_pop(L, 1); /* shared */

    } else {
        lua_newtable(L);    /* ngx.shared */
    }

    lua_setfield(L, -2, "shared");
}