libamxd  6.4.1
Data Model Manager
amxd_object_search_priv.c File Reference
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <amxc/amxc.h>
#include <amxp/amxp.h>
#include <amxd/amxd_types.h>
#include <amxd/amxd_object.h>
#include <amxd/amxd_object_expression.h>
#include <amxd/amxd_dm.h>
#include <amxd/amxd_dm_functions.h>
#include "amxd_priv.h"
#include "amxd_dm_priv.h"
#include "amxd_object_priv.h"
#include "amxd_assert.h"

Go to the source code of this file.

Macros

#define _GNU_SOURCE
 

Functions

static amxd_status_t amxd_object_resolve_next (amxd_object_t *const object, bool *key_path, amxc_llist_t *paths, amxc_llist_it_t *part)
 
static amxd_object_tamxd_template_find (amxd_object_t *const object, bool *key_path, const char *const path, amxd_status_t *status)
 
static amxd_object_tamxd_object_find (amxd_object_t *const object, bool *key_path, const char *path, amxd_status_t *status)
 
static amxd_object_tamxd_template_find_instance (amxd_object_t *templ, bool *key_path, char *str_part, amxd_status_t *status)
 
static amxd_status_t amxd_resolve_add_path_or_continue (amxd_object_t *object, bool *key_path, amxc_llist_t *paths, amxc_llist_it_t *next)
 
static amxd_status_t amxd_template_add_all_instances (amxd_object_t *object, bool *key_path, amxc_llist_t *paths, amxc_llist_it_t *part)
 
static amxd_status_t amxd_template_add_matching_instances (amxd_object_t *object, bool *key_path, amxc_llist_t *paths, amxc_llist_it_t *part)
 
static amxd_status_t amxd_object_resolve_instances (amxd_object_t *const object, bool *key_path, amxc_llist_t *paths, amxc_llist_it_t *part)
 
amxd_object_tamxd_object_find_internal (amxd_object_t *const object, bool *key_path, amxd_path_t *path, amxd_status_t *status)
 
amxd_status_t amxd_object_resolve_internal (amxd_object_t *const object, bool *key_path, amxc_llist_t *paths, amxd_path_t *path)
 

Macro Definition Documentation

◆ _GNU_SOURCE

#define _GNU_SOURCE

Definition at line 56 of file amxd_object_search_priv.c.

Function Documentation

◆ amxd_object_find()

static amxd_object_t* amxd_object_find ( amxd_object_t *const  object,
bool *  key_path,
const char *  path,
amxd_status_t status 
)
static

Definition at line 128 of file amxd_object_search_priv.c.

131  {
132  amxd_object_t* result = object;
133  amxd_object_t* child = NULL;
134  size_t length = strlen(path);
135  when_true(length == 0, exit);
136 
137  child = amxd_object_get_child(result, path);
138  if(child != NULL) {
139  result = child;
140  } else {
141  result = amxd_template_find(object, key_path, path, status);
142  }
143 
144 exit:
145  if(result == NULL) {
147  }
148  return result;
149 }
static amxd_object_t * amxd_template_find(amxd_object_t *const object, bool *key_path, const char *const path, amxd_status_t *status)
@ amxd_status_object_not_found
Definition: amxd_types.h:80
amxd_object_t * amxd_object_get_child(const amxd_object_t *object, const char *name)
Get a child of the object.
static amxd_status_t status

◆ amxd_object_find_internal()

amxd_object_t* amxd_object_find_internal ( amxd_object_t *const  object,
bool *  key_path,
amxd_path_t path,
amxd_status_t status 
)

Definition at line 364 of file amxd_object_search_priv.c.

