naev 0.11.5
nlua.c
Go to the documentation of this file.
1/*
2 * See Licensing and Copyright notice in naev.h
3 */
11#include "physfs.h"
12
13#include "naev.h"
16#include "nlua.h"
17
18#include "log.h"
19#include "conf.h"
20#include "debug.h"
21#include "lua_enet.h"
22#include "lutf8lib.h"
23#include "ndata.h"
24#include "nfile.h"
25#include "nlua_cli.h"
26#include "nlua_audio.h"
27#include "nlua_commodity.h"
28#include "nlua_data.h"
29#include "nlua_diff.h"
30#include "nlua_faction.h"
31#include "nlua_file.h"
32#include "nlua_jump.h"
33#include "nlua_linopt.h"
34#include "nlua_naev.h"
35#include "nlua_news.h"
36#include "nlua_outfit.h"
37#include "nlua_pilot.h"
38#include "nlua_spob.h"
39#include "nlua_player.h"
40#include "nlua_rnd.h"
41#include "nlua_safelanes.h"
42#include "nlua_spfx.h"
43#include "nlua_shiplog.h"
44#include "nlua_system.h"
45#include "nlua_time.h"
46#include "nlua_var.h"
47#include "nlua_vec2.h"
48#include "nluadef.h"
49#include "nstring.h"
50
51lua_State *naevL = NULL;
52nlua_env __NLUA_CURENV = LUA_NOREF;
53static char *common_script;
54static size_t common_sz;
55static int nlua_envs = LUA_NOREF;
56
57/*
58 * prototypes
59 */
60static int nlua_package_loader_lua( lua_State* L );
61static int nlua_package_loader_c( lua_State* L );
62static int nlua_package_loader_croot( lua_State* L );
63static int nlua_require( lua_State* L );
64static lua_State *nlua_newState (void); /* creates a new state */
65static int nlua_loadBasic( lua_State* L );
66static int luaB_loadstring( lua_State *L );
67/* gettext */
68static int nlua_gettext( lua_State *L );
69static int nlua_ngettext( lua_State *L );
70static int nlua_pgettext( lua_State *L );
71static int nlua_gettext_noop( lua_State *L );
72static const luaL_Reg gettext_methods[] = {
73 { "gettext", nlua_gettext },
74 { "ngettext", nlua_ngettext },
75 { "pgettext", nlua_pgettext },
76 { "gettext_noop", nlua_gettext_noop },
77 {0,0}
78};
88static int nlua_gettext( lua_State *L )
89{
90 const char *str = luaL_checkstring(L, 1);
91 lua_pushstring(L, _(str) );
92 return 1;
93}
94
105static int nlua_ngettext( lua_State *L )
106{
107 const char *stra = luaL_checkstring(L, 1);
108 const char *strb = luaL_checkstring(L, 2);
109 int n = luaL_checkinteger(L,3);
110 lua_pushstring(L, n_( stra, strb, n ) );
111 return 1;
112}
113
123static int nlua_pgettext( lua_State *L )
124{
125 const char *msgctxt = luaL_checkstring(L, 1);
126 const char *msgid = luaL_checkstring(L, 2);
127 lua_pushstring(L, pgettext_var( msgctxt, msgid ) );
128 return 1;
129}
130
139static int nlua_gettext_noop( lua_State *L )
140{
141 const char *str = luaL_checkstring(L, 1);
142 lua_pushstring(L, str );
143 return 1;
144}
145
147static int nlua_log2( lua_State *L )
148{
149 double n = luaL_checknumber(L,1);
150 lua_pushnumber(L, log2(n));
151 return 1;
152}
153
157static int nlua_os_getenv( lua_State *L )
158{
159 const char *var = luaL_checkstring(L, 1);
160 if (strcmp(var, "HOME"))
161 return 0;
162 lua_pushstring(L, "lua_home");
163 return 1;
164}
165
171static int nlua_panic( lua_State *L )
172{
173 ERR( _("LUA PANIC: %s"), lua_tostring(L,-1) );
174 return 0;
175}
176
177/*
178 * @brief Initializes the global Lua state.
179 */
180void lua_init (void)
181{
182 naevL = nlua_newState();
183 nlua_loadBasic(naevL);
184
185 /* Environment table. */
186 lua_newtable( naevL );
187 nlua_envs = luaL_ref(naevL, LUA_REGISTRYINDEX);
188
189 /* Better clean up. */
190 lua_atpanic( naevL, nlua_panic );
191}
192
196static int luaB_loadstring( lua_State *L )
197{
198 size_t l;
199 const char *s = luaL_checklstring(L, 1, &l);
200 const char *chunkname = luaL_optstring(L, 2, s);
201 int status = luaL_loadbuffer(L, s, l, chunkname);
202 if (status == 0) /* OK? */
203 return 1;
204 else {
205 lua_pushnil(L);
206 lua_insert(L, -2); /* put before error message */
207 return 2; /* return nil plus error message */
208 }
209}
210
211/*
212 * @brief Closes the global Lua state.
213 */
214void lua_exit (void)
215{
216 free( common_script );
217 lua_close(naevL);
218 naevL = NULL;
219}
220
221/*
222 * @brief Run code from buffer in Lua environment.
223 *
224 * @param env Lua environment.
225 * @param buff Pointer to buffer.
226 * @param sz Size of buffer.
227 * @param name Name to use in error messages.
228 * @return 0 on success.
229 */
230int nlua_dobufenv( nlua_env env,
231 const char *buff,
232 size_t sz,
233 const char *name )
234{
235 int ret;
236#if DEBUGGING
237 /* We don't really want to do this, but Lua seems to trigger all sorts of
238 * FPE exceptions on a daily basis.
239 * TODO get rid of if possible. */
240 if (conf.fpu_except)
241 debug_disableFPUExcept();
242#endif /* DEBUGGING */
243 ret = luaL_loadbuffer(naevL, buff, sz, name);
244 if (ret != 0)
245 return ret;
246#if DEBUGGING
247 if (conf.fpu_except)
248 debug_enableFPUExcept();
249#endif /* DEBUGGING */
250
251 nlua_pushenv(naevL, env);
252 lua_setfenv(naevL, -2);
253 ret = nlua_pcall(env, 0, LUA_MULTRET);
254 if (ret != 0)
255 return ret;
256#if DEBUGGING
257 lua_pushstring( naevL, name );
258 nlua_setenv( naevL, env, "__name" );
259#endif /* DEBUGGING */
260 return 0;
261}
262
263/*
264 * @brief Run code a file in Lua environment.
265 *
266 * @param env Lua environment.
267 * @param filename Filename of Lua script.
268 */
269int nlua_dofileenv( nlua_env env, const char *filename )
270{
271 if (luaL_loadfile(naevL, filename) != 0)
272 return -1;
273 nlua_pushenv(naevL, env);
274 lua_setfenv(naevL, -2);
275 if (nlua_pcall(env, 0, LUA_MULTRET) != 0)
276 return -1;
277 return 0;
278}
279
280/*
281 * @brief Run code from chunk in Lua environment.
282 *
283 * @param env Lua environment.
284 * @param chunk Chunk to run.
285 * @return 0 on success.
286 */
287int nlua_dochunkenv( nlua_env env, int chunk, const char *name )
288{
289 (void) name;
290 int ret;
291 lua_rawgeti( naevL, LUA_REGISTRYINDEX, chunk );
292 nlua_pushenv(naevL, env);
293 lua_setfenv(naevL, -2);
294 ret = nlua_pcall( env, 0, LUA_MULTRET );
295 if (ret != 0)
296 return ret;
297#if DEBUGGING
298 lua_pushstring( naevL, name );
299 nlua_setenv( naevL, env, "__name" );
300#endif /* DEBUGGING */
301 return 0;
302}
303
304#if DEBUGGING
305void nlua_pushEnvTable( lua_State *L )
306{
307 lua_rawgeti( L, LUA_REGISTRYINDEX, nlua_envs );
308}
309#endif /* DEBBUGING */
310
311/*
312 * @brief Create an new environment in global Lua state.
313 *
314 * An "environment" is a table used with setfenv for sandboxing.
315 */
316nlua_env nlua_newEnv (void)
317{
318 nlua_env ref;
319 lua_newtable(naevL); /* t */
320 lua_pushvalue(naevL, -1); /* t, t */
321 ref = luaL_ref(naevL, LUA_REGISTRYINDEX); /* t */
322
323 /* Store in the environment table. */
324 lua_rawgeti(naevL, LUA_REGISTRYINDEX, nlua_envs); /* t, e */
325 lua_pushvalue(naevL, -2); /* t, e, t */
326 lua_pushinteger(naevL, ref); /* t, e, t, r */
327 lua_rawset(naevL, -3); /* t, e */
328 lua_pop(naevL,1); /* t */
329
330 /* Metatable */
331 lua_newtable(naevL); /* t, m */
332 lua_pushvalue(naevL, LUA_GLOBALSINDEX); /* t, m, g */
333 lua_setfield(naevL, -2, "__index"); /* t, m */
334 lua_setmetatable(naevL, -2); /* t */
335
336 /* Replace require() function with one that considers fenv */
337 lua_pushvalue(naevL, -1); /* t, t, */
338 lua_pushcclosure(naevL, nlua_require, 1); /* t, t, c */
339 lua_setfield(naevL, -2, "require"); /* t, t */
340
341 /* Set up paths.
342 * "package.path" to look in the data.
343 * "package.cpath" unset */
344 lua_getglobal(naevL, "package"); /* t, t, p */
345 lua_pushstring(naevL, "?.lua;"LUA_INCLUDE_PATH"?.lua"); /* t, t, p, s */
346 lua_setfield(naevL, -2, "path"); /* t, t, p */
347 lua_pushstring(naevL, ""); /* t, t, p, s */
348 lua_setfield(naevL, -2, "cpath"); /* t, t, p */
349 lua_getfield(naevL, -1, "loaders"); /* t, t, p, l */
350 lua_pushcfunction(naevL, nlua_package_loader_lua); /* t, t, p, l, f */
351 lua_rawseti(naevL, -2, 2); /* t, t, p, l */
352 lua_pushcfunction(naevL, nlua_package_loader_c); /* t, t, p, l, f */
353 lua_rawseti(naevL, -2, 3); /* t, t, p, l */
354 lua_pushcfunction(naevL, nlua_package_loader_croot); /* t, t, p, l, f */
355 lua_rawseti(naevL, -2, 4); /* t, t, p, l */
356 lua_pop(naevL, 2); /* t, t */
357
358 /* The global table _G should refer back to the environment. */
359 lua_pushvalue(naevL, -1); /* t, t, t */
360 lua_setfield(naevL, -2, "_G"); /* t, t */
361
362 /* Push if naev is built with debugging. */
363#if DEBUGGING
364 lua_pushboolean(naevL, 1); /* t, t, b */
365 lua_setfield(naevL, -2, "__debugging"); /* t, t, */
366#endif /* DEBUGGING */
367
368 /* Set up naev namespace. */
369 lua_newtable(naevL); /* t, t, n */
370 lua_setfield(naevL, -2, "naev"); /* t, t */
371
372 /* Run common script. */
373 if (conf.loaded && common_script==NULL) {
374 common_script = ndata_read( LUA_COMMON_PATH, &common_sz );
375 if (common_script==NULL)
376 WARN(_("Unable to load common script '%s'!"), LUA_COMMON_PATH);
377 }
378 if (common_script != NULL) {
379 if (luaL_loadbuffer(naevL, common_script, common_sz, LUA_COMMON_PATH) == 0) {
380 if (nlua_pcall( ref, 0, 0 ) != 0) {
381 WARN(_("Failed to run '%s':\n%s"), LUA_COMMON_PATH, lua_tostring(naevL,-1));
382 lua_pop(naevL, 1);
383 }
384 }
385 else {
386 WARN(_("Failed to load '%s':\n%s"), LUA_COMMON_PATH, lua_tostring(naevL,-1));
387 lua_pop(naevL, 1);
388 }
389 }
390
391 lua_pop(naevL, 1); /* t */
392 return ref;
393}
394
395/*
396 * @brief Frees an environment created with nlua_newEnv()
397 *
398 * @param env Enviornment to free.
399 */
400void nlua_freeEnv( nlua_env env )
401{
402 if (naevL==NULL)
403 return;
404 if (env == LUA_NOREF)
405 return;
406
407 /* Remove from the environment table. */
408 lua_rawgeti(naevL, LUA_REGISTRYINDEX, nlua_envs);
409 lua_rawgeti(naevL, LUA_REGISTRYINDEX, env);
410 lua_pushnil(naevL);
411 lua_rawset(naevL, -3);
412 lua_pop(naevL,1);
413
414 /* Unref. */
415 luaL_unref(naevL, LUA_REGISTRYINDEX, env);
416}
417
418/*
419 * @brief Push environment table to stack
420 *
421 * @param env Environment.
422 */
423void nlua_pushenv( lua_State* L, nlua_env env )
424{
425 lua_rawgeti(L, LUA_REGISTRYINDEX, env);
426}
427
428/*
429 * @brief Gets variable from enviornment and pushes it to stack
430 *
431 * This is meant to replace lua_getglobal()
432 *
433 * @param env Environment.
434 * @param name Name of variable.
435 */
436void nlua_getenv( lua_State* L, nlua_env env, const char *name )
437{
438 nlua_pushenv(L, env); /* env */
439 lua_getfield(L, -1, name); /* env, value */
440 lua_remove(L, -2); /* value */
441}
442
443/*
444 * @brief Pops a value from the stack and sets it in the environment.
445 *
446 * This is meant to replace lua_setglobal()
447 *
448 * @param env Environment.
449 * @param name Name of variable.
450 */
451void nlua_setenv( lua_State* L, nlua_env env, const char *name )
452{
453 /* value */
454 nlua_pushenv(L, env); /* value, env */
455 lua_insert(L, -2); /* env, value */
456 lua_setfield(L, -2, name); /* env */
457 lua_pop(L, 1); /* */
458}
459
460/*
461 * @brief Registers C functions as lua library in environment
462 *
463 * This is meant to replace luaL_register()
464 *
465 * @param env Environment.
466 * @param libname Name of library table.
467 * @param l Array of functions to register.
468 * @param metatable Library will be used as metatable (so register __index).
469 */
470void nlua_register( nlua_env env, const char *libname,
471 const luaL_Reg *l, int metatable )
472{
473 if (luaL_newmetatable(naevL, libname)) {
474 if (metatable) {
475 lua_pushvalue(naevL,-1);
476 lua_setfield(naevL,-2,"__index");
477 }
478 luaL_register(naevL, NULL, l);
479 } /* lib */
480 nlua_getenv(naevL, env, "naev"); /* lib, naev */
481 lua_pushvalue(naevL, -2); /* lib, naev, lib */
482 lua_setfield(naevL, -2, libname);/* lib, naev */
483 lua_pop(naevL, 1); /* lib */
484 nlua_setenv(naevL, env, libname);/* */
485}
486
492static lua_State *nlua_newState (void)
493{
494 /* Try to create the new state */
495 lua_State *L = luaL_newstate();
496 if (L == NULL) {
497 WARN(_("Failed to create new Lua state."));
498 return NULL;
499 }
500 return L;
501}
502
509static int nlua_loadBasic( lua_State* L )
510{
511 const char *override[] = { /* unsafe functions */
512 /*"collectgarbage",*/
513 "dofile",
514 "getfenv",
515 "load",
516 "loadfile",
517 NULL
518 };
519
520 luaL_openlibs(L);
521
522 /* move [un]pack to table.[un]pack as in Lua5.2 */
523 lua_getglobal(L, "table"); /* t */
524 lua_getglobal(L, "unpack"); /* t, u */
525 lua_setfield(L,-2,"unpack"); /* t */
526 lua_pop(L,1); /* */
527 lua_pushnil(L); /* nil */
528 lua_setglobal(L, "unpack"); /* */
529
530 /* replace non-safe functions */
531 for (int i=0; override[i]!=NULL; i++) {
532 lua_pushnil(L);
533 lua_setglobal(L, override[i]);
534 }
535
536 /* Override built-ins to use Naev for I/O. */
537 lua_register(L, "loadstring", luaB_loadstring);
538 lua_register(L, "print", cli_print);
539 lua_register(L, "printRaw", cli_printRaw);
540 lua_register(L, "warn", cli_warn);
541
542 /* Gettext functionality. */
543 lua_register(L, "_", nlua_gettext);
544 lua_register(L, "N_", nlua_gettext_noop);
545 lua_register(L, "n_", nlua_ngettext);
546 lua_register(L, "p_", nlua_pgettext);
547 luaL_register(L, "gettext", gettext_methods);
548
549 /* Sandbox "io" and "os". */
550 lua_newtable(L); /* io table */
551 lua_setglobal(L,"io");
552 lua_newtable(L); /* os table */
553 lua_pushcfunction(L, nlua_os_getenv);
554 lua_setfield(L,-2,"getenv");
555 lua_setglobal(L,"os");
556
557 /* Special math functions function. */
558 lua_getglobal(L,"math");
559 lua_pushcfunction(L, nlua_log2);
560 lua_setfield(L,-2,"log2");
561 lua_pushnil(L);
562 lua_setfield(L,-2,"mod"); /* Get rid of math.mod */
563 lua_pop(L,1);
564
565 return 0;
566}
567
574static int nlua_package_loader_lua( lua_State* L )
575{
576 size_t bufsize, l = 0;
577 char *buf = NULL;
578 char path_filename[PATH_MAX], tmpname[PATH_MAX], tried_paths[STRMAX];
579 const char *packagepath, *start, *end;
580 const char *name = luaL_checkstring(L,1);
581 int done = 0;
582
583 /* Get paths to check. */
584 lua_getglobal(L, "package");
585 if (!lua_istable(L,-1)) {
586 lua_pop(L,1);
587 lua_pushstring(L, _(" package.path not found."));
588 return 1;
589 }
590 lua_getfield(L, -1, "path");
591 if (!lua_isstring(L,-1)) {
592 lua_pop(L,2);
593 lua_pushstring(L, _(" package.path not found."));
594 return 1;
595 }
596 packagepath = lua_tostring(L,-1);
597 lua_pop(L,2);
598
599 /* Parse path. */
600 start = packagepath;
601 while (!done) {
602 char *q;
603 end = strchr( start, ';' );
604 if (end == NULL) {
605 done = 1;
606 end = &start[ strlen(start) ];
607 }
608 strncpy( tmpname, start, end-start );
609 tmpname[ end-start ] = '\0';
610 q = strchr( tmpname, '?' );
611 if (q==NULL) {
612 snprintf( path_filename, sizeof(path_filename), "%s%s", tmpname, name );
613 }
614 else {
615 *q = '\0';
616 snprintf( path_filename, sizeof(path_filename), "%s%s%s", tmpname, name, q+1 );
617 }
618 start = end+1;
619
620 /* Replace all '.' before the last '.' with '/' as they are a security risk. */
621 q = strrchr( path_filename, '.' );
622 for (int i=0; i < q-path_filename; i++)
623 if (path_filename[i]=='.')
624 path_filename[i] = '/';
625
626 /* Try to load the file. */
627 if (PHYSFS_exists( path_filename )) {
628 buf = ndata_read( path_filename, &bufsize );
629 if (buf != NULL)
630 break;
631 }
632
633 /* Didn't get to load it. */
634 l += scnprintf( &tried_paths[l], sizeof(tried_paths)-l, _("\n no ndata path '%s'"), path_filename );
635 }
636
637 /* Must have buf by now. */
638 if (buf == NULL) {
639 lua_pushstring(L, tried_paths);
640 return 1;
641 }
642
643 /* Try to process the Lua. It will leave a function or message on the stack, as required. */
644 luaL_loadbuffer(L, buf, bufsize, path_filename);
645 free(buf);
646 return 1;
647}
648
655static int nlua_package_loader_c( lua_State* L )
656{
657 const char *name = luaL_checkstring(L,1);
658 /* Hardcoded libraries only: we DO NOT honor package.cpath. */
659 if (strcmp( name, "utf8" ) == 0)
660 lua_pushcfunction( L, luaopen_utf8 );
661 else if (strcmp( name, "enet" ) == 0 && conf.lua_enet)
662 lua_pushcfunction( L, luaopen_enet );
663 else
664 lua_pushnil( L );
665 return 1;
666}
667
674static int nlua_package_loader_croot( lua_State* L )
675{
676 lua_pushnil( L );
677 return 1;
678}
679
688static int nlua_require( lua_State* L )
689{
690 const char *filename = luaL_checkstring(L,1);
691
692 /* Environment table to load module into */
693 int envtab = lua_upvalueindex(1);
694
695 /* Check to see if already included. */
696 lua_getfield( L, envtab, NLUA_LOAD_TABLE ); /* t */
697 if (!lua_isnil(L,-1)) {
698 lua_getfield(L,-1,filename); /* t, f */
699 /* Already included. */
700 if (!lua_isnil(L,-1)) {
701 lua_remove(L, -2); /* val */
702 return 1;
703 }
704 lua_pop(L,2); /* */
705 }
706 /* Must create new NLUA_LOAD_TABLE table. */
707 else {
708 lua_newtable(L); /* t */
709 lua_setfield(L, envtab, NLUA_LOAD_TABLE); /* */
710 }
711
712 lua_getglobal(L, "package");
713 if (!lua_istable(L,-1)) {
714 lua_pop(L,1);
715 lua_pushstring(L, _("package.loaders must be a table"));
716 return 1;
717 }
718 lua_getfield(L, -1, "loaders");
719 lua_remove(L, -2);
720 if (!lua_istable(L, -1))
721 luaL_error(L, _("package.loaders must be a table"));
722 lua_pushliteral(L, ""); /* error message accumulator */
723 for (int i=1; ; i++) {
724 lua_rawgeti(L, -2, i); /* get a loader */
725 if (lua_isnil(L, -1))
726 luaL_error(L, _("module '%s' not found:%s"), filename, lua_tostring(L, -2));
727 lua_pushstring(L, filename);
728 lua_call(L, 1, 1); /* call it */
729 if (lua_isfunction(L, -1)) /* did it find module? */
730 break; /* module loaded successfully */
731 else if (lua_isstring(L, -1)) /* loader returned error message? */
732 lua_concat(L, 2); /* accumulate it */
733 else
734 lua_pop(L, 1);
735 }
736 lua_remove(L, -2);
737 lua_remove(L, -2);
738
739 lua_pushvalue(L, envtab);
740 lua_setfenv(L, -2);
741
742 /* run the buffer */
743 lua_pushstring(L, filename); /* pass name as first parameter */
744#if 0
745 if (lua_pcall(L, 1, 1, 0) != 0) {
746 /* will push the current error from the dobuffer */
747 lua_error(L);
748 return 1;
749 }
750#endif
751 lua_call(L, 1, 1);
752
753 /* Mark as loaded. */
754 /* val */
755 if (lua_isnil(L,-1)) {
756 lua_pop(L, 1);
757 lua_pushboolean(L, 1);
758 }
759 lua_getfield(L, envtab, NLUA_LOAD_TABLE); /* val, t */
760 lua_pushvalue(L, -2); /* val, t, val */
761 lua_setfield(L, -2, filename); /* val, t */
762 lua_pop(L, 1); /* val */
763
764 /* cleanup, success */
765 return 1;
766}
767
798int nlua_loadStandard( nlua_env env )
799{
800 int r = 0;
801 r |= nlua_loadNaev(env);
802 r |= nlua_loadVar(env);
803 r |= nlua_loadSpob(env);
804 r |= nlua_loadSystem(env);
805 r |= nlua_loadJump(env);
806 r |= nlua_loadTime(env);
807 r |= nlua_loadPlayer(env);
808 r |= nlua_loadPilot(env);
809 r |= nlua_loadRnd(env);
810 r |= nlua_loadDiff(env);
811 r |= nlua_loadFaction(env);
812 r |= nlua_loadVector(env);
813 r |= nlua_loadOutfit(env);
814 r |= nlua_loadCommodity(env);
815 r |= nlua_loadNews(env);
816 r |= nlua_loadShiplog(env);
817 r |= nlua_loadFile(env);
818 r |= nlua_loadData(env);
819 r |= nlua_loadLinOpt(env);
820 r |= nlua_loadSafelanes(env);
821 r |= nlua_loadSpfx(env);
822 r |= nlua_loadAudio(env);
823
824 return r;
825}
826
830int nlua_errTrace( lua_State *L )
831{
832 /* Handle special done case. */
833 const char *str = luaL_checkstring(L,1);
834 if (strcmp(str,NLUA_DONE)==0)
835 return 1;
836
837 /* Otherwise execute "debug.traceback( str, int )". */
838 lua_getglobal(L, "debug");
839 if (!lua_istable(L, -1)) {
840 lua_pop(L, 1);
841 return 1;
842 }
843 lua_getfield(L, -1, "traceback");
844 if (!lua_isfunction(L, -1)) {
845 lua_pop(L, 2);
846 return 1;
847 }
848 lua_pushvalue(L, 1);
849 lua_pushinteger(L, 2);
850 lua_call(L, 2, 1);
851 return 1;
852}
853
854/*
855 * @brief Wrapper around lua_pcall() that handles errors and enviornments
856 *
857 * @param env Environment.
858 * @param nargs Number of arguments to pass.
859 * @param nresults Number of return values to take.
860 */
861int nlua_pcall( nlua_env env, int nargs, int nresults )
862{
863 int errf, ret, prev_env;
864
865#if DEBUGGING
866 errf = lua_gettop(naevL) - nargs;
867 lua_pushcfunction(naevL, nlua_errTrace);
868 lua_insert(naevL, errf);
869
870 /* We don't really want to do this, but Lua seems to trigger all sorts of
871 * FPE exceptions on a daily basis.
872 * TODO get rid of if possible. */
873 if (conf.fpu_except)
874 debug_disableFPUExcept();
875#else /* DEBUGGING */
876 errf = 0;
877#endif /* DEBUGGING */
878
879 prev_env = __NLUA_CURENV;
880 __NLUA_CURENV = env;
881
882 ret = lua_pcall(naevL, nargs, nresults, errf);
883
884 __NLUA_CURENV = prev_env;
885
886#if DEBUGGING
887 lua_remove(naevL, errf);
888
889 if (conf.fpu_except)
890 debug_enableFPUExcept();
891#endif /* DEBUGGING */
892
893 return ret;
894}
895
903int nlua_refenv( nlua_env env, const char *name )
904{
905 nlua_getenv( naevL, env, name );
906 if (!lua_isnil( naevL, -1 ))
907 return luaL_ref( naevL, LUA_REGISTRYINDEX );
908 lua_pop(naevL, 1);
909 return LUA_NOREF;
910}
911
920int nlua_refenvtype( nlua_env env, const char *name, int type )
921{
922 nlua_getenv( naevL, env, name );
923 if (lua_type( naevL, -1 ) == type)
924 return luaL_ref( naevL, LUA_REGISTRYINDEX );
925 lua_pop(naevL, 1);
926 return LUA_NOREF;
927}
928
936int nlua_reffield( int objref, const char *name )
937{
938 if (objref == LUA_NOREF)
939 return LUA_NOREF;
940 lua_rawgeti( naevL, LUA_REGISTRYINDEX, objref );
941 lua_getfield( naevL, -1, name );
942 lua_remove( naevL, -2 );
943 if (!lua_isnil( naevL, -1 ))
944 return luaL_ref( naevL, LUA_REGISTRYINDEX );
945 lua_pop(naevL, 1);
946 return LUA_NOREF;
947}
948
952int nlua_ref( lua_State *L, int idx )
953{
954 lua_pushvalue( L, idx );
955 return luaL_ref( L, LUA_REGISTRYINDEX );
956}
957
961void nlua_unref( lua_State *L, int idx )
962{
963 if (idx != LUA_NOREF)
964 luaL_unref( L, LUA_REGISTRYINDEX, idx );
965}
966
970void nlua_resize (void)
971{
972 lua_rawgeti(naevL, LUA_REGISTRYINDEX, nlua_envs); /* t */
973 lua_pushnil(naevL); /* t, n */
974 while (lua_next(naevL, -2) != 0) { /* t, k, v */
975 int env = lua_tointeger(naevL,-1); /* t, k, v */
976 lua_getfield(naevL, -2, "__resize"); /* t, k, v, f */
977 if (!lua_isnil(naevL,-1)) {
978 lua_pushinteger( naevL, SCREEN_W ); /* t, k, v, f, w */
979 lua_pushinteger( naevL, SCREEN_H ); /* t, k, v, f, w, h */
980 nlua_pcall( env, 2, 0 ); /* t, k, v */
981 lua_pop(naevL,1); /* t, k */
982 }
983 else
984 lua_pop(naevL,2); /* t, k */
985 } /* t */
986 lua_pop(naevL,1); /* */
987}
int cli_warn(lua_State *L)
Barebones warn implementation for Lua, allowing scripts to print warnings to stderr.
Definition console.c:166
int cli_printRaw(lua_State *L)
Prints raw markup to the console.
Definition console.c:188
int cli_print(lua_State *L)
Replacement for the internal Lua print to print to both the console and the terminal.
Definition console.c:178
const char * pgettext_var(const char *msgctxt, const char *msgid)
Definition gettext.c:318
Header file with generic functions and naev-specifics.
#define PATH_MAX
Definition naev.h:50
void * ndata_read(const char *path, size_t *filesize)
Reads a file from the ndata (will be NUL terminated).
Definition ndata.c:154
static int nlua_require(lua_State *L)
include( string module )
Definition nlua.c:688
void nlua_unref(lua_State *L, int idx)
Removes a reference set with nlua_ref.
Definition nlua.c:961
static int nlua_log2(lua_State *L)
Implements the Lua function math.log2 (base-2 logarithm).
Definition nlua.c:147
static int nlua_loadBasic(lua_State *L)
Loads specially modified basic stuff.
Definition nlua.c:509
int nlua_refenv(nlua_env env, const char *name)
Gets the reference of a global in a lua environment.
Definition nlua.c:903
static int nlua_pgettext(lua_State *L)
gettext support with context.
Definition nlua.c:123
int nlua_ref(lua_State *L, int idx)
Creates a new reference to a Lua structure at a position.
Definition nlua.c:952
static int nlua_panic(lua_State *L)
Handles what to do when Lua panics.
Definition nlua.c:171
int nlua_loadStandard(nlua_env env)
Loads the standard Naev Lua API.
Definition nlua.c:798
static lua_State * nlua_newState(void)
Wrapper around luaL_newstate.
Definition nlua.c:492
static int nlua_gettext_noop(lua_State *L)
gettext support (noop). Does not actually do anything, but gets detected by gettext.
Definition nlua.c:139
int nlua_refenvtype(nlua_env env, const char *name, int type)
Gets the reference of a global in a lua environment if it matches a type.
Definition nlua.c:920
static int nlua_gettext(lua_State *L)
gettext support.
Definition nlua.c:88
int nlua_reffield(int objref, const char *name)
Gets the reference to the specified field from an object reference.
Definition nlua.c:936
static size_t common_sz
Definition nlua.c:54
static int nlua_package_loader_croot(lua_State *L)
load( string module ) – searcher function to replace package.loaders[4] (Lua 5.1),...
Definition nlua.c:674
static char * common_script
Definition nlua.c:53
static int nlua_package_loader_lua(lua_State *L)
load( string module ) – searcher function to replace package.loaders[2] (Lua 5.1),...
Definition nlua.c:574
void nlua_resize(void)
Propagates a resize event to all the environments forcibly.
Definition nlua.c:970
int nlua_errTrace(lua_State *L)
Gets a trace from Lua.
Definition nlua.c:830
static int nlua_ngettext(lua_State *L)
gettext support for singular and plurals.
Definition nlua.c:105
static int nlua_os_getenv(lua_State *L)
Implements the Lua function os.getenv. In the sandbox we only make a fake $HOME visible.
Definition nlua.c:157
static int luaB_loadstring(lua_State *L)
Replacement for the internal Lua loadstring().
Definition nlua.c:196
static int nlua_package_loader_c(lua_State *L)
load( string module ) – searcher function to replace package.loaders[3] (Lua 5.1),...
Definition nlua.c:655
static const luaL_Reg gettext_methods[]
Definition nlua.c:72
int nlua_loadAudio(nlua_env env)
Loads the audio library.
Definition nlua_audio.c:311
int nlua_loadCommodity(nlua_env env)
Loads the commodity library.
int nlua_loadData(nlua_env env)
Loads the data library.
Definition nlua_data.c:54
int nlua_loadDiff(nlua_env env)
Loads the diff Lua library.
Definition nlua_diff.c:42
int nlua_loadFaction(nlua_env env)
Loads the faction library.
int nlua_loadFile(nlua_env env)
Loads the file library.
Definition nlua_file.c:66
int nlua_loadJump(nlua_env env)
Loads the jump library.
Definition nlua_jump.c:64
int nlua_loadLinOpt(nlua_env env)
Loads the linopt library.
Definition nlua_linopt.c:71
int nlua_loadNaev(nlua_env env)
Loads the Naev Lua library.
Definition nlua_naev.c:124
int nlua_loadNews(nlua_env env)
Loads the news library.
Definition nlua_news.c:59
int nlua_loadOutfit(nlua_env env)
Loads the outfit library.
Definition nlua_outfit.c:97
int nlua_loadPilot(nlua_env env)
Loads the pilot library.
Definition nlua_pilot.c:468
int nlua_loadPlayer(nlua_env env)
Loads the player Lua library.
int nlua_loadRnd(nlua_env env)
Loads the Random Number Lua library.
Definition nlua_rnd.c:48
int nlua_loadSafelanes(nlua_env env)
Loads the safelanes Lua library.
int nlua_loadShiplog(nlua_env env)
Loads the mission Lua library.
int nlua_loadSpfx(nlua_env env)
Loads the spfx library.
Definition nlua_spfx.c:108
int nlua_loadSpob(nlua_env env)
Loads the spob library.
Definition nlua_spob.c:121
int nlua_loadSystem(nlua_env env)
Loads the system library.
int nlua_loadTime(nlua_env env)
Loads the Time Lua library.
Definition nlua_time.c:60
int nlua_loadVar(nlua_env env)
Loads the mission variable Lua library.
Definition nlua_var.c:51
int nlua_loadVector(nlua_env env)
Loads the vector metatable.
Definition nlua_vec2.c:86
int scnprintf(char *text, size_t maxlen, const char *fmt,...)
Like snprintf(), but returns the number of characters ACTUALLY "printed" into the buffer....
Definition nstring.c:99
int loaded
Definition conf.h:72
int lua_enet
Definition conf.h:159
int fpu_except
Definition conf.h:167