aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/ClientHamr
diff options
context:
space:
mode:
authorDavid Walter Seikel2014-04-17 00:15:09 +1000
committerDavid Walter Seikel2014-04-17 00:15:09 +1000
commit3d3766f53f8a4165db2b631ce991d859d35386b3 (patch)
tree659d4fed8e38cb92a49432cf47ed72b28153b6db /ClientHamr
parentConvert GuiLua and skang to Elementary. (diff)
downloadSledjHamr-3d3766f53f8a4165db2b631ce991d859d35386b3.zip
SledjHamr-3d3766f53f8a4165db2b631ce991d859d35386b3.tar.gz
SledjHamr-3d3766f53f8a4165db2b631ce991d859d35386b3.tar.bz2
SledjHamr-3d3766f53f8a4165db2b631ce991d859d35386b3.tar.xz
Make C calling Lua easier with wrapper functions, lifted from edje_lua2, and modified a bit.
Diffstat (limited to 'ClientHamr')
-rw-r--r--ClientHamr/GuiLua/GuiLua.c320
-rw-r--r--ClientHamr/GuiLua/GuiLua.h3
-rw-r--r--ClientHamr/GuiLua/test_c.c1
3 files changed, 286 insertions, 38 deletions
diff --git a/ClientHamr/GuiLua/GuiLua.c b/ClientHamr/GuiLua/GuiLua.c
index 985d0c6..e26ce36 100644
--- a/ClientHamr/GuiLua/GuiLua.c
+++ b/ClientHamr/GuiLua/GuiLua.c
@@ -230,6 +230,278 @@ char *getDateTime(struct tm **nowOut, char *dateOut, time_t *timeOut)
230} 230}
231 231
232 232
233// These are what the various symbols are for each type -
234// int %
235// num #
236// str $
237// bool !
238// C func &
239// table.field @ Expects an integer and a string.
240// nil ~
241// table {} Starts and stops filling up a new table.
242// ( Just syntax sugar for call.
243// call ) Expects an integer, the number of results left after the call.
244// FIXME: Still to do, if we ever use them -
245// userdata +
246// lightuserdata *
247// thread ^
248
249static char *_push_name(lua_State *L, char *q, int *idx) // Stack usage [-0, +1, e or m]
250{
251 char *p = q;
252 char temp = '\0';
253
254 // A simplistic scan through an identifier, it's wrong, but it's quick,
255 // and we don't mind that it's wrong, coz this is only internal.
256 while (isalnum((int)*q))
257 q++;
258 temp = *q;
259 *q = '\0';
260 if (*idx > 0)
261 lua_getfield(L, *idx, p); // Stack usage [-0, +1, e]
262 else
263 {
264 if (p != q)
265 lua_pushstring(L, p); // Stack usage [-0, +1, m]
266 else
267 {
268 lua_pushnumber(L, (lua_Number) (0 - (*idx)));
269 (*idx)--;
270 }
271 }
272 *q = temp;
273
274 return q;
275}
276
277int pull_lua(lua_State *L, int i, char *params, ...) // Stack usage -
278 // if i is a table
279 // [-n, +n, e]
280 // else
281 // [-0, +0, -]
282{
283 va_list vl;
284 char *f = strdup(params);
285 char *p = f;
286 int n = 0, j = i, count = 0;
287 Eina_Bool table = EINA_FALSE;
288
289 if (!f) return -1;
290 va_start(vl, params);
291
292 if (lua_istable(L, i)) // Stack usage [-0, +0, -]
293 {
294 j = -1;
295 table = EINA_TRUE;
296 }
297
298 while (*p)
299 {
300 char *q;
301 Eina_Bool get = EINA_TRUE;
302
303 while (isspace((int)*p))
304 p++;
305 q = p + 1;
306 switch (*p)
307 {
308 case '%':
309 {
310 if (table) q = _push_name(L, q, &i); // Stack usage [-0, +1, e]
311 if (lua_isnumber(L, j)) // Stack usage [-0, +0, -]
312 {
313 int *v = va_arg(vl, int *);
314 *v = lua_tointeger(L, j); // Stack usage [-0, +0, -]
315 n++;
316 }
317 break;
318 }
319 case '#':
320 {
321 if (table) q = _push_name(L, q, &i); // Stack usage [-0, +1, e]
322 if (lua_isnumber(L, j)) // Stack usage [-0, +0, -]
323 {
324 double *v = va_arg(vl, double *);
325 *v = lua_tonumber(L, j); // Stack usage [-0, +0, -]
326 n++;
327 }
328 break;
329 }
330 case '$':
331 {
332 if (table) q = _push_name(L, q, &i); // Stack usage [-0, +1, e]
333 if (lua_isstring(L, j)) // Stack usage [-0, +0, -]
334 {
335 char **v = va_arg(vl, char **);
336 size_t len;
337 char *temp = (char *) lua_tolstring(L, j, &len); // Stack usage [-0, +0, m]
338
339 len++; // Cater for the null at the end.
340 *v = malloc(len);
341 if (*v)
342 {
343 memcpy(*v, temp, len);
344 n++;
345 }
346 }
347 break;
348 }
349 case '!':
350 {
351 if (table) q = _push_name(L, q, &i); // Stack usage [-0, +1, e]
352 if (lua_isboolean(L, j)) // Stack usage [-0, +0, -]
353 {
354 int *v = va_arg(vl, int *);
355 *v = lua_toboolean(L, j); // Stack usage [-0, +0, -]
356 n++;
357 }
358 break;
359 }
360 default:
361 {
362 get = EINA_FALSE;
363 break;
364 }
365 }
366
367 if (get)
368 {
369 if (table)
370 {
371 // If this is a table, then we pushed a value on the stack, pop it off.
372 lua_pop(L, 1); // Stack usage [-n, +0, -]
373 }
374 else
375 j++;
376 count++;
377 }
378 p = q;
379 }
380
381 va_end(vl);
382 free(f);
383 if (count > n)
384 n = 0;
385 else if (table)
386 n = 1;
387 return n;
388}
389
390int push_lua(lua_State *L, char *params, ...) // Stack usage [-0, +n, em]
391{
392 va_list vl;
393 char *f = strdup(params);
394 char *p = f;
395 int n = 0, table = 0, i = -1;
396
397 if (!f) return -1;
398
399 va_start(vl, params);
400
401 while (*p)
402 {
403 char *q;
404 Eina_Bool set = EINA_TRUE;
405
406 while (isspace((int)*p))
407 p++;
408 q = p + 1;
409 switch (*p)
410 {
411 case '%':
412 {
413 if (table) q = _push_name(L, q, &i); // Stack usage [-0, +1, m]
414 lua_pushinteger(L, va_arg(vl, int)); // Stack usage [-0, +1, -]
415 break;
416 }
417 case '#':
418 {
419 if (table) q = _push_name(L, q, &i); // Stack usage [-0, +1, m]
420 lua_pushnumber(L, va_arg(vl, double)); // Stack usage [-0, +1, -]
421 break;
422 }
423 case '$':
424 {
425 if (table) q = _push_name(L, q, &i); // Stack usage [-0, +1, m]
426 lua_pushstring(L, va_arg(vl, char *)); // Stack usage [-0, +1, m]
427 break;
428 }
429 case '!':
430 {
431 if (table) q = _push_name(L, q, &i); // Stack usage [-0, +1, m]
432 lua_pushboolean(L, va_arg(vl, int)); // Stack usage [-0, +1, -]
433 break;
434 }
435 case '@':
436 {
437 int tabl = va_arg(vl, int);
438 char *field = va_arg(vl, char *);
439
440 if (table) q = _push_name(L, q, &i); // Stack usage [-0, +1, m]
441 lua_getfield(L, tabl, field); // Stack usage [-0, +1, e]
442 break;
443 }
444 case '&':
445 {
446 if (table) q = _push_name(L, q, &i); // Stack usage [-0, +1, m]
447 lua_pushcfunction(L, va_arg(vl, void *)); // Stack usage [-0, +1, m]
448 break;
449 }
450 case '~':
451 {
452 if (table) q = _push_name(L, q, &i); // Stack usage [-0, +1, m]
453 lua_pushnil(L); // Stack usage [-0, +1, -]
454 break;
455 }
456 case '(': // Just syntax sugar.
457 {
458 set = EINA_FALSE;
459 break;
460 }
461 case ')':
462 {
463 lua_call(L, n - 1, va_arg(vl, int));
464 n = 0;
465 set = EINA_FALSE;
466 break;
467 }
468 case '{':
469 {
470 lua_newtable(L);
471 table++;
472 n++;
473 set = EINA_FALSE;
474 break;
475 }
476 case '}':
477 {
478 table--;
479 set = EINA_FALSE;
480 break;
481 }
482 default:
483 {
484 set = EINA_FALSE;
485 break;
486 }
487 }
488
489 if (set)
490 {
491 if (table > 0)
492 lua_settable(L, -3); // Stack usage [-2, +0, e]
493 else
494 n++;
495 }
496 p = q;
497 }
498
499 va_end(vl);
500 free(f);
501 return n;
502}
503
504
233static void _on_done(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) 505static void _on_done(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
234{ 506{
235// globals *ourGlobals = data; 507// globals *ourGlobals = data;
@@ -332,48 +604,23 @@ int luaopen_widget(lua_State *L)
332 lua_getfield(L, LUA_REGISTRYINDEX, "skang"); 604 lua_getfield(L, LUA_REGISTRYINDEX, "skang");
333 605
334// local _M = skang.moduleBegin('widget', nil, 'Copyright 2014 David Seikel', '0.1', '2014-04-08 00:42:00', nil, false) 606// local _M = skang.moduleBegin('widget', nil, 'Copyright 2014 David Seikel', '0.1', '2014-04-08 00:42:00', nil, false)
335 lua_getfield(L, skang, "moduleBegin"); 607 push_lua(L, "@ ( $ ~ $ $ $ ~ ! )", skang, "moduleBegin", ourName, "Copyright 2014 David Seikel", "0.1", "2014-04-08 00:42:00", 0, 1);
336 lua_pushstring(L, ourName);
337 lua_pushnil(L); // Author comes from copyright.
338 lua_pushstring(L, "Copyright 2014 David Seikel");
339 lua_pushstring(L, "0.1");
340 lua_pushstring(L, "2014-04-08 00:42:00");
341 lua_pushnil(L); // No skin.
342 lua_pushboolean(L, 0); // We are not a Lua module.
343 lua_call(L, 7, 1); // call 'skang.moduleBegin' with 7 arguments and 1 result.
344
345 _M = lua_gettop(L); 608 _M = lua_gettop(L);
346 // Save this module in the C registry. 609 // Save this module in the C registry.
347 lua_setfield(L, LUA_REGISTRYINDEX, ourName); 610 lua_setfield(L, LUA_REGISTRYINDEX, ourName);
348 611
349 // Define our functions. 612 // Define our functions.
350 lua_getfield(L, skang, "thingasm"); 613 push_lua(L, "@ ( @ $ $ & )", skang, "thingasm", LUA_REGISTRYINDEX, ourName, "openWindow", "Opens our window.", openWindow, 0);
351 lua_getfield(L, LUA_REGISTRYINDEX, ourName); // Coz getfenv() can't find C environment. 614 push_lua(L, "@ ( @ $ $ & )", skang, "thingasm", LUA_REGISTRYINDEX, ourName, "loopWindow", "Run our windows main loop.", loopWindow, 0);
352 lua_pushstring(L, "openWindow"); 615 push_lua(L, "@ ( @ $ $ & )", skang, "thingasm", LUA_REGISTRYINDEX, ourName, "closeWindow", "Closes our window.", closeWindow, 0);
353 lua_pushstring(L, "Opens our window."); 616
354 lua_pushcfunction(L, openWindow); 617// skang.thingasm{_M, 'cfooble,c', 'cfooble help text', 1, widget=\"'edit', 'The cfooble:', 1, 1, 10, 50\", required=true}
355 lua_call(L, 4, 0); 618 push_lua(L, "@ ( { @ $ $ % $widget !required } )", skang, "thingasm", LUA_REGISTRYINDEX, ourName, "wibble", "It's wibbly!", 1, "'edit', 'The wibblinator:', 1, 1, 10, 50", 1, 0);
356
357 lua_getfield(L, skang, "thingasm");
358 lua_getfield(L, LUA_REGISTRYINDEX, ourName); // Coz getfenv() can't find C environment.
359 lua_pushstring(L, "loopWindow");
360 lua_pushstring(L, "Run our windows main loop.");
361 lua_pushcfunction(L, loopWindow);
362 lua_call(L, 4, 0);
363
364 lua_getfield(L, skang, "thingasm");
365 lua_getfield(L, LUA_REGISTRYINDEX, ourName); // Coz getfenv() can't find C environment.
366 lua_pushstring(L, "closeWindow");
367 lua_pushstring(L, "Closes our window.");
368 lua_pushcfunction(L, closeWindow);
369 lua_call(L, 4, 0);
370 619
371 lua_pop(L, openWindow(L)); 620 lua_pop(L, openWindow(L));
372 621
373// skang.moduleEnd(_M) 622// skang.moduleEnd(_M)
374 lua_getfield(L, skang, "moduleEnd"); 623 push_lua(L, "@ ( @ )", skang, "moduleEnd", LUA_REGISTRYINDEX, ourName, 0);
375 lua_getfield(L, LUA_REGISTRYINDEX, ourName);
376 lua_call(L, 1, 0);
377 624
378 return 1; 625 return 1;
379} 626}
@@ -399,8 +646,7 @@ void GuiLuaDo(int argc, char **argv)
399 646
400 // Pass all our command line arguments to skang. 647 // Pass all our command line arguments to skang.
401 i = 1; 648 i = 1;
402 lua_getfield(ourGlobals.L, LUA_REGISTRYINDEX, "skang"); 649 push_lua(ourGlobals.L, "@ ( @", LUA_REGISTRYINDEX, "skang", 1, "scanArguments");
403 lua_getfield(ourGlobals.L, 1, "scanArguments");
404 lua_newtable(ourGlobals.L); 650 lua_newtable(ourGlobals.L);
405 while (--argc > 0 && *++argv != '\0') 651 while (--argc > 0 && *++argv != '\0')
406 { 652 {
@@ -409,9 +655,7 @@ void GuiLuaDo(int argc, char **argv)
409 lua_settable(ourGlobals.L, -3); 655 lua_settable(ourGlobals.L, -3);
410 } 656 }
411 lua_call(ourGlobals.L, 1, 0); 657 lua_call(ourGlobals.L, 1, 0);
412 lua_getfield(ourGlobals.L, 1, "pullArguments"); 658 push_lua(ourGlobals.L, "@ ( @ )", 1, "pullArguments", LUA_REGISTRYINDEX, "skang", 0);
413 lua_getfield(ourGlobals.L, LUA_REGISTRYINDEX, "skang");
414 lua_call(ourGlobals.L, 1, 0);
415 659
416 // Run the main loop via a Lua call. 660 // Run the main loop via a Lua call.
417 lua_pop(ourGlobals.L, loopWindow(ourGlobals.L)); 661 lua_pop(ourGlobals.L, loopWindow(ourGlobals.L));
diff --git a/ClientHamr/GuiLua/GuiLua.h b/ClientHamr/GuiLua/GuiLua.h
index 6debac5..dfc554a 100644
--- a/ClientHamr/GuiLua/GuiLua.h
+++ b/ClientHamr/GuiLua/GuiLua.h
@@ -56,5 +56,8 @@ void dumpStack(lua_State *L, int i);
56void loggingStartup(globals *ourGlobals); 56void loggingStartup(globals *ourGlobals);
57char *getDateTime(struct tm **nowOut, char *dateOut, time_t *tiemOut); 57char *getDateTime(struct tm **nowOut, char *dateOut, time_t *tiemOut);
58 58
59int pull_lua(lua_State *L, int i, char *params, ...);
60int push_lua(lua_State *L, char *params, ...);
61
59int luaopen_widget(lua_State *L); 62int luaopen_widget(lua_State *L);
60void GuiLuaDo(int argc, char **argv); 63void GuiLuaDo(int argc, char **argv);
diff --git a/ClientHamr/GuiLua/test_c.c b/ClientHamr/GuiLua/test_c.c
index 6faf928..ae21139 100644
--- a/ClientHamr/GuiLua/test_c.c
+++ b/ClientHamr/GuiLua/test_c.c
@@ -158,6 +158,7 @@ int luaopen_test_c(lua_State *L)
158 lua_call(L, 2, 0); 158 lua_call(L, 2, 0);
159 159
160// skang.thingasm(_M, 'cfunc', 'cfunc does nothing really', cfunc, 'number,string') 160// skang.thingasm(_M, 'cfunc', 'cfunc does nothing really', cfunc, 'number,string')
161// push_lua(L, "@ @ $ $ & $", skang, "thingasm", LUA_REGISTRYINDEX, ourName, "cfunc", "cfunc does nothing really", cfunc, "number,string");
161 lua_getfield(L, skang, "thingasm"); 162 lua_getfield(L, skang, "thingasm");
162 lua_getfield(L, LUA_REGISTRYINDEX, ourName); // Coz getfenv() can't find C environment. 163 lua_getfield(L, LUA_REGISTRYINDEX, ourName); // Coz getfenv() can't find C environment.
163 lua_pushstring(L, "cfunc"); 164 lua_pushstring(L, "cfunc");