367  {
368  amxd_object_t* result = object;
369  char* str_part = NULL;
370 
371  amxc_var_for_each(var, (&path->parts)) {
372  str_part = amxc_var_take(cstring_t, var);
373  switch(str_part[0]) {
374  case '*':
376  result = NULL;
377  break;
378  case '{':
381  result = NULL;
382  }
383  break;
384  case '[':
387  result = NULL;
388  } else {
389  result = amxd_template_find_instance(result, key_path, str_part, status);
390  }
391  break;
392  case '.':
393  break;
394  case '^':
395  result = amxd_object_get_parent(result);
396  break;
397  default:
398  result = amxd_object_find(result, key_path, str_part, status);
399  break;
400  }
401  amxc_var_push(cstring_t, var, str_part);
402 
403  when_null(result, exit);
404  }
405 
406 exit:
407  return result;
408 }
static amxd_object_t * amxd_template_find_instance(amxd_object_t *templ, bool *key_path, char *str_part, amxd_status_t *status)
static amxd_object_t * amxd_object_find(amxd_object_t *const object, bool *key_path, const char *path, amxd_status_t *status)
@ amxd_status_invalid_path
Definition: amxd_types.h:99
@ amxd_object_template
Definition: amxd_types.h:183
amxd_object_t * amxd_object_get_parent(const amxd_object_t *const object)
Get the parent object.
static amxd_object_type_t amxd_object_get_type(const amxd_object_t *const object)
Returns the object type.
Definition: amxd_object.h:586
amxc_var_t parts
Definition: amxd_types.h:409

◆ amxd_object_resolve_instances()

static amxd_status_t amxd_object_resolve_instances ( amxd_object_t *const  object,
bool *  key_path,
amxc_llist_t *  paths,
amxc_llist_it_t *  part 
)
static

Definition at line 299 of file amxd_object_search_priv.c.

302  {
304  amxc_var_t* var_part = amxc_var_from_llist_it(part);
305  const char* str_part = amxc_var_constcast(cstring_t, var_part);
306 
307  if(str_part[0] == '*') {
308  status = amxd_template_add_all_instances(object, key_path, paths, part);
309  } else {
310  status = amxd_template_add_matching_instances(object, key_path, paths, part);
311  }
312 
313  return status;
314 }
static amxd_status_t amxd_template_add_all_instances(amxd_object_t *object, bool *key_path, amxc_llist_t *paths, amxc_llist_it_t *part)
static amxd_status_t amxd_template_add_matching_instances(amxd_object_t *object, bool *key_path, amxc_llist_t *paths, amxc_llist_it_t *part)
enum _amxd_status amxd_status_t
@ amxd_status_ok
Definition: amxd_types.h:78

◆ amxd_object_resolve_internal()

amxd_status_t amxd_object_resolve_internal ( amxd_object_t *const  object,
bool *  key_path,
amxc_llist_t *  paths,
amxd_path_t path 
)

Definition at line 410 of file amxd_object_search_priv.c.

413  {
415  amxc_llist_it_t* path_part_it = NULL;
416  const amxc_llist_t* lparts = NULL;
417 
418  lparts = amxc_var_constcast(amxc_llist_t, &path->parts);
419  path_part_it = amxc_llist_get_first(lparts);
420  if(path_part_it != NULL) {
421  status = amxd_object_resolve_next(object, key_path, paths, path_part_it);
422  } else {
423  status = amxd_resolve_add_path_or_continue(object, key_path, paths, NULL);
424  }
425  when_failed(status, exit);
426 
427 exit:
428  if(status != amxd_status_ok) {
429  amxc_llist_clean(paths, amxc_string_list_it_free);
430  }
431  return status;
432 }
static amxd_status_t amxd_object_resolve_next(amxd_object_t *const object, bool *key_path, amxc_llist_t *paths, amxc_llist_it_t *part)
static amxd_status_t amxd_resolve_add_path_or_continue(amxd_object_t *object, bool *key_path, amxc_llist_t *paths, amxc_llist_it_t *next)

◆ amxd_object_resolve_next()

static amxd_status_t amxd_object_resolve_next ( amxd_object_t *const  object,
bool *  key_path,
amxc_llist_t *  paths,
amxc_llist_it_t *  part 
)
static

Definition at line 317 of file amxd_object_search_priv.c.

