libamxc  1.10.3
C Generic Data Containers
String
Collaboration diagram for String:

Modules

 Join composite types into a single string
 
 Split a string into a composite type
 
 string utility functions
 

Data Structures

struct  _amxc_string
 The string structure. More...
 

Macros

#define amxc_string_from_llist_it(ll_it)    amxc_container_of(ll_it, amxc_string_t, it)
 Get the pointer to a string structure from an amxc linked list iterator. More...
 

Typedefs

typedef struct _amxc_string amxc_string_t
 The string structure. More...
 
typedef enum _amxc_string_flags amxc_string_flags_t
 amxc_string_set_at possible flags More...
 
typedef int(* amxc_string_is_char_fn_t) (int c)
 Definition of the signature of the "is char" callback function. More...
 
typedef bool(* amxc_string_is_safe_cb_t) (const char *replacement)
 Checks if given replacement is safe to be included in a bigger string in a particular language. More...
 

Enumerations

enum  _amxc_string_flags { amxc_string_no_flags = 0x00 , amxc_string_insert = 0x00 , amxc_string_overwrite = 0x01 }
 amxc_string_set_at possible flags More...
 

Functions

int amxc_string_new (amxc_string_t **string, const size_t length)
 Allocates a string. More...
 
void amxc_string_delete (amxc_string_t **string)
 Frees the previously allocated string. More...
 
int amxc_string_init (amxc_string_t *const string, const size_t length)
 Initializes a string. More...
 
void amxc_string_clean (amxc_string_t *const string)
 Frees the string buffer and reset length attributes. More...
 
void amxc_string_reset (amxc_string_t *const string)
 Resets the buffer, reset the content to all 0. More...
 
int amxc_string_copy (amxc_string_t *const dest, const amxc_string_t *const src)
 Copies the content. More...
 
int amxc_string_grow (amxc_string_t *const string, const size_t length)
 Grows the string buffer. More...
 
int amxc_string_shrink (amxc_string_t *const string, const size_t length)
 Shrinks the string buffer. More...
 
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. More...
 
int amxc_string_remove_at (amxc_string_t *const string, const size_t pos, size_t length)
 Removes part of the text in the string buffer. More...
 
const char * amxc_string_get (const amxc_string_t *const string, const size_t offset)
 Gets the content of the string buffer. More...
 
char * amxc_string_take_buffer (amxc_string_t *const string)
 Takes the string buffer. More...
 
int amxc_string_push_buffer (amxc_string_t *const string, char *buffer, size_t length)
 Sets the string buffer. More...
 
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. More...
 
void amxc_string_triml (amxc_string_t *const string, amxc_string_is_char_fn_t fn)
 Trim left. More...
 
void amxc_string_trimr (amxc_string_t *const string, amxc_string_is_char_fn_t fn)
 Trim right. More...
 
void amxc_string_trim (amxc_string_t *const string, amxc_string_is_char_fn_t fn)
 Trim. More...
 
int amxc_string_vsetf (amxc_string_t *const string, const char *fmt, va_list ap)
 Sets the content of the string using printf like formatting. More...
 
