libamxo  4.3.4
Object Definition Language (ODL) parsing
amxo_parser_include.c File Reference
#include "amxo_parser_priv.h"
#include "amxo_parser_hooks_priv.h"
#include "amxo_parser.tab.h"

Go to the source code of this file.

Macros

#define _GNU_SOURCE
 

Functions

static void amxo_parser_push (amxo_parser_t *parent, amxo_parser_t *child)
 
static void amxo_parser_pop (amxo_parser_t *parent, amxo_parser_t *child)
 
static amxc_var_t * amxo_parser_can_include (amxo_parser_t *pctx, const char *full_path)
 
static bool amxo_parser_exists (const char *incdir, const char *file_path, char **full_path)
 
static int amxo_parser_check (amxo_parser_t *pctx, const char *file_path, amxc_var_t **incstack, char **full_path)
 
static int amxo_parser_include_file (amxo_parser_t *pctx, const char *full_path)
 
static int amxo_parser_include_dir (amxo_parser_t *pctx, const char *full_path)
 
bool amxo_parser_find (amxo_parser_t *parser, const amxc_llist_t *dirs, const char *file_path, char **full_path)
 
int amxo_parser_add_post_include (amxo_parser_t *pctx, const char *file_path)
 
int amxo_parser_include (amxo_parser_t *pctx, const char *file_path)
 

Macro Definition Documentation

◆ _GNU_SOURCE

#define _GNU_SOURCE

Definition at line 55 of file amxo_parser_include.c.

Function Documentation

◆ amxo_parser_add_post_include()

int amxo_parser_add_post_include ( amxo_parser_t pctx,
const char *  file_path 
)

Definition at line 290 of file amxo_parser_include.c.

290  {
291  int retval = -1;
292  char* full_path = NULL;
293  amxc_var_t* incstack = NULL;
294 
295  retval = amxo_parser_check(pctx, file_path, &incstack, &full_path);
296  when_failed(retval, exit);
297 
298  if(pctx->post_includes == NULL) {
299  amxc_var_new(&pctx->post_includes);
300  amxc_var_set_type(pctx->post_includes, AMXC_VAR_ID_LIST);
301  }
302 
303  amxc_var_add(cstring_t, pctx->post_includes, full_path);
304 
305 exit:
306  amxc_var_delete(&incstack);
307  free(full_path);
308  return retval;
309 }
static int amxo_parser_check(amxo_parser_t *pctx, const char *file_path, amxc_var_t **incstack, char **full_path)
amxc_var_t * post_includes
Definition: amxo_types.h:275

◆ amxo_parser_can_include()

static amxc_var_t* amxo_parser_can_include ( amxo_parser_t pctx,
const char *  full_path 
)
static

Definition at line 102 of file amxo_parser_include.c.

103  {
104  amxc_var_t* incstack = NULL;
105  if(amxc_var_get_key(pctx->include_stack, full_path, AMXC_VAR_FLAG_DEFAULT) != NULL) {
106  goto exit;
107  }
108  if(pctx->include_stack == NULL) {
109  amxc_var_new(&pctx->include_stack);
110  amxc_var_set_type(pctx->include_stack, AMXC_VAR_ID_HTABLE);
111  }
112  incstack = amxc_var_add_key(bool, pctx->include_stack, full_path, true);
113 
114 exit:
115  return incstack;
116 }
amxc_var_t * include_stack
Definition: amxo_types.h:277

◆ amxo_parser_check()

static int amxo_parser_check ( amxo_parser_t pctx,
const char *  file_path,
amxc_var_t **  incstack,
char **  full_path 
)
static

Definition at line 139 of file amxo_parser_include.c.

142  {
143  int retval = -1;
144  amxc_var_t* config = amxo_parser_get_config(pctx, "include-dirs");
145  const amxc_llist_t* incdirs = amxc_var_constcast(amxc_llist_t, config);
146  amxc_string_t res_file_path;
147  struct stat statbuf;
148 
149  amxc_string_init(&res_file_path, 0);
150 
151  if(amxc_string_set_resolved(&res_file_path, file_path, &pctx->config) > 0) {
152  file_path = amxc_string_get(&res_file_path, 0);
153  }
154 
155  if(!amxo_parser_find(pctx, incdirs, file_path, full_path)) {
156  retval = 2;
157  pctx->status = amxd_status_file_not_found;
158  amxo_parser_msg(pctx, "Include file not found \"%s\"", file_path);
159  goto exit;
160  }
161 
162  if(stat(*full_path, &statbuf) != 0) {
163  retval = 2;
164  pctx->status = amxd_status_file_not_found;
165  amxo_parser_msg(pctx, "Include file not found \"%s\"", file_path);
166  goto exit;
167  }
168 
169  *incstack = amxo_parser_can_include(pctx, *full_path);
170  if(*incstack == NULL) {
171  pctx->status = amxd_status_recursion;
172  amxo_parser_msg(pctx, "Recursive include detected \"%s\"", file_path);
173  goto exit;
174  }
175 
176  retval = 0;
177 
178 exit:
179  amxc_string_clean(&res_file_path);
180  return retval;
181 }
static amxc_var_t * amxo_parser_can_include(amxo_parser_t *pctx, const char *full_path)
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
config
amxc_var_t * amxo_parser_get_config(amxo_parser_t *parser, const char *path)
Gets a configuration option.
amxc_var_t config
Definition: amxo_types.h:250
amxd_status_t status
Definition: amxo_types.h:258

