Freeciv-3.3: /fast/freeciv/nightly/main/common/scriptcore/luascript_func.c Source File

Freeciv-3.3

Loading...
Searching...
No Matches
luascript_func.c
Go to the documentation of this file.
1/*****************************************************************************
2 Freeciv - Copyright (C) 2005 - The Freeciv Project
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12*****************************************************************************/
13
14#ifdef HAVE_CONFIG_H
15#include <fc_config.h>
16#endif
17
18#include <stdarg.h>
19
20/* dependencies/lua */
21#include "lua.h"
22#include "lualib.h"
23
24/* utility */
25#include "string_vector.h"
26
27/* common/scriptcore */
28#include "luascript.h"
29#include "luascript_types.h"
30
31#include "luascript_func.h"
32
33static struct luascript_func *func_new(bool required, int nargs,
34 enum api_types *parg_types,
35 int nreturns,
36 enum api_types *preturn_types);
37static void func_destroy(struct luascript_func *pfunc);
38
39 struct luascript_func {
40 bool required; /* if this function is required */
41 int nargs; /* number of arguments to pass */
42 int nreturns; /* number of return values to accept */
43 enum api_types *arg_types; /* argument types */
44 enum api_types *return_types; /* return types */
45};
46
47#define SPECHASH_TAG luascript_func
48#define SPECHASH_ASTR_KEY_TYPE
49#define SPECHASH_IDATA_TYPE struct luascript_func *
50#define SPECHASH_IDATA_FREE func_destroy
51#include "spechash.h"
52
53#define luascript_func_hash_keys_iterate(phash, key) \
54 TYPED_HASH_KEYS_ITERATE(char *, phash, key)
55#define luascript_func_hash_keys_iterate_end \
56 HASH_KEYS_ITERATE_END
57
58/**********************************************************************/
61 static struct luascript_func *func_new(bool required, int nargs,
62 enum api_types *parg_types,
63 int nreturns,
64 enum api_types *preturn_types)
65{
66 struct luascript_func *pfunc = fc_malloc(sizeof(*pfunc));
67
68 pfunc->required = required;
69 pfunc->nargs = nargs;
70 pfunc->arg_types = parg_types;
71 pfunc->nreturns = nreturns;
72 pfunc->return_types = preturn_types;
73
74 return pfunc;
75}
76
77/**********************************************************************/
80 static void func_destroy(struct luascript_func *pfunc)
81{
82 if (pfunc->arg_types) {
83 free(pfunc->arg_types);
84 free(pfunc->return_types);
85 }
86 free(pfunc);
87}
88
89/**********************************************************************/
94 bool luascript_func_check(struct fc_lua *fcl,
95 struct strvec *missing_func_required,
96 struct strvec *missing_func_optional)
97{
98 bool ret = TRUE;
99
100 fc_assert_ret_val(fcl, FALSE);
101 fc_assert_ret_val(fcl->funcs, FALSE);
102
103 luascript_func_hash_keys_iterate(fcl->funcs, func_name) {
104 if (!luascript_check_function(fcl, func_name)) {
105 struct luascript_func *pfunc;
106
107#ifndef FREECIV_NDEBUG
108 bool success =
109#endif
110 luascript_func_hash_lookup(fcl->funcs, func_name, &pfunc);
111
112 fc_assert_ret_val(success, FALSE);
113
114 if (pfunc->required) {
115 strvec_append(missing_func_required, func_name);
116 } else {
117 strvec_append(missing_func_optional, func_name);
118 }
119
120 ret = FALSE;
121 }
122 } luascript_func_hash_keys_iterate_end;
123
124 return ret;
125}
126
127/**********************************************************************/
130 void luascript_func_add_valist(struct fc_lua *fcl, const char *func_name,
131 bool required, int nargs, int nreturns,
132 va_list args)
133{
134 struct luascript_func *pfunc;
135 enum api_types *parg_types;
136 enum api_types *pret_types;
137
138 fc_assert_ret(fcl);
139 fc_assert_ret(fcl->funcs);
140
141 if (luascript_func_hash_lookup(fcl->funcs, func_name, &pfunc)) {
142 luascript_log(fcl, LOG_ERROR, "Function '%s' was already created.",
143 func_name);
144 return;
145 }
146
147 if (nargs > 0) {
148 int i;
149
150 parg_types = fc_calloc(nargs, sizeof(*parg_types));
151
152 for (i = 0; i < nargs; i++) {
153 *(parg_types + i) = va_arg(args, int);
154 }
155 } else {
156 parg_types = NULL;
157 }
158
159 if (nreturns > 0) {
160 int i;
161
162 pret_types = fc_calloc(nreturns, sizeof(*pret_types));
163
164 for (i = 0; i < nreturns; i++) {
165 *(pret_types + i) = va_arg(args, int);
166 }
167 } else {
168 pret_types = NULL;
169 }
170
171 pfunc = func_new(required, nargs, parg_types, nreturns, pret_types);
172 luascript_func_hash_insert(fcl->funcs, func_name, pfunc);
173}
174
175/**********************************************************************/
178 void luascript_func_add(struct fc_lua *fcl, const char *func_name,
179 bool required, int nargs, int nreturns, ...)
180{
181 va_list args;
182
183 va_start(args, nreturns);
184 luascript_func_add_valist(fcl, func_name, required, nargs, nreturns, args);
185 va_end(args);
186}
187
188
189/**********************************************************************/
192 void luascript_func_free(struct fc_lua *fcl)
193{
194 if (fcl && fcl->funcs) {
195 luascript_func_hash_destroy(fcl->funcs);
196 fcl->funcs = NULL;
197 }
198}
199
200/**********************************************************************/
203 void luascript_func_init(struct fc_lua *fcl)
204{
205 fc_assert_ret(fcl != NULL);
206
207 if (fcl->funcs == NULL) {
208 /* Define the prototypes for the needed lua functions. */
209 fcl->funcs = luascript_func_hash_new();
210 }
211}
212
213/**********************************************************************/
220 bool luascript_func_call_valist(struct fc_lua *fcl, const char *func_name,
221 va_list args)
222{
223 struct luascript_func *pfunc;
224 bool success = FALSE;
225
226 fc_assert_ret_val(fcl, FALSE);
227 fc_assert_ret_val(fcl->state, FALSE);
228 fc_assert_ret_val(fcl->funcs, FALSE);
229
230 if (!luascript_func_hash_lookup(fcl->funcs, func_name, &pfunc)) {
231 luascript_log(fcl, LOG_ERROR, "Lua function '%s' does not exist, "
232 "so cannot be invoked.", func_name);
233 return FALSE;
234 }
235
236 /* The function name */
237 lua_getglobal(fcl->state, func_name);
238
239 if (!lua_isfunction(fcl->state, -1)) {
240 if (pfunc->required) {
241 /* This function is required. Thus, this is an error. */
242 luascript_log(fcl, LOG_ERROR, "Unknown lua function '%s'", func_name);
243 lua_pop(fcl->state, 1);
244 }
245 return FALSE;
246 }
247
248 luascript_push_args(fcl, pfunc->nargs, pfunc->arg_types, args);
249
250 /* Call the function with nargs arguments, return 1 results */
251 if (luascript_call(fcl, pfunc->nargs, pfunc->nreturns, NULL) == 0) {
252 /* Successful call to the script. */
253 success = TRUE;
254
255 luascript_pop_returns(fcl, func_name, pfunc->nreturns,
256 pfunc->return_types, args);
257 }
258
259 return success;
260}
261
262/**********************************************************************/
269 bool luascript_func_call(struct fc_lua *fcl, const char *func_name, ...)
270{
271 va_list args;
272 bool success;
273
274 va_start(args, func_name);
275 success = luascript_func_call_valist(fcl, func_name, args);
276 va_end(args);
277
278 return success;
279}
280
281/**********************************************************************/
284 bool luascript_func_is_required(struct fc_lua *fcl, const char *func_name)
285{
286 struct luascript_func *pfunc;
287
288 fc_assert_ret_val(fcl, FALSE);
289 fc_assert_ret_val(fcl->state, FALSE);
290 fc_assert_ret_val(fcl->funcs, FALSE);
291
292 if (!luascript_func_hash_lookup(fcl->funcs, func_name, &pfunc)) {
293 luascript_log(fcl, LOG_ERROR, "Lua function '%s' does not exist.",
294 func_name);
295 return FALSE;
296 }
297
298 return pfunc->required;
299}
incite_cost
char * incite_cost
Definition comments.c:74
fc_assert_ret
#define fc_assert_ret(condition)
Definition log.h:191
fc_assert_ret_val
#define fc_assert_ret_val(condition, val)
Definition log.h:194
LOG_ERROR
@ LOG_ERROR
Definition log.h:30
luascript_pop_returns
void luascript_pop_returns(struct fc_lua *fcl, const char *func_name, int nreturns, enum api_types *preturn_types, va_list args)
Definition luascript.c:443
luascript_push_args
void luascript_push_args(struct fc_lua *fcl, int nargs, enum api_types *parg_types, va_list args)
Definition luascript.c:502
luascript_check_function
bool luascript_check_function(struct fc_lua *fcl, const char *funcname)
Definition luascript.c:553
luascript_log
void luascript_log(struct fc_lua *fcl, enum log_level level, const char *format,...)
Definition luascript.c:410
luascript_call
int luascript_call(struct fc_lua *fcl, int narg, int nret, const char *code)
Definition luascript.c:579
luascript.h
luascript_func_call_valist
bool luascript_func_call_valist(struct fc_lua *fcl, const char *func_name, va_list args)
Definition luascript_func.c:220
func_destroy
static void func_destroy(struct luascript_func *pfunc)
Definition luascript_func.c:80
luascript_func_hash_keys_iterate_end
#define luascript_func_hash_keys_iterate_end
Definition luascript_func.c:55
luascript_func_check
bool luascript_func_check(struct fc_lua *fcl, struct strvec *missing_func_required, struct strvec *missing_func_optional)
Definition luascript_func.c:94
luascript_func_init
void luascript_func_init(struct fc_lua *fcl)
Definition luascript_func.c:203
luascript_func_add
void luascript_func_add(struct fc_lua *fcl, const char *func_name, bool required, int nargs, int nreturns,...)
Definition luascript_func.c:178
func_new
static struct luascript_func * func_new(bool required, int nargs, enum api_types *parg_types, int nreturns, enum api_types *preturn_types)
Definition luascript_func.c:61
luascript_func_call
bool luascript_func_call(struct fc_lua *fcl, const char *func_name,...)
Definition luascript_func.c:269
luascript_func_add_valist
void luascript_func_add_valist(struct fc_lua *fcl, const char *func_name, bool required, int nargs, int nreturns, va_list args)
Definition luascript_func.c:130
luascript_func_is_required
bool luascript_func_is_required(struct fc_lua *fcl, const char *func_name)
Definition luascript_func.c:284
luascript_func_hash_keys_iterate
#define luascript_func_hash_keys_iterate(phash, key)
Definition luascript_func.c:53
luascript_func_free
void luascript_func_free(struct fc_lua *fcl)
Definition luascript_func.c:192
luascript_func.h
luascript_types.h
fc_calloc
#define fc_calloc(n, esz)
Definition mem.h:38
fc_malloc
#define fc_malloc(sz)
Definition mem.h:34
spechash.h
strvec_append
void strvec_append(struct strvec *psv, const char *string)
Definition string_vector.c:279
string_vector.h
fc_lua
Definition luascript.h:44
luascript_func
Definition luascript_func.c:39
luascript_func::required
bool required
Definition luascript_func.c:40
luascript_func::nreturns
int nreturns
Definition luascript_func.c:42
luascript_func::arg_types
enum api_types * arg_types
Definition luascript_func.c:43
luascript_func::nargs
int nargs
Definition luascript_func.c:41
luascript_func::return_types
enum api_types * return_types
Definition luascript_func.c:44
strvec
Definition string_vector.c:29
TRUE
#define TRUE
Definition support.h:46
FALSE
#define FALSE
Definition support.h:47