libamxd  6.4.1
Data Model Manager
amxd_path.c File Reference
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <limits.h>
#include <errno.h>
#include <amxc/amxc.h>
#include <amxp/amxp.h>
#include <amxd/amxd_object.h>
#include <amxd/amxd_path.h>
#include "amxd_priv.h"
#include "amxd_object_priv.h"
#include "amxd_assert.h"

Go to the source code of this file.

Functions

static bool amxd_build_path_common (amxc_string_t *path_part, amxc_var_t *path_parts, const char *token, bool *quotes, bool *sb, bool *cb)
 
static amxc_string_split_status_t amxd_build_path_parts (amxc_llist_t *all, amxc_var_t *path_parts)
 
static amxd_path_type_t amxd_path_is (amxd_path_t *path)
 
static amxd_status_t amxd_path_take_param (amxd_path_t *path)
 
static amxd_status_t amxd_path_split (amxd_path_t *path, amxc_string_split_builder_t fn)
 
static int isdot (int c)
 
static void amxd_path_add_dot (amxd_path_t *path, bool add_dot)
 
static amxd_status_t amxd_path_validate (amxd_path_t *path)
 
amxd_status_t amxd_path_init (amxd_path_t *path, const char *object_path)
 Initializes an amxd_path_t structure. More...
 
void amxd_path_clean (amxd_path_t *path)
 Cleans an amxd_path_t structure. More...
 
amxd_status_t amxd_path_new (amxd_path_t **path, const char *object_path)
 Allocates and initializes an amxd_path_t structure. More...
 
void amxd_path_delete (amxd_path_t **path)
 Frees an allocated amxd_path_t structure. More...
 
void amxd_path_reset (amxd_path_t *path)
 Resets the amxd_path_t structure. More...
 
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. More...
 
amxd_status_t amxd_path_setf (amxd_path_t *path, bool add_dot, const char *obj_path,...)
 
amxd_status_t amxd_path_append (amxd_path_t *path, const char *extension, bool add_dot)
 Appends a parameter name or object name/index to the path. More...
 
amxd_status_t amxd_path_prepend (amxd_path_t *path, const char *extension)
 Prepends an object name/index to the path. More...
 
const char * amxd_path_get (amxd_path_t *path, int flags)
 Returns the path stored in the amxd_path_t structure. More...
 
const char * amxd_path_get_param (amxd_path_t *path)
 Gets the parameter name. More...
 
char * amxd_path_get_first (amxd_path_t *path, bool remove)
 Gets the first part of the path. More...
 
char * amxd_path_get_last (amxd_path_t *path, bool remove)
 Gets the last part of the path. More...
 
char * amxd_path_get_fixed_part (amxd_path_t *path, bool remove)
 Gets the fixed part of the path. More...
 
char * amxd_path_get_supported_path (amxd_path_t *path)
 Translates the path into a path that can be used to fetch the object definition. More...
 
char * amxd_path_get_reference_part (amxd_path_t *path, bool remove)
 Returns the reference path. More...
 
uint32_t amxd_path_get_reference_index (amxd_path_t *path)
 Returns the reference path index. More...
 
char * amxd_path_build_supported_path (amxd_path_t *path)
 Creates the supported path representation of the given path. More...
 
uint32_t amxd_path_get_depth (const amxd_path_t *const path)
 Calculates the depth of the path. More...
 
bool amxd_path_is_instance_path (const amxd_path_t *const path)
 Checks if the path is in the instantiated data model. More...
 
char * amxd_path_get_param_path (amxd_path_t *path)
 Get the full parameter path from the provided amxd_path_t struct. More...
 

Function Documentation

◆ amxd_build_path_common()

static bool amxd_build_path_common ( amxc_string_t *  path_part,
amxc_var_t *  path_parts,
const char *  token,
bool *  quotes,
bool *  sb,
bool *  cb 
)
static

Definition at line 72 of file amxd_path.c.

73  {
74  bool dot = false;
75  switch(token[0]) {
76  case '"':
77  case '\'':
78  amxc_string_appendf(path_part, "%s", token);
79  (*quotes) = !(*quotes);
80  break;
81  case '*':
82  amxc_string_appendf(path_part, "%s", token);
83  if(!(*quotes)) {
84  amxc_var_add(cstring_t, path_parts, amxc_string_get(path_part, 0));
85  amxc_string_reset(path_part);
86  }
87  break;
88  case '[':
89  if(!(*quotes)) {
90  *sb = true;
91  }
92  amxc_string_appendf(path_part, "%s", token);
93  break;
94  case ']':
95  amxc_string_appendf(path_part, "%s", token);
96  if(!(*quotes)) {
97  amxc_var_add(cstring_t, path_parts, amxc_string_get(path_part, 0));
98  amxc_string_reset(path_part);
99  *sb = false;
100  }
101  break;
102  case '{':
103  *cb = true;
104  amxc_string_appendf(path_part, "%s", token);
105  break;
106  case '}':
107  amxc_string_appendf(path_part, "%s", token);
108  amxc_var_add(cstring_t, path_parts, amxc_string_get(path_part, 0));
109  amxc_string_reset(path_part);
110  *cb = false;
111  break;
112  case '.':
113  amxc_string_appendf(path_part, "%s", token);
114  dot = !(*quotes) && !(*sb);
115  break;
116  case '+':
117  case '#':
118  if(!(*quotes) && !(*sb)) {
119  amxc_var_add(cstring_t, path_parts, amxc_string_get(path_part, 0));
120  amxc_string_reset(path_part);
121  amxc_string_appendf(path_part, "%s", token);
122  dot = !(*quotes) && !(*sb);
123  }
124  break;
125  default:
126  amxc_string_appendf(path_part, "%s", token);
127  break;
128  }
129  return dot;
130 }

