61 #define GET_OPTION(parser, name) \
62 amxo_parser_get_config(parser, name)
76 static bool dbg =
false;
79 amxc_htable_it_t* it) {
82 char* no_dlclose = getenv(
"AMXO_NO_DLCLOSE");
84 if(no_dlclose == NULL) {
94 amxc_var_set_type(
config, AMXC_VAR_ID_LIST);
95 amxc_var_add(cstring_t,
config,
".");
98 amxc_var_set_type(
config, AMXC_VAR_ID_BOOL);
99 amxc_var_set(
bool,
config,
false);
107 amxc_string_t symbol;
108 amxc_string_init(&symbol, 0);
110 if(parser->
param != NULL) {
111 const char* param_name = amxd_param_get_name(parser->
param);
113 amxc_string_setf(&symbol,
"_%s_%s", param_name, fn_name);
115 amxc_string_setf(&symbol,
"_%s", fn_name);
118 const char* obj_name = amxd_object_get_name(parser->
object,
120 if(obj_name != NULL) {
122 amxc_string_setf(&symbol,
"_%s_%s", obj_name, fn_name);
124 amxc_string_setf(&symbol,
"_%s", fn_name);
127 amxc_string_setf(&symbol,
"_%s", fn_name);
131 return amxc_string_take_buffer(&symbol);
137 const char* lib_name,
139 amxc_string_t* msg) {
140 char* dl_error = NULL;
142 bool silent = amxc_var_constcast(
bool,
GET_OPTION(parser,
"silent"));
143 dbg = amxc_var_constcast(
bool,
GET_OPTION(parser,
"import-dbg"));
147 helper.
fn = dlsym(lib->
handle, symbol);
148 dl_error = dlerror();
149 if(dl_error == NULL) {
152 "[IMPORT-DBG] - symbol %s resolved (for %s) from %s\n",
160 amxc_string_appendf(msg,
161 "[IMPORT-DBG] - resolving symbol %s (for %s) from %s failed - [%s]\n",
174 amxc_string_t str_data;
177 amxc_llist_it_t* it = NULL;
179 amxc_llist_init(&parts);
180 amxc_string_init(&str_data, 0);
181 amxc_string_push_buffer(&str_data, (
char*) data, strlen(data) + 1);
182 amxc_string_split_to_llist(&str_data, &parts,
':');
183 length = amxc_llist_size(&parts);
185 when_true(length > 2, exit);
187 it = amxc_llist_get_first(&parts);
188 amxc_string_trim(amxc_string_from_llist_it(it), NULL);
189 *lib = amxc_string_take_buffer(amxc_string_from_llist_it(it));
192 it = amxc_llist_get_last(&parts);
193 amxc_string_trim(amxc_string_from_llist_it(it), NULL);
194 *symbol = amxc_string_take_buffer(amxc_string_from_llist_it(it));
198 amxc_llist_clean(&parts, amxc_string_list_it_free);
203 amxc_htable_t* import_data,
209 amxc_string_t res_name;
210 amxc_htable_it_t* it = NULL;
213 amxc_string_init(&msg, 0);
214 amxc_string_init(&res_name, 0);
217 if(amxc_string_set_resolved(&res_name, lib, &parser->
config) > 0) {
219 lib = amxc_string_take_buffer(&res_name);
222 it = amxc_htable_get(import_data, lib);
225 amxo_parser_msg(parser,
"No import library found with name \"%s\"", lib);
226 parser->
status = amxd_status_file_not_found;
235 when_true(fn != NULL, exit);
241 if((fn == NULL) && !amxc_string_is_empty(&msg)) {
242 fprintf(stderr,
"%s", amxc_string_get(&msg, 0));
246 amxc_string_clean(&res_name);
247 amxc_string_clean(&msg);
263 amxc_string_init(&msg, 0);
265 if((data != NULL) && (data[0] != 0)) {
268 amxc_htable_for_each(it, import_data) {
269 const char* lib_name = amxc_htable_it_get_key(it);
286 if((fn == NULL) && !amxc_string_is_empty(&msg)) {
287 fprintf(stderr,
"%s", amxc_string_get(&msg, 0));
290 amxc_string_clean(&msg);
297 amxc_htable_it_t* it = NULL;
301 amxc_htable_insert(import_data, alias, it);
304 it = amxc_htable_get(import_data, alias);
316 amxc_var_t* var_import =
GET_OPTION(parser,
"odl-import");
319 if(var_import != NULL) {
320 import = amxc_var_dyncast(
bool, var_import);
328 const char* full_path,
331 bool silent = amxc_var_constcast(
bool,
GET_OPTION(parser,
"silent"));
332 dbg = amxc_var_constcast(
bool,
GET_OPTION(parser,
"import-dbg"));
334 if((flags & (RTLD_LAZY | RTLD_NOW)) == 0) {
338 handle = dlopen(full_path, flags);
340 char* error = dlerror();
342 fprintf(stderr,
"[IMPORT-DBG] - failed to load %s - %s\n", so_name, error);
344 amxc_string_setf(&parser->
msg,
"Failed to load lib %s", error);
347 fprintf(stderr,
"[IMPORT-DBG] - dlopen - %s (%p)\n", so_name, handle);
361 char* full_path = NULL;
362 bool silent = amxc_var_constcast(
bool,
GET_OPTION(parser,
"silent"));
363 const amxc_llist_t* impdirs =
364 amxc_var_constcast(amxc_llist_t,
GET_OPTION(parser,
"import-dirs"));
366 amxc_string_t res_so_name;
367 amxc_string_t res_alias;
368 amxc_string_init(&res_so_name, 0);
369 amxc_string_init(&res_alias, 0);
371 dbg = amxc_var_constcast(
bool,
GET_OPTION(parser,
"import-dbg"));
373 when_null(parser, exit);
374 parser->
status = amxd_status_invalid_arg;
375 when_str_empty(so_name, exit);
376 when_true(alias != NULL && alias[0] == 0, exit);
378 parser->
status = amxd_status_ok;
381 if(amxc_string_set_resolved(&res_alias, alias, &parser->
config) > 0) {
382 alias = amxc_string_get(&res_alias, 0);
384 if(amxc_string_set_resolved(&res_so_name, so_name, &parser->
config) > 0) {
385 so_name = amxc_string_get(&res_so_name, 0);
394 fprintf(stderr,
"[IMPORT-DBG] - file not found %s\n", so_name);
396 parser->
status = amxd_status_file_not_found;
402 when_null(handle, exit);
405 when_true_status(import_lib == NULL, exit, parser->
status = amxd_status_out_of_mem);
407 import_lib->
handle = handle;
408 if((flags & RTLD_NODELETE) == RTLD_NODELETE) {
411 amxc_htable_insert(import_data, alias, &import_lib->
hit);
415 amxc_string_clean(&res_alias);
416 amxc_string_clean(&res_so_name);
418 if((retval != 0) && (handle != NULL)) {
426 amxc_htable_t* import_data = NULL;
427 amxc_htable_it_t* it = NULL;
428 bool silent = amxc_var_constcast(
bool,
GET_OPTION(parser,
"silent"));
429 dbg = amxc_var_constcast(
bool,
GET_OPTION(parser,
"import-dbg"));
432 it = amxc_htable_take_first(import_data);
436 const char* key = amxc_htable_it_get_key(it);
438 fprintf(stderr,
"[IMPORT-DBG] - symbols used of %s = %d\n", key,
import->references);
440 if(
import->references != 0) {
445 it = amxc_htable_take_first(import_data);
457 .
hit = { .ait = NULL, .key = NULL, .next = NULL },
static bool amxo_parser_no_import(amxo_parser_t *parser)
static amxo_fn_ptr_t amxo_resolver_import(amxo_parser_t *parser, const char *fn_name, UNUSED amxo_fn_type_t type, const char *data, UNUSED void *priv)
static amxc_htable_t import_libs
union _fn_caster fn_caster_t
static amxo_fn_ptr_t amxo_resolver_import_data(amxo_parser_t *parser, amxc_htable_t *import_data, const char *fn_name, const char *data)
static void amxo_resolver_import_parse_data(const char *data, char **lib, char **symbol)
static amxo_resolver_t import
static void * amxo_resolver_import_lib(amxo_parser_t *parser, const char *so_name, const char *full_path, int flags)
static amxo_fn_ptr_t amxo_resolver_try(amxo_parser_t *parser, const char *fn_name, const char *symbol, const char *lib_name, amxo_import_lib_t *lib, amxc_string_t *msg)
static void amxo_resolver_import_defaults(amxo_parser_t *parser, UNUSED void *priv)
struct _amxo_import_lib amxo_import_lib_t
static void amxo_import_lib_free(UNUSED const char *key, amxc_htable_it_t *it)
#define GET_OPTION(parser, name)
static bool amxo_resolver_import_alias_exists(amxc_htable_t *import_data, const char *alias)
void amxo_resolver_import_clean(amxo_parser_t *parser, UNUSED void *priv)
static char * amxo_resolver_import_get_symbol(amxo_parser_t *parser, const char *fn_name, bool prefix)
PRIVATE void PRIVATE int PRIVATE bool amxo_parser_find(amxo_parser_t *parser, const amxc_llist_t *dirs, const char *file_path, char **full_path)
PRIVATE void amxo_parser_msg(amxo_parser_t *parser, const char *format,...) __attribute__((format(printf
void(* amxo_fn_ptr_t)(void)
enum _amxo_fn_type amxo_fn_type_t
amxc_var_t * amxo_parser_claim_config(amxo_parser_t *parser, const char *path)
Gets or creates a configuration option.
int amxo_resolver_import_open(amxo_parser_t *parser, const char *so_name, const char *alias, int flags)
Opens a shared object file (.so file)
void amxo_resolver_import_close_all(void)
Unloads all loaded shared objects.
int amxo_unregister_resolver(const char *name)
Unregisters a function resolver.
amxc_htable_t * amxo_parser_get_resolver_data(amxo_parser_t *parser, const char *resolver_name)
Gets the resolver specific parser data.
amxc_htable_t * amxo_parser_claim_resolver_data(amxo_parser_t *parser, const char *resolver_name)
Fetches resolver specific data for a parser instance.
int amxo_register_resolver(const char *name, amxo_resolver_t *resolver)
Registers a function resolver.
void amxo_parser_remove_resolver_data(amxo_parser_t *parser, const char *resolver_name)
Removes the resolver specific parser data.
The ODL parser structure.