int amxc_string_setf (amxc_string_t *const string, const char *fmt,...) __attribute__((format(printf
 Sets the content of the string using printf like formatting. More...
 
int int amxc_string_vsetf_checked (amxc_string_t *const string, amxc_string_is_safe_cb_t is_safe_cb, const char *fmt, va_list args)
 va_list version of amxc_string_setf_checked More...
 
int amxc_string_setf_checked (amxc_string_t *target_string, amxc_string_is_safe_cb_t is_safe_cb, const char *fmt,...) __attribute__((format(printf
 Sets the content of a string using printf like formatting while performing safety checks on the replacements. More...
 
int int amxc_string_vappendf (amxc_string_t *const string, const char *fmt, va_list ap)
 Appends a formatted string to a string. More...
 
int amxc_string_appendf (amxc_string_t *const string, const char *fmt,...) __attribute__((format(printf
 Appends a formatted string to a string. More...
 
int int amxc_string_vappendf_checked (amxc_string_t *target_string, amxc_string_is_safe_cb_t is_safe_cb, const char *fmt, va_list args)
 va_list version of amxc_string_appendf_checked More...
 
int amxc_string_appendf_checked (amxc_string_t *string, amxc_string_is_safe_cb_t is_safe_cb, const char *fmt,...) __attribute__((format(printf
 Appends a formatted string while performing safety checks on the replacements. More...
 
int int amxc_string_vprependf (amxc_string_t *const string, const char *fmt, va_list ap)
 Prepends a formatted string to a string. More...
 
int amxc_string_prependf (amxc_string_t *const string, const char *fmt,...) __attribute__((format(printf
 Prepends a formatted string to a string. More...
 
int bool amxc_string_is_numeric (const amxc_string_t *const string)
 Checks if a string is fully numeric. More...
 
int amxc_string_search (const amxc_string_t *const string, const char *needle, uint32_t start_pos)
 Searches a sub-string in a string. More...
 
int amxc_string_replace (amxc_string_t *const string, const char *needle, const char *newstr, uint32_t max)
 Replaces a number of sub-string occurrences in a string. More...
 
int amxc_string_to_upper (amxc_string_t *const string)
 Converts all lower case characters to upper case. More...
 
int amxc_string_to_lower (amxc_string_t *const string)
 Converts all upper case characters to lower case. More...
 
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. More...
 
AMXC_INLINE int amxc_string_prepend (amxc_string_t *const string, const char *const text, const size_t length)
 Inserts text at the beginning of the current content of the string buffer. More...
 
AMXC_INLINE size_t amxc_string_buffer_length (const amxc_string_t *const string)
 Gets the current size of the allocate string buffer. More...
 
AMXC_INLINE size_t amxc_string_text_length (const amxc_string_t *const string)
 Gets the current size of the used string buffer. More...
 
AMXC_INLINE bool amxc_string_is_empty (const amxc_string_t *const string)
 Checks if the string is empty. More...
 
AMXC_INLINE int amxc_string_insert_at (amxc_string_t *const string, const size_t pos, const char *text, size_t length)
 Inserts a string of the given length into a string at a certain position. More...
 
size_t amxc_string_set (amxc_string_t *const string, const char *text)
 Sets a 0 terminated string in the string buffer. More...
 
int amxc_string_bytes_2_hex_binary (amxc_string_t *const string, const char bytes[], const uint32_t len, const char *sep)
 Creates a hexbinary string from an array of bytes. More...
 
int amxc_string_hex_binary_2_bytes (const amxc_string_t *const string, char **bytes, uint32_t *len, const char *sep)
 Creates an array of bytes from a hex binary string. More...
 

Detailed Description

Macro Definition Documentation

◆ amxc_string_from_llist_it

#define amxc_string_from_llist_it (   ll_it)     amxc_container_of(ll_it, amxc_string_t, it)

Get the pointer to a string structure from an amxc linked list iterator.

The linked list iterator given, must be an linked list iterator of a string structure.

Gives the pointer to the string structure.

Definition at line 95 of file amxc_string.h.

Typedef Documentation

◆ amxc_string_flags_t

amxc_string_set_at possible flags

One of these flags can be passed to the amxc_string_set_at function as the flags argument.

◆ amxc_string_is_char_fn_t

typedef int(* amxc_string_is_char_fn_t) (int c)

Definition of the signature of the "is char" callback function.

Some of the string functions needs to know if certain character matches a criteria. You can provide your own matching function or use any of the standard c library functions for this, like is_space, ...

The functions using such a callback function are:

Parameters
cthe character
Returns
Callback functions must return non zero when the given character matches

Definition at line 145 of file amxc_string.h.

◆ amxc_string_is_safe_cb_t

typedef bool(* amxc_string_is_safe_cb_t) (const char *replacement)

Checks if given replacement is safe to be included in a bigger string in a particular language.

See amxc_string_appendf_checked for the background on this.

Returns
true if and only if the given replacement is considered safe in the language that this callback is for.

Definition at line 158 of file amxc_string.h.

◆ amxc_string_t

typedef struct _amxc_string amxc_string_t

The string structure.

Enumeration Type Documentation

◆ _amxc_string_flags

amxc_string_set_at possible flags

One of these flags can be passed to the amxc_string_set_at function as the flags argument.

Enumerator
amxc_string_no_flags 

Use default behavior (insert)

amxc_string_insert 

Insert the string

amxc_string_overwrite 

Overwrite the existing string with the given string

Definition at line 120 of file amxc_string.h.

120  {
121  amxc_string_no_flags = 0x00,
122  amxc_string_insert = 0x00,
123  amxc_string_overwrite = 0x01
enum _amxc_string_flags amxc_string_flags_t
amxc_string_set_at possible flags
@ amxc_string_overwrite
Definition: amxc_string.h:123
@ amxc_string_no_flags
Definition: amxc_string.h:121
@ amxc_string_insert
Definition: amxc_string.h:122

Function Documentation

◆ amxc_string_append()

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.

This method uses amxc_string_set_at with the pos argument set to the last used position of the string buffer.

When the size of the current buffer is insufficient, the buffer will grow.

Note
The provided text block must at least contain as much data as specified in the length argument. If the provide text block is smaller, the function will go out of boundery.
Parameters
stringa pointer to the string structure
textthe text block that needs to be inserted
lengththe length of the text block
Returns
0 on success. -1 if an error has occurred

Definition at line 920 of file amxc_string.h.

922  {
923  return amxc_string_set_at(string,
924  string != NULL ? string->last_used : 0,
925  text,
926  length,
928 }
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
size_t last_used
Definition: amxc_string.h:106

◆ amxc_string_appendf()

int amxc_string_appendf ( amxc_string_t *const  string,
const char *  fmt,
  ... 
)

Appends a formatted string to a string.

Using a string literal that can contain printf like formatting a string is added to the end of the string.

If needed memory is allocated or the already allocated buffer grows so the new content can be added.

The variadic arguments must match the printf formatting placeholders in the format string literal

Parameters
stringa pointer to the string structure
fmtstring literal that can contain printf formatting
Returns
0 when the new content is added

◆ amxc_string_appendf_checked()

int amxc_string_appendf_checked ( amxc_string_t string,
amxc_string_is_safe_cb_t  is_safe_cb,
const char *  fmt,
  ... 
)

Appends a formatted string while performing safety checks on the replacements.

The specifications from amxc_string_appendf apply here, but an additional safety check is performed. If this check fail, non 0 is returned and the given string is cleared.

The safety check consists of calling the given is_safe_cb callback on each replacement. The safety check is considered failed if is_safe_cb fails on at least one replacement. For example:

amxc_string_appendf_checked(&str, html_is_safe_replacement, "<html><body>Hello %s!", username);
int amxc_string_appendf_checked(amxc_string_t *string, amxc_string_is_safe_cb_t is_safe_cb, const char *fmt,...) __attribute__((format(printf
Appends a formatted string while performing safety checks on the replacements.
int amxc_string_init(amxc_string_t *const string, const size_t length)
Initializes a string.
Definition: amxc_string.c:163
The string structure.
Definition: amxc_string.h:103

Here, if the replacement, i.e. username, is Bob, then the string becomes

<html><body>Hello Bob!

If the replacement is Bob<script>transfer_money("Alice", "Bob", 1000000);</script> then without safety checks the string would become

<html><body>Hello Bob<script>transfer_money("Alice", "Bob", 1000000);</script>!

This is undesired, so html_is_safe_replacement is supposed to return false on Bob<script>transfer_money("Alice", "Bob", 1000000);</script>, and then amxc_string_appendf_checked will return non 0 and make the string empty.

Note that there is no universal is_safe_cb since it depends on the language (HTML, SQL, amx expression, ...) and even on the role of the replacement in the language (HTML body vs tag field, string literal vs comment, ...).

is_safe_cb is also called if the format string placeholder is not s.

Only the following format string placeholders (and the non-placeholder "%%") are supported: "%s","%d", "%lld", "%ld", "%i", "%lli", "%li", "%u", "%llu", "%lu", "%x", "%llx", "%lx", "%%", "%c", "%f", "%F", "%X".

Note that all other format string placeholders are not supported. So all other type characters, all flags, all width, and all precision format specifications are not supported. For example, "%20s", "%.2f", "%03d", "%1$d", "%2$.*3$d", "%4$.*3$d", etc. are not supported. In case an unsupported format string placeholder is used, non 0 is returned and the string is cleared.

Parameters
stringa pointer to the string structure
fmtstring literal that can contain printf formatting
is_safe_cbvalidator of whether a string is safe to build a bigger expression with. If NULL, then every string is assumed to be safe.
Returns
0 when success, none 0 on failure including failed safety check.

◆ amxc_string_buffer_length()

AMXC_INLINE size_t amxc_string_buffer_length ( const amxc_string_t *const  string)

Gets the current size of the allocate string buffer.

The allocated string buffer size is not the same as the used buffer size (or text length). Use amxc_string_text_length to get the current used buffer size. The allocated buffer size and the used buffer size can be the same length, but the used buffer size can never be higher then the allocated buffer size.

Parameters
stringa pointer to the string structure
Returns
The size in bytes of the allocated memory for the string buffer.

Definition at line 976 of file amxc_string.h.

976  {
977  return string != NULL ? string->length : 0;
978 }

◆ amxc_string_bytes_2_hex_binary()

int amxc_string_bytes_2_hex_binary ( amxc_string_t *const  string,
const char  bytes[],
const uint32_t  len,
const char *  sep 
)

Creates a hexbinary string from an array of bytes.

A hexbinary string is a hexadecimal representation of the bytes in the byte array. Each byte will be represented by 2 hexadecimal characters.

Parameters
stringa pointer to the string structure
bytesthe array of bytes
lenlength of the byte array
sepan optional separator string that is put between the bytes, can be NULL
Returns
Non zero value when building of the hexbinary string failed

Definition at line 870 of file amxc_string.c.

873  {
874  int retval = -1;
875  const char* s = "";
876 
877  when_null(string, exit);
878 
879  amxc_string_reset(string);
880 
881  when_null(bytes, exit);
882  when_true(len == 0, exit);
883 
884  for(uint32_t i = 0; i < len; i++) {
885  retval = amxc_string_appendf(string, "%s%2.2X", s, (unsigned char) bytes[i]);
886  if(retval != 0) {
887  amxc_string_reset(string);
888  goto exit;
889  }
890  if(sep != NULL) {
891  s = sep;
892  }
893  }
894 
895  retval = 0;
896 
897 exit:
898  return retval;
899 }
#define when_true(x, l)
Definition: amxc_macros.h:134
#define when_null(x, l)
Definition: amxc_macros.h:126
int amxc_string_appendf(amxc_string_t *const string, const char *fmt,...)
Definition: amxc_string.c:570
void amxc_string_reset(amxc_string_t *const string)
Resets the buffer, reset the content to all 0.
Definition: amxc_string.c:203

◆ amxc_string_clean()

void amxc_string_clean ( amxc_string_t *const  string)

Frees the string buffer and reset length attributes.

Parameters
stringa pointer to the string structure

Definition at line 189 of file amxc_string.c.

189  {
190  when_null(string, exit);
191 
192  amxc_llist_it_take(&string->it);
193 
194  free(string->buffer);
195  string->buffer = NULL;
196  string->last_used = 0;
197  string->length = 0;
198 
199 exit:
200  return;
201 }
void amxc_llist_it_take(amxc_llist_it_t *const it)
Removes the iterator from the list.
char * buffer
Definition: amxc_string.h:104
amxc_llist_it_t it
Definition: amxc_string.h:108

◆ amxc_string_copy()

int amxc_string_copy ( amxc_string_t *const  dest,
const amxc_string_t *const  src 
)

Copies the content.

Parameters
desta pointer to the destination string structure
srca pointer to the source string structure
Returns
0 on success. -1 if a NULL pointer is given.

Definition at line 215 of file amxc_string.c.

216  {
217  int retval = -1;
218  when_null(dest, exit);
219  when_null(src, exit);
220 
221  amxc_string_reset(dest);
222 
223  if(src->length == 0) {
224  dest->last_used = 0;
225  retval = 0;
226  goto exit;
227  }
228 
229  amxc_string_realloc(dest, src->length);
230  when_null(dest->buffer, exit);
231  memcpy(dest->buffer, src->buffer, src->length);
232  dest->last_used = src->last_used;
233 
234  retval = 0;
235 
236 exit:
237  return retval;
238 }
static int amxc_string_realloc(amxc_string_t *string, const size_t length)
Definition: amxc_string.c:75
size_t length
Definition: amxc_string.h:105

◆ amxc_string_delete()

void amxc_string_delete ( amxc_string_t **  string)

Frees the previously allocated string.

Frees the allocated memory and sets the pointer to the string to NULL.

Note
Only call this function for string that are allocated on the heap using amxc_string_new
Parameters
stringa pointer to the location where the pointer to the string is stored

Definition at line 150 of file amxc_string.c.

150  {
151  when_null(string, exit);
152  when_null((*string), exit);
153 
154  amxc_llist_it_take(&(*string)->it);
155  free((*string)->buffer);
156  free(*string);
157  *string = NULL;
158 
159 exit:
160  return;
161 }

◆ amxc_string_dup()

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.

A new memory block is allocated on the heap. The full content of the string buffer or partial content of the string buffer is copied in this new allocated memory block.

The start position can not be higher then the last used position. If the length (Starting to count for the start position), is going over the last used position, the length is re-calculated so it matches the last used position.

Note
The returned pointer must be freed. Failing to free the allocated memory, will result in a memory leak.
Parameters
stringa pointer to the string structure
startthe position in the string buffer
lengththe length of the text block
Returns
Pointer to the string buffer or NULL when no buffer was available or the start position is over the last used position in the buffer.

Definition at line 400 of file amxc_string.c.

402  {
403 
404  char* text = NULL;
405  when_null(string, exit);
406  when_true(start > string->last_used, exit);
407  when_true(length == 0, exit);
408 
409  if((length == SIZE_MAX) ||
410  ( start + length > string->last_used)) {
411  length = string->last_used - start;
412  }
413 
414  text = (char*) calloc(length + 1, sizeof(char));
415  when_null(text, exit);
416  memcpy(text, string->buffer + start, length);
417  text[length] = 0;
418 
419 exit:
420  return text;
421 }

◆ amxc_string_get()

const char* amxc_string_get ( const amxc_string_t *const  string,
const size_t  offset 
)

Gets the content of the string buffer.

Get the content from the string buffer. The pointer returned is the actual string buffer, or an offset of it.

The offset can not be higher then the value return by amxc_string_text_length.

If no buffer is allocated this function will return an empty string.

Parameters
stringa pointer to the string structure
offsetthe offset
Returns
Pointer to the string buffer, or a NULL pointer if no buffer is available

Definition at line 339 of file amxc_string.c.

340  {
341  const char* text = NULL;
342  when_null(string, exit);
343  when_true(string->buffer != NULL && offset > string->last_used, exit);
344 
345  if(string->buffer == NULL) {
346  text = "";
347  } else {
348  string->buffer[string->last_used] = 0;
349  text = string->buffer + offset;
350  }
351 
352 exit:
353  return text;
354 }

◆ amxc_string_grow()

int amxc_string_grow ( amxc_string_t *const  string,
const size_t  length 
)

Grows the string buffer.

Grows the string buffer by the given number of bytes. Extra memory is allocated to be able to store the number of bytes requested.

Parameters
stringa pointer to the string structure
lengththe number of bytes the string buffer has to grow
Returns
0 on success. -1 if an error has occurred.

Definition at line 240 of file amxc_string.c.

240  {
241  int retval = -1;
242  size_t old_length = 0;
243  when_null(string, exit);
244 
245  if(length == 0) {
246  retval = 0;
247  goto exit;
248  }
249 
250  old_length = string->length;
251  when_failed(amxc_string_realloc(string, old_length + length), exit);
252  when_null(string->buffer, exit);
253  memset(string->buffer + old_length, 0, length);
254  retval = 0;
255 
256 exit:
257  return retval;
258 }
#define when_failed(x, l)
Definition: amxc_macros.h:142

◆ amxc_string_hex_binary_2_bytes()

int amxc_string_hex_binary_2_bytes ( const amxc_string_t *const  string,
char **  bytes,
uint32_t *  len,
const char *  sep 
)

Creates an array of bytes from a hex binary string.

A hexbinary string is a hexadecimal representation of bytes. Each byte will be represented by 2 hexadecimal characters.

This function will allocate a buffer and converts the string to an array of bytes.

The function will fail if the string contains invalid characters. Valid characters are [0-9], [a-f], [A-F].

Parameters
stringa pointer to the string structure
bytesthe allocated of bytes
lenlength of the byte array
septhe separator between the bytes or NULL when no separator is used
Returns
Non zero value when building of the byte array fails.

Definition at line 901 of file amxc_string.c.

904  {
905  int retval = -1;
906  uint32_t str_len = 0;
907  uint32_t pos = 0;
908  uint32_t sep_count = 0;
909  const char* hex_binary = NULL;
910  uint32_t sep_len = sep == NULL ? 0 : strlen(sep);
911  char* buffer = NULL;
912 
913  when_true(amxc_string_is_empty(string), exit);
914  when_null(bytes, exit);
915  when_null(len, exit);
916 
917  str_len = amxc_string_text_length(string);
918  *len = (str_len + 1) >> 1;
919  buffer = (char*) calloc(1, *len);
920 
921  when_null(buffer, exit);
922  hex_binary = amxc_string_get(string, 0);
923 
924  for(uint32_t i = 0; i < str_len; i++) {
925  int shift = 0;
926  if((sep != NULL) && (sep_len != 0) &&
927  ( strncmp(hex_binary + i, sep, sep_len) == 0)) {
928  sep_count++;
929  continue;
930  }
931  if(((i - sep_count) % 2 == 0) && ((i + 1) != str_len)) {
932  shift = 4;
933  }
934  if((hex_binary[i] >= '0') && (hex_binary[i] <= '9')) {
935  buffer[pos] |= (hex_binary[i] - '0') << shift;
936  } else if((hex_binary[i] >= 'A') && (hex_binary[i] <= 'F')) {
937  buffer[pos] |= (hex_binary[i] - 'A' + 10) << shift;
938  } else if((hex_binary[i] >= 'a') && (hex_binary[i] <= 'f')) {
939  buffer[pos] |= (hex_binary[i] - 'a' + 10) << shift;
940  } else {
941  // invalid character
942  goto exit;
943  }
944  if((i - sep_count) % 2 != 0) {
945  pos++;
946  }
947  }
948 
949  if(sep_count != 0) {
950  char* tmp = NULL;
951  *len -= (((sep_len * sep_count) + 1) >> 1);
952  *bytes = buffer;
953  tmp = (char*) realloc(buffer, *len);
954  if(tmp != NULL) {
955  *bytes = tmp;
956  }
957  } else {
958  *bytes = buffer;
959  }
960  retval = 0;
961 
962 exit:
963  if(retval != 0) {
964  free(buffer);
965  if(bytes != NULL) {
966  *bytes = NULL;
967  }
968  if(len != NULL) {
969  *len = 0;
970  }
971  }
972  return retval;
973 }
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
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
AMXC_INLINE bool amxc_string_is_empty(const amxc_string_t *const string)
Checks if the string is empty.
Definition: amxc_string.h:1015

◆ amxc_string_init()

int amxc_string_init ( amxc_string_t *const  string,
const size_t  length 
)

Initializes a string.

Initializes the string structure. Memory is allocated from the heap to be able to store a string.

This function is typically called for string objects that are on the stack. Allocating and initializing a string object on the heap can be done using amxc_string_new

Note
When calling this function on an already initialized string objects, the string is reset and the previous content is gone. The string buffer resizes to the size given.

Use amxc_string_clean to clean the string buffer without resizing.

Parameters
stringa pointer to the string structure.
lengththe size of the string buffer in number of items
Returns
0 on success. -1 if a NULL pointer is given.

Definition at line 163 of file amxc_string.c.

163  {
164  int retval = -1;
165  when_null(string, exit);
166 
167  string->buffer = NULL;
168  string->length = 0;
169  string->last_used = 0;
170 
171  amxc_llist_it_init(&string->it);
172 
173  // if no items need to be pre-allocated, leave
174  if(length == 0) {
175  retval = 0;
176  goto exit;
177  }
178 
179  amxc_string_realloc(string, length);
180  when_null(string->buffer, exit);
181  string->length = length;
182 
183  retval = 0;
184 
185 exit:
186  return retval;
187 }
int amxc_llist_it_init(amxc_llist_it_t *const it)
Initializes a linked list iterator.
Definition: amxc_llist_it.c:89

◆ amxc_string_insert_at()

AMXC_INLINE int amxc_string_insert_at ( amxc_string_t *const  string,
const size_t  pos,
const char *  text,
size_t  length 
)

Inserts a string of the given length into a string at a certain position.

Inserts text of a certain length at a given position in the string

Parameters
stringa pointer to the string structure
posposition in the string
textthe text that needs to be inserted
lengththe length of the text
Returns
0 when the text is inserted

Definition at line 1035 of file amxc_string.h.

1038  {
1039  return amxc_string_set_at(string, pos, text, length, amxc_string_insert);
1040 }

◆ amxc_string_is_empty()

AMXC_INLINE bool amxc_string_is_empty ( const amxc_string_t *const  string)

Checks if the string is empty.

A string is considered empty if the length of the string is 0 or when the internal buffer pointer is NULL.

Parameters
stringa pointer to the string structure
Returns
true when empty or false otherwise

Definition at line 1015 of file amxc_string.h.

1015  {
1016  return string != NULL ? (string->last_used == 0) : true;
1017 }

◆ amxc_string_is_numeric()

int bool amxc_string_is_numeric ( const amxc_string_t *const  string)

Checks if a string is fully numeric.

If all characters in the string are numeric this function returns true.

Parameters
stringa pointer to the string structure
Returns
true when all characters in the string are numeric.

Definition at line 746 of file amxc_string.c.

746  {
747  bool retval = false;
748  char* data = NULL;
749 
750  when_true(amxc_string_is_empty(string), exit);
751 
752  data = string->buffer;
753  while((*data) != '\0') {
754  if(isdigit(*data) == 0) {
755  goto exit;
756  }
757  data++;
758  }
759 
760  retval = true;
761 exit:
762  return retval;
763 }
char data[]

◆ amxc_string_new()

int amxc_string_new ( amxc_string_t **  string,
const size_t  length 
)

Allocates a string.

Allocates and initializes memory to store a string. This function allocates memory from the heap, if a string is on the stack, it can be initialized using function amxc_string_init

The size of the string buffer is not fixed and can be changed with the functions amxc_string_grow or amxc_string_shrink

The string buffer will grow automatically when adding text to it.

The size of the string is expressed in number of bytes that can be stored in the buffer.

Note
The allocated memory must be freed when not used anymore, use amxc_string_delete to free the memory
Parameters
stringa pointer to the location where the pointer to the new string can be stored
lengththe size of the string in number of bytes
Returns
-1 if an error occured. 0 on success

Definition at line 118 of file amxc_string.c.

118  {
119  int retval = -1;
120  when_null(string, exit);
121 
122  /* allocate the array structure */
123  *string = (amxc_string_t*) calloc(1, sizeof(amxc_string_t));
124  when_null(*string, exit);
125 
126  /* set the number of items in the array */
127  (*string)->length = length;
128  (*string)->last_used = 0;
129 
130  /* if no buffer needs to pre-allocated, leave */
131  if(length == 0) {
132  retval = 0;
133  goto exit;
134  }
135 
136  /* allocate the buffer */
137  amxc_string_realloc(*string, length);
138  when_null(*string, exit);
139 
140  retval = 0;
141 
142 exit:
143  if((retval != 0) && (string != NULL)) {
144  free(*string);
145  *string = NULL;
146  }
147  return retval;
148 }

◆ amxc_string_prepend()

AMXC_INLINE int amxc_string_prepend ( amxc_string_t *const  string,
const char *const  text,
const size_t  length 
)

Inserts text at the beginning of the current content of the string buffer.

This method uses amxc_string_set_at with the pos argument set to 0.

When the size of the current buffer is insufficient, the buffer will grow.

Note
The provided text block must at least contain as much data as specified in the length argument. If the provide text block is smaller, the function will go out of boundary.
Parameters
stringa pointer to the string structure
textthe text block that needs to be inserted
lengththe length of the text block
Returns
0 on success. -1 if an error has occured

Definition at line 953 of file amxc_string.h.

955  {
956  return amxc_string_set_at(string, 0, text, length, amxc_string_no_flags);
957 }

◆ amxc_string_prependf()

int amxc_string_prependf ( amxc_string_t *const  string,
const char *  fmt,
  ... 
)

Prepends a formatted string to a string.

Using a string literal that can contain printf like formatting a string is added to the beginning of the string.

If needed memory is allocated or the already allocated buffer grows so the new content can be added.

The variadic arguments must match the printf formatting placeholders in the format string literal

Parameters
stringa pointer to the string structure
fmtstring literal that can contain printf formatting
Returns
0 when the new content is added

◆ amxc_string_push_buffer()

int amxc_string_push_buffer ( amxc_string_t *const  string,
char *  buffer,
size_t  length 
)

Sets the string buffer.

Replaces the string buffer with the given one. If the string object is containing a buffer, the buffer is freed and the given buffer is used.

Note
When calling this function the string object takes ownership of the given pointer. Do not modify the content of the buffer, unless using the amxc_string functions. Do not free the buffer directly, use amxc_string_clean or amxc_string_delete
Parameters
stringa pointer to the string structure
buffera pointer to the buffer
lengththe length of the allocated memory (not the string length)
Returns
0 when successful, none 0 otherwise.

Definition at line 372 of file amxc_string.c.

374  {
375  int retval = -1;
376  char* original = NULL;
377  when_null(string, exit);
378 
379  original = string->buffer;
380 
381  if(buffer != NULL) {
382  when_true(length < strlen(buffer) + 1, exit);
383  string->buffer = buffer;
384  string->last_used = strlen(buffer);
385  string->length = length;
386  } else {
387  string->buffer = NULL;
388  string->last_used = 0;
389  string->length = 0;
390  }
391 
392  free(original);
393 
394  retval = 0;
395 
396 exit:
397  return retval;
398 }

◆ amxc_string_remove_at()

int amxc_string_remove_at ( amxc_string_t *const  string,
const size_t  pos,
size_t  length 
)

Removes part of the text in the string buffer.

This method removes 1 or more characters from the string buffer. The text right from the removed blocked is moved to the start of the removed block.

It is not possible to remove blocks after the last used position. If the length provided (counting from the given position), is over the last used position, all text from the given position to the end of the used buffer is removed.

Parameters
stringa pointer to the string structure
posthe position in the string buffer
lengththe length of the text block
Returns
0 on success. -1 if an error has occurred

Definition at line 314 of file amxc_string.c.

316  {
317  int retval = -1;
318  size_t bytes_to_move = 0;
319  when_null(string, exit);
320  when_null(string->buffer, exit);
321  when_true(length == 0, exit);
322  when_true(pos > string->last_used, exit);
323 
324  if((length == SIZE_MAX) ||
325  ( pos + length > string->last_used)) {
326  length = string->last_used - pos;
327  }
328 
329  bytes_to_move = string->last_used - (pos + length);
330  memmove(string->buffer + pos, string->buffer + pos + length, bytes_to_move);
331  string->last_used -= length;
332  string->buffer[string->last_used] = 0;
333  retval = 0;
334 
335 exit:
336  return retval;
337 }

◆ amxc_string_replace()

int amxc_string_replace ( amxc_string_t *const  string,
const char *  needle,
const char *  newstr,
uint32_t  max 
)

Replaces a number of sub-string occurrences in a string.

Searches a sub-string in a string starting from beginning and replaces a certain number of the sub-string with another string.

When the newstr is empty all occurrences of the sub-string are removed from the string.

When max is set to UINT32_MAX all occurrences of the sub-string are replaced.

Parameters
stringa pointer to the string structure
needlethe sub-string to be searched
newstrthe replacement string
maxthe maximum number of replacements, use UINT32_MAX for all
Returns
the number of replacements done

Definition at line 789 of file amxc_string.c.

792  {
793  int retval = 0;
794  int pos = 0;
795  size_t needle_len = 0;
796  size_t newstr_len = 0;
797 
798  when_null(string, exit);
799  when_null(string->buffer, exit);
800  when_true(string->last_used == 0, exit);
801  when_true(needle == NULL || *needle == 0, exit);
802  when_null(newstr, exit);
803 
804  needle_len = strlen(needle);
805  newstr_len = strlen(newstr);
806 
807  when_true(needle_len > string->last_used, exit);
808 
809  pos = amxc_string_search(string, needle, pos);
810  while(pos != -1 && max > 0) {
811  amxc_string_remove_at(string, pos, needle_len);
812  if(newstr_len != 0) {
813  amxc_string_insert_at(string, pos, newstr, newstr_len);
814  }
815  retval++;
816  if(max != UINT32_MAX) {
817  max--;
818  }
819  pos = amxc_string_search(string, needle, pos + newstr_len);
820  }
821 
822 exit:
823  return retval;
824 }
AMXC_INLINE int amxc_string_insert_at(amxc_string_t *const string, const size_t pos, const char *text, size_t length)
Inserts a string of the given length into a string at a certain position.
Definition: amxc_string.h:1035
int amxc_string_search(const amxc_string_t *const string, const char *needle, uint32_t start_pos)
Searches a sub-string in a string.
Definition: amxc_string.c:765
int amxc_string_remove_at(amxc_string_t *const string, const size_t pos, size_t length)
Removes part of the text in the string buffer.
Definition: amxc_string.c:314

◆ amxc_string_reset()

void amxc_string_reset ( amxc_string_t *const  string)

Resets the buffer, reset the content to all 0.

Parameters
stringa pointer to the string structure

Definition at line 203 of file amxc_string.c.

203  {
204  when_null(string, exit);
205 
206  if(string->buffer) {
207  string->buffer[0] = 0;
208  }
209  string->last_used = 0;
210 
211 exit:
212  return;
213 }

◆ amxc_string_search()

int amxc_string_search ( const amxc_string_t *const  string,
const char *  needle,
uint32_t  start_pos 
)

Searches a sub-string in a string.

Searches a sub-string in a string starting from the start_pos.

When no occurrence is found the function returns -1, otherwise it returns the position in the string where the sub-string starts.

Parameters
stringa pointer to the string structure
needlethe sub-string to be searched
start_posthe search start position in the string
Returns
-1 when the substring is not found, otherwise the position where the sub-string starts.

Definition at line 765 of file amxc_string.c.

767  {
768  int retval = -1;
769  size_t needle_len = 0;
770  const char* needle_loc = NULL;
771 
772  when_null(string, exit);
773  when_null(string->buffer, exit);
774  when_true(string->last_used == 0, exit);
775  when_true(needle == NULL || *needle == 0, exit);
776 
777  needle_len = strlen(needle);
778  when_true(start_pos + needle_len > string->last_used, exit);
779 
780  needle_loc = strstr(string->buffer + start_pos, needle);
781  if(needle_loc != NULL) {
782  retval = needle_loc - string->buffer;
783  }
784 
785 exit:
786  return retval;
787 }

◆ amxc_string_set()

size_t amxc_string_set ( amxc_string_t *const  string,
const char *  text 
)

Sets a 0 terminated string in the string buffer.

The current content of amxc_string_t will be removed. The provided 0 terminated string is copied into the buffer.

Parameters
stringa pointer to the string structure
textthe text that needs to be set
Returns
number of bytes written in to the string buffer.

Definition at line 826 of file amxc_string.c.

826  {
827  size_t retval = 0;
828 
829  when_null(string, exit);
830  amxc_string_reset(string);
831  when_null(data, exit);
832 
833  retval = strlen(data);
834  if(amxc_string_insert_at(string, 0, data, retval) != 0) {
835  retval = 0;
836  }
837 
838 exit:
839  return retval;
840 }

◆ amxc_string_set_at()

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.

A block of text can be inserted at a certain position, or can overwrite the current content of the string buffer at the given position.

When the size of the current buffer is insufficient, the buffer will grow. It is not possible to insert a text block after the current last used byte in the buffer.

Note
The provided text block must at least contain as much data as specified in the length argument. If the provide text block is smaller, the function will go out of boundary.
Parameters
stringa pointer to the string structure
posthe position in the string buffer
textthe text block that needs to be inserted
lengththe length of the text block
flagsTODO:not documented yet
Returns
0 on success. -1 if an error has occurred

Definition at line 276 of file amxc_string.c.

280  {
281  int retval = -1;
282  when_null(string, exit);
283  when_null(text, exit);
284  when_true(length == 0, exit);
285  when_true(pos > string->last_used, exit);
286 
288  if(pos + length > string->length) {
290  pos + length), exit);
291  when_null(string->buffer, exit);
292  }
293  string->last_used = pos + length > string->last_used ? pos + length : string->last_used;
294  } else {
295  if(length + string->last_used >= string->length) {
297  length + string->last_used + 1), exit);
298  when_null(string->buffer, exit);
299  }
300  memmove(string->buffer + pos + length,
301  string->buffer + pos,
302  string->last_used - pos);
303  string->last_used += length;
304  }
305 
306  memcpy(string->buffer + pos, text, length);
307  string->buffer[string->last_used] = 0;
308  retval = 0;
309 
310 exit:
311  return retval;
312 }

◆ amxc_string_setf()

int amxc_string_setf ( amxc_string_t *const  string,
const char *  fmt,
  ... 
)

Sets the content of the string using printf like formatting.

Using a string literal that can contain printf like formatting the content of the string is filled.

If needed memory is allocated or the already allocated buffer grows so the new content can be stored.

The variadic arguments must match the printf formatting placeholders in the format string literal

Parameters
stringa pointer to the string structure
fmtstring literal that can contain printf formatting
Returns
0 when the new content is set

◆ amxc_string_setf_checked()

int amxc_string_setf_checked ( amxc_string_t target_string,
amxc_string_is_safe_cb_t  is_safe_cb,
const char *  fmt,
  ... 
)

Sets the content of a string using printf like formatting while performing safety checks on the replacements.

The specifications from amxc_string_setf apply here, but an additional safety check is performed. If this check fail, non 0 is returned and the given string is cleared.

The safety check consists of calling the given is_safe_cb callback on each replacement. The safety check is considered failed if is_safe_cb fails on at least one replacement. For example:

amxc_string_appendf_checked(&str, html_is_safe_replacement, "<html><body>Hello %s!", username);

Here, if the replacement, i.e. username, is Bob, then the string becomes

<html><body>Hello Bob!

If the replacement is Bob<script>transfer_money("Alice", "Bob", 1000000);</script> then without safety checks the string would become

<html><body>Hello Bob<script>transfer_money("Alice", "Bob", 1000000);</script>!

This is undesired, so html_is_safe_replacement is supposed to return false on Bob<script>transfer_money("Alice", "Bob", 1000000);</script>, and then amxc_string_appendf_checked will return non 0 and make the string empty.

Note that there is no universal is_safe_cb since it depends on the language (HTML, SQL, amx expression, ...) and even on the role of the replacement in the language (HTML body vs tag field, string literal vs comment, ...).

is_safe_cb is also called if the format string placeholder is not s.

Only the following format string placeholders (and the non-placeholder "%%") are supported: "%s","%d", "%lld", "%ld", "%i", "%lli", "%li", "%u", "%llu", "%lu", "%x", "%llx", "%lx", "%%", "%c", "%f", "%F", "%X".

Note that all other format string placeholders are not supported. So all other type characters, all flags, all width, and all precision format specifications are not supported. For example, "%20s", "%.2f", "%03d", "%1$d", "%2$.*3$d", "%4$.*3$d", etc. are not supported. In case an unsupported format string placeholder is used, non 0 is returned and the string is cleared.

Parameters
stringa pointer to the string structure
fmtstring literal that can contain printf formatting
is_safe_cbvalidator of whether a string is safe to build a bigger expression with. If NULL, then every string is assumed to be safe.
Returns
0 when success, none 0 on failure including failed safety check.

◆ amxc_string_shrink()

int amxc_string_shrink ( amxc_string_t *const  string,
const size_t  length 
)

Shrinks the string buffer.

Shrinks the string by the given number of bytes.

Note
Shrinking the string buffer can lead to data loss. Data loss will happen at the end of the string.
Parameters
stringa pointer to the string structure
lengththe number of bytes the string buffer has to shrink
Returns
0 on success. -1 if an error has occurred

Definition at line 260 of file amxc_string.c.

260  {
261  int retval = -1;
262  when_null(string, exit);
263  when_true(length > string->length, exit); // out of range
264 
265  if(length == 0) {
266  retval = 0;
267  goto exit;
268  }
269 
270  retval = amxc_string_realloc(string, string->length - length);
271 
272 exit:
273  return retval;
274 }

◆ amxc_string_take_buffer()

char* amxc_string_take_buffer ( amxc_string_t *const  string)

Takes the string buffer.

Takes the string buffer (char *) from the string object. The string object is reset.

Note
When calling this function the ownership of the pointer is moved. Calling amxc_string_clean will not free the buffer. You need to free the allocated memory (returned pointer) by yourself. The returned pointer must be freed. Failing to free the allocated memory, will result in a memory leak.
Parameters
stringa pointer to the string structure
Returns
Pointer to the string buffer, or a NULL pointer if no buffer is available

Definition at line 356 of file amxc_string.c.

356  {
357  char* buffer = NULL;
358  when_null(string, exit);
359 
360  if(string->buffer != NULL) {
361  string->buffer[string->last_used] = 0;
362  }
363  buffer = string->buffer;
364  string->buffer = NULL;
365  string->last_used = 0;
366  string->length = 0;
367 
368 exit:
369  return buffer;
370 }

◆ amxc_string_text_length()

AMXC_INLINE size_t amxc_string_text_length ( const amxc_string_t *const  string)

Gets the current size of the used string buffer.

The used string buffer size is not the same as the allocated buffer size. Use amxc_string_buffer_length to get the allocated buffer size. The allocated buffer size and the used buffer size can be the same length, but the used buffer size can never be higher then the allocated buffer size.

Parameters
stringa pointer to the string structure
Returns
The size in bytes of the allocated memory for the string buffer.

Definition at line 997 of file amxc_string.h.

997  {
998  return string != NULL ? string->last_used : 0;
999 }

◆ amxc_string_to_lower()

int amxc_string_to_lower ( amxc_string_t *const  string)

Converts all upper case characters to lower case.

Only upper case text characters are modified, all other characters are not changed.

Parameters
stringa pointer to the string structure
Returns
0 on success, any other value indicates failure.

Definition at line 856 of file amxc_string.c.

856  {
857  int retval = -1;
858 
859  when_null(string, exit);
860 
861  for(uint32_t i = 0; i <= string->last_used; i++) {
862  string->buffer[i] = tolower(string->buffer[i]);
863  }
864  retval = 0;
865 
866 exit:
867  return retval;
868 }

◆ amxc_string_to_upper()

int amxc_string_to_upper ( amxc_string_t *const  string)

Converts all lower case characters to upper case.

Only lower case text characters are modified, all other characters are not changed.

Parameters
stringa pointer to the string structure
Returns
0 on success, any other value indicates failure.

Definition at line 842 of file amxc_string.c.

842  {
843  int retval = -1;
844 
845  when_null(string, exit);
846 
847  for(uint32_t i = 0; i <= string->last_used; i++) {
848  string->buffer[i] = toupper(string->buffer[i]);
849  }
850  retval = 0;
851 
852 exit:
853  return retval;
854 }

◆ amxc_string_trim()

void amxc_string_trim ( amxc_string_t *const  string,
amxc_string_is_char_fn_t  fn 
)

Trim.

Removes trailing and leading characters from the string. The characters that will be removed are defined by the provided character classification function.

If no character classification function is provided the "isspace" function is used by default.

You can provide any character classification function or create your own. Such a function must return a none zero value when the character must be removed from the string.

Parameters
stringa pointer to the string structure
fna pointer to a character classification function or NULL

Definition at line 471 of file amxc_string.c.

471  {
472  amxc_string_trimr(string, fn);
473  amxc_string_triml(string, fn);
474 }
void amxc_string_triml(amxc_string_t *const string, amxc_string_is_char_fn_t fn)
Trim left.
Definition: amxc_string.c:423
void amxc_string_trimr(amxc_string_t *const string, amxc_string_is_char_fn_t fn)
Trim right.
Definition: amxc_string.c:453

◆ amxc_string_triml()

void amxc_string_triml ( amxc_string_t *const  string,
amxc_string_is_char_fn_t  fn 
)

Trim left.

Removes leading characters from the string. The characters that will be removed are defined by the provided character classification function.

If no character classification function is provided the "isspace" function is used by default.

You can provide any character classification function or create your own. Such a function must return a none zero value when the character must be removed from the string.

Parameters
stringa pointer to the string structure
fna pointer to a character classification function or NULL

Definition at line 423 of file amxc_string.c.

423  {
424  uint32_t pos = 0;
425  when_null(string, exit);
426  when_true(string->last_used == 0, exit);
427 
428  if(fn == NULL) {
429  fn = isspace;
430  }
431 
432  while(pos <= string->last_used &&
433  fn(string->buffer[pos]) != 0) {
434  pos++;
435  }
436 
437  if(pos >= string->last_used) {
438  string->last_used = 0;
439  string->buffer[0] = 0;
440  goto exit;
441  }
442 
443  if(pos > 0) {
444  memmove(string->buffer, string->buffer + pos, string->last_used - pos);
445  string->last_used -= pos;
446  }
447  string->buffer[string->last_used] = 0;
448 
449 exit:
450  return;
451 }

◆ amxc_string_trimr()

void amxc_string_trimr ( amxc_string_t *const  string,
amxc_string_is_char_fn_t  fn 
)

Trim right.

Removes trailing characters from the string. The characters that will be removed are defined by the provided character classification function.

If no character classification function is provided the "isspace" function is used by default.

You can provide any character classification function or create your own. Such a function must return a none zero value when the character must be removed from the string.

Parameters
stringa pointer to the string structure
fna pointer to a character classification function or NULL

Definition at line 453 of file amxc_string.c.

453  {
454  when_null(string, exit);
455  when_true(string->last_used == 0, exit);
456 
457  if(fn == NULL) {
458  fn = isspace;
459  }
460 
461  while(string->last_used > 0 &&
462  fn(string->buffer[string->last_used - 1]) != 0) {
463  string->last_used--;
464  }
465  string->buffer[string->last_used] = 0;
466 
467 exit:
468  return;
469 }

◆ amxc_string_vappendf()

int int amxc_string_vappendf ( amxc_string_t *const  string,
const char *  fmt,
va_list  ap 
)

Appends a formatted string to a string.

Using a string literal that can contain printf like formatting a string is added to the end of the string.

If needed memory is allocated or the already allocated buffer grows so the new content can be added.

The variadic arguments must match the printf formatting placeholders in the format string literal

Parameters
stringa pointer to the string structure
fmtstring literal that can contain printf formatting
apa va_list, containing the values for the printf formatting
Returns
0 when the new content is added

Definition at line 537 of file amxc_string.c.

539  {
540 
541  int retval = -1;
542  int size_needed = 0;
543  va_list copy;
544 
545  when_null(string, exit);
546  when_null(fmt, exit);
547 
548  va_copy(copy, args);
549  size_needed = vsnprintf(NULL, 0, fmt, args) + 1;
550 
551  if(string->length < string->last_used + size_needed) {
552  size_t grow = (string->last_used + size_needed - string->length);
553  when_failed(amxc_string_grow(string, grow), exit);
554  }
555 
556  size_needed = vsnprintf(string->buffer + string->last_used,
557  size_needed,
558  fmt,
559  copy);
560  string->buffer[string->length] = 0;
561 
562  string->last_used += size_needed;
563 
564  retval = 0;
565 
566 exit:
567  return retval;
568 }
int amxc_string_grow(amxc_string_t *const string, const size_t length)
Grows the string buffer.
Definition: amxc_string.c:240

◆ amxc_string_vappendf_checked()

int int amxc_string_vappendf_checked ( amxc_string_t target_string,
amxc_string_is_safe_cb_t  is_safe_cb,
const char *  fmt,
va_list  args 
)

va_list version of amxc_string_appendf_checked

See also
amxc_string_appendf_checked

Definition at line 600 of file amxc_string.c.

601  {
602 
603  const char* pos = fmt;
604  int status = -1;
605  when_null(string, error);
606  when_null(fmt, error);
607  while(*pos != '\0') {
608  size_t len_pos_old = 0;
609  size_t len_new_fixed = 0;
610  const char* placeholder = NULL;
611  const char* placeholder_in_pos = strchr(pos, '%');
612  bool placeholder_handled = false;
613 
614  // If no "%" left, add all the rest:
615  if(placeholder_in_pos == NULL) {
616  status = amxc_string_append(string, pos, strlen(pos));
617  when_failed(status, error);
618  return 0;
619  }
620 
621  // Add the fixed part, i.e. until "%":
622  len_new_fixed = placeholder_in_pos - pos;
623  if(len_new_fixed != 0) {
624  status = amxc_string_append(string, pos, len_new_fixed);
625  when_failed(status, error);
626  }
627 
628  // Identify placeholder (e.g. "%i"):
629  placeholder = s_get_format_placeholder(placeholder_in_pos);
630  if(placeholder == NULL) {
631  goto error; // unsupported placeholder.
632  }
633  len_pos_old = amxc_string_text_length(string);
634 
635  // Add replacement
636  // Note: Unfortunately, we cannot make this more clean by splitting off functions
637  // because "If [the va_list] is passed to a function that uses va_arg(ap,type), then
638  // the value of ap is undefined after the return of that function." (man va_arg(3))
639  // and because getting an item from a va_list requires hardcoding its type.
640  placeholder_handled = REPLACE_PLACEHOLDER(string, placeholder, status, args, "%s", const char*)
641  || REPLACE_PLACEHOLDER(string, placeholder, status, args, "%d", int)
642  || REPLACE_PLACEHOLDER(string, placeholder, status, args, "%lld", long long int)
643  || REPLACE_PLACEHOLDER(string, placeholder, status, args, "%ld", long int)
644  || REPLACE_PLACEHOLDER(string, placeholder, status, args, "%i", int)
645  || REPLACE_PLACEHOLDER(string, placeholder, status, args, "%lli", long long int)
646  || REPLACE_PLACEHOLDER(string, placeholder, status, args, "%li", long int)
647  || REPLACE_PLACEHOLDER(string, placeholder, status, args, "%u", unsigned int)
648  || REPLACE_PLACEHOLDER(string, placeholder, status, args, "%llu", long long unsigned int)
649  || REPLACE_PLACEHOLDER(string, placeholder, status, args, "%lu", long unsigned int)
650  || REPLACE_PLACEHOLDER(string, placeholder, status, args, "%x", unsigned int)
651  || REPLACE_PLACEHOLDER(string, placeholder, status, args, "%llx", long long unsigned int)
652  || REPLACE_PLACEHOLDER(string, placeholder, status, args, "%lx", long unsigned int)
653  || REPLACE_PLACEHOLDER(string, placeholder, status, args, "%c", int) // unsigned char promoted to int
654  || REPLACE_PLACEHOLDER(string, placeholder, status, args, "%f", double)
655  || REPLACE_PLACEHOLDER(string, placeholder, status, args, "%F", double)
656  || REPLACE_PLACEHOLDER(string, placeholder, status, args, "%X", unsigned int)
657  || s_replace_percentage(string, placeholder, &status);
658 
659  when_false(placeholder_handled, error);
660 
661  when_failed(status, error);
662 
663  // Check if added string safe:
664  if((is_safe_cb != NULL) && !is_safe_cb(amxc_string_get(string, len_pos_old))) {
665  goto error;
666  }
667 
668  pos += len_new_fixed + strlen(placeholder);
669  }
670  return 0;
671 
672 error:
673  amxc_string_clean(string);
674  return -1;
675 }
#define when_false(x, l)
Definition: amxc_macros.h:138
static bool s_replace_percentage(amxc_string_t *string, const char *actual_placeholder, int *status)
Definition: amxc_string.c:585
static const char * s_get_format_placeholder(const char *input)
Definition: amxc_string.c:104
#define REPLACE_PLACEHOLDER(string, actual_placeholder, status, args, searched_placeholder, type)
Definition: amxc_string.c:595
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
void amxc_string_clean(amxc_string_t *const string)
Frees the string buffer and reset length attributes.
Definition: amxc_string.c:189

◆ amxc_string_vprependf()

int int amxc_string_vprependf ( amxc_string_t *const  string,
const char *  fmt,
va_list  ap 
)

Prepends a formatted string to a string.

Using a string literal that can contain printf like formatting a string is added to the beginning of the string.

If needed memory is allocated or the already allocated buffer grows so the new content can be added.

The variadic arguments must match the printf formatting placeholders in the format string literal

Parameters
stringa pointer to the string structure
fmtstring literal that can contain printf formatting
apa va_list, containing the values for the printf formatting
Returns
0 when the new content is added

Definition at line 692 of file amxc_string.c.

694  {
695 
696  int retval = -1;
697  int size_needed = 0;
698  char first_char = 0;
699  va_list copy;
700 
701  when_null(string, exit);
702  when_null(fmt, exit);
703 
704  va_copy(copy, args);
705  size_needed = vsnprintf(NULL, 0, fmt, args) + 1;
706 
707  if(string->length < string->last_used + size_needed) {
708  size_t grow = (string->last_used + size_needed - string->length);
709  when_failed(amxc_string_grow(string, grow), exit);
710  }
711  first_char = string->buffer[0];
712 
713  if(string->last_used > 0) {
714  memmove(string->buffer + size_needed - 1,
715  string->buffer,
716  string->last_used);
717  }
718 
719  size_needed = vsnprintf(string->buffer,
720  size_needed,
721  fmt,
722  copy);
723  string->buffer[size_needed] = first_char;
724  string->last_used += size_needed;
725 
726  retval = 0;
727 
728 exit:
729  return retval;
730 }

◆ amxc_string_vsetf()

int amxc_string_vsetf ( amxc_string_t *const  string,
const char *  fmt,
va_list  ap 
)

Sets the content of the string using printf like formatting.

Using a string literal that can contain printf like formatting the content of the string is filled.

If needed memory is allocated or the already allocated buffer grows so the new content can be stored.

Parameters
stringa pointer to the string structure
fmtstring literal that can contain printf formatting
apa va_list, containing the values for the printf formatting
Returns
0 when the new content is set

Definition at line 476 of file amxc_string.c.

478  {
479  int retval = -1;
480 
481  when_null(string, exit);
482  when_null(fmt, exit);
483 
484  amxc_string_reset(string);
485  retval = amxc_string_vappendf(string, fmt, args);
486 
487 exit:
488  return retval;
489 }
int amxc_string_vappendf(amxc_string_t *const string, const char *fmt, va_list args)
Appends a formatted string to a string.
Definition: amxc_string.c:537

◆ amxc_string_vsetf_checked()

int int amxc_string_vsetf_checked ( amxc_string_t *const  string,
amxc_string_is_safe_cb_t  is_safe_cb,
const char *  fmt,
va_list  args 
)

va_list version of amxc_string_setf_checked

See also
amxc_string_setf_checked

Definition at line 505 of file amxc_string.c.

508  {
509  int retval = -1;
510 
511  when_null(string, exit);
512  when_null(fmt, exit);
513 
514  amxc_string_reset(string);
515  retval = amxc_string_vappendf_checked(string, is_safe_cb, fmt, args);
516 
517 exit:
518  return retval;
519 }
int amxc_string_vappendf_checked(amxc_string_t *string, amxc_string_is_safe_cb_t is_safe_cb, const char *fmt, va_list args)
va_list version of amxc_string_appendf_checked
Definition: amxc_string.c:600