naev 0.12.5
lvar.c
Go to the documentation of this file.
1/*
2 * See Licensing and Copyright notice in naev.h
3 */
9#include <inttypes.h>
10
11#include "lvar.h"
12
13#include "array.h"
14#include "nlua_time.h"
15#include "nluadef.h"
16
17/*
18 * prototypes
19 */
20static int lvar_cmp( const void *p1, const void *p2 );
21static void lvar_free( lvar *var );
22
26static int lvar_cmp( const void *p1, const void *p2 )
27{
28 const lvar *mv1, *mv2;
29 mv1 = (const lvar *)p1;
30 mv2 = (const lvar *)p2;
31 return strcmp( mv1->name, mv2->name );
32}
33
41lvar *lvar_get( const lvar *arr, const char *str )
42{
43 const lvar mv = { .name = (char *)str };
44 if (arr == NULL)
45 return NULL;
46 return bsearch( &mv, arr, array_size( arr ), sizeof( lvar ), lvar_cmp );
47}
48
56int lvar_push( lua_State *L, const lvar *v )
57{
58 switch (v->type) {
59 case LVAR_NIL:
60 lua_pushnil( L );
61 break;
62 case LVAR_NUM:
63 lua_pushnumber( L, v->d.num );
64 break;
65 case LVAR_BOOL:
66 lua_pushboolean( L, v->d.b );
67 break;
68 case LVAR_STR:
69 lua_pushstring( L, v->d.str );
70 break;
71 case LVAR_TIME:
72 lua_pushtime( L, v->d.time );
73 break;
74 }
75 return 1;
76}
77
86lvar lvar_tovar( lua_State *L, const char *name, int idx )
87{
88 lvar var;
89
90 /* Store appropriate data */
91 if (lua_isnil( L, idx ))
92 var.type = LVAR_NIL;
93 else if (lua_istime( L, idx )) {
94 var.type = LVAR_TIME;
95 var.d.time = luaL_validtime( L, idx );
96 } else if (lua_type( L, idx ) == LUA_TNUMBER) {
97 var.type = LVAR_NUM;
98 var.d.num = (double)lua_tonumber( L, idx );
99 } else if (lua_isboolean( L, idx )) {
100 var.type = LVAR_BOOL;
101 var.d.b = lua_toboolean( L, idx );
102 } else if (lua_type( L, idx ) == LUA_TSTRING) {
103 var.type = LVAR_STR;
104 var.d.str = strdup( lua_tostring( L, idx ) );
105 } else {
106 /* Hack because we don't want to return 0 and can't use
107 * NLUA_INVALID_PARAMETER */
108 DEBUG( "Invalid parameter for %s.", __func__ );
109 luaL_error( L, "Invalid parameter for %s.", __func__ );
110 var.type = LVAR_NIL;
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, const 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 } else if (strcmp( str, "bool" ) == 0) {
261 var.type = LVAR_BOOL;
262 var.d.b = xml_getInt( node );
263 } else if (strcmp( str, "str" ) == 0) {
264 var.type = LVAR_STR;
265 var.d.str = xml_getStrd( node );
266 } else if (strcmp( str, "time" ) == 0) {
267 var.type = LVAR_TIME;
268 var.d.time = xml_getLong( node );
269 } else { /* super error checking */
270 WARN( _( "Unknown var type '%s'" ), str );
271 free( var.name );
272 free( str );
273 continue;
274 }
275 free( str );
276 lvar_addArray( &arr, &var, 0 );
277 } while (xml_nextNode( node ));
278 qsort( arr, array_size( arr ), sizeof( lvar ), lvar_cmp );
279
280 return arr;
281}
Provides macros to work with dynamic arrays.
#define array_free(ptr_array)
Frees memory allocated and sets array to NULL.
Definition array.h:170
#define array_erase(ptr_array, first, last)
Erases elements in interval [first, last).
Definition array.h:148
static ALWAYS_INLINE int array_size(const void *array)
Returns number of elements in the array.
Definition array.h:179
#define array_grow(ptr_array)
Increases the number of elements by one and returns the last element.
Definition array.h:122
#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: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:26
lvar * lvar_get(const lvar *arr, const char *str)
Gets a lua var by name.
Definition lvar.c:41
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:86
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:56
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:123
int lua_istime(lua_State *L, int ind)
Checks to see if ind is a time.
Definition nlua_time.c:138
ntime_t luaL_validtime(lua_State *L, int ind)
Gets a time directly.
Definition nlua_time.c:112
Contains a mission variable.
Definition lvar.h:24
int b
Definition lvar.h:30
lvar_type type
Definition lvar.h:26
union lvar::@023075132313371256041113105176070262233002345356 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