320  {
322  amxd_object_t* result = object;
323  amxc_var_t* var_part = NULL;
324  const char* str_part = NULL;
325 
326  var_part = amxc_var_from_llist_it(part);
327  str_part = amxc_var_constcast(cstring_t, var_part);
328 
329  switch(str_part[0]) {
330  case '[':
331  case '*':
334  goto exit;
335  }
336  status = amxd_object_resolve_instances(object, key_path, paths, part);
337  break;
338  case '.':
339  status = amxd_resolve_add_path_or_continue(result, key_path, paths, part->next);
340  break;
341  case '^':
342  result = amxd_object_get_parent(result);
343  status = amxd_resolve_add_path_or_continue(result, key_path, paths, part->next);
344  break;
345  default:
347  result = amxd_object_find(result, key_path, str_part, &status);
348  if(result == NULL) {
350  }
351  } else {
352  result = amxd_object_find(result, key_path, str_part, &status);
353  }
354  if(result != NULL) {
355  status = amxd_resolve_add_path_or_continue(result, key_path, paths, part->next);
356  }
357  break;
358  }
359 
360 exit:
361  return status;
362 }
static amxd_status_t amxd_object_resolve_instances(amxd_object_t *const object, bool *key_path, amxc_llist_t *paths, amxc_llist_it_t *part)

◆ amxd_resolve_add_path_or_continue()

static amxd_status_t amxd_resolve_add_path_or_continue ( amxd_object_t object,
bool *  key_path,
amxc_llist_t *  paths,
amxc_llist_it_t *  next 
)
static

Definition at line 210 of file amxd_object_search_priv.c.

213  {
215  if(next == NULL) {
216  amxc_string_t* obj_path = NULL;
218  if(path == NULL) {
220  goto exit;
221  }
222  amxc_string_new(&obj_path, 0);
223  amxc_string_push_buffer(obj_path, path, strlen(path) + 1);
224  amxc_llist_append(paths, &obj_path->it);
225  } else {
226  status = amxd_object_resolve_next(object, key_path, paths, next);
227  }
228 
229 exit:
230  return status;
231 }
#define AMXD_OBJECT_INDEXED
Name and path format flag - use index for instance objects.
Definition: amxd_object.h:176
#define AMXD_OBJECT_TERMINATE
Path format flag - when set the object path is terminated with a dot.
Definition: amxd_object.h:214
amxd_object_t amxd_status_t amxd_status_t char * amxd_object_get_path(const amxd_object_t *object, const uint32_t flags)
Get the full path of the object.

◆ amxd_template_add_all_instances()

static amxd_status_t amxd_template_add_all_instances ( amxd_object_t object,
bool *  key_path,
amxc_llist_t *  paths,
amxc_llist_it_t *  part 
)
static

Definition at line 234 of file amxd_object_search_priv.c.

237  {
239  uint32_t count = 0;
240  amxd_object_for_each(instance, it, object) {
241  amxd_object_t* instance = amxc_container_of(it, amxd_object_t, it);
242  status = amxd_resolve_add_path_or_continue(instance, key_path, paths, part->next);
243  if(status == amxd_status_ok) {
244  count++;
245  }
246  }
247 
248  status = (count > 0 || amxc_llist_is_empty(&object->instances)) ?
250 
251  return status;
252 }
#define amxd_object_for_each(type, it, object)
Helper macro for iterating object content.
Definition: amxd_object.h:113
amxc_llist_t instances
Definition: amxd_types.h:244

◆ amxd_template_add_matching_instances()

static amxd_status_t amxd_template_add_matching_instances ( amxd_object_t object,
bool *  key_path,
amxc_llist_t *  paths,
amxc_llist_it_t *  part 
)
static

Definition at line 255 of file amxd_object_search_priv.c.

