libamxd  6.4.1
Data Model Manager
amxd_object_hierarchy.c
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** SPDX-License-Identifier: BSD-2-Clause-Patent
4 **
5 ** SPDX-FileCopyrightText: Copyright (c) 2023 SoftAtHome
6 **
7 ** Redistribution and use in source and binary forms, with or without modification,
8 ** are permitted provided that the following conditions are met:
9 **
10 ** 1. Redistributions of source code must retain the above copyright notice,
11 ** this list of conditions and the following disclaimer.
12 **
13 ** 2. Redistributions in binary form must reproduce the above copyright notice,
14 ** this list of conditions and the following disclaimer in the documentation
15 ** and/or other materials provided with the distribution.
16 **
17 ** Subject to the terms and conditions of this license, each copyright holder
18 ** and contributor hereby grants to those receiving rights under this license
19 ** a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable
20 ** (except for failure to satisfy the conditions of this license) patent license
21 ** to make, have made, use, offer to sell, sell, import, and otherwise transfer
22 ** this software, where such license applies only to those patent claims, already
23 ** acquired or hereafter acquired, licensable by such copyright holder or contributor
24 ** that are necessarily infringed by:
25 **
26 ** (a) their Contribution(s) (the licensed copyrights of copyright holders and
27 ** non-copyrightable additions of contributors, in source or binary form) alone;
28 ** or
29 **
30 ** (b) combination of their Contribution(s) with the work of authorship to which
31 ** such Contribution(s) was added by such copyright holder or contributor, if,
32 ** at the time the Contribution is added, such addition causes such combination
33 ** to be necessarily infringed. The patent license shall not apply to any other
34 ** combinations which include the Contribution.
35 **
36 ** Except as expressly stated above, no rights or licenses from any copyright
37 ** holder or contributor is granted under this license, whether expressly, by
38 ** implication, estoppel or otherwise.
39 **
40 ** DISCLAIMER
41 **
42 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
43 ** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
44 ** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
45 ** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
46 ** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
47 ** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
48 ** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
49 ** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
50 ** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
51 ** USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
52 **
53 ****************************************************************************/
54 
55 #ifndef _GNU_SOURCE
56 #define _GNU_SOURCE
57 #endif
58 
59 #include <stdlib.h>
60 #include <string.h>
61 #include <stdarg.h>
62 #include <ctype.h>
63 
64 #include "amxd_priv.h"
65 
66 #include <amxd/amxd_common.h>
67 #include <amxd/amxd_dm.h>
68 #include <amxd/amxd_object.h>
69 #include <amxd/amxd_path.h>
70 
71 #include "amxd_priv.h"
72 #include "amxd_dm_priv.h"
73 #include "amxd_object_priv.h"
74 #include "amxd_assert.h"
75 
76 static void amxd_object_hierarchy_up(amxd_object_t* const object,
79  int32_t depth,
80  void* priv) {
81  amxd_object_t* current = object;
82  while(current != NULL && depth >= 0) {
83  if((filter != NULL) && !filter(current, depth, priv)) {
84  break;
85  }
86  cb(current, depth, priv);
87  current = amxd_object_get_parent(current);
88  depth = depth == INT32_MAX ? INT32_MAX : depth - 1;
89  }
90 }
91 
92 static void amxd_object_hierarchy_down(amxd_object_t* const object,
93  const amxd_direction_t direction,
96  int32_t depth,
97  void* priv) {
98  if(depth < 0) {
99  return;
100  }
101 
102  if((filter != NULL) && !filter(object, depth, priv)) {
103  return;
104  }
105  if(direction == amxd_direction_down) {
106  cb(object, depth, priv);
107  }
108 
109  depth = depth == INT32_MAX ? INT32_MAX : depth - 1;
110  amxd_object_for_each(child, it, object) {
111  amxd_object_t* child = amxc_container_of(it, amxd_object_t, it);
112  amxd_object_hierarchy_down(child, direction, filter, cb, depth, priv);
113  }
114 
115  amxd_object_for_each(instance, it, object) {
116  amxd_object_t* instance = amxc_container_of(it, amxd_object_t, it);
117  amxd_object_hierarchy_down(instance, direction, filter, cb, depth, priv);
118  }
119  if(direction == amxd_direction_down_reverse) {
120  cb(object, depth, priv);
121  }
122 }
123 
124 static void amxd_path_prepend_instance(const amxd_object_t* object,
125  amxc_string_t* path,
126  const char* name,
127  uint32_t length,
128  const uint32_t flags) {
130  if((flags & AMXD_OBJECT_EXTENDED) == AMXD_OBJECT_EXTENDED) {
131  if((flags & AMXD_OBJECT_REGEXP) == AMXD_OBJECT_REGEXP) {
132  amxc_string_prepend(path, "\\]", 2);
133  } else {
134  amxc_string_prepend(path, "]", 1);
135  }
136  }
137  if((flags & AMXD_OBJECT_INDEXED) == AMXD_OBJECT_INDEXED) {
138  amxc_string_prependf(path, "%" PRId32, object->index);
139  } else {
140  amxc_string_prepend(path, name, length);
141  }
142  if((flags & AMXD_OBJECT_EXTENDED) == AMXD_OBJECT_EXTENDED) {
143  if((flags & AMXD_OBJECT_REGEXP) == AMXD_OBJECT_REGEXP) {
144  amxc_string_prepend(path, "\\[", 2);
145  } else {
146  amxc_string_prepend(path, "[", 1);
147  }
148  }
149  }
150 }
151 
152 static char* amxd_object_build_path(const amxd_object_t* object,
153  const amxd_object_t* stop,
154  const uint32_t flags) {
155  amxc_string_t path;
156  const amxd_object_t* current = object;
157  const char* sep = NULL;
158  char* str_path = NULL;
159  int sep_length = 0;
160 
161  if((flags & AMXD_OBJECT_REGEXP) == AMXD_OBJECT_REGEXP) {
162  sep = "\\.";
163  sep_length = 2;
164  } else {
165  sep = ".";
166  sep_length = 1;
167  }
168 
169  amxc_string_init(&path, 64);
170 
171  while(current != stop &&
172  amxd_object_get_name(current, flags) != NULL) {
173  const char* name = amxd_object_get_name(current, flags);
174  int length = strlen(name);
175 
176  if(!amxc_string_is_empty(&path) &&
177  ( strncmp(path.buffer, sep, sep_length) != 0)) {
178  amxc_string_prepend(&path, sep, sep_length);
179  }
180 
182  amxd_path_prepend_instance(current, &path, name, length, flags);
183  } else {
184  if(((flags & AMXD_OBJECT_SUPPORTED) == AMXD_OBJECT_SUPPORTED) &&
186  amxc_string_prepend(&path, "{i}", 3);
187  amxc_string_prepend(&path, sep, sep_length);
188  }
189  amxc_string_prepend(&path, name, length);
190  }
191  current = amxd_object_get_parent(current);
192  }
193 
195  amxc_string_append(&path, sep, sep_length);
196  }
197 
198  str_path = amxc_string_take_buffer(&path);
199  amxc_string_clean(&path);
200 
201  return str_path;
202 }
203 
205  amxd_path_t* path) {
206  char* part = NULL;
207 
209  part = amxd_path_get_first(path, true);
210  free(part);
211  }
212  part = amxd_path_get_first(path, true);
213  if((part != NULL) && (part[0] == '.')) {
214  free(part);
215  part = amxd_path_get_first(path, true);
216  }
217  when_null(part, exit);
218  object = amxd_object_get(object, part);
219  free(part);
220  when_null(object, exit);
221  object = amxd_object_is_supported_impl(object, path);
222 
223 exit:
224  return object;
225 }
226 
228  amxd_object_t* parent = NULL;
229  when_null(object, exit);
230  when_true(amxd_object_is_base(object), exit);
231  when_true(object->type == amxd_object_mib, exit);
232  when_null(object->it.llist, exit);
233 
234  if(object->type == amxd_object_instance) {
235  parent = amxc_container_of(object->it.llist, amxd_object_t, instances);
236  } else {
237  parent = amxc_container_of(object->it.llist, amxd_object_t, objects);
238  }
239 
240 exit:
241  return parent;
242 }
243 
245  amxd_object_t* root = NULL;
246  when_null(object, exit);
247  when_true(amxd_object_is_base(object), exit);
248  when_true(object->type == amxd_object_mib, exit);
249 
250  root = amxd_object_get_parent(object);
251  when_null(root, exit);
252 
253  while(root && root->it.llist != NULL) {
254  root = amxd_object_get_parent(root);
255  }
256 
257  if((root != NULL) && (root->type != amxd_object_root)) {
258  root = NULL;
259  }
260 
261 exit:
262  return root;
263 }
264 
266  amxd_object_t* parent = NULL;
267  amxd_dm_t* dm = NULL;
268 
269  when_null(object, exit);
270  when_true(amxd_object_is_base(object), exit);
271 
272  if(amxd_object_get_type(object) == amxd_object_mib) {
273  when_null(object->it.llist, exit);
274  dm = amxc_container_of(object->it.llist, amxd_dm_t, mibs);
275  goto exit;
276  } else if(amxd_object_get_type(object) == amxd_object_root) {
277  dm = amxc_container_of(object, amxd_dm_t, object);
278  goto exit;
279  }
280 
281  parent = amxd_object_get_parent(object);
282  while(parent != NULL &&
283  parent->type != amxd_object_mib &&
284  parent->type != amxd_object_root) {
285  parent = amxd_object_get_parent(parent);
286  }
287 
288  if(amxd_object_get_type(parent) == amxd_object_mib) {
289  when_null(parent->it.llist, exit);
290  dm = amxc_container_of(parent->it.llist, amxd_dm_t, mibs);
291  } else if(amxd_object_get_type(parent) == amxd_object_root) {
292  dm = amxc_container_of(parent, amxd_dm_t, object);
293  }
294 
295 exit:
296  return dm;
297 }
298 
300  const char* name) {
301  amxd_object_t* result = NULL;
302  int length = 0;
303  when_null(object, exit);
304  when_str_empty(name, exit);
305 
306  length = strlen(name);
307  if(name[length - 1] == '.') {
308  length--;
309  }
310 
311  amxc_llist_for_each(it, (&object->objects)) {
312  const char* n = NULL;
313  int nlen = 0;
314  result = amxc_llist_it_get_data(it, amxd_object_t, it);
316  nlen = strlen(n);
317  if((nlen == length) && (strncmp(n, name, length) == 0)) {
318  break;
319  }
320  result = NULL;
321  }
322 
323 exit:
324  return result;
325 }
326 
328  const char* name,
329  uint32_t index) {
330  amxd_object_t* result = NULL;
331  int length = 0;
332  int offset = 0;
333  when_null(object, exit);
334 
335  if((name != NULL) && (name[0] != 0)) {
336  amxd_param_t* alias_param = amxd_object_get_param_def(object, "Alias");
337  length = strlen(name);
338  if(alias_param == NULL) {
339  if(name[length - 1] == '.') {
340  length--;
341  }
342  if(name[0] == '[') {
343  length = strlen(name);
344  length -= 2;
345  offset = 1;
346  }
347  }
348  }
349 
350  amxc_llist_for_each(it, (&object->instances)) {
351  const char* n = NULL;
352  result = amxc_llist_it_get_data(it, amxd_object_t, it);
354  if(index != 0) {
355  if(result->index == index) {
356  break;
357  }
358  } else {
359  if((name != NULL) && (name[0] != 0)) {
360  int nlen = strlen(n);
361  if((nlen == length) && (strncmp(n, name + offset, length) == 0)) {
362  break;
363  }
364  }
365  }
366  result = NULL;
367  }
368 
369 exit:
370  return result;
371 }
372 
373 amxd_object_t* amxd_object_get(const amxd_object_t* object, const char* name) {
374  amxd_object_t* result = NULL;
375  when_str_empty(name, exit);
376 
378  if(isdigit(name[0]) == 0) {
379  result = amxd_object_get_instance(object, name, 0);
380  } else {
381  result = amxd_object_get_instance(object, NULL, atoi(name));
382  }
383  }
384  if(result == NULL) {
385  result = amxd_object_get_child(object, name);
386  }
387 
388 exit:
389  return result;
390 }
391 
393  const char* rel_path,
394  ...) {
395  amxd_object_t* result = NULL;
396  amxd_dm_t* dm = NULL;
398  amxd_path_t path;
399  va_list args;
400  bool key_path = false;
401 
402  amxd_path_init(&path, NULL);
403 
404  when_null(object, exit);
405  when_str_empty(rel_path, exit);
406 
407  if(!amxd_object_is_base(object)) {
408  dm = amxd_object_get_dm(object);
409  }
410 
411  va_start(args, rel_path);
412  status = amxd_path_vsetf(&path, true, rel_path, args);
413  va_end(args);
414  when_failed(status, exit);
415 
416  result = amxd_object_find_internal(object, &key_path, &path, &status);
417 
418 exit:
419  if(dm != NULL) {
420  dm->status = status;
421  }
422  amxd_path_clean(&path);
423  return result;
424 }
425 
427  amxc_llist_t* paths,
428  const char* rel_path,
429  ...) {
431  amxd_path_t path;
432  va_list args;
433  bool key_path = false;
434 
435  amxd_path_init(&path, NULL);
436 
437  when_null(object, exit);
438  when_true(amxd_object_is_base(object), exit);
439  when_str_empty(rel_path, exit);
440 
441  va_start(args, rel_path);
442  status = amxd_path_vsetf(&path, true, rel_path, args);
443  va_end(args);
444  when_failed(status, exit);
445 
446  status = amxd_object_resolve_internal(object, &key_path, paths, &path);
447 
448 exit:
449  amxd_path_clean(&path);
450  return status;
451 }
452 
454  bool* key_path,
455  amxc_llist_t* paths,
456  const char* rel_path,
457  ...) {
459  amxd_path_t path;
460  va_list args;
461 
462  amxd_path_init(&path, NULL);
463 
464  when_null(key_path, exit);
465  when_null(object, exit);
466  when_true(amxd_object_is_base(object), exit);
467  when_str_empty(rel_path, exit);
468 
469  *key_path = false;
470 
471  va_start(args, rel_path);
472  status = amxd_path_vsetf(&path, true, rel_path, args);
473  va_end(args);
474  when_failed(status, exit);
475 
476  status = amxd_object_resolve_internal(object, key_path, paths, &path);
477 
478 exit:
479  amxd_path_clean(&path);
480  return status;
481 }
482 
484  const uint32_t flags) {
485  char* path = NULL;
486  when_null(object, exit);
487  when_true(amxd_object_is_base(object), exit);
488  when_null(amxd_object_get_name(object, flags), exit);
489 
490  path = amxd_object_build_path(object, NULL, flags);
491 
492 exit:
493  return path;
494 }
495 
497  const amxd_object_t* parent,
498  const uint32_t flags) {
499 
500  char* path = NULL;
501  when_null(child, exit);
502  when_true(amxd_object_is_base(child), exit);
503  when_null(parent, exit);
504  when_true(amxd_object_is_base(parent), exit);
505 
506  when_true(!amxd_object_is_child_of(child, parent), exit);
507  when_null(amxd_object_get_name(child, flags), exit);
508 
509  path = amxd_object_build_path(child, parent, flags);
510 
511 exit:
512  return path;
513 }
514 
515 bool amxd_object_is_child_of(const amxd_object_t* const child,
516  const amxd_object_t* const parent) {
517  amxd_object_t* upper = NULL;
518  when_null(child, exit);
519  when_true(amxd_object_is_base(child), exit);
520  when_null(parent, exit);
521  when_true(amxd_object_is_base(parent), exit);
522 
523  upper = amxd_object_get_parent(child);
524  while(upper != NULL) {
525  if(upper == parent) {
526  break;
527  }
528  upper = amxd_object_get_parent(upper);
529  }
530 
531 exit:
532  return (upper != NULL);
533 }
534 
536  const amxd_direction_t direction,
539  int32_t depth,
540  void* priv) {
541  when_null(object, exit);
542  when_null(cb, exit);
543 
544  if(direction == amxd_direction_up) {
545  amxd_object_hierarchy_up(object, filter, cb, depth, priv);
546  } else {
547  amxd_object_hierarchy_down(object, direction, filter, cb, depth, priv);
548  }
549 
550 exit:
551  return;
552 }
553 
555  const char* rel_spath,
557  void* priv) {
558  amxc_llist_t paths;
559  amxd_dm_t* dm = NULL;
560 
561  amxc_llist_init(&paths);
562 
563  when_null(object, exit);
564  when_true(amxd_object_is_base(object), exit);
565  when_null(fn, exit);
566  when_str_empty(rel_spath, exit);
567 
568  dm = amxd_object_get_dm(object);
569 
570  amxd_object_resolve_pathf(object, &paths, "%s", rel_spath);
571 
572  amxc_llist_for_each(it, (&paths)) {
573  amxc_string_t* path = amxc_string_from_llist_it(it);
574  amxd_object_t* mobject = amxd_dm_findf(dm, "%s", amxc_string_get(path, 0));
575  if(mobject != NULL) {
576  fn(object, mobject, priv);
577  }
578  }
579 
580 exit:
581  amxc_llist_clean(&paths, amxc_string_list_it_free);
582  return;
583 }
584 
586  const char* req_path) {
587  amxd_object_t* sup_obj = NULL;
588  amxd_path_t path;
589  amxc_llist_t paths;
590  bool retval = false;
591 
592  amxd_path_init(&path, req_path);
593  amxc_llist_init(&paths);
594 
595  when_null(object, exit);
596  when_true(amxd_object_is_base(object), exit);
597 
598  retval = true;
599  when_str_empty(req_path, exit);
600 
601  sup_obj = amxd_object_is_supported_impl(object, &path);
602  when_not_null(sup_obj, exit); // object is in supported data model
603 
604  // when objects are added using mibs, they will not be visible in the
605  // supported data model part.
606  // therefor when the object(s) exist (at least one is found),
607  // also return true
608  amxd_object_resolve_pathf(object, &paths, "%s", req_path);
609  retval = !amxc_llist_is_empty(&paths);
610 
611 exit:
612  amxc_llist_clean(&paths, amxc_string_list_it_free);
613  amxd_path_clean(&path);
614  return retval;
615 }
Ambiorix Data Model API header file.
amxd_object_t * amxd_dm_findf(amxd_dm_t *const dm, const char *abs_path,...) __attribute__((format(printf
bool PRIVATE amxd_object_is_base(const amxd_object_t *const object)
Definition: amxd_dm_priv.c:504
Ambiorix Data Model API header file.
static amxd_object_t * amxd_object_is_supported_impl(amxd_object_t *object, amxd_path_t *path)
amxd_status_t amxd_object_resolve_pathf(amxd_object_t *object, amxc_llist_t *paths, const char *rel_path,...)
static void amxd_path_prepend_instance(const amxd_object_t *object, amxc_string_t *path, const char *name, uint32_t length, const uint32_t flags)
static void amxd_object_hierarchy_down(amxd_object_t *const object, const amxd_direction_t direction, amxd_object_filter_fn_t filter, amxd_object_cb_fn_t cb, int32_t depth, void *priv)
amxd_object_t * amxd_object_findf(amxd_object_t *const object, const char *rel_path,...)
amxd_status_t amxd_object_resolve_pathf_ext(amxd_object_t *object, bool *key_path, amxc_llist_t *paths, const char *rel_path,...)
static void amxd_object_hierarchy_up(amxd_object_t *const object, amxd_object_filter_fn_t filter, amxd_object_cb_fn_t cb, int32_t depth, void *priv)
static char * amxd_object_build_path(const amxd_object_t *object, const amxd_object_t *stop, const uint32_t flags)
PRIVATE amxd_object_t * amxd_object_find_internal(amxd_object_t *const object, bool *key_path, amxd_path_t *path, amxd_status_t *status)
PRIVATE amxd_status_t amxd_object_resolve_internal(amxd_object_t *const object, bool *key_path, amxc_llist_t *paths, amxd_path_t *path)
Ambiorix path API header file.
enum _amxd_direction amxd_direction_t
enum _amxd_status amxd_status_t
@ amxd_status_ok
Definition: amxd_types.h:78
@ amxd_status_unknown_error
Definition: amxd_types.h:79
@ amxd_direction_down
Definition: amxd_types.h:216
@ amxd_direction_down_reverse
Definition: amxd_types.h:217
@ amxd_direction_up
Definition: amxd_types.h:215
#define AMXD_OBJECT_SUPPORTED
Path format flag - adds {i} as placeholder for an instance object.
Definition: amxd_object.h:226
#define AMXD_OBJECT_INDEXED
Name and path format flag - use index for instance objects.
Definition: amxd_object.h:176
#define AMXD_OBJECT_REGEXP
Path format flag - create path that can be used as regular expression.
Definition: amxd_object.h:202
#define AMXD_OBJECT_NAMED
Name and path format flag - default behavior, use name for instance objects.
Definition: amxd_object.h:164
#define AMXD_OBJECT_EXTENDED
Path format flag - set name or index of instrance objects between '[' and ']'.
Definition: amxd_object.h:188
#define AMXD_OBJECT_TERMINATE
Path format flag - when set the object path is terminated with a dot.
Definition: amxd_object.h:214
@ amxd_object_root
Definition: amxd_types.h:178
@ amxd_object_template
Definition: amxd_types.h:183
@ amxd_object_mib
Definition: amxd_types.h:188
@ amxd_object_instance
Definition: amxd_types.h:186
char * amxd_object_get_path(const amxd_object_t *object, const uint32_t flags)
Get the full path of the object.
bool amxd_object_is_child_of(const amxd_object_t *const child, const amxd_object_t *const parent)
Checks if the child object is in the hierarchical tree of the parent object.
amxd_object_t * amxd_object_get_parent(const amxd_object_t *const object)
Get the parent object.
amxd_object_t * amxd_object_get_child(const amxd_object_t *object, const char *name)
Get a child of the object.
amxd_object_t * amxd_object_get_root(const amxd_object_t *const object)
Get the data model root.
char * amxd_object_get_rel_path(const amxd_object_t *child, const amxd_object_t *parent, const uint32_t flags)
Get the relative path of the object.
void amxd_object_hierarchy_walk(amxd_object_t *const object, const amxd_direction_t direction, amxd_object_filter_fn_t filter, amxd_object_cb_fn_t cb, int32_t depth, void *priv)
Iterates over all objects in the data model tree.
int(* amxd_mobject_cb_t)(amxd_object_t *object, amxd_object_t *mobject, void *priv)
Definition of matching object callback function.
amxd_dm_t * amxd_object_get_dm(const amxd_object_t *const object)
Get the data model.
void amxd_object_for_all(amxd_object_t *object, const char *rel_spath, amxd_mobject_cb_t fn, void *priv)
Executes a task for all matching objects in an object tree.
amxd_object_t * amxd_object_get(const amxd_object_t *object, const char *name)
Get an instance or child of an object.
void(* amxd_object_cb_fn_t)(amxd_object_t *const object, int32_t depth, void *priv)
Definition of object walk callback function.
bool amxd_object_is_supported(amxd_object_t *object, const char *req_path)
Checks if a path is in the supported data model.
bool(* amxd_object_filter_fn_t)(amxd_object_t *const object, int32_t depth, void *priv)
Definition of object filter function.
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_param_t * amxd_object_get_param_def(const amxd_object_t *const object, const char *name)
Gets a parameter definition from an 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
const char * amxd_object_get_name(const amxd_object_t *const object, const uint32_t flags)
Get the name of the object (or index as a string for instance objects)
Definition: amxd_object.c:239
#define amxd_object_for_each(type, it, object)
Helper macro for iterating object content.
Definition: amxd_object.h:113
amxd_status_t amxd_path_init(amxd_path_t *path, const char *object_path)
Initializes an amxd_path_t structure.
Definition: amxd_path.c:328
char * amxd_path_get_first(amxd_path_t *path, bool remove)
Gets the first part of the path.
Definition: amxd_path.c:501
void amxd_path_clean(amxd_path_t *path)
Cleans an amxd_path_t structure.
Definition: amxd_path.c:351
amxd_status_t amxd_path_vsetf(amxd_path_t *path, bool add_dot, const char *obj_path, va_list args)
Sets or replaces the path contained in the amxd_path_t structure.
Definition: amxd_path.c:403
amxd_status_t status
Definition: amxd_types.h:263
amxd_object_type_t type
Definition: amxd_types.h:236
uint32_t index
Definition: amxd_types.h:240
amxc_llist_t objects
Definition: amxd_types.h:243
amxc_llist_it_t it
Definition: amxd_types.h:230
amxc_llist_t instances
Definition: amxd_types.h:244
static amxd_dm_t dm
static amxd_status_t status