efl

Форк
0
/
elua.c 
874 строки · 22.1 Кб
1
#include <limits.h>
2
#include <Ecore_File.h>
3
#include "elua_private.h"
4

5
static Eina_Prefix *_elua_pfx = NULL;
6

7
static int _elua_init_counter = 0;
8
int _elua_log_dom = -1;
9

10
EAPI int
11
elua_init(void)
12
{
13
   const char *dom = "elua";
14
   if (_elua_init_counter > 0) return ++_elua_init_counter;
15

16
   eina_init();
17
   ecore_file_init();
18

19
   _elua_log_dom = eina_log_domain_register(dom, EINA_COLOR_LIGHTBLUE);
20
   if (_elua_log_dom < 0)
21
     {
22
        EINA_LOG_ERR("Could not register log domain: %s", dom);
23
        return EINA_FALSE;
24
     }
25

26
   eina_log_timing(_elua_log_dom, EINA_LOG_STATE_STOP, EINA_LOG_STATE_INIT);
27
   INF("elua init");
28

29
   _elua_pfx = eina_prefix_new(NULL, elua_init, "ELUA", "elua", "checkme",
30
                               PACKAGE_BIN_DIR, "", PACKAGE_DATA_DIR,
31
                               LOCALE_DIR);
32

33
   if (!_elua_pfx)
34
     {
35
        ERR("coul not find elua prefix");
36
        return EINA_FALSE;
37
     }
38

39
   return ++_elua_init_counter;
40
}
41

42
EAPI int
43
elua_shutdown(void)
44
{
45
   if (_elua_init_counter <= 0)
46
     {
47
        EINA_LOG_ERR("Init count not greater than 0 in shutdown.");
48
        return EINA_FALSE;
49
     }
50
   --_elua_init_counter;
51

52
   if (_elua_init_counter > 0)
53
     return _elua_init_counter;
54

55
   INF("shutdown");
56
   eina_log_timing(_elua_log_dom, EINA_LOG_STATE_START, EINA_LOG_STATE_SHUTDOWN);
57

58
   eina_prefix_free(_elua_pfx);
59
   _elua_pfx = NULL;
60

61
   eina_log_domain_unregister(_elua_log_dom);
62
   _elua_log_dom = -1;
63

64
   ecore_file_shutdown();
65
   eina_shutdown();
66
   return _elua_init_counter;
67
}
68

69
#ifdef ENABLE_LUA_OLD
70
static int
71
_ffi_loader(lua_State *L)
72
{
73
   lua_pushvalue(L, lua_upvalueindex(1));
74
   lua_pushliteral(L, "cffi");
75
   lua_pushvalue(L, lua_upvalueindex(2));
76
   lua_call(L, 2, 1);
77
   return 1;
78
}
79

80
#if LUA_VERSION_NUM < 502
81
/* adapted from lua 5.2 source */
82
static const char *
83
_push_next_template(lua_State *L, const char *path)
84
{
85
   while (*path == *LUA_PATHSEP) ++path;
86
   if (!*path)
87
     return NULL;
88
   const char *l = strchr(path, *LUA_PATHSEP);
89
   if (!l)
90
     l = path + strlen(path);
91
   lua_pushlstring(L, path, l - path);
92
   return l;
93
}
94

95
static int
96
_elua_searchpath(lua_State *L)
97
{
98
   const char *name = luaL_checkstring(L, 1);
99
   const char *path = luaL_checkstring(L, 2);
100
   const char *sep  = luaL_optstring(L, 3, ".");
101
   const char *dsep = luaL_optstring(L, 4, LUA_DIRSEP);
102
   luaL_Buffer msg;
103
   luaL_buffinit(L, &msg);
104
   if (*sep)
105
     name = luaL_gsub(L, name, sep, dsep);
106
   while ((path = _push_next_template(L, path)))
107
     {
108
        const char *fname = luaL_gsub(L, lua_tostring(L, -1), LUA_PATH_MARK, name);
109
        lua_remove(L, -2);
110
        FILE *rf = fopen(fname, "r");
111
        if (rf)
112
          {
113
             fclose(rf);
114
             return 1; /* found */
115
          }
116
        lua_pushfstring(L, "\n\tno file " LUA_QS, fname);
117
        lua_remove(L, -2);
118
        luaL_addvalue(&msg);
119
     }
120
   luaL_pushresult(&msg);
121
   lua_pushnil(L);
122
   lua_insert(L, -2);
123
   return 2; /* nil plus error message */
124
}
125
#endif
126
#endif
127