◆ amxd_build_path_parts()

static amxc_string_split_status_t amxd_build_path_parts ( amxc_llist_t *  all,
amxc_var_t *  path_parts 
)
static

Definition at line 132 of file amxd_path.c.

133  {
134  bool quotes = false;
135  bool sb = false;
136  bool cb = false;
137  amxc_string_t path_part;
138 
139  amxc_var_set_type(path_parts, AMXC_VAR_ID_LIST);
140 
141  amxc_string_init(&path_part, 0);
142  amxc_llist_for_each(it, all) {
143  amxc_string_t* part = amxc_string_from_llist_it(it);
144  const char* txt_part = amxc_string_get(part, 0);
145  if(amxc_string_text_length(part) == 1) {
146  if(amxd_build_path_common(&path_part, path_parts, txt_part, &quotes, &sb, &cb)) {
147  amxc_var_add(cstring_t, path_parts, amxc_string_get(&path_part, 0));
148  amxc_string_reset(&path_part);
149  }
150  } else {
151  amxc_string_appendf(&path_part, "%s", txt_part);
152  }
153  }
154  if(amxc_string_text_length(&path_part) > 0) {
155  amxc_var_add(cstring_t, path_parts, amxc_string_get(&path_part, 0));
156  }
157  amxc_string_clean(&path_part);
158  return AMXC_STRING_SPLIT_OK;
159 }
static bool amxd_build_path_common(amxc_string_t *path_part, amxc_var_t *path_parts, const char *token, bool *quotes, bool *sb, bool *cb)
Definition: amxd_path.c:72

◆ amxd_path_add_dot()

static void amxd_path_add_dot ( amxd_path_t path,
bool  add_dot 
)
static

Definition at line 300 of file amxd_path.c.

300  {
301  if(!amxc_string_is_empty(&path->path) && add_dot) {
302  if(path->path.buffer[path->path.last_used - 1] != '.') {
303  amxc_string_append(&path->path, ".", 1);
304  }
305  }
306 }
amxc_string_t path
Definition: amxd_types.h:407

◆ amxd_path_is()

static amxd_path_type_t amxd_path_is ( amxd_path_t path)
static

Definition at line 161 of file amxd_path.c.

161  {
162  bool has_supported = false;
163  bool has_search = false;
164  bool has_ref_index = false;
166 
167  path->ref_index = 1;
168 
169  amxc_var_for_each(part, (&path->parts)) {
170  const char* path_str = amxc_var_constcast(cstring_t, part);
171  if(has_ref_index) {
172  char* endptr = NULL;
173  path->ref_index = labs(strtol(path_str, &endptr, 0));
174  when_true_status(((errno == ERANGE) && ((path->ref_index == 0) || (path->ref_index == ULONG_MAX))) ||
175  ((errno != 0) && (path->ref_index == 0)),
176  exit,
177  type = amxd_path_invalid);
178  when_true_status((endptr == path_str) || (*endptr != '\0'),
179  exit,
180  type = amxd_path_invalid);
181  has_ref_index = false;
182  continue;
183  }
184  switch(path_str[0]) {
185  case '{':
186  if(strncmp(path_str, "{i}", 3) != 0) {
187  type = amxd_path_invalid;
188  goto exit;
189  }
190  has_supported = true;
191  break;
192  case '*':
193  case '[':
194  has_search = true;
195  break;
196  case '"':
197  case '\'':
198  type = amxd_path_invalid;
199  goto exit;
200  break;
201  case '+':
202  type = amxd_path_reference;
203  goto exit;
204  break;
205  case '#':
206  has_ref_index = true;
207  break;
208  }
209  }
210 
211  if(path->param != NULL) {
212  if((path->param[0] == '{') && has_search) {
213  type = amxd_path_invalid;
214  goto exit;
215  }
216  }
217 
218  if(has_supported && !has_search) {
219  type = amxd_path_supported;
220  } else if(!has_supported && has_search) {
221  type = amxd_path_search;
222  } else if(has_supported && has_search) {
223  type = amxd_path_invalid;
224  }
225 
226  path->ref_index = (type != amxd_path_reference)? 0:path->ref_index;
227 
228 exit:
229  return type;
230 }
enum _amxd_path_type amxd_path_type_t
@ amxd_path_invalid
Definition: amxd_types.h:399
@ amxd_path_reference
Definition: amxd_types.h:403
@ amxd_path_supported
Definition: amxd_types.h:402
@ amxd_path_search
Definition: amxd_types.h:401
@ amxd_path_object
Definition: amxd_types.h:400
char * param
Definition: amxd_types.h:408
amxc_var_t parts
Definition: amxd_types.h:409
uint64_t ref_index
Definition: amxd_types.h:412

