naev 0.10.4
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( lvar *arr, const char *str )
40{
41 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 return var;
112 }
113 /* Set name. */
114 var.name = strdup(name);
115 return var;
116}
117
123static void lvar_free( lvar *var )
124{
125 switch (var->type) {
126 case LVAR_STR:
127 free(var->d.str);
128 var->d.str = NULL;
129 break;
130 case LVAR_NIL:
131 case LVAR_NUM:
132 case LVAR_BOOL:
133 case LVAR_TIME:
134 break;
135 }
136 free(var->name);
137 var->name = NULL;
138}
139
146{
147 for (int i=0; i<array_size(arr); i++)
148 lvar_free( &arr[i] );
149 array_free( arr );
150}
151
160int lvar_addArray( lvar **arr, lvar *new_var, int sort )
161{
162 /* Avoid Duplicates. */
163 lvar *mv = lvar_get( *arr, new_var->name );
164 if (mv != NULL) {
165 lvar_free( mv );
166 *mv = *new_var;
167 return 0;
168 }
169
170 /* need new one. */
171 mv = &array_grow( arr );
172 *mv = *new_var;
173
174 /* Sort if necessary. */
175 if (sort)
176 qsort( *arr, array_size(*arr), sizeof(lvar), lvar_cmp );
177
178 return 0;
179}
180
187void lvar_rmArray( lvar **arr, lvar *rm_var )
188{
189 lvar_free( rm_var );
190 array_erase( arr, rm_var, rm_var+1 );
191}
192
200int lvar_save( const lvar *arr, xmlTextWriterPtr writer )
201{
202 for (int i=0; i<array_size(arr); i++) {
203 const lvar *v = &arr[i];
204 xmlw_startElem(writer,"var");
205
206 xmlw_attr(writer,"name","%s",v->name);
207
208 switch (v->type) {
209 case LVAR_NIL:
210 xmlw_attr(writer,"type","nil");
211 break;
212 case LVAR_NUM:
213 xmlw_attr(writer,"type","num");
214 xmlw_str(writer,"%f",v->d.num);
215 break;
216 case LVAR_BOOL:
217 xmlw_attr(writer,"type","bool");
218 xmlw_str(writer,"%d",v->d.b);
219 break;
220 case LVAR_STR:
221 xmlw_attr(writer,"type","str");
222 xmlw_str(writer,"%s",v->d.str);
223 break;
224 case LVAR_TIME:
225 xmlw_attr(writer,"type","time");
226 xmlw_str(writer,"%"TIME_PRI,v->d.time);
227 break;
228 }
229 xmlw_endElem(writer); /* "var" */
230 }
231
232 return 0;
233}
234
241lvar *lvar_load( xmlNodePtr parent )
242{
243 lvar *arr = array_create( lvar );
244 xmlNodePtr node = parent->xmlChildrenNode;
245 do {
246 xml_onlyNodes(node);
247 if (!xml_isNode(node,"var")) {
248 WARN(_("Lua Var stack has unknown node '%s'!"), xml_get(node));
249 continue;
250 }
251 lvar var;
252 char *str;
253 xmlr_attr_strd(node,"name",var.name);
254 xmlr_attr_strd(node,"type",str);
255 if (strcmp(str,"nil")==0)
256 var.type = LVAR_NIL;
257 else if (strcmp(str,"num")==0) {
258 var.type = LVAR_NUM;
259 var.d.num = xml_getFloat(node);
260 }
261 else if (strcmp(str,"bool")==0) {
262 var.type = LVAR_BOOL;
263 var.d.b = xml_getInt(node);
264 }
265 else if (strcmp(str,"str")==0) {
266 var.type = LVAR_STR;
267 var.d.str = xml_getStrd(node);
268 }
269 else if (strcmp(str,"time")==0) {
270 var.type = LVAR_TIME;
271 var.d.time = xml_getLong(node);
272 }
273 else { /* super error checking */
274 WARN(_("Unknown var type '%s'"), str);
275 free(var.name);
276 free(str);
277 continue;
278 }
279 free(str);
280 lvar_addArray( &arr, &var, 0 );
281 } while (xml_nextNode(node));
282 qsort( arr, array_size(arr), sizeof(lvar), lvar_cmp );
283
284 return arr;
285}
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, lvar *new_var, int sort)
Adds a var to a var array.
Definition: lvar.c:160
void lvar_rmArray(lvar **arr, lvar *rm_var)
Removes a var from a var array.
Definition: lvar.c:187
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(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:145
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:200
lvar * lvar_load(xmlNodePtr parent)
Loads the vars from XML file.
Definition: lvar.c:241
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:123
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
ntime_t time
Definition: lvar.h:31
double num
Definition: lvar.h:28
char * str
Definition: lvar.h:29
union lvar::@13 d
char * name
Definition: lvar.h:25