128
EAPI Elua_State *
129
elua_state_new(const char *progname)
130
{
131
   Elua_State *ret = NULL;
132
   lua_State *L = luaL_newstate();
133
   if (!L)
134
     return NULL;
135
   ret = calloc(1, sizeof(Elua_State));
136
   ret->luastate = L;
137
   if (progname) ret->progname = eina_stringshare_add(progname);
138
   luaL_openlibs(L);
139
#ifdef ENABLE_LUA_OLD
140
   /* search for cffi-lua early, and pass it through as ffi */
141
   lua_getglobal(L, "package");
142
#if LUA_VERSION_NUM < 502
143
   /* lua 5.1 does not have package.searchpath, we rely on having that */
144
   lua_getfield(L, -1, "searchpath");
145
   if (lua_isnil(L, -1))
146
     {
147
        lua_pushcfunction(L, _elua_searchpath);
148
        lua_setfield(L, -3, "searchpath");
149
     }
150
   lua_pop(L, 1);
151
#endif
152
   lua_getfield(L, -1, "preload");
153
   lua_getfield(L, -2, "searchers");
154
   if (lua_isnil(L, -1))
155
     {
156
        lua_pop(L, 1);
157
        lua_getfield(L, -2, "loaders");
158
     }
159
   if (lua_isnil(L, -1))
160
     {
161
        ERR("could not find a module searcher");
162
        goto err;
163
     }
164
   lua_rawgeti(L, -1, 3);
165
   lua_pushliteral(L, "cffi");
166
   if (lua_pcall(L, 1, 2, 0))
167
     {
168
        ERR("could not find the cffi module");
169
        goto err;
170
     }
171
   if (!lua_isfunction(L, -2))
172
     {
173
        ERR("could not find the cffi module: %s", lua_tostring(L, -2));
174
        goto err;
175
     }
176
   lua_pushcclosure(L, _ffi_loader, 2);
177
   lua_setfield(L, -3, "ffi");
178
   lua_pop(L, 3);
179
#endif
180
   /* on 64-bit, split the state pointer into two and reconstruct later */
181
   size_t retn = (size_t)ret;
182
   if (sizeof(void *) < sizeof(lua_Number))
183
     {
184
        lua_pushnumber(L, 0);
185
        lua_pushnumber(L, (lua_Number)retn);
186
     }
187
   else
188
     {
189
        size_t hbits = (sizeof(void *) / 2) * CHAR_BIT;
190
        lua_pushnumber(L, (lua_Number)(retn >> hbits));
191
        lua_pushnumber(L, (lua_Number)(retn & (((size_t)1 << hbits) - 1)));
192
     }
193
   lua_setfield(L, LUA_REGISTRYINDEX, "elua_ptr1");
194
   lua_setfield(L, LUA_REGISTRYINDEX, "elua_ptr2");
195
   return ret;
196
#ifdef ENABLE_LUA_OLD
197
err:
198
   lua_close(L);
199
   eina_stringshare_del(ret->progname);
200
   free(ret);
201
   return NULL;
202
#endif
203
}
204

205
EAPI void
206
elua_state_free(Elua_State *es)
207
{
208
   void *data;
209
   if (!es) return;
210
   if (es->luastate)
211
     {
212
        EINA_LIST_FREE(es->cmods, data)
213
          {
214
             lua_rawgeti(es->luastate, LUA_REGISTRYINDEX, (size_t)data);
215
             lua_call(es->luastate, 0, 0);
216
          }
217
        lua_close(es->luastate);
218
     }
219
   else if (es->cmods)
220
     eina_list_free(es->cmods);
221
   EINA_LIST_FREE(es->lmods, data)
222
     eina_stringshare_del(data);
223
   EINA_LIST_FREE(es->lincs, data)
224
     eina_stringshare_del(data);
225
   eina_stringshare_del(es->progname);
226
   eina_stringshare_del(es->coredir);
227
   eina_stringshare_del(es->moddir);
228
   eina_stringshare_del(es->appsdir);
229
   free(es);
230
}
231

