libamxo  4.3.4
Object Definition Language (ODL) parsing
amxo_import_resolver.c File Reference
#include "amxo_parser_priv.h"

Go to the source code of this file.

Data Structures

struct  _amxo_import_lib
 
union  _fn_caster
 

Macros

#define _GNU_SOURCE
 
#define GET_OPTION(parser, name)    amxo_parser_get_config(parser, name)
 

Typedefs

typedef struct _amxo_import_lib amxo_import_lib_t
 
typedef union _fn_caster fn_caster_t
 

Functions

static void amxo_import_lib_free (UNUSED const char *key, amxc_htable_it_t *it)
 
static void amxo_resolver_import_defaults (amxo_parser_t *parser, UNUSED void *priv)
 
static char * amxo_resolver_import_get_symbol (amxo_parser_t *parser, const char *fn_name, bool prefix)
 
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_parse_data (const char *data, char **lib, char **symbol)
 
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 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 bool amxo_resolver_import_alias_exists (amxc_htable_t *import_data, const char *alias)
 
static bool amxo_parser_no_import (amxo_parser_t *parser)
 
static void * amxo_resolver_import_lib (amxo_parser_t *parser, const char *so_name, const char *full_path, int flags)
 
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) More...
 
void amxo_resolver_import_clean (amxo_parser_t *parser, UNUSED void *priv)
 
void amxo_resolver_import_close_all (void)
 Unloads all loaded shared objects. More...
 
 CONSTRUCTOR_LVL (110)
 
 DESTRUCTOR_LVL (110)
 

Variables

static amxc_htable_t import_libs
 
static bool dbg = false
 
static amxo_resolver_t import
 

Macro Definition Documentation

◆ _GNU_SOURCE

#define _GNU_SOURCE

Definition at line 56 of file amxo_import_resolver.c.

◆ GET_OPTION

#define GET_OPTION (   parser,
  name 
)     amxo_parser_get_config(parser, name)

Definition at line 61 of file amxo_import_resolver.c.

Typedef Documentation

◆ amxo_import_lib_t

◆ fn_caster_t

typedef union _fn_caster fn_caster_t

Function Documentation

◆ amxo_import_lib_free()

static void amxo_import_lib_free ( UNUSED const char *  key,
amxc_htable_it_t *  it 
)
static

Definition at line 78 of file amxo_import_resolver.c.

79  {
80  amxo_import_lib_t* import =
81  amxc_htable_it_get_data(it, amxo_import_lib_t, hit);
82  char* no_dlclose = getenv("AMXO_NO_DLCLOSE");
83 
84  if(no_dlclose == NULL) {
85  dlclose(import->handle);
86  }
87  free(import);
88 }
static amxo_resolver_t import

◆ amxo_parser_no_import()

static bool amxo_parser_no_import ( amxo_parser_t parser)
static

Definition at line 315 of file amxo_import_resolver.c.

315  {
316  amxc_var_t* var_import = GET_OPTION(parser, "odl-import");
317  bool import = true;
318 
319  if(var_import != NULL) {
320  import = amxc_var_dyncast(bool, var_import);
321  }
322 
323  return !import;
324 }
#define GET_OPTION(parser, name)

◆ amxo_resolver_import()

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

Definition at line 254 of file amxo_import_resolver.c.