◆ amxo_parser_exists()

static bool amxo_parser_exists ( const char *  incdir,
const char *  file_path,
char **  full_path 
)
static

Definition at line 118 of file amxo_parser_include.c.

120  {
121  bool retval = false;
122  amxc_string_t concat_path;
123  amxc_string_init(&concat_path, 0);
124 
125  if((incdir != NULL) && (*incdir != 0)) {
126  amxc_string_setf(&concat_path, "%s/%s", incdir, file_path);
127  } else {
128  amxc_string_setf(&concat_path, "%s", file_path);
129  }
130  *full_path = realpath(amxc_string_get(&concat_path, 0), NULL);
131  if(*full_path != NULL) {
132  retval = true;
133  }
134  amxc_string_clean(&concat_path);
135 
136  return retval;
137 }

◆ amxo_parser_find()

bool amxo_parser_find ( amxo_parser_t parser,
const amxc_llist_t *  dirs,
const char *  file_path,
char **  full_path 
)

Definition at line 256 of file amxo_parser_include.c.

259  {
260  bool retval = false;
261 
262  if(file_path[0] != '/') {
263  amxc_string_t res_path;
264  amxc_string_init(&res_path, 0);
265  amxc_llist_for_each(it, dirs) {
266  amxc_var_t* var_dir = amxc_var_from_llist_it(it);
267  const char* dir = amxc_var_constcast(cstring_t, var_dir);
268  if(amxc_string_set_resolved(&res_path, dir, &parser->config) > 0) {
269  dir = amxc_string_get(&res_path, 0);
270  }
271 
272  if(amxo_parser_exists(dir, file_path, full_path)) {
273  break;
274  }
275  amxc_string_reset(&res_path);
276  }
277  amxc_string_clean(&res_path);
278  when_null(*full_path, exit);
279  } else {
280  if(!amxo_parser_exists(NULL, file_path, full_path)) {
281  goto exit;
282  }
283  }
284  retval = true;
285 
286 exit:
287  return retval;
288 }
static bool amxo_parser_exists(const char *incdir, const char *file_path, char **full_path)

◆ amxo_parser_include()

int amxo_parser_include ( amxo_parser_t pctx,
const char *  file_path 
)

Definition at line 311 of file amxo_parser_include.c.

311  {
312  int retval = -1;
313  char* full_path = NULL;
314  amxc_var_t* incstack = NULL;
315  struct stat statbuf;
316 
317  retval = amxo_parser_check(pctx, file_path, &incstack, &full_path);
318  when_failed(retval, exit);
319 
320  stat(full_path, &statbuf);
321 
322  if(S_ISDIR(statbuf.st_mode)) {
323  retval = amxo_parser_include_dir(pctx, full_path);
324  } else {
325  retval = amxo_parser_include_file(pctx, full_path);
326  }
327 
328 exit:
329  amxc_var_delete(&incstack);
330  free(full_path);
331  return retval;
332 }
static int amxo_parser_include_file(amxo_parser_t *pctx, const char *full_path)
static int amxo_parser_include_dir(amxo_parser_t *pctx, const char *full_path)

◆ amxo_parser_include_dir()

static int amxo_parser_include_dir ( amxo_parser_t pctx,
const char *  full_path 
)
static

Definition at line 207 of file amxo_parser_include.c.

208  {
209  int retval = -1;
210  int count = 0;
211  struct dirent** namelist;
212  amxc_string_t file;
213  int n;
214 
215  amxc_string_init(&file, 0);
216 
217  n = scandir(full_path, &namelist, NULL, alphasort);
218  if(n == -1) {
219  pctx->status = amxd_status_unknown_error;
220  goto exit;
221  }
222 
223  retval = 0;
224  for(int i = 0; i < n; i++) {
225  int len = 0;
226  if(retval != 0) {
227  free(namelist[i]);
228  continue;
229  }
230  if(namelist[i]->d_type == DT_DIR) {
231  free(namelist[i]);
232  continue;
233  }
234  len = strlen(namelist[i]->d_name);
235  if(strncmp(namelist[i]->d_name + len - 4, ".odl", 4) != 0) {
236  free(namelist[i]);
237  continue;
238  }
239  amxc_string_setf(&file, "%s/%s", full_path, namelist[i]->d_name);
240  retval = amxo_parser_include_file(pctx, amxc_string_get(&file, 0));
241  count++;
242  free(namelist[i]);
243  }
244 
245  if(count == 0) {
246  pctx->status = amxd_status_ok;
247  retval = 4;
248  }
249  free(namelist);
250 
251 exit:
252  amxc_string_clean(&file);
253  return retval;
254 }