◆ amxd_path_setf()

amxd_status_t amxd_path_setf ( amxd_path_t path,
bool  add_dot,
const char *  obj_path,
  ... 
)

Definition at line 424 of file amxd_path.c.

426  {
428  va_list args;
429 
430  when_null(path, exit);
431  when_str_empty(obj_path, exit);
432 
433  va_start(args, obj_path);
434  status = amxd_path_vsetf(path, add_dot, obj_path, args);
435  va_end(args);
436 
437 exit:
438  return status;
439 }
enum _amxd_status amxd_status_t
@ amxd_status_unknown_error
Definition: amxd_types.h:79
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
static amxd_status_t status

◆ amxd_path_split()

static amxd_status_t amxd_path_split ( amxd_path_t path,
amxc_string_split_builder_t  fn 
)
static

Definition at line 269 of file amxd_path.c.

270  {
272 
273  amxc_var_set_type(&path->parts, AMXC_VAR_ID_LIST);
274  when_true_status(amxc_string_is_empty(&path->path),
275  exit,
277 
278  if(fn == NULL) {
280  }
281 
282  if(amxc_string_split(&path->path,
283  &path->parts,
284  fn,
285  &path->reason) != AMXC_STRING_SPLIT_OK) {
287  amxc_var_clean(&path->parts);
288  goto exit;
289  }
291 
292 exit:
293  return status;
294 }
static amxc_string_split_status_t amxd_build_path_parts(amxc_llist_t *all, amxc_var_t *path_parts)
Definition: amxd_path.c:132
static amxd_status_t amxd_path_take_param(amxd_path_t *path)
Definition: amxd_path.c:232
@ amxd_status_invalid_path
Definition: amxd_types.h:99
@ amxd_status_ok
Definition: amxd_types.h:78
const char * reason
Definition: amxd_types.h:411

◆ amxd_path_take_param()

static amxd_status_t amxd_path_take_param ( amxd_path_t path)
static

Definition at line 232 of file amxd_path.c.

232  {
234  amxc_llist_it_t* last = amxc_llist_get_last(&path->parts.data.vl);
235  amxc_var_t* last_part = amxc_var_from_llist_it(last);
236  const char* name = amxc_var_constcast(cstring_t, last_part);
237  int length = 0;
238 
239  when_str_empty(name, exit);
240  length = strlen(name);
241 
242  if(name[length - 1] != '.') {
243  path->param = amxc_var_take(cstring_t, last_part);
244 
245  if(path->param[0] == '[') {
247  amxc_var_push(cstring_t, last_part, path->param);
248  path->param = NULL;
249  goto exit;
250  }
251 
252  amxc_llist_it_take(last);
253 
254  if(amxc_llist_is_empty(&path->parts.data.vl)) {
255  amxc_var_set(cstring_t, last_part, ".");
256  amxc_llist_append(&path->parts.data.vl, last);
257  } else {
258  amxc_var_delete(&last_part);
259  }
260 
261  amxc_string_reset(&path->path);
262  amxc_string_join_var(&path->path, &path->parts, "");
263  }
264 
265 exit:
266  return status;
267 }

◆ amxd_path_validate()

static amxd_status_t amxd_path_validate ( amxd_path_t path)
static

Definition at line 308 of file amxd_path.c.

308  {
310  if((path->path.last_used > 0) &&
311  ( path->path.buffer[path->path.last_used - 1] == '*')) {
312  path->type = amxd_path_invalid;
314  goto exit;
315  }
316  status = amxd_path_split(path, NULL);
317  if(status != amxd_status_ok) {
318  path->type = amxd_path_invalid;
319  } else {
320  path->type = amxd_path_is(path);
322  }
323 
324 exit:
325  return status;
326 }
static amxd_path_type_t amxd_path_is(amxd_path_t *path)
Definition: amxd_path.c:161
static amxd_status_t amxd_path_split(amxd_path_t *path, amxc_string_split_builder_t fn)
Definition: amxd_path.c:269
amxd_path_type_t type
Definition: amxd_types.h:410

◆ isdot()

static int isdot ( int  c)
static

Definition at line 296 of file amxd_path.c.

296  {
297  return (c == '.') ? 1 : 0;
298 }