258  {
259  amxc_htable_t* import_data = amxo_parser_get_resolver_data(parser, "import");
260  amxo_fn_ptr_t fn = NULL;
261  amxc_string_t msg;
262 
263  amxc_string_init(&msg, 0);
264 
265  if((data != NULL) && (data[0] != 0)) {
266  fn = amxo_resolver_import_data(parser, import_data, fn_name, data);
267  } else {
268  amxc_htable_for_each(it, import_data) {
269  const char* lib_name = amxc_htable_it_get_key(it);
270  amxo_import_lib_t* import =
271  amxc_htable_it_get_data(it, amxo_import_lib_t, hit);
272  char* symbol = amxo_resolver_import_get_symbol(parser, fn_name, true);
273  fn = amxo_resolver_try(parser, fn_name, symbol, lib_name, import, &msg);
274  free(symbol);
275  if(fn == NULL) {
276  symbol = amxo_resolver_import_get_symbol(parser, fn_name, false);
277  fn = amxo_resolver_try(parser, fn_name, symbol, lib_name, import, &msg);
278  free(symbol);
279  }
280  if(fn != NULL) {
281  break;
282  }
283  }
284  }
285 
286  if((fn == NULL) && !amxc_string_is_empty(&msg)) {
287  fprintf(stderr, "%s", amxc_string_get(&msg, 0));
288  }
289 
290  amxc_string_clean(&msg);
291  return fn;
292 }
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 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 char * amxo_resolver_import_get_symbol(amxo_parser_t *parser, const char *fn_name, bool prefix)
void(* amxo_fn_ptr_t)(void)
Definition: amxo_types.h:71
amxc_htable_t * amxo_parser_get_resolver_data(amxo_parser_t *parser, const char *resolver_name)
Gets the resolver specific parser data.

◆ amxo_resolver_import_alias_exists()

static bool amxo_resolver_import_alias_exists ( amxc_htable_t *  import_data,
const char *  alias 
)
static

Definition at line 294 of file amxo_import_resolver.c.

295  {
296  bool retval = true;
297  amxc_htable_it_t* it = NULL;
298 
299  it = amxc_htable_get(&import_libs, alias);
300  if(it != NULL) {
301  amxc_htable_insert(import_data, alias, it);
302  goto exit;
303  }
304  it = amxc_htable_get(import_data, alias);
305  if(it != NULL) {
306  goto exit;
307  }
308 
309  retval = false;
310 
311 exit:
312  return retval;
313 }
static amxc_htable_t import_libs

◆ amxo_resolver_import_clean()

void amxo_resolver_import_clean ( amxo_parser_t parser,
UNUSED void *  priv 
)

Definition at line 424 of file amxo_import_resolver.c.

425  {
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"));
430  import_data = amxo_parser_get_resolver_data(parser, "import");
431 
432  it = amxc_htable_take_first(import_data);
433  while(it) {
434  amxo_import_lib_t* import =
435  amxc_htable_it_get_data(it, amxo_import_lib_t, hit);
436  const char* key = amxc_htable_it_get_key(it);
437  if(dbg && !silent) {
438  fprintf(stderr, "[IMPORT-DBG] - symbols used of %s = %d\n", key, import->references);
439  }
440  if(import->references != 0) {
441  amxc_htable_insert(&import_libs, key, it);
442  } else {
443  amxc_htable_it_clean(it, amxo_import_lib_free);
444  }
445  it = amxc_htable_take_first(import_data);
446  }
447  amxc_htable_clean(import_data, amxo_import_lib_free);
448  amxo_parser_remove_resolver_data(parser, "import");
449 }
static bool dbg
static void amxo_import_lib_free(UNUSED const char *key, amxc_htable_it_t *it)
void amxo_parser_remove_resolver_data(amxo_parser_t *parser, const char *resolver_name)
Removes the resolver specific parser data.

◆ amxo_resolver_import_data()

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

Definition at line 202 of file amxo_import_resolver.c.