258  {
260  amxc_var_t* var_part = amxc_var_from_llist_it(part);
261  char* txt_part = amxc_var_dyncast(cstring_t, var_part);
262  amxd_object_t* tmp = NULL;
263  amxp_expr_t expr;
264  int length = strlen(txt_part);
265 
266  tmp = amxd_template_find(object, key_path, txt_part, &status);
267  if(tmp != NULL) {
268  status = amxd_resolve_add_path_or_continue(tmp, key_path, paths, part->next);
269  goto exit;
270  }
271 
273  goto exit;
274  }
275 
276  txt_part[length - 1] = 0;
277  if(amxp_expr_init(&expr, txt_part + 1) != 0) {
279  goto exit;
280  }
281 
283  object = amxd_object_find_instance(object, &expr);
284 
285  while(object != NULL) {
286  status = amxd_resolve_add_path_or_continue(object, key_path, paths, part->next);
287  when_failed_status(status, exit, amxp_expr_clean(&expr));
288  object = amxd_object_find_next_instance(object, &expr);
289  }
290 
291  amxp_expr_clean(&expr);
292 
293 exit:
294  free(txt_part);
295  return status;
296 }
#define when_failed_status(x, l, c)
Definition: amxd_assert.h:65
amxd_object_t * amxd_object_find_next_instance(const amxd_object_t *const instance, amxp_expr_t *expr)
amxd_object_t * amxd_object_find_instance(const amxd_object_t *const templ, amxp_expr_t *expr)

◆ amxd_template_find()

static amxd_object_t* amxd_template_find ( amxd_object_t *const  object,
bool *  key_path,
const char *const  path,
amxd_status_t status 
)
static

Definition at line 84 of file amxd_object_search_priv.c.

87  {
88  amxd_object_t* result = NULL;
89  size_t length = strlen(path);
90  int64_t index = 0;
91  int offset = 0;
92  char* endptr = NULL;
93 
94  if(path[length - 1] == '.') {
95  length--;
96  }
97  if(path[0] == '[') {
98  offset = 1;
99  length -= 2;
100  }
101 
102  when_true_status(length == 0,
103  exit,
105 
106  index = strtoll(path + offset, &endptr, 0);
107 
108  if((endptr != path) && ((*endptr == '.') || (*endptr == '\0') || (*endptr == ']'))) {
109  result = amxd_object_get_instance(object, NULL, index);
110  } else {
111  char* copy_path = strdup(path + offset);
112  copy_path[length] = 0;
113  result = amxd_object_get_instance(object, copy_path, 0);
114  if(result != NULL) {
115  *key_path = true;
116  }
117  free(copy_path);
118  }
119  if(result == NULL) {
121  }
122 
123 exit:
124  return result;
125 }
amxd_object_t * amxd_object_get_instance(const amxd_object_t *object, const char *name, uint32_t index)
Get an instance of the template object.

◆ amxd_template_find_instance()

static amxd_object_t* amxd_template_find_instance ( amxd_object_t templ,
bool *  key_path,
char *  str_part,
amxd_status_t status 
)
static

Definition at line 152 of file amxd_object_search_priv.c.

155  {
156  amxd_object_t* result = NULL;
157  amxd_object_t* tmp = NULL;
158  amxp_expr_t expr;
159  int length = 0;
160  int offset = 0;
161 
162  length = strlen(str_part);
163  tmp = amxd_template_find(templ, key_path, str_part, status);
164  if(tmp != NULL) {
165  result = tmp;
166  goto exit;
167  }
168 
169  when_true(*status != amxd_status_object_not_found, exit);
170 
171  if(str_part[0] == '[') {
172  length = strlen(str_part);
173  offset = 1;
174  str_part[length - 1] = 0;
175  }
176 
177  if(amxp_expr_init(&expr, str_part + offset) != 0) {
179  goto exit;
180  }
181 
182  result = amxd_object_find_instance(templ, &expr);
183  if(result == NULL) {
184  if(expr.status != amxp_expr_status_ok) {
186  } else {
188  }
189  amxp_expr_clean(&expr);
190  goto exit;
191  }
192 
193  tmp = amxd_object_find_next_instance(result, &expr);
194  if(tmp != NULL) {
196  result = NULL;
197  }
198 
199  amxp_expr_clean(&expr);
200 
201 exit:
202  if(str_part[0] == '[') {
203  str_part[length - 1] = ']';
204  }
205 
206  return result;
207 }
@ amxd_status_duplicate
Definition: amxd_types.h:91