From a6bca29fa1b693f644058cd694ab6f841d5d1943 Mon Sep 17 00:00:00 2001 From: Allanis Date: Sat, 20 Apr 2013 14:36:23 +0100 Subject: [PATCH] [Add] Log more verbose, and added a variable stack to missions. --- src/log.h | 4 +- src/misn_lua.c | 181 +++++++++++++++++++++++++++++++++++++++++++++++-- src/misn_lua.h | 3 + src/ship.c | 1 + 4 files changed, 182 insertions(+), 7 deletions(-) diff --git a/src/log.h b/src/log.h index 4ab7e7d..d0ebe44 100644 --- a/src/log.h +++ b/src/log.h @@ -3,8 +3,8 @@ #define LOG(str, args...)(fprintf(stdout, str"\n", ## args)) #define WARN(str, args...)(fprintf(stderr, "Warning: "str"\n", ## args)) -#define ERR(str, args...) (fprintf(stderr, "ERROR %s:%d: "str"\n", \ - __FILE__, __LINE__, ## args)) +#define ERR(str, args...) (fprintf(stderr, "ERROR %s:%d: [%s] "str"\n", \ + __FILE__, __LINE__, __func__, ## args)) #ifdef DEBUG # undef DEBUG diff --git a/src/misn_lua.c b/src/misn_lua.c index e61b5f8..1ea012b 100644 --- a/src/misn_lua.c +++ b/src/misn_lua.c @@ -13,10 +13,34 @@ #include "player.h" #include "misn_lua.h" -// FUCK LUA!!! -//#define luaL_register(L,n,l) (luaL_openlib(L, (n),(l), 0)) +#define MISN_DEBUG(str, args...) (fprintf(stdout, "Mission '%s': "str"\n", \ + cur_mission->data->name, ## args)) -#define MIN_ARGS(n) if(lua_gettop(L) < n) return 0 +#define MIN_ARGS(n) { \ + if(lua_gettop(L) < n) \ + MISN_DEBUG("[%s] Too few arguments", __func__); \ + return 0; \ +} + +// Similar to lua vars, but with less variety. +#define MISN_VAR_NIL 0 +#define MISN_VAR_NUM 1 +#define MISN_VAR_BOOL 2 +#define MISN_VAR_STR 3 +typedef struct misn_var_ { + char* name; + char type; + union { + double num; + char* str; + int b; + } d; +} misn_var; + +// Variable stack. +static misn_var* var_stack = NULL; +static int var_nstack = 0; +static int var_mstack = 0; // Current mission. static Mission* cur_mission = NULL; @@ -48,6 +72,17 @@ static const luaL_Reg misn_methods[] = { { 0, 0 } }; +// Var. +static int var_peek(lua_State* L); +static int var_pop(lua_State* L); +static int var_push(lua_State* L); +static const luaL_reg var_methods[] = { + { "peek", var_peek }, + { "pop", var_pop}, + { "push", var_push}, + {0, 0} +}; + // Space. static int space_getPlanet(lua_State* L); static int space_getSystem(lua_State* L); @@ -100,6 +135,7 @@ static const luaL_Reg hook_methods[] = { int misn_loadLibs(lua_State* L) { luaL_register(L, "lephisto", lephisto_methods); luaL_register(L, "misn", misn_methods); + luaL_register(L, "var", var_methods); luaL_register(L, "space", space_methods); luaL_register(L, "player", player_methods); luaL_register(L, "rnd", rnd_methods); @@ -222,8 +258,7 @@ static int misn_finish(lua_State* L) { if(lua_isboolean(L, -1)) b = lua_toboolean(L, -1); else { - DEBUG("Mission '%s' trying to finish without specifying if mission is complete", - cur_mission->data->name); + MISN_DEBUG("Trying to finish without specifyint if mission is complete."); return 0; } misn_delete = 1; @@ -237,6 +272,142 @@ static int misn_finish(lua_State* L) { return 0; } +// -- Var. -- + +// Check if a variable exists. +int var_checkflag(char* str) { + int i; + for(i = 0; i < var_nstack; i++) + if(strcmp(var_stack[i].name, str)==0) + return 1; + return 0; +} + +static int var_peek(lua_State* L) { + MIN_ARGS(1); + int i; + char* str; + + if(lua_isstring(L, -1)) str = (char*) lua_tostring(L, -1); + else { + MISN_DEBUG("Trying to peek a var with non-string name"); + return 0; + } + + for(i = 0; i < var_nstack; i++) + if(strcmp(str, var_stack[i].name)==0) { + switch(var_stack[i].type) { + case MISN_VAR_NIL: + lua_pushnil(L); + break; + case MISN_VAR_NUM: + lua_pushnumber(L, var_stack[i].d.num); + break; + case MISN_VAR_BOOL: + lua_pushboolean(L, var_stack[i].d.b); + break; + case MISN_VAR_STR: + lua_pushstring(L, var_stack[i].d.str); + break; + } + return 1; + } + lua_pushnil(L); + return 1; +} + +static int var_pop(lua_State* L) { + MIN_ARGS(1); + int i; + char* str; + + if(lua_isstring(L, -1)) str = (char*) lua_tostring(L, -1); + else { + MISN_DEBUG("Trying to pop a var with non-string name"); + return 0; + } + + for(i = 0; i < var_nstack; i++) + if(strcmp(str, var_stack[i].name)==0) { + switch(var_stack[i].type) { + case MISN_VAR_STR: + if(var_stack[i].d.str != NULL) { + free(var_stack[i].d.str); + var_stack[i].d.str = NULL; + } + break; + case MISN_VAR_NIL: + case MISN_VAR_NUM: + case MISN_VAR_BOOL: + break; + } + memmove(&var_stack[i], &var_stack[i+1], sizeof(misn_var)*(var_nstack-i-1)); + var_stack--; + return 0; + } + MISN_DEBUG("Var '%s' not found in stack", str); + return 0; +} + +static int var_push(lua_State* L) { + MIN_ARGS(2); + int i; + char* str; + misn_var* var; + + if(lua_isstring(L, -2)) str = (char*) lua_tostring(L, -2); + else { + MISN_DEBUG("Trying to push a var with non-string name"); + return 0; + } + + if(var_nstack+1 > var_mstack) { + // More memory. + var_mstack += 10; + var_stack = realloc(var_stack, var_mstack*sizeof(misn_var)); + } + + // Check if already exists. + var = NULL; + for(i = 0; i < var_nstack; i++) + if(strcmp(str, var_stack[i].name)==0) + var = &var_stack[i]; + + if(var == NULL) + var = &var_stack[var_nstack]; + else if((var->type == MISN_VAR_STR) && (var->d.str != NULL)) { + // Must free. + free(var->d.str); + var->d.str = NULL; + } + + // Store appropriate data. + if(lua_isnil(L, -1)) + var->type = MISN_VAR_NIL; + else if(lua_isnumber(L, -1)) { + var->type = MISN_VAR_NUM; + var->d.num = (double)lua_tonumber(L, -1); + } + else if(lua_isboolean(L, -1)) { + var->type = MISN_VAR_BOOL; + var->d.b = lua_toboolean(L, -1); + } + else if(lua_isstring(L, -1)) { + var->type = MISN_VAR_STR; + var->d.str = strdup((char*)lua_tostring(L, -1)); + } else { + MISN_DEBUG("Trying to push a var of invalid data type to stack"); + return 0; + } + + if(i >= var_nstack) { + // Var is new. + var->name = strdup(str); + var_nstack++; + } + return 0; +} + static int space_getPlanet(lua_State* L) { int i; int *factions; diff --git a/src/misn_lua.h b/src/misn_lua.h index 5b98897..812aa52 100644 --- a/src/misn_lua.h +++ b/src/misn_lua.h @@ -2,6 +2,9 @@ #include "lua.h" +// Check if a flag exists on the variable stack. +int var_checkflag(char* str); + // Load the libraries for a lua state. int misn_loadLibs(lua_State* L); diff --git a/src/ship.c b/src/ship.c index 6f668cc..c90760f 100644 --- a/src/ship.c +++ b/src/ship.c @@ -260,6 +260,7 @@ void ships_free(void) { if((ship_stack+i)->description) free(ship_stack[i].description); if((ship_stack+i)->gui) free(ship_stack[i].gui); if((ship_stack+i)->fabricator) free(ship_stack[i].fabricator); + so = (ship_stack+i)->outfit; while(so) { // free the ship outfit. sot = so;