◆ amxo_parser_include_file()

static int amxo_parser_include_file ( amxo_parser_t pctx,
const char *  full_path 
)
static

Definition at line 183 of file amxo_parser_include.c.

184  {
185  int retval = -1;
186  amxo_parser_t parser;
187 
188  amxo_parser_child_init(&parser);
189  amxo_hooks_start_include(pctx, full_path);
190  amxo_parser_push(pctx, &parser);
191  retval = amxo_parser_parse_file_impl(&parser, full_path, pctx->object);
192  amxo_parser_pop(pctx, &parser);
193  amxo_hooks_end_include(pctx, full_path);
194  amxo_parser_clean(&parser);
195 
196  if(retval != 0) {
197  retval = 3;
198  if(pctx->status == amxd_status_ok) {
199  pctx->status = amxd_status_unknown_error;
200  }
201  amxo_parser_msg(pctx, "Error found in %s", full_path);
202  }
203 
204  return retval;
205 }
PRIVATE void amxo_hooks_end_include(amxo_parser_t *parser, const char *file)
PRIVATE void amxo_hooks_start_include(amxo_parser_t *parser, const char *file)
static void amxo_parser_push(amxo_parser_t *parent, amxo_parser_t *child)
static void amxo_parser_pop(amxo_parser_t *parent, amxo_parser_t *child)
PRIVATE int amxo_parser_parse_file_impl(amxo_parser_t *parser, const char *file_path, amxd_object_t *object)
PRIVATE void amxo_parser_child_init(amxo_parser_t *parser)
void amxo_parser_clean(amxo_parser_t *parser)
Cleans up the odl parser instance.
The ODL parser structure.
Definition: amxo_types.h:245
amxd_object_t * object
Definition: amxo_types.h:262

◆ amxo_parser_pop()

static void amxo_parser_pop ( amxo_parser_t parent,
amxo_parser_t child 
)
static

Definition at line 74 of file amxo_parser_include.c.

75  {
76  parent->resolvers = child->resolvers;
77  parent->entry_points = child->entry_points;
78  parent->post_includes = child->post_includes;
79  parent->sync_contexts = child->sync_contexts;
80  amxc_llist_move(&parent->event_list, &child->event_list);
81  amxc_llist_move(&parent->function_names, &child->function_names);
82  child->include_stack = NULL;
83  child->hooks = NULL;
84  child->resolvers = NULL;
85  child->entry_points = NULL;
86  child->post_includes = NULL;
87  child->parent = NULL;
88  child->sync_contexts = NULL;
89  amxc_llist_for_each(it, (&child->global_config)) {
90  amxc_string_t* str_name = amxc_string_from_llist_it(it);
91  const char* name = amxc_string_get(str_name, 0);
92  amxc_var_t* option = amxc_var_get_path(&child->config,
93  name,
94  AMXC_VAR_FLAG_DEFAULT);
95  if(!amxc_var_is_null(option)) {
96  amxc_var_set_path(&parent->config, name, option, AMXC_VAR_FLAG_UPDATE | AMXC_VAR_FLAG_AUTO_ADD);
97  amxc_llist_append(&parent->global_config, &str_name->it);
98  }
99  }
100 }
amxc_htable_t * resolvers
Definition: amxo_types.h:269
amxc_llist_t * hooks
Definition: amxo_types.h:274
amxc_lstack_t event_list
Definition: amxo_types.h:283
amxc_llist_t function_names
Definition: amxo_types.h:268
amxc_llist_t * entry_points
Definition: amxo_types.h:273
amxc_llist_t global_config
Definition: amxo_types.h:253
amxo_parser_t * parent
Definition: amxo_types.h:285
amxc_llist_t * sync_contexts
Definition: amxo_types.h:290

◆ amxo_parser_push()

static void amxo_parser_push ( amxo_parser_t parent,
amxo_parser_t child 
)
static

Definition at line 62 of file amxo_parser_include.c.

63  {
64  child->resolvers = parent->resolvers;
65  child->hooks = parent->hooks;
66  child->include_stack = parent->include_stack;
67  child->entry_points = parent->entry_points;
68  child->post_includes = parent->post_includes;
69  child->parent = parent;
70  child->sync_contexts = parent->sync_contexts;
71  amxc_var_copy(&child->config, &parent->config);
72 }