naev 0.11.5
lvar.c
Go to the documentation of this file.
1/*
2 * See Licensing and Copyright notice in naev.h
3 */
9#include "lvar.h"
10
11#include "array.h"
12#include "nluadef.h"
13#include "nlua_time.h"
14
15/*
16 * prototypes
17 */
18static int lvar_cmp( const void *p1, const void *p2 );
19static void lvar_free( lvar *var );
20
24static int lvar_cmp( const void *p1, const void *p2 )
25{
26 const lvar *mv1, *mv2;
27 mv1 = (const lvar*) p1;
28 mv2 = (const lvar*) p2;
29 return strcmp(mv1->name,mv2->name);
30}
31
39lvar *lvar_get( const lvar *arr, const char *str )
40{
41 const lvar mv = {.name=(char*)str};
42 if (arr == NULL)
43 return NULL;
44 return bsearch( &mv, arr, array_size(arr), sizeof(lvar), lvar_cmp );
45}
46
54int lvar_push( lua_State *L, const lvar *v )
55{
56 switch (v->type) {
57 case LVAR_NIL:
58 lua_pushnil(L);
59 break;
60 case LVAR_NUM:
61 lua_pushnumber(L,v->d.num);
62 break;
63 case LVAR_BOOL:
64 lua_pushboolean(L,v->d.b);
65 break;
66 case LVAR_STR:
67 lua_pushstring(L,v->d.str);
68 break;
69 case LVAR_TIME:
70 lua_pushtime(L,v->d.time);
71 break;
72 }
73 return 1;
74}
75
84lvar lvar_tovar( lua_State *L, const char *name, int idx )
85{
86 lvar var;
87
88 /* Store appropriate data */
89 if (lua_isnil(L,idx))
90 var.type = LVAR_NIL;
91 else if (lua_istime(L,idx)) {
92 var.type = LVAR_TIME;
93 var.d.time = luaL_validtime(L,idx);
94 }
95 else if (lua_type(L,idx) == LUA_TNUMBER) {
96 var.type = LVAR_NUM;
97 var.d.num = (double) lua_tonumber(L,idx);
98 }
99 else if (lua_isboolean(L,idx)) {
100 var.type = LVAR_BOOL;
101 var.d.b = lua_toboolean(L,idx);
102 }
103 else if (lua_type(L,idx) == LUA_TSTRING) {
104 var.type = LVAR_STR;
105 var.d.str = strdup( lua_tostring(L,idx) );
106 }
107 else {
108 /* Hack because we don't want to return 0 and can't use NLUA_INVALID_PARAMETER */
109 DEBUG( "Invalid parameter for %s.", __func__ );
110 luaL_error( L, "Invalid parameter for %s.", __func__ );
111 var.type = LVAR_NIL;
112 return var;
113 }
114 /* Set name. */
115 var.name = strdup(name);
116 return var;
117}
118
124static void lvar_free( lvar *var )
125{
126 switch (var->type) {
127 case LVAR_STR:
128 free(var->d.str);
129 var->d.str = NULL;
130 break;
131 case LVAR_NIL:
132 case LVAR_NUM:
133 case LVAR_BOOL:
134 case LVAR_TIME:
135 break;
136 }
137 free(var->name);
138 var->name = NULL;
139}
140
147{
148 for (int i=0; i<array_size(arr); i++)
149 lvar_free( &arr[i] );
150 array_free( arr );
151}
152
161int lvar_addArray( lvar **arr, const lvar *new_var, int sort )
162{
163 /* Avoid Duplicates. */
164 lvar *mv = lvar_get( *arr, new_var->name );
165 if (mv != NULL) {
166 lvar_free( mv );
167 *mv = *new_var;
168 return 0;
169 }
170
171 /* need new one. */
172 mv = &array_grow( arr );
173 *mv = *new_var;
174
175 /* Sort if necessary. */
176 if (sort)
177 qsort( *arr, array_size(*arr), sizeof(lvar), lvar_cmp );
178
179 return 0;
180}
181
188void lvar_rmArray( lvar **arr, lvar *rm_var )
189{
190 lvar_free( rm_var );
191 array_erase( arr, rm_var, rm_var+1 );
192}
193
201int lvar_save( const lvar *arr, xmlTextWriterPtr writer )
202{
203 for (int i=0; i<array_size(arr); i++) {
204 const lvar *v = &arr[i];
205 xmlw_startElem(writer,"var");
206
207 xmlw_attr(writer,"name","%s",v->name);
208
209 switch (v->type) {
210 case LVAR_NIL:
211 xmlw_attr(writer,"type","nil");
212 break;
213 case LVAR_NUM:
214 xmlw_attr(writer,"type","num");
215 xmlw_str(writer,"%f",v->d.num);
216 break;
217 case LVAR_BOOL:
218 xmlw_attr(writer,"type","bool");
219 xmlw_str(writer,"%d",v->d.b);
220 break;
221 case LVAR_STR:
222 xmlw_attr(writer,"type","str");
223 xmlw_str(writer,"%s",v->d.str);
224 break;
225 case LVAR_TIME:
226 xmlw_attr(writer,"type","time");
227 xmlw_str(writer,"%"TIME_PRI,v->d.time);
228 break;
229 }
230 xmlw_endElem(writer); /* "var" */
231 }
232
233 return 0;
234}
235
242lvar *lvar_load( xmlNodePtr parent )
243{
244 lvar *arr = array_create( lvar );
245 xmlNodePtr node = parent->xmlChildrenNode;
246 do {
247 xml_onlyNodes(node);
248 if (!xml_isNode(node,"var")) {
249 WARN(_("Lua Var stack has unknown node '%s'!"), xml_get(node));
250 continue;
251 }
252 lvar var;
253 char *str;
254 xmlr_attr_strd(node,"name",var.name);
255 xmlr_attr_strd(node,"type",str);
256 if (strcmp(str,"nil")==0)
257 var.type = LVAR_NIL;
258 else if (strcmp(str,"num")==0) {
259 var.type = LVAR_NUM;
260 var.d.num = xml_getFloat(node);
261 }
262 else if (strcmp(str,"bool")==0) {
263 var.type = LVAR_BOOL;
264 var.d.b = xml_getInt(node);
265 }
266 else if (strcmp(str,"str")==0) {
267 var.type = LVAR_STR;
268 var.d.str = xml_getStrd(node);
269 }
270 else if (strcmp(str,"time")==0) {
271 var.type = LVAR_TIME;
272 var.d.time = xml_getLong(node);
273 }
274 else { /* super error checking */
275 WARN(_("Unknown var type '%s'"), str);
276 free(var.name);
277 free(str);
278 continue;
279 }
280 free(str);
281 lvar_addArray( &arr, &var, 0 );
282 } while (xml_nextNode(node));
283 qsort( arr, array_size(arr), sizeof(lvar), lvar_cmp );
284
285 return arr;
286}
Provides macros to work with dynamic arrays.
#define array_free(ptr_array)
Frees memory allocated and sets array to NULL.
Definition array.h:158
#define array_erase(ptr_array, first, last)
Erases elements in interval [first, last).
Definition array.h:140
static ALWAYS_INLINE int array_size(const void *array)
Returns number of elements in the array.
Definition array.h:168
#define array_grow(ptr_array)
Increases the number of elements by one and returns the last element.
Definition array.h:119
#define array_create(basic_type)
Creates a new dynamic array of ‘basic_type’.
Definition array.h:93
int lvar_addArray(lvar **arr, const lvar *new_var, int sort)
Adds a var to a var array.
Definition lvar.c:161
void lvar_rmArray(lvar **arr, lvar *rm_var)
Removes a var from a var array.
Definition lvar.c:188
static int lvar_cmp(const void *p1, const void *p2)
Compares two lua variable names. For use with qsort/bsearch.
Definition lvar.c:24
lvar * lvar_get(const lvar *arr, const char *str)
Gets a lua var by name.
Definition lvar.c:39
void lvar_freeArray(lvar *arr)
Frees a variable array.
Definition lvar.c:146
lvar lvar_tovar(lua_State *L, const char *name, int idx)
Gets a lua variable from an index from a lua state.
Definition lvar.c:84
int lvar_save(const lvar *arr, xmlTextWriterPtr writer)
Saves the mission variables.
Definition lvar.c:201
lvar * lvar_load(xmlNodePtr parent)
Loads the vars from XML file.
Definition lvar.c:242
int lvar_push(lua_State *L, const lvar *v)
Pushes a lua var to a lua state.
Definition lvar.c:54
static void lvar_free(lvar *var)
Frees a lua variable.
Definition lvar.c:124
ntime_t * lua_pushtime(lua_State *L, ntime_t time)
Pushes a time on the stack.
Definition nlua_time.c:126
int lua_istime(lua_State *L, int ind)
Checks to see if ind is a time.
Definition nlua_time.c:141
ntime_t luaL_validtime(lua_State *L, int ind)
Gets a time directly.
Definition nlua_time.c:115
Contains a mission variable.
Definition lvar.h:24
int b
Definition lvar.h:30
lvar_type type
Definition lvar.h:26
union lvar::@11 d
ntime_t time
Definition lvar.h:31
double num
Definition lvar.h:28
char * str
Definition lvar.h:29
char * name
Definition lvar.h:25