232
EAPI void
233
elua_state_dirs_set(Elua_State *es, const char *core, const char *mods,
234
                    const char *apps)
235
{
236
   char *spath = NULL;
237
   EINA_SAFETY_ON_NULL_RETURN(es);
238
   if (core)
239
     {
240
        eina_stringshare_del(es->coredir);
241
        spath = eina_file_path_sanitize(core);
242
        es->coredir = eina_stringshare_add(spath);
243
        free(spath);
244
     }
245
   if (mods)
246
     {
247
        eina_stringshare_del(es->moddir);
248
        spath = eina_file_path_sanitize(mods);
249
        es->moddir = eina_stringshare_add(spath);
250
        free(spath);
251
     }
252
   if (apps)
253
     {
254
        eina_stringshare_del(es->appsdir);
255
        spath = eina_file_path_sanitize(apps);
256
        es->appsdir = eina_stringshare_add(spath);
257
        free(spath);
258
     }
259
}
260

261
EAPI void
262
elua_state_dirs_fill(Elua_State *es, Eina_Bool ignore_env)
263
{
264
   const char *coredir = NULL, *moddir = NULL, *appsdir = NULL;
265
   char coredirbuf[PATH_MAX], moddirbuf[PATH_MAX], appsdirbuf[PATH_MAX];
266
   EINA_SAFETY_ON_NULL_RETURN(es);
267
   if (!(coredir = es->coredir))
268
     {
269
        if (ignore_env || !(coredir = getenv("ELUA_CORE_DIR")) || !coredir[0])
270
          {
271
             coredir = coredirbuf;
272
             snprintf(coredirbuf, sizeof(coredirbuf), "%s/core",
273
                      eina_prefix_data_get(_elua_pfx));
274
          }
275
        if (coredir) {
276
            char *sdir = eina_file_path_sanitize(coredir);
277
            es->coredir = eina_stringshare_add(sdir);
278
            free(sdir);
279
        }
280
     }
281
   if (!(moddir = es->moddir))
282
     {
283
        if (ignore_env || !(moddir = getenv("ELUA_MODULES_DIR")) || !moddir[0])
284
          {
285
             moddir = moddirbuf;
286
             snprintf(moddirbuf, sizeof(moddirbuf), "%s/modules",
287
                      eina_prefix_data_get(_elua_pfx));
288
          }
289
        if (moddir) {
290
            char *sdir = eina_file_path_sanitize(moddir);
291
            es->moddir = eina_stringshare_add(sdir);
292
            free(sdir);
293
        }
294
     }
295
   if (!(appsdir = es->appsdir))
296
     {
297
        if (ignore_env || !(appsdir = getenv("ELUA_APPS_DIR")) || !appsdir[0])
298
          {
299
             appsdir = appsdirbuf;
300
             snprintf(appsdirbuf, sizeof(appsdirbuf), "%s/apps",
301
                      eina_prefix_data_get(_elua_pfx));
302
          }
303
        if (appsdir) {
304
            char *sdir = eina_file_path_sanitize(appsdir);
305
            es->appsdir = eina_stringshare_add(sdir);
306
            free(sdir);
307
        }
308
     }
309
}
310

311
EAPI Eina_Stringshare *
312
elua_state_core_dir_get(const Elua_State *es)
313
{
314
   EINA_SAFETY_ON_NULL_RETURN_VAL(es, NULL);
315
   return es->coredir;
316
}
317

318
EAPI Eina_Stringshare *
319
elua_state_mod_dir_get(const Elua_State *es)
320
{
321
   EINA_SAFETY_ON_NULL_RETURN_VAL(es, NULL);
322
   return es->moddir;
323
}
324

325
EAPI Eina_Stringshare *
326
elua_state_apps_dir_get(const Elua_State *es)
327
{
328
   EINA_SAFETY_ON_NULL_RETURN_VAL(es, NULL);
329
   return es->appsdir;
330
}
331

332
EAPI Eina_Stringshare *
333
elua_state_prog_name_get(const Elua_State *es)
334
{
335
   EINA_SAFETY_ON_NULL_RETURN_VAL(es, NULL);
336
   return es->progname;
337
}
338

