File: test_script.c

package info (click to toggle)
fungw 1.2.2-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 2,268 kB
  • sloc: ansic: 24,257; makefile: 500; sh: 32; awk: 9; perl: 8; tcl: 7; javascript: 7; ruby: 7; python: 6
file content (145 lines) | stat: -rw-r--r-- 3,216 bytes parent folder | download | duplicates (3)
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;
}