205  {
206  amxo_fn_ptr_t fn = NULL;
207  char* lib = NULL;
208  char* symbol = NULL;
209  amxc_string_t res_name;
210  amxc_htable_it_t* it = NULL;
211  amxo_import_lib_t* import = NULL;
212  amxc_string_t msg;
213  amxc_string_init(&msg, 0);
214  amxc_string_init(&res_name, 0);
215  amxo_resolver_import_parse_data(data, &lib, &symbol);
216 
217  if(amxc_string_set_resolved(&res_name, lib, &parser->config) > 0) {
218  free(lib);
219  lib = amxc_string_take_buffer(&res_name);
220  }
221 
222  it = amxc_htable_get(import_data, lib);
223  import = amxc_htable_it_get_data(it, amxo_import_lib_t, hit);
224  if(import == NULL) {
225  amxo_parser_msg(parser, "No import library found with name \"%s\"", lib);
226  parser->status = amxd_status_file_not_found;
227  goto exit;
228  }
229 
230  if(symbol != NULL) {
231  fn = amxo_resolver_try(parser, fn_name, symbol, lib, import, &msg);
232  } else {
233  symbol = amxo_resolver_import_get_symbol(parser, fn_name, true);
234  fn = amxo_resolver_try(parser, fn_name, symbol, lib, import, &msg);
235  when_true(fn != NULL, exit);
236  free(symbol);
237  symbol = amxo_resolver_import_get_symbol(parser, fn_name, false);
238  fn = amxo_resolver_try(parser, fn_name, symbol, lib, import, &msg);
239  }
240 
241  if((fn == NULL) && !amxc_string_is_empty(&msg)) {
242  fprintf(stderr, "%s", amxc_string_get(&msg, 0));
243  }
244 
245 exit:
246  amxc_string_clean(&res_name);
247  amxc_string_clean(&msg);
248  free(lib);
249  free(symbol);
250 
251  return fn;
252 }
static void amxo_resolver_import_parse_data(const char *data, char **lib, char **symbol)
PRIVATE void amxo_parser_msg(amxo_parser_t *parser, const char *format,...) __attribute__((format(printf
amxc_var_t config
Definition: amxo_types.h:250
amxd_status_t status
Definition: amxo_types.h:258

◆ amxo_resolver_import_defaults()

static void amxo_resolver_import_defaults ( amxo_parser_t parser,
UNUSED void *  priv 
)
static

Definition at line 90 of file amxo_import_resolver.c.

91  {
92  amxc_var_t* config = amxo_parser_claim_config(parser, "import-dirs");
93 
94  amxc_var_set_type(config, AMXC_VAR_ID_LIST);
95  amxc_var_add(cstring_t, config, ".");
96 
97  config = amxo_parser_claim_config(parser, "import-dbg");
98  amxc_var_set_type(config, AMXC_VAR_ID_BOOL);
99  amxc_var_set(bool, config, false);
100 
101  return;
102 }
config
amxc_var_t * amxo_parser_claim_config(amxo_parser_t *parser, const char *path)
Gets or creates a configuration option.

◆ amxo_resolver_import_get_symbol()

static char* amxo_resolver_import_get_symbol ( amxo_parser_t parser,
const char *  fn_name,
bool  prefix 
)
static

Definition at line 104 of file amxo_import_resolver.c.

106  {
107  amxc_string_t symbol;
108  amxc_string_init(&symbol, 0);
109 
110  if(parser->param != NULL) {
111  const char* param_name = amxd_param_get_name(parser->param);
112  if(prefix) {
113  amxc_string_setf(&symbol, "_%s_%s", param_name, fn_name);
114  } else {
115  amxc_string_setf(&symbol, "_%s", fn_name);
116  }
117  } else {
118  const char* obj_name = amxd_object_get_name(parser->object,
119  AMXD_OBJECT_NAMED);
120  if(obj_name != NULL) {
121  if(prefix) {
122  amxc_string_setf(&symbol, "_%s_%s", obj_name, fn_name);
123  } else {
124  amxc_string_setf(&symbol, "_%s", fn_name);
125  }
126  } else {
127  amxc_string_setf(&symbol, "_%s", fn_name);
128  }
129  }
130 
131  return amxc_string_take_buffer(&symbol);
132 }
amxd_param_t * param
Definition: amxo_types.h:263
amxd_object_t * object
Definition: amxo_types.h:262

◆ amxo_resolver_import_lib()

static void* amxo_resolver_import_lib ( amxo_parser_t parser,
const char *  so_name,
const char *  full_path,
int  flags 
)
static

Definition at line 326 of file amxo_import_resolver.c.

329  {
330  void* handle = NULL;
331  bool silent = amxc_var_constcast(bool, GET_OPTION(parser, "silent"));
332  dbg = amxc_var_constcast(bool, GET_OPTION(parser, "import-dbg"));
333 
334  if((flags & (RTLD_LAZY | RTLD_NOW)) == 0) {
335  flags |= RTLD_LAZY;
336  }
337  dlerror();
338  handle = dlopen(full_path, flags);
339  if(handle == NULL) {
340  char* error = dlerror();
341  if(dbg && !silent) {
342  fprintf(stderr, "[IMPORT-DBG] - failed to load %s - %s\n", so_name, error);
343  }
344  amxc_string_setf(&parser->msg, "Failed to load lib %s", error);
345  } else {
346  if(dbg && !silent) {
347  fprintf(stderr, "[IMPORT-DBG] - dlopen - %s (%p)\n", so_name, handle);
348  }
349  }
350 
351  return handle;
352 }
amxc_string_t msg
Definition: amxo_types.h:259

◆ amxo_resolver_import_parse_data()

static void amxo_resolver_import_parse_data ( const char *  data,
char **  lib,
char **  symbol 
)
static

Definition at line 171 of file amxo_import_resolver.c.

173  {
174  amxc_string_t str_data;
175  amxc_llist_t parts;
176  size_t length = 0;
177  amxc_llist_it_t* it = NULL;
178 
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);
184 
185  when_true(length > 2, exit);
186 
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));
190 
191  if(length > 1) {
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));
195  }
196 
197 exit:
198  amxc_llist_clean(&parts, amxc_string_list_it_free);
199  return;
200 }