339
EAPI void
340
elua_state_include_path_add(Elua_State *es, const char *path)
341
{
342
   char *spath = NULL;
343
   EINA_SAFETY_ON_NULL_RETURN(es);
344
   EINA_SAFETY_ON_NULL_RETURN(path);
345
   EINA_SAFETY_ON_FALSE_RETURN(path[0]);
346
   spath = eina_file_path_sanitize(path);
347
   es->lincs = eina_list_append(es->lincs, eina_stringshare_add(spath));
348
   free(spath);
349
}
350

351
EAPI Eina_Bool
352
elua_state_require_ref_push(Elua_State *es)
353
{
354
   EINA_SAFETY_ON_NULL_RETURN_VAL(es, EINA_FALSE);
355
   EINA_SAFETY_ON_FALSE_RETURN_VAL(es->requireref != LUA_REFNIL, EINA_FALSE);
356
   lua_rawgeti(es->luastate, LUA_REGISTRYINDEX, es->requireref);
357
   return EINA_TRUE;
358
}
359

360
EAPI Eina_Bool
361
elua_state_appload_ref_push(Elua_State *es)
362
{
363
   EINA_SAFETY_ON_NULL_RETURN_VAL(es, EINA_FALSE);
364
   EINA_SAFETY_ON_FALSE_RETURN_VAL(es->apploadref != LUA_REFNIL, EINA_FALSE);
365
   lua_rawgeti(es->luastate, LUA_REGISTRYINDEX, es->apploadref);
366
   return EINA_TRUE;
367
}
368

369
EAPI lua_State *
370
elua_state_lua_state_get(const Elua_State *es)
371
{
372
   EINA_SAFETY_ON_NULL_RETURN_VAL(es, NULL);
373
   return es->luastate;
374
}
375

376
EAPI Elua_State *
377
elua_state_from_lua_state_get(lua_State *L)
378
{
379
   EINA_SAFETY_ON_NULL_RETURN_VAL(L, NULL);
380
   lua_getfield(L, LUA_REGISTRYINDEX, "elua_ptr1");
381
   lua_getfield(L, LUA_REGISTRYINDEX, "elua_ptr2");
382
   if (!lua_isnil(L, -1) && !lua_isnil(L, -2))
383
     {
384
        size_t p1 = (size_t)lua_tonumber(L, -2),
385
               p2 = (size_t)lua_tonumber(L, -1);
386
        if (p2 && (sizeof(void *) >= sizeof(lua_Number)))
387
          p1 |= p2 << ((sizeof(void *) / 2) * CHAR_BIT);
388
        lua_pop(L, 2);
389
        return (Elua_State *)p1;
390
     }
391
   lua_pop(L, 2);
392
   return NULL;
393
}
394

395
static int
396
_elua_gettext_bind_textdomain(lua_State *L)
397
{
398
#ifdef ENABLE_NLS
399
   const char *textdomain = luaL_checkstring(L, 1);
400
   const char *dirname    = luaL_checkstring(L, 2);
401
   const char *ret;
402
   if (!textdomain[0] || !strcmp(textdomain, PACKAGE))
403
     {
404
        lua_pushnil(L);
405
        lua_pushliteral(L, "invalid textdomain");
406
        return 2;
407
     }
408
   if (!(ret = bindtextdomain(textdomain, dirname)))
409
     {
410
        lua_pushnil(L);
411
        lua_pushstring(L, strerror(errno));
412
        return 2;
413
     }
414
   bind_textdomain_codeset(textdomain, "UTF-8");
415
   lua_pushstring(L, ret);
416
   return 1;
417
#else
418
   lua_pushliteral(L, "");
419
   return 1;
420
#endif
421
}
422

423
static int
424
_elua_get_message_language(lua_State *L)
425
{
426
   const char *e;
427
   e = getenv("LANGUAGE");
428
   if (e && e[0]) goto success;
429
   e = getenv("LC_ALL");
430
   if (e && e[0]) goto success;
431
   e = getenv("LC_MESSAGES");
432
   if (e && e[0]) goto success;
433
   e = getenv("LANG");
434
   if (e && e[0]) goto success;
435
   lua_pushnil(L);
436
   return 1;
437
success:
438
   lua_pushstring(L, e);
439
   return 1;
440
};
441

