1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
|
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "fgw_string.h"
#include <libfungwbind/c/fungw_c.h>
#include "static_lang.c"
char *def_script = NULL;
int ref_ucc;
extern int *atoi_ucc;
void async_error(fgw_obj_t *obj, const char *msg)
{
printf("Async error: %s: %s\n", obj->name, msg);
}
/* call a function defined in an object (e.g. from lua) */
int hello(fgw_ctx_t *ctx, int how_many, char *who)
{
fgw_arg_t res, arg[3];
fgw_func_t *f;
f = fgw_func_lookup(ctx, "hello");
if (f != NULL) {
arg[0].type = FGW_FUNC;
arg[0].val.argv0.func = f;
arg[0].val.argv0.user_call_ctx = &ref_ucc;
arg[1].type = FGW_INT;
arg[1].val.nat_int = how_many;
arg[2].type = FGW_STR;
arg[2].val.str = who;
f->func(&res, 3, arg);
if (res.type != FGW_INT) {
if ((res.type != FGW_DOUBLE) && (res.type != FGW_LONG) && (res.type != FGW_STR) && (res.type != (FGW_STR | FGW_DYN)))
printf("WARNING: returned non-int, non-double, non-str: %x\n", res.type);
fgw_arg_conv(ctx, &res, FGW_INT);
}
}
else {
printf("ERROR: hello() not found.\n");
return -1;
}
return res.val.nat_int;
}
/* Glue for C "scripting" */
extern void hello_load(fgw_obj_t *obj); /* the code is static linked for this example; could load a .so in real code */
static int c_loader(fgw_obj_t *obj, const char *filename, const char *opts)
{
if (strcmp(filename, "hello.c") != 0) {
fprintf(stderr, "C \"script\" %s is not available\n", filename);
exit(1);
}
hello_load(obj);
return 0;
}
const char *lng;
char *script, script_buff[128];
void config()
{
FILE *f;
lng = getenv("LNG");
script = getenv("SCRIPT");
if (script == NULL) {
fprintf(stderr, "Error: need SCRIPT set to the test script path\n");
exit(1);
}
f = fopen(script, "r");
if (f == NULL) {
fprintf(stderr, "Error: can not open %s for read\n", script);
exit(1);
}
if ((lng == NULL) || (*lng == '\0')) {
lng = fgw_engine_find(script, f);
if (lng == NULL) {
fprintf(stderr, "Error: can not figure the language of %s; please specify it in LNG\n", script);
exit(1);
}
}
fclose(f);
}
int main()
{
fgw_ctx_t ctx;
int res;
/* initialize the "string" engine and language binding engines */
string_init();
static_lang_init();
/* glue for C "scripting" - always needs special treatment */
fgw_c_eng.load = c_loader;
fgw_eng_reg(&fgw_c_eng);
config();
printf("\n### Set up %s (%s)\n", lng, script);
fflush(stdout);
/* initialize a context */
fgw_init(&ctx, "host");
ctx.async_error = async_error;
/* create objects (load script if needed) */
fgw_obj_new(&ctx, "str", "string", NULL, NULL);
fgw_obj_new(&ctx, "hello", lng, script, NULL);
/* Call an object function using a local wrapper */
printf("\n### Call hello()\n");
fflush(stdout);
res = hello(&ctx, 12, "blobbs");
printf("res=%d\n", res);
fflush(stdout);
if (getenv("VERBOSE") != NULL) {
printf("\n### Public functions:\n");
fgw_dump_ctx(&ctx, stdout, "");
fflush(stdout);
}
fgw_uninit(&ctx);
fgw_atexit();
printf("user call context: ");
if (atoi_ucc == &ref_ucc)
printf("ok\n");
else if (atoi_ucc == NULL)
printf("BROKEN! (NULL)\n");
else
printf("BROKEN! (wrong value)\n");
return 0;
}
|