libamxc  1.10.3
C Generic Data Containers
amxc_string_split.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 <ctype.h>
62 
63 #include <amxc/amxc_common.h>
64 #include <amxc/amxc_variant.h>
65 #include <amxc/amxc_string_split.h>
66 #include <amxc/amxc_utils.h>
67 #include <amxc/amxc_macros.h>
68 
75 typedef struct _string_word_flags {
79  bool escape;
84 
85 typedef int (* amxc_string_create_part_t) (const amxc_string_t* const string,
86  amxc_llist_t* const list,
87  const size_t start_pos,
88  const size_t length);
89 
91  const char delimiter);
92 
93 static void amxc_trim_llist(amxc_llist_t* const list) {
96  if(amxc_string_text_length(part) != 1) {
97  break;
98  }
99  if(isspace(part->buffer[0]) == 0) {
100  break;
101  }
102  amxc_string_delete(&part);
103  }
104 
105  while(true) {
107  amxc_llist_it_t* last = amxc_llist_get_last(list);
108 
109  if((first != NULL) && (last != NULL)) {
112 
113  if((amxc_string_text_length(fpart) == 1) &&
114  ( amxc_string_text_length(lpart) == 1)) {
115  if((fpart->buffer[0] == '[') &&
116  ( lpart->buffer[0] == ']')) {
117  amxc_string_delete(&fpart);
118  amxc_string_delete(&lpart);
119  continue;
120  }
121  }
122  }
123  break;
124  }
125 }
126 
127 static int amxc_string_create_part(const amxc_string_t* const string,
128  amxc_llist_t* const list,
129  const size_t start_pos,
130  const size_t length) {
131  int retval = -1;
132  amxc_string_t* part = NULL;
133  char* buffer = NULL;
134 
135  buffer = amxc_string_dup(string, start_pos, length);
136  when_null(buffer, exit);
137  when_failed(amxc_string_new(&part, 0), exit);
138  if((length == 1) && isspace(buffer[0])) {
139  amxc_string_set_at(part, 0, buffer, 1, amxc_string_no_flags);
140  free(buffer);
141  } else {
142  when_failed(amxc_string_push_buffer(part, buffer, length + 1), exit);
143  }
144  amxc_llist_append(list, &part->it);
145 
146  retval = 0;
147 
148 exit:
149  if(retval != 0) {
150  free(buffer);
151  amxc_string_delete(&part);
152  }
153  return retval;
154 }
155 
156 static bool amxc_string_split_update_status(const amxc_string_t* const string,
157  size_t i,
158  amxc_string_word_flags_t* flags) {
159  bool skip = false;
160  if(string->buffer[i] == '\\') {
161  flags->escape = true;
162  skip = true;
163  }
164  flags->start_quote = false;
165  if(!flags->between_single_quotes && (string->buffer[i] == '"')) {
167  flags->start_quote = flags->between_double_quotes;
168  }
169  if(!flags->between_double_quotes && (string->buffer[i] == '\'')) {
171  flags->start_quote = flags->between_single_quotes;
172  }
173  if(!(flags->between_double_quotes || flags->between_single_quotes)) {
174  switch(string->buffer[i]) {
175  case '(':
176  flags->round_brackets++;
177  break;
178  case ')':
179  flags->round_brackets--;
180  break;
181  case '{':
182  flags->curly_brackets++;
183  break;
184  case '}':
185  flags->curly_brackets--;
186  break;
187  case '[':
188  flags->square_brackets++;
189  break;
190  case ']':
191  flags->square_brackets--;
192  break;
193  }
194  }
195 
196  return skip;
197 }
198 
201  const char** reason) {
203  const char* msg = "";
204 
205  if(flags->between_double_quotes) {
207  msg = "Missing closing double quote - \"";
208  goto exit;
209  }
210  if(flags->between_single_quotes) {
212  msg = "Missing closing single quote - '";
213  goto exit;
214  }
215  if(flags->round_brackets > 0) {
217  msg = "Missing closing round bracket - )";
218  goto exit;
219  }
220  if(flags->round_brackets < 0) {
222  msg = "Missing open round bracket - (";
223  goto exit;
224  }
225  if(flags->curly_brackets > 0) {
227  msg = "Missing closing curly bracket - }";
228  goto exit;
229  }
230  if(flags->curly_brackets < 0) {
232  msg = "Missing opening curly bracket - {";
233  goto exit;
234  }
235  if(flags->square_brackets > 0) {
237  msg = "Missing closing square bracket - ]";
238  goto exit;
239  }
240  if(flags->square_brackets < 0) {
242  msg = "Missing opening square bracket - [";
243  goto exit;
244  }
245 
246 exit:
247  if(reason != NULL) {
248  *reason = msg;
249  }
250  return retval;
251 }
252 
254  const char delimiter) {
255  bool retval = false;
257  amxc_string_t* str_part = NULL;
258  const char* part = NULL;
259 
260  if(it == NULL) {
261  retval = (isspace(delimiter) == 0);
262  goto exit;
263  }
264 
265  str_part = amxc_string_from_llist_it(it);
266  part = amxc_string_get(str_part, 0);
267 
268  retval = true;
269 
270  if(amxc_string_text_length(str_part) == 1) {
271  if(isspace(part[0]) != 0) {
272  if((isspace(delimiter) != 0) && (delimiter != '\n')) {
273  retval = false;
274  }
275  }
276  }
277 
278 exit:
279  return retval;
280 }
281 
284  amxc_llist_t* list,
287  const char** reason) {
289  size_t start_pos = 0;
290  size_t i = 0;
292 
293  flags.start_quote = false;
294  flags.between_double_quotes = false;
295  flags.between_single_quotes = false;
296  flags.escape = false;
297  flags.round_brackets = 0;
298  flags.curly_brackets = 0;
299  flags.square_brackets = 0;
300 
301  for(i = 0; i < string->last_used; i++) {
302  if(flags.escape == false) {
303  if(amxc_string_split_update_status(string, i, &flags) == true) {
304  continue;
305  }
306  }
307 
308  flags.escape = false;
309 
310  if(((flags.between_double_quotes == false) &&
311  (flags.between_single_quotes == false)) ||
312  ( flags.start_quote == true)) {
313  if(isspace(string->buffer[i])) {
314  if(i - start_pos > 0) {
315  when_failed(create(string, list, start_pos, i - start_pos), exit);
316  }
317  if(check(list, string->buffer[i])) {
318  when_failed(create(string, list, i, 1), exit);
319  }
320  start_pos = i + 1;
321  continue;
322  }
323  if(ispunct(string->buffer[i])) {
324  if(i - start_pos > 0) {
325  when_failed(create(string, list, start_pos, i - start_pos), exit);
326  }
327  if(check(list, string->buffer[i])) {
328  when_failed(create(string, list, i, 1), exit);
329  }
330  start_pos = i + 1;
331  continue;
332  }
333  }
334  }
335 
336  if(i - start_pos != 0) {
337  when_failed(create(string, list, start_pos, i - start_pos), exit);
338  }
339 
340  retval = amxc_string_split_word_is_valid(&flags, reason);
341 
342 exit:
343  return retval;
344 }
345 
349  bool quotes = false;
350  bool sqbrackets = false;
351  bool add_empty = true;
352  bool last_is_comma = false;
353  amxc_string_t csv_part;
354 
356 
357  amxc_string_init(&csv_part, 0);
358  amxc_llist_for_each(it, all) {
360  const char* txt_part = amxc_string_get(part, 0);
361  last_is_comma = false;
362  if(amxc_string_text_length(part) == 1) {
363  switch(txt_part[0]) {
364  case '"':
365  case '\'':
366  amxc_string_append(&csv_part, txt_part, amxc_string_text_length(part));
367  quotes = !quotes;
368  break;
369  case '[':
370  if(amxc_string_is_empty(&csv_part)) {
371  csv_list = amxc_var_add(amxc_llist_t, csv_list, NULL);
372  sqbrackets = !sqbrackets;
373  } else {
374  amxc_string_append(&csv_part, txt_part, amxc_string_text_length(part));
375  }
376  break;
377  case ']':
378  if(sqbrackets) {
379  if(amxc_string_text_length(&csv_part) > 0) {
380  amxc_var_t* item = amxc_var_add_new(csv_list);
381  amxc_string_trim(&csv_part, NULL);
383  }
384  if(csv_list != NULL) {
385  csv_list = amxc_container_of(csv_list->lit.llist, amxc_var_t, data);
386  }
387  sqbrackets = !sqbrackets;
388  add_empty = false;
389  } else {
390  amxc_string_append(&csv_part, txt_part, amxc_string_text_length(part));
391  }
392  break;
393  case ',':
394  if(quotes) {
395  amxc_string_append(&csv_part, txt_part, amxc_string_text_length(part));
396  } else {
397  if(amxc_string_text_length(&csv_part) > 0) {
398  amxc_var_t* item = amxc_var_add_new(csv_list);
399  amxc_string_trim(&csv_part, NULL);
401  } else if(add_empty) {
402  amxc_var_t* item = amxc_var_add_new(csv_list);
403  amxc_var_set(cstring_t, item, "");
404  }
405  add_empty = true;
406  }
407  last_is_comma = true;
408  break;
409  case ' ':
410  amxc_string_append(&csv_part, txt_part, amxc_string_text_length(part));
411  break;
412  default:
413  amxc_string_append(&csv_part, txt_part, amxc_string_text_length(part));
414  break;
415  }
416  } else {
417  amxc_string_append(&csv_part, txt_part, amxc_string_text_length(part));
418  }
419  }
420  if(amxc_string_text_length(&csv_part) > 0) {
421  amxc_var_t* item = amxc_var_add_new(csv_list);
422  amxc_string_trim(&csv_part, NULL);
424  } else if(last_is_comma && add_empty) {
425  amxc_var_add(cstring_t, csv_list, "");
426  }
427  amxc_string_clean(&csv_part);
428 
429  retval = AMXC_STRING_SPLIT_OK;
430 
431  return retval;
432 }
433 
437  bool quotes = false;
438  bool sqbrackets = false;
439  amxc_string_t csv_part;
440 
442 
443  amxc_string_init(&csv_part, 0);
444  amxc_llist_for_each(it, all) {
446  const char* txt_part = amxc_string_get(part, 0);
447  if(amxc_string_text_length(part) == 1) {
448  switch(txt_part[0]) {
449  case '"':
450  case '\'':
451  amxc_string_append(&csv_part, txt_part, amxc_string_text_length(part));
452  quotes = !quotes;
453  break;
454  case '[':
455  ssv_list = amxc_var_add(amxc_llist_t, ssv_list, NULL);
456  sqbrackets = !sqbrackets;
457  break;
458  case ']':
459  if(amxc_string_text_length(&csv_part) > 0) {
460  amxc_var_t* item = amxc_var_add_new(ssv_list);
462  }
463  if(ssv_list != NULL) {
464  ssv_list = amxc_container_of(ssv_list->lit.llist, amxc_var_t, data);
465  }
466  sqbrackets = !sqbrackets;
467  break;
468  case ' ':
469  if(quotes) {
470  amxc_string_append(&csv_part, txt_part, amxc_string_text_length(part));
471  } else {
472  if(amxc_string_text_length(&csv_part) > 0) {
473  amxc_var_t* item = amxc_var_add_new(ssv_list);
475  }
476  amxc_string_reset(&csv_part);
477  }
478  break;
479  default:
480  amxc_string_append(&csv_part, txt_part, amxc_string_text_length(part));
481  break;
482  }
483  } else {
484  amxc_string_append(&csv_part, txt_part, amxc_string_text_length(part));
485  }
486  }
487  if(amxc_string_text_length(&csv_part) > 0) {
488  amxc_var_t* item = amxc_var_add_new(ssv_list);
490  }
491  amxc_string_clean(&csv_part);
492 
493  retval = AMXC_STRING_SPLIT_OK;
494 
495  return retval;
496 }
497 
500  amxc_llist_t* list,
501  const char** reason) {
503 
504  when_null(list, exit);
505  when_null(string, exit);
506 
507  retval = amxc_string_split_words_internal(string,
508  list,
511  reason);
512  if(retval != 0) {
514  }
515 
516 exit:
517  return retval;
518 }
519 
521 amxc_string_split(const amxc_string_t* const string,
522  amxc_var_t* var,
524  const char** reason) {
526  amxc_llist_t all_parts;
527 
528  amxc_llist_init(&all_parts);
529  when_null(string, exit);
530  when_null(var, exit);
531 
532  retval = amxc_string_split_words_internal(string,
533  &all_parts,
536  reason);
537 
538  if(fn != NULL) {
539  fn(&all_parts, var);
540  } else {
542  amxc_llist_for_each(it, (&all_parts)) {
545  amxc_string_delete(&part);
546  }
547  }
548 
549 exit:
551  return retval;
552 }
553 
556  amxc_var_t* var,
557  const char** reason) {
558  return amxc_string_split(string, var, amxc_build_csv_var_list, reason);
559 }
560 
563  amxc_var_t* var,
564  const char** reason) {
565  return amxc_string_split(string, var, amxc_build_ssv_var_list, reason);
566 }
567 
570  amxc_llist_t* list,
571  const char separator) {
573  amxc_string_t* current = NULL;
574  amxc_llist_t parts_list;
575  bool in_sbrackets = false;
576 
577  amxc_llist_init(&parts_list);
578  when_null(string, exit);
579  when_null(list, exit);
580  when_true(isalnum(separator) != 0, exit);
581  when_true(separator == '[' || separator == ']', exit);
582 
583  retval = amxc_string_split_word(string, &parts_list, NULL);
584  when_failed(retval, exit);
585  amxc_trim_llist(&parts_list);
586 
587  amxc_llist_for_each(it, (&parts_list)) {
589  const char* txt_part = amxc_string_get(part, 0);
590  amxc_llist_append(list, &part->it);
591  if(amxc_string_text_length(part) == 1) {
592  if((separator == txt_part[0]) && !in_sbrackets) {
593  amxc_string_reset(part);
594  if(amxc_llist_it_get_previous(it) != NULL) {
595  current = part;
596  }
597  continue;
598  }
599  if(txt_part[0] == '[') {
600  if((amxc_string_text_length(current) > 0) && (isspace(separator) == 0)) {
601  amxc_string_append(current, txt_part, amxc_string_text_length(part));
602  amxc_string_delete(&part);
603  continue;
604  } else {
605  if(amxc_string_is_empty(current)) {
606  amxc_string_delete(&current);
607  }
608  current = part;
609  in_sbrackets = !in_sbrackets;
610  continue;
611  }
612  }
613  if((txt_part[0] == ']') && in_sbrackets) {
614  amxc_string_append(current, txt_part, amxc_string_text_length(part));
615  amxc_string_delete(&part);
616  in_sbrackets = !in_sbrackets;
617  current = NULL;
618  continue;
619  }
620  if(isspace(txt_part[0]) && !in_sbrackets) {
621  if(!amxc_string_is_empty(current)) {
622  amxc_string_append(current, txt_part, amxc_string_text_length(part));
623  }
624  amxc_string_delete(&part);
625  continue;
626  }
627  }
628  if(current == NULL) {
629  current = part;
630  } else {
631  amxc_string_append(current, txt_part, amxc_string_text_length(part));
632  amxc_string_delete(&part);
633  }
634  }
635 
636 exit:
638  return retval;
639 }
640 
642  const unsigned int index) {
643  amxc_string_t* retval = NULL;
644  amxc_llist_it_t* it = NULL;
645 
646  when_null(llist, exit);
647 
648  it = amxc_llist_get_at(llist, index);
649  when_null(it, exit);
650 
651  retval = amxc_string_from_llist_it(it);
652 exit:
653  return retval;
654 }
655 
657  const unsigned int index) {
658  const char* retval = NULL;
659  amxc_string_t* var_str = NULL;
660 
661  var_str = amxc_string_get_from_llist(llist, index);
662  when_null(var_str, exit);
663 
664  retval = amxc_string_get(var_str, 0);
665 exit:
666  return retval;
667 }
#define when_failed(x, l)
Definition: amxc_macros.h:142
#define when_true(x, l)
Definition: amxc_macros.h:134
#define when_null(x, l)
Definition: amxc_macros.h:126
bool(* amxc_string_check_delimiter_t)(amxc_llist_t *list, const char delimiter)
static amxc_string_split_status_t amxc_build_ssv_var_list(amxc_llist_t *all, amxc_var_t *ssv_list)
static void amxc_trim_llist(amxc_llist_t *const list)
static bool amxc_string_split_update_status(const amxc_string_t *const string, size_t i, amxc_string_word_flags_t *flags)
static amxc_string_split_status_t amxc_build_csv_var_list(amxc_llist_t *all, amxc_var_t *csv_list)
int(* amxc_string_create_part_t)(const amxc_string_t *const string, amxc_llist_t *const list, const size_t start_pos, const size_t length)
static amxc_string_split_status_t amxc_string_split_words_internal(const amxc_string_t *const string, amxc_llist_t *list, amxc_string_create_part_t create, amxc_string_check_delimiter_t check, const char **reason)
static amxc_string_split_status_t amxc_string_split_word_is_valid(amxc_string_word_flags_t *flags, const char **reason)
static int amxc_string_create_part(const amxc_string_t *const string, amxc_llist_t *const list, const size_t start_pos, const size_t length)
struct _string_word_flags amxc_string_word_flags_t
static bool amxc_need_to_add_delimiter(amxc_llist_t *list, const char delimiter)
Ambiorix variant API header file.
#define cstring_t
Convenience macro.
Definition: amxc_variant.h:584
#define amxc_container_of(addr, type, member)
Calculates the address of the containing structure.
Definition: amxc_common.h:83
AMXC_INLINE amxc_llist_it_t * amxc_llist_it_get_previous(const amxc_llist_it_t *const reference)
Gets the previous iterator in the list.
Definition: amxc_llist.h:842
int amxc_llist_append(amxc_llist_t *const llist, amxc_llist_it_t *const it)
Adds an item to the end of the linked list.
Definition: amxc_llist.c:169
int amxc_llist_init(amxc_llist_t *const llist)
Initializes a linked list.
Definition: amxc_llist.c:111
#define amxc_llist_for_each_reverse(it, list)
Loops over the list from tail to head.
Definition: amxc_llist.h:287
amxc_llist_it_t * amxc_llist_get_at(const amxc_llist_t *const llist, const unsigned int index)
Gets an item at a certain position of the linked list.
Definition: amxc_llist.c:222
void amxc_llist_clean(amxc_llist_t *const llist, amxc_llist_it_delete_t func)
Removes all items from the linked list.
Definition: amxc_llist.c:124
#define amxc_llist_for_each(it, list)
Loops over the list from head to tail.
Definition: amxc_llist.h:253
AMXC_INLINE amxc_llist_it_t * amxc_llist_get_last(const amxc_llist_t *const llist)
Gets the last item of the linked list.
Definition: amxc_llist.h:732
AMXC_INLINE amxc_llist_it_t * amxc_llist_get_first(const amxc_llist_t *const llist)
Gets the first item of the linked list.
Definition: amxc_llist.h:713
amxc_string_split_status_t amxc_string_csv_to_var(const amxc_string_t *const string, amxc_var_t *var, const char **reason)
Split a string in individual parts assuming that the string contains comma separated values.
amxc_string_split_status_t amxc_string_ssv_to_var(const amxc_string_t *const string, amxc_var_t *var, const char **reason)
Split a string in individual parts assuming that the string contains space separated values.
amxc_string_split_status_t amxc_string_split_word(const amxc_string_t *const string, amxc_llist_t *list, const char **reason)
Split a string in individual words or punctuation signs.
amxc_string_split_status_t amxc_string_split_to_llist(const amxc_string_t *const string, amxc_llist_t *list, const char separator)
Simple split function using a single character separator.
const char * amxc_string_get_text_from_llist(const amxc_llist_t *const llist, const unsigned int index)
Helper function to be used with amxc_string_split_llist.
amxc_string_t * amxc_string_get_from_llist(const amxc_llist_t *const llist, const unsigned int index)
Helper function to be used with amxc_string_split_llist.
amxc_string_split_status_t amxc_string_split(const amxc_string_t *const string, amxc_var_t *var, amxc_string_split_builder_t fn, const char **reason)
Split a string in individual words or punctuation signs.
enum _amxc_string_split_status amxc_string_split_status_t
The possible string split errors.
amxc_string_split_status_t(* amxc_string_split_builder_t)(amxc_llist_t *all, amxc_var_t *var)
Callback function definition.
@ AMXC_STRING_SPLIT_OK
@ AMXC_ERROR_STRING_SPLIT_INVALID_INPUT
@ AMXC_ERROR_STRING_MISSING_CBRACKET
@ AMXC_ERROR_STRING_MISSING_RBRACKET
@ AMXC_ERROR_STRING_MISSING_SQUOTE
@ AMXC_ERROR_STRING_MISSING_DQUOTE
@ AMXC_ERROR_STRING_MISSING_SBRACKET
void amxc_string_list_it_free(amxc_llist_it_t *it)
Helper function to delete an item in a linked list.
Definition: amxc_utils.c:327
void amxc_string_delete(amxc_string_t **string)
Frees the previously allocated string.
Definition: amxc_string.c:150
const char * amxc_string_get(const amxc_string_t *const string, const size_t offset)
Gets the content of the string buffer.
Definition: amxc_string.c:339
int amxc_string_push_buffer(amxc_string_t *const string, char *buffer, size_t length)
Sets the string buffer.
Definition: amxc_string.c:372
AMXC_INLINE int amxc_string_append(amxc_string_t *const string, const char *const text, const size_t length)
Appends text to the end of the current content of the string buffer.
Definition: amxc_string.h:920
#define amxc_string_from_llist_it(ll_it)
Get the pointer to a string structure from an amxc linked list iterator.
Definition: amxc_string.h:95
char * amxc_string_dup(const amxc_string_t *const string, const size_t start, size_t length)
Creates a full or partial copy of the text in the string buffer.
Definition: amxc_string.c:400
void amxc_string_reset(amxc_string_t *const string)
Resets the buffer, reset the content to all 0.
Definition: amxc_string.c:203
int amxc_string_new(amxc_string_t **string, const size_t length)
Allocates a string.
Definition: amxc_string.c:118
AMXC_INLINE size_t amxc_string_text_length(const amxc_string_t *const string)
Gets the current size of the used string buffer.
Definition: amxc_string.h:997
void amxc_string_trim(amxc_string_t *const string, amxc_string_is_char_fn_t fn)
Trim.
Definition: amxc_string.c:471
int amxc_string_init(amxc_string_t *const string, const size_t length)
Initializes a string.
Definition: amxc_string.c:163
int amxc_string_set_at(amxc_string_t *const string, const size_t pos, const char *const text, const size_t length, const amxc_string_flags_t flags)
Set text in the string buffer at a certain position.
Definition: amxc_string.c:276
AMXC_INLINE bool amxc_string_is_empty(const amxc_string_t *const string)
Checks if the string is empty.
Definition: amxc_string.h:1015
void amxc_string_clean(amxc_string_t *const string)
Frees the string buffer and reset length attributes.
Definition: amxc_string.c:189
char * amxc_string_take_buffer(amxc_string_t *const string)
Takes the string buffer.
Definition: amxc_string.c:356
@ amxc_string_no_flags
Definition: amxc_string.h:121
#define AMXC_VAR_ID_LIST
Ambiorix Linked List variant id.
Definition: amxc_variant.h:206
#define amxc_var_add(type, var, data)
Convenience macro for adding a variant to composite variant type.
Definition: amxc_variant.h:618
int amxc_var_set_type(amxc_var_t *const var, const uint32_t type)
Change the variant data type.
Definition: amxc_variant.c:261
amxc_var_t * amxc_var_add_new(amxc_var_t *const var)
Adds a new variant to a composite variant.
Definition: amxc_variant.c:551
#define amxc_var_push(type, var, val)
Pushes a value into the variant.
Definition: amxc_variant.h:780
#define amxc_var_set(type, var, data)
Convenience macro for setting a value in a variant.
Definition: amxc_variant.h:609
The linked list iterator structure.
Definition: amxc_llist.h:215
struct _amxc_llist * llist
Definition: amxc_llist.h:220
The linked list structure.
Definition: amxc_llist.h:228
The string structure.
Definition: amxc_string.h:103
char * buffer
Definition: amxc_string.h:104
amxc_llist_it_t it
Definition: amxc_string.h:108
The variant struct definition.
Definition: amxc_variant.h:861
amxc_llist_it_t lit
Definition: amxc_variant.h:862
char data[]
static amxc_htable_it_t it[2000]
static amxc_llist_t * llist
static amxc_var_t * var
Definition: test_issue_58.c:77
static amxc_var_t * first
Definition: test_issue_59.c:81