442
static int
443
_elua_get_localeconv(lua_State *L)
444
{
445
   struct lconv *lc = localeconv();
446
   lua_createtable(L, 0, 24);
447

448
#define ELUA_LCF_S(name) \
449
   lua_pushstring(L, lc->name); \
450
   lua_setfield(L, -2, #name);
451

452
#define ELUA_LCF_C(name) \
453
   lua_pushinteger(L, (lc->name == CHAR_MAX) ? -1 : (int)lc->name); \
454
   lua_setfield(L, -2, #name);
455

456
   ELUA_LCF_S(decimal_point);
457
   ELUA_LCF_S(thousands_sep);
458
   ELUA_LCF_S(grouping);
459
   ELUA_LCF_S(int_curr_symbol);
460
   ELUA_LCF_S(currency_symbol);
461
   ELUA_LCF_S(mon_decimal_point);
462
   ELUA_LCF_S(mon_thousands_sep);
463
   ELUA_LCF_S(mon_grouping);
464
   ELUA_LCF_S(positive_sign);
465
   ELUA_LCF_S(negative_sign);
466

467
   ELUA_LCF_C(frac_digits);
468
   ELUA_LCF_C(p_cs_precedes);
469
   ELUA_LCF_C(n_cs_precedes);
470
   ELUA_LCF_C(p_sep_by_space);
471
   ELUA_LCF_C(n_sep_by_space);
472
   ELUA_LCF_C(p_sign_posn);
473
   ELUA_LCF_C(n_sign_posn);
474
   ELUA_LCF_C(int_frac_digits);
475

476
#undef ELUA_LCF_S
477
#undef ELUA_LCF_C
478

479
   return 1;
480
};
481

482
#ifdef ENABLE_NLS
483
static int
484
_elua_dgettext(lua_State *L)
485
{
486
   const char *domain = luaL_checkstring(L, 1);
487
   const char *msgid  = luaL_checkstring(L, 2);
488
   char *ret = dgettext(domain, msgid);
489
   if (!ret)
490
     lua_pushnil(L);
491
   else
492
     lua_pushstring(L, ret);
493
   return 1;
494
}
495

496
static int
497
_elua_dngettext(lua_State *L)
498
{
499
   const char *domain  = luaL_checkstring(L, 1);
500
   const char *msgid   = luaL_checkstring(L, 2);
501
   const char *plmsgid = luaL_checkstring(L, 3);
502
   char *ret = dngettext(domain, msgid, plmsgid, luaL_checklong(L, 4));
503
   if (!ret)
504
     lua_pushnil(L);
505
   else
506
     lua_pushstring(L, ret);
507
   return 1;
508
}
509
#endif
510

511
const luaL_Reg gettextlib[] =
512
{
513
   { "bind_textdomain", _elua_gettext_bind_textdomain },
514
   { "get_message_language", _elua_get_message_language },
515
   { "get_localeconv", _elua_get_localeconv },
516
#ifdef ENABLE_NLS
517
   { "dgettext", _elua_dgettext },
518
   { "dngettext", _elua_dngettext },
519
#endif
520
   { NULL, NULL }
521
};
522

523
static Eina_Bool
524
_elua_state_i18n_setup(Elua_State *es)
525
{
526
   char buf[PATH_MAX];
527
   EINA_SAFETY_ON_NULL_RETURN_VAL(es, EINA_FALSE);
528
   EINA_SAFETY_ON_NULL_RETURN_VAL(es->coredir, EINA_FALSE);
529
   EINA_SAFETY_ON_NULL_RETURN_VAL(es->progname, EINA_FALSE);
530
   snprintf(buf, sizeof(buf), "%s/gettext.lua", es->coredir);
531
   if (elua_util_error_report(es, elua_io_loadfile(es, buf)))
532
     return EINA_FALSE;
533
   lua_createtable(es->luastate, 0, 0);
534
   elua_register(es->luastate, gettextlib);
535
   lua_call(es->luastate, 1, 0);
536
   return EINA_TRUE;
537
}
538

539
int _elua_module_init(lua_State *L);
540
int _elua_module_system_init(lua_State *L);
541

542
static int
543
_elua_file_is_dir(lua_State *L)
544
{
545
   lua_pushboolean(L, ecore_file_is_dir(luaL_checkstring(L, 1)));
546
   return 1;
547
}
548

549
static int
550
_elua_file_exists(lua_State *L)
551
{
552
   lua_pushboolean(L, ecore_file_exists(luaL_checkstring(L, 1)));
553
   return 1;
554
}
555

556
static int
557
_elua_file_mkdir(lua_State *L)
558
{
559
   lua_pushboolean(L, ecore_file_mkdir(luaL_checkstring(L, 1)));
560
   return 1;
561
}
562

563
static int
564
_elua_file_mkpath(lua_State *L)
565
{
566
   lua_pushboolean(L, ecore_file_mkpath(luaL_checkstring(L, 1)));
567
   return 1;
568
}
569

570
static int
571
_elua_file_rmdir(lua_State *L)
572
{
573
   lua_pushboolean(L, ecore_file_rmdir(luaL_checkstring(L, 1)));
574
   return 1;
575
}
576

577
static int
578
_elua_file_unlink(lua_State *L)
579
{
580
   lua_pushboolean(L, ecore_file_unlink(luaL_checkstring(L, 1)));
581
   return 1;
582
}
583

584
static int
585
_elua_file_rmrf(lua_State *L)
586
{
587
   lua_pushboolean(L, ecore_file_recursive_rm(luaL_checkstring(L, 1)));
588
   return 1;
589
}
590

591
const luaL_Reg _elua_cutillib[] =
592
{
593
   { "init_module", _elua_module_init },
594
   { "popenv"     , _elua_io_popen    },
595
   { "file_is_dir", _elua_file_is_dir },
596
   { "file_exists", _elua_file_exists },
597
   { "file_mkdir" , _elua_file_mkdir  },
598
   { "file_mkpath", _elua_file_mkpath },
599
   { "file_rmdir" , _elua_file_rmdir  },
600
   { "file_unlink", _elua_file_unlink },
601
   { "file_rmrf"  , _elua_file_rmrf   },
602
   { NULL         , NULL              }
603
};
604

605
static Eina_Bool
606
_elua_state_modules_setup(const Elua_State *es)
607
{
608
   char buf[PATH_MAX];
609
   EINA_SAFETY_ON_NULL_RETURN_VAL(es, EINA_FALSE);
610
   EINA_SAFETY_ON_NULL_RETURN_VAL(es->coredir, EINA_FALSE);
611
   EINA_SAFETY_ON_NULL_RETURN_VAL(es->progname, EINA_FALSE);
612
   snprintf(buf, sizeof(buf), "%s/module.lua", es->coredir);
613
   if (elua_util_error_report(es, elua_io_loadfile(es, buf)))
614
     return EINA_FALSE;
615
   lua_pushcfunction(es->luastate, _elua_module_system_init);
616
   lua_createtable(es->luastate, 0, 0);
617
   elua_register(es->luastate, _elua_cutillib);
618
   lua_call(es->luastate, 2, 0);
619
   return EINA_TRUE;
620
}
621

622
int
623
_elua_module_init(lua_State *L)
624
{
625
   Elua_State *es = elua_state_from_lua_state_get(L);
626
   if (!lua_isnoneornil(L, 1))
627
     {
628
        lua_pushvalue(L, 1);
629
        lua_call(L, 0, 0);
630
     }
631
   if (!lua_isnoneornil(L, 2))
632
     {
633
        lua_pushvalue(L, 2);
634
        es->cmods = eina_list_append(es->cmods,
635
           (void*)(size_t)luaL_ref(L, LUA_REGISTRYINDEX));
636
     }
637
   return 0;
638
}
639

640
int
641
_elua_module_system_init(lua_State *L)
642
{
643
   Elua_State       *es       = elua_state_from_lua_state_get(L);
644
   const char       *corepath = es->coredir;
645
   const char       *modpath  = es->moddir;
646
   const char       *appspath = es->appsdir;
647
   Eina_Stringshare *data     = NULL;
648
   if (!corepath || !modpath || !appspath)
649
     return 0;
650
   lua_pushvalue(L, 1);
651
   es->requireref = luaL_ref(L, LUA_REGISTRYINDEX);
652
   lua_pushvalue(L, 2);
653
   es->apploadref = luaL_ref(L, LUA_REGISTRYINDEX);
654

655
   /* module path, local directories take priority */
656
   int n = 0;
657
   lua_pushvalue(L, 3); ++n;
658
   lua_pushfstring(L, ";%s/?.lua", corepath); ++n;
659
   EINA_LIST_FREE(es->lincs, data)
660
     {
661
        lua_pushfstring(L, ";%s/?.lua", data);
662
        eina_stringshare_del(data);
663
        ++n;
664
     }
665
   lua_pushfstring(L, ";%s/?.eo.lua", modpath); ++n;
666
   lua_pushfstring(L, ";%s/?.lua", modpath); ++n;
667
   lua_pushfstring(L, ";%s/?.lua", appspath); ++n;
668
   lua_concat(L, n);
669

670
   /* apps path, local directory takes priority as well */
671
   lua_pushvalue(L, 4);
672
   lua_pushfstring(L, ";%s/?.lua", appspath);
673
   lua_concat(L, 2);
674

675
   return 2;
676
}
677

678
EAPI Eina_Bool
679
elua_state_setup(Elua_State *es)
680
{
681
   Eina_Stringshare *data;
682
   Eina_Bool failed = EINA_FALSE;
683

684
   if (!_elua_state_modules_setup(es))
685
     return EINA_FALSE;
686
   if (!_elua_state_i18n_setup(es))
687
     return EINA_FALSE;
688
   if (!_elua_state_io_setup(es))
689
     return EINA_FALSE;
690

691
   /* finally require the necessary modules */
692
   EINA_LIST_FREE(es->lmods, data)
693
     {
694
        if (!failed)
695
          {
696
             if (!elua_state_require_ref_push(es))
697
               {
698
                  failed = EINA_TRUE;
699
                  break;
700
               }
701
             lua_pushstring(es->luastate, data);
702
             if (elua_util_error_report(es, lua_pcall(es->luastate, 1, 0, 0)))
703
               {
704
                  failed = EINA_TRUE;
705
                  break;
706
               }
707
          }
708
        eina_stringshare_del(data);
709
     }
710

711
   return EINA_TRUE;
712
}
713

714
/* Utility functions - these could be written using the other APIs */
715

716
static int
717
_elua_traceback(lua_State *L)
718
{
719
   lua_getglobal(L, "debug");
720
   if (!lua_istable(L, -1))
721
     {
722
        lua_pop(L, 1);
723
        return 1;
724
     }
725
   lua_getfield(L, -1, "traceback");
726
   if (!lua_isfunction(L, -1))
727
     {
728
        lua_pop(L, 2);
729
        return 1;
730
     }
731
   lua_pushvalue(L, 1);
732
   lua_pushinteger(L, 2);
733
   lua_call(L, 2, 1);
734
   return 1;
735
}
736

737
static int
738
_elua_docall(Elua_State *es, int narg, int nret)
739
{
740
   int status;
741
   EINA_SAFETY_ON_NULL_RETURN_VAL(es, -1);
742
   int bs = lua_gettop(es->luastate) - narg;
743
   lua_pushcfunction(es->luastate, _elua_traceback);
744
   lua_insert(es->luastate, bs);
745
   status = lua_pcall(es->luastate, narg, nret, bs);
746
   lua_remove(es->luastate, bs);
747
   if (status)
748
      lua_gc(es->luastate, LUA_GCCOLLECT, 0);
749
   return status;
750
}
751

752
static int
753
_elua_getargs(Elua_State *es, int argc, char **argv, int n)
754
{
755
   int i;
756
   int narg = argc - (n + 1);
757
   EINA_SAFETY_ON_NULL_RETURN_VAL(es, -1);
758
   luaL_checkstack(es->luastate, narg + 3, "too many arguments to script");
759
   for (i = n + 1; i < argc; ++i)
760
     {
761
        lua_pushstring(es->luastate, argv[i]);
762
     }
763
   lua_createtable(es->luastate, narg, n + 1);
764
   for (i = 0; i < argc; ++i)
765
     {
766
        lua_pushstring(es->luastate, argv[i]);
767
        lua_rawseti(es->luastate, -2, i - n);
768
     }
769
   return narg;
770
}
771

772
EAPI Eina_Bool
773
elua_util_require(Elua_State *es, const char *libname)
774
{
775
   EINA_SAFETY_ON_NULL_RETURN_VAL(es, EINA_FALSE);
776
   if (!elua_state_require_ref_push(es))
777
     {
778
        /* store stuff until things are correctly set up */
779
        es->lmods = eina_list_append(es->lmods, eina_stringshare_add(libname));
780
        return 0;
781
     }
782
   lua_pushstring(es->luastate, libname);
783
   return !elua_util_error_report(es, lua_pcall(es->luastate, 1, 0, 0));
784
}
785

786
EAPI Eina_Bool
787
elua_util_file_run(Elua_State *es, const char *fname)
788
{
789
   EINA_SAFETY_ON_NULL_RETURN_VAL(es, EINA_FALSE);
790
   return !elua_util_error_report(es, elua_io_loadfile(es, fname)
791
                                  || _elua_docall(es, 0, 1));
792
}
793

794
EAPI Eina_Bool
795
elua_util_string_run(Elua_State *es, const char *chunk, const char *chname)
796
{
797
   EINA_SAFETY_ON_NULL_RETURN_VAL(es, EINA_FALSE);
798
   return !elua_util_error_report(es, luaL_loadbuffer(es->luastate, chunk,
799
                                                      strlen(chunk), chname)
800
                                      || _elua_docall(es, 0, 0));
801
}
802

803
EAPI int
804
elua_util_app_load(Elua_State *es, const char *appname)
805
{
806
   EINA_SAFETY_ON_NULL_RETURN_VAL(es, -1);
807
   EINA_SAFETY_ON_FALSE_RETURN_VAL(elua_state_appload_ref_push(es), -1);
808
   lua_pushstring(es->luastate, appname);
809
   lua_call(es->luastate, 1, 2);
810
   if (lua_isnil(es->luastate, -2))
811
     {
812
        lua_remove(es->luastate, -2);
813
        return 1;
814
     }
815
   lua_pop(es->luastate, 1);
816
   return 0;
817
}
818

819
EAPI Eina_Bool
820
elua_util_script_run(Elua_State *es, int argc, char **argv, int n, int *quit)
821
{
822
   int status, narg;
823
   const char *fname;
824
   EINA_SAFETY_ON_FALSE_RETURN_VAL(n < argc, -1);
825
   EINA_SAFETY_ON_NULL_RETURN_VAL(es, -1);
826
   fname = argv[n];
827
   narg = _elua_getargs(es, argc, argv, n);
828
   lua_setglobal(es->luastate, "arg");
829
   if (fname[0] == '-' && !fname[1]) fname = NULL;
830
   if (fname)
831
     {
832
        /* check if there is a file of that name */
833
        FILE *f = fopen(fname, "rb");
834
        if (f)
835
          {
836
             fclose(f);
837
             status = elua_io_loadfile(es, fname);
838
          }
839
        else
840
          status = elua_util_app_load(es, fname);
841
     }
842
   else
843
     status = elua_io_loadfile(es, fname);
844
   lua_insert(es->luastate, -(narg + 1));
845
   if (!status)
846
     status = _elua_docall(es, narg, 1);
847
   else
848
     lua_pop(es->luastate, narg);
849
   if (!status)
850
     {
851
        *quit = lua_toboolean(es->luastate, -1);
852
        lua_pop(es->luastate, 1);
853
     }
854
   return !elua_util_error_report(es, status);
855
}
856

857
static void
858
_elua_errmsg(const char *pname, const char *msg)
859
{
860
   ERR("%s%s%s", pname ? pname : "", pname ? ": " : "", msg);
861
}
862

863
EAPI int
864
elua_util_error_report(const Elua_State *es, int status)
865
{
866
   EINA_SAFETY_ON_FALSE_RETURN_VAL(es, status);
867
   if (status && !lua_isnil(es->luastate, -1))
868
     {
869
        const char *msg = lua_tostring(es->luastate, -1);
870
        _elua_errmsg(es->progname, msg ? msg : "(non-string error)");
871
        lua_pop(es->luastate, 1);
872
     }
873
   return status;
874
}
875

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.