◆ amxo_resolver_try()

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

Definition at line 134 of file amxo_import_resolver.c.

139  {
140  char* dl_error = NULL;
141  fn_caster_t helper;
142  bool silent = amxc_var_constcast(bool, GET_OPTION(parser, "silent"));
143  dbg = amxc_var_constcast(bool, GET_OPTION(parser, "import-dbg"));
144 
145  helper.fn = NULL;
146  dlerror();
147  helper.fn = dlsym(lib->handle, symbol);
148  dl_error = dlerror();
149  if(dl_error == NULL) {
150  if(dbg && !silent) {
151  fprintf(stderr,
152  "[IMPORT-DBG] - symbol %s resolved (for %s) from %s\n",
153  symbol,
154  fn_name,
155  lib_name);
156  }
157  lib->references++;
158  } else {
159  if(dbg && !silent) {
160  amxc_string_appendf(msg,
161  "[IMPORT-DBG] - resolving symbol %s (for %s) from %s failed - [%s]\n",
162  symbol,
163  fn_name,
164  lib_name,
165  dl_error);
166  }
167  }
168  return helper.amxo_fn;
169 }
amxo_fn_ptr_t amxo_fn

◆ CONSTRUCTOR_LVL()

CONSTRUCTOR_LVL ( 110  )

Definition at line 464 of file amxo_import_resolver.c.

464  {
465  amxc_htable_init(&import_libs, 10);
466  amxo_register_resolver("import", &import);
467 }
int amxo_register_resolver(const char *name, amxo_resolver_t *resolver)
Registers a function resolver.

◆ DESTRUCTOR_LVL()

DESTRUCTOR_LVL ( 110  )

Definition at line 469 of file amxo_import_resolver.c.

469  {
470  amxc_htable_clean(&import_libs, amxo_import_lib_free);
471  amxo_unregister_resolver("import");
472 }
int amxo_unregister_resolver(const char *name)
Unregisters a function resolver.

Variable Documentation

◆ dbg

bool dbg = false
static

Definition at line 76 of file amxo_import_resolver.c.

◆ import

amxo_resolver_t import
static
Initial value:
= {
.hit = { .ait = NULL, .key = NULL, .next = NULL },
.priv = NULL
}
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 void amxo_resolver_import_defaults(amxo_parser_t *parser, UNUSED void *priv)
void amxo_resolver_import_clean(amxo_parser_t *parser, UNUSED void *priv)

Definition at line 456 of file amxo_import_resolver.c.

◆ import_libs

amxc_htable_t import_libs
static

Definition at line 75 of file amxo_import_resolver.c.