[Add] Log more verbose, and added a variable stack to missions.

This commit is contained in:
Allanis 2013-04-20 14:36:23 +01:00
parent f6b0171562
commit a6bca29fa1
4 changed files with 182 additions and 7 deletions

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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;