string_util.c
Go to the documentation of this file.
1 
9 #include "string_util.h"
11 #include "mcl_core/mcl_assert.h"
12 #include "mcl_core/mcl_memory.h"
13 #include <string.h>
14 #include <stdio.h>
15 #include <stdarg.h>
16 #include <stdlib.h>
17 
18 #define LOWERCASE(n) ((n >= 'A' && n <= 'Z') ? (n + ('a' - 'A')) : n)
19 
20 // This function receives variable arguments as va_list type and print them in the desired format.
21 static mcl_error_t _print_formatted_string(char *string, mcl_size_t length, const char *format, va_list args);
22 
24 {
25  mcl_size_t length;
26 
27  MCL_DEBUG_ENTRY("const char *buffer = <%p>", buffer);
28 
29  (MCL_NULL == buffer) ? (length = 0) : (length = string_util_strlen(buffer));
30 
31  MCL_DEBUG_LEAVE("retVal = <%lu>", length);
32  return length;
33 }
34 
35 mcl_size_t string_util_strlen(const char *buffer)
36 {
37  mcl_size_t return_value;
38 
39  MCL_DEBUG_ENTRY("const char *buffer = <%p>", buffer);
40 
41  return_value = strlen(buffer);
42 
43  MCL_DEBUG_LEAVE("retVal = <%lu>", return_value);
44  return return_value;
45 }
46 
47 mcl_size_t mcl_string_util_strnlen(const char *buffer, mcl_size_t maximum_length)
48 {
49  mcl_size_t length;
50 
51  MCL_DEBUG_ENTRY("const char *buffer = <%p>, mcl_size_t maximum_length = <%lu>", buffer, maximum_length);
52 
53  (MCL_NULL == buffer) ? (length = 0) : (length = string_util_strnlen(buffer, maximum_length));
54 
55  MCL_DEBUG_LEAVE("retVal = <%lu>", length);
56  return length;
57 }
58 
59 mcl_size_t string_util_strnlen(const char *buffer, mcl_size_t maximum_length)
60 {
61  mcl_size_t count = 0;
62 
63  MCL_DEBUG_ENTRY("const char *buffer = <%p>, mcl_size_t maximum_length = <%lu>", buffer, maximum_length);
64 
65  while ((count < maximum_length) && (MCL_NULL_CHAR != buffer[count]))
66  {
67  ++count;
68  }
69 
70  MCL_DEBUG_LEAVE("retVal = <%lu>", count);
71  return count;
72 }
73 
74 void mcl_string_util_strncpy(char *destination, const char *source, mcl_size_t count)
75 {
76  MCL_DEBUG_ENTRY("char *destination = <%p>, const char *source = <%p>, mcl_size_t count = <%lu>", destination, source, count);
77 
78  string_util_strncpy(destination, source, count);
79 
80  MCL_DEBUG_LEAVE("retVal = void");
81 }
82 
83 void string_util_strncpy(char *destination, const char *source, mcl_size_t count)
84 {
85  MCL_DEBUG_ENTRY("char *destination = <%p>, const char *source = <%p>, mcl_size_t count = <%lu>", destination, source, count);
86 
87 #if defined(WIN32) || defined(WIN64)
88  strncpy_s(destination, count + 1, source, count);
89 #else
90  strncpy(destination, source, count);
91 #endif
92 
93  MCL_DEBUG_LEAVE("retVal = void");
94 }
95 
96 void mcl_string_util_strncat(char *destination, const char *source, mcl_size_t count)
97 {
98  MCL_DEBUG_ENTRY("char *destination = <%p>, const char *source = <%p>, mcl_size_t count = <%lu>", destination, source, count);
99 
100  string_util_strncat(destination, source, count);
101 
102  MCL_DEBUG_LEAVE("retVal = void");
103 }
104 
105 void string_util_strncat(char *destination, const char *source, mcl_size_t count)
106 {
107  MCL_DEBUG_ENTRY("char *destination = <%p>, const char *source = <%p>, mcl_size_t count = <%lu>", destination, source, count);
108 
109 #if defined(WIN32) || defined(WIN64)
110  strncat_s(destination, strlen(destination) + count + 1, source, count);
111 #else
112  strncat(destination, source, count);
113 #endif
114 
115  MCL_DEBUG_LEAVE("retVal = void");
116 }
117 
118 mcl_error_t mcl_string_util_strncmp(const char *string_1, const char *string_2, mcl_size_t count)
119 {
120  mcl_error_t code;
121 
122  MCL_DEBUG_ENTRY("const char *string_1 = <%p>, const char *string_2 = <%p>, mcl_size_t count = <%lu>", string_1, string_2, count);
123 
124  // Null check.
125  MCL_ASSERT_NOT_NULL(string_1, code);
126  MCL_ASSERT_NOT_NULL(string_2, code);
127 
128  code = string_util_strncmp(string_1, string_2, count);
129 
131  MCL_DEBUG_LEAVE("retVal = <%d>", code);
132  return code;
133 }
134 
135 mcl_error_t string_util_strncmp(const char *string_1, const char *string_2, mcl_size_t count)
136 {
137  mcl_error_t code;
138  int result;
139 
140  MCL_DEBUG_ENTRY("const char *string_1 = <%p>, const char *string_2 = <%p>, mcl_size_t count = <%lu>", string_1, string_2, count);
141 
142  result = strncmp(string_1, string_2, count);
143 
144  // This check is necessary since result can be < 0.
145  if (0 == result)
146  {
147  code = MCL_OK;
148  }
149  else
150  {
151  code = MCL_FAIL;
152  }
153 
154  MCL_DEBUG_LEAVE("retVal = <%d>", code);
155  return code;
156 }
157 
158 mcl_error_t mcl_string_util_snprintf(char *string, mcl_size_t length, const char *format, ...)
159 {
160  mcl_error_t code;
161  va_list args;
162 
163  MCL_DEBUG_ENTRY("char *string = <%p>, mcl_size_t length = <%lu>, const char *format = <%p>", string, length, format);
164 
165  // Initialize argument list.
166  va_start(args, format);
167 
168  code = _print_formatted_string(string, length, format, args);
169 
170  // End using variable argument list.
171  va_end(args);
172 
173  MCL_DEBUG_LEAVE("retVal = <%d>", code);
174  return code;
175 }
176 
177 mcl_error_t string_util_snprintf(char *string, mcl_size_t length, const char *format, ...)
178 {
179  mcl_error_t code;
180  va_list args;
181 
182  MCL_DEBUG_ENTRY("char *string = <%p>, mcl_size_t length = <%lu>, const char *format = <%p>", string, length, format);
183 
184  // Initialize argument list.
185  va_start(args, format);
186 
187  code = _print_formatted_string(string, length, format, args);
188 
189  // End using variable argument list.
190  va_end(args);
191 
192  MCL_DEBUG_LEAVE("retVal = <%d>", code);
193  return code;
194 }
195 
196 mcl_bool_t mcl_string_util_memcmp(const void *block_1, const void *block_2, mcl_size_t count)
197 {
198  mcl_bool_t result;
199 
200  MCL_DEBUG_ENTRY("const void *block_1 = <%p>, const void *block_2 = <%p>, mcl_size_t count = <%lu>", block_1, block_2, count);
201 
202  result = string_util_memcmp(block_1, block_2, count);
203 
204  MCL_DEBUG_LEAVE("retVal = <%s>", result ? "MCL_TRUE" : "MCL_FALSE");
205  return result;
206 }
207 
208 mcl_bool_t string_util_memcmp(const void *block_1, const void *block_2, mcl_size_t count)
209 {
210  mcl_bool_t result;
211 
212  MCL_DEBUG_ENTRY("const void *block_1 = <%p>, const void *block_2 = <%p>, mcl_size_t count = <%lu>", block_1, block_2, count);
213 
214  result = (0 == memcmp(block_1, block_2, count)) ? MCL_TRUE : MCL_FALSE;
215 
216  MCL_DEBUG_LEAVE("retVal = <%s>", result ? "MCL_TRUE" : "MCL_FALSE");
217  return result;
218 }
219 
220 void mcl_string_util_memcpy(void *destination, const void *source, mcl_size_t count)
221 {
222  MCL_DEBUG_ENTRY("void *destination = <%p>, const void *source = <%p>, mcl_size_t count = <%lu>", destination, source, count);
223 
224  string_util_memcpy(destination, source, count);
225 
226  MCL_DEBUG_LEAVE("retVal = void");
227 }
228 
229 void string_util_memcpy(void *destination, const void *source, mcl_size_t count)
230 {
231  MCL_DEBUG_ENTRY("void *destination = <%p>, const void *source = <%p>, mcl_size_t count = <%lu>", destination, source, count);
232 
233  memcpy(destination, source, count);
234 
235  MCL_DEBUG_LEAVE("retVal = void");
236 }
237 
238 void mcl_string_util_memset(void *destination, mcl_uint8_t value, mcl_size_t count)
239 {
240  MCL_DEBUG_ENTRY("void *destination = <%p>, mcl_uint8_t value = <%u>, mcl_size_t count = <%lu>", destination, value, count);
241 
242  if (MCL_NULL != destination)
243  {
244  string_util_memset(destination, value, count);
245  }
246 
247  MCL_DEBUG_LEAVE("retVal = void");
248 }
249 
250 void string_util_memset(void *destination, mcl_uint8_t value, mcl_size_t count)
251 {
252  MCL_DEBUG_ENTRY("void *destination = <%p>, mcl_uint8_t value = <%u>, mcl_size_t count = <%lu>", destination, value, count);
253 
254  memset(destination, value, count);
255 
256  MCL_DEBUG_LEAVE("retVal = void");
257 }
258 
259 char *mcl_string_util_strdup(const char *string)
260 {
261  char *result = MCL_NULL;
262 
263  MCL_DEBUG_ENTRY("const char *string = <%p>", string);
264 
265  if (MCL_NULL != string)
266  {
267  result = string_util_strdup(string);
268  }
269 
270  MCL_DEBUG_LEAVE("retVal = <%p>", result);
271  return result;
272 }
273 
274 char *string_util_strdup(const char *string)
275 {
276  char *result;
277  mcl_size_t string_length;
278 
279  MCL_DEBUG_ENTRY("const char *string = <%p>", string);
280 
281  string_length = string_util_strlen(string);
282  result = MCL_MALLOC(string_length + MCL_NULL_CHAR_SIZE);
283 
284  if (MCL_NULL != result)
285  {
286  string_util_memcpy(result, string, string_length + MCL_NULL_CHAR_SIZE);
287  }
288 
289  MCL_DEBUG_LEAVE("retVal = <%p>", result);
290  return result;
291 }
292 
293 mcl_bool_t mcl_string_util_find(const char *source, const char *target, mcl_size_t *start_index)
294 {
295  mcl_bool_t is_found = MCL_FALSE;
296 
297  MCL_DEBUG_ENTRY("const char *source = <%p>, const char *target = <%p>, mcl_size_t *start_index = <%p>", source, target, start_index);
298 
299  if ((MCL_NULL != source) && (MCL_NULL != target))
300  {
301  is_found = string_util_find(source, target, start_index);
302  }
303 
304  MCL_DEBUG_LEAVE("retVal = <%s>", is_found ? "MCL_TRUE" : "MCL_FALSE");
305  return is_found;
306 }
307 
308 mcl_bool_t string_util_find(const char *source, const char *target, mcl_size_t *start_index)
309 {
310  mcl_size_t index;
311  mcl_size_t source_length;
312  mcl_size_t target_length;
313  mcl_bool_t is_found = MCL_FALSE;
314 
315  MCL_DEBUG_ENTRY("const char *source = <%p>, const char *target = <%p>, mcl_size_t *start_index = <%p>", source, target, start_index);
316 
317  source_length = string_util_strlen(source);
318  target_length = string_util_strlen(target);
319 
320  // Search target string in source string. If it is found, assign index of the first character of target to start index and return MCL_TRUE.
321  if ((0 != target_length) && (target_length <= source_length))
322  {
323  mcl_size_t state = 0;
324 
325  for (index = 0; index < source_length; ++index)
326  {
327  state = (source[index] == target[state]) ? (state + 1) : 0;
328 
329  if (state == target_length)
330  {
331  *start_index = index - (target_length - 1);
332  is_found = MCL_TRUE;
333  break;
334  }
335  }
336  }
337 
338  MCL_DEBUG_LEAVE("retVal = <%s>", is_found ? "MCL_TRUE" : "MCL_FALSE");
339  return is_found;
340 }
341 
342 mcl_bool_t mcl_string_util_find_case_insensitive(const char *source, const char *target, mcl_size_t *start_index)
343 {
344  mcl_bool_t is_found = MCL_FALSE;
345 
346  MCL_DEBUG_ENTRY("const char *source = <%p>, const char *target = <%p>, mcl_size_t *start_index = <%p>", source, target, start_index);
347 
348  if ((MCL_NULL != source) && (MCL_NULL != target))
349  {
350  is_found = string_util_find_case_insensitive(source, target, start_index);
351  }
352 
353  MCL_DEBUG_LEAVE("retVal = <%s>", is_found ? "MCL_TRUE" : "MCL_FALSE");
354  return is_found;
355 }
356 
357 mcl_bool_t string_util_find_case_insensitive(const char *source, const char *target, mcl_size_t *start_index)
358 {
359  mcl_size_t index;
360  mcl_size_t source_length;
361  mcl_size_t target_length;
362  mcl_bool_t is_found = MCL_FALSE;
363 
364  MCL_DEBUG_ENTRY("char *source = <%p>, char *target = <%p>, mcl_size_t *start_index = <%p>", source, target, start_index);
365 
366  source_length = string_util_strlen(source);
367  target_length = string_util_strlen(target);
368 
369  if ((0 != target_length) && (target_length <= source_length))
370  {
371  mcl_size_t state = 0;
372 
373  for (index = 0; index < source_length; ++index)
374  {
375  state = ((source[index] == target[state]) || (LOWERCASE(source[index]) == LOWERCASE(target[state]))) ? (state + 1) : 0;
376 
377  if (state == target_length)
378  {
379  *start_index = index - (target_length - 1);
380  is_found = MCL_TRUE;
381  break;
382  }
383  }
384  }
385 
386  MCL_DEBUG_LEAVE("retVal = <%s>", is_found ? "MCL_TRUE" : "MCL_FALSE");
387  return is_found;
388 }
389 
390 long mcl_string_util_strtol(const char *source, int base, char **end_pointer)
391 {
392  long result;
393 
394  MCL_DEBUG_ENTRY("const char *source = <%p>, int base = <%d>, char **end_pointer = <%p>", source, base, end_pointer);
395 
396  result = string_util_strtol(source, base, end_pointer);
397 
398  MCL_DEBUG_LEAVE("retVal = <%u>", result);
399  return result;
400 }
401 
402 long string_util_strtol(const char *source, int base, char **end_pointer)
403 {
404  long result;
405 
406  MCL_DEBUG_ENTRY("char* source = <%p>, int base = <%p>, char *end_pointer = <%p>", source, end_pointer, base);
407 
408  result = strtol(source, end_pointer, base);
409 
410  MCL_DEBUG_LEAVE("retVal = <%ld>", result);
411  return result;
412 }
413 
414 mcl_error_t mcl_string_util_reset(const void *value, char **target)
415 {
416  mcl_error_t code;
417 
418  MCL_DEBUG_ENTRY("const void *value = <%p>, char **target = <%p>", value, target);
419 
420  // Null check.
421  MCL_ASSERT_NOT_NULL(value, code);
422  MCL_ASSERT_NOT_NULL(target, code);
423 
424  code = string_util_reset(value, target);
425 
427  MCL_DEBUG_LEAVE("retVal = <%d>", code);
428  return code;
429 }
430 
431 mcl_error_t string_util_reset(const void *value, char **target)
432 {
434 
435  MCL_DEBUG_ENTRY("const void *value = <%p>, char **target = <%p>", value, target);
436 
437  // Clean previous target if exists.
438  MCL_FREE(*target);
439 
440  // Duplicate value to target.
441  *target = string_util_strdup(value);
442 
443  if (MCL_NULL != *target)
444  {
445  code = MCL_OK;
446  }
447 
448  MCL_DEBUG_LEAVE("retVal = <%d>", code);
449  return code;
450 }
451 
452 mcl_error_t mcl_string_util_concatenate(const char *string_1, const char *string_2, char **result)
453 {
455 
456  MCL_DEBUG_ENTRY("const char *string_1 = <%p>, const char *string_2 = <%p>, char **result = <%p>", string_1, string_2, result);
457 
458  if ((MCL_NULL != string_1) && (MCL_NULL != string_2))
459  {
460  code = string_util_concatenate(string_1, string_2, result);
461  }
462 
463  MCL_DEBUG_LEAVE("retVal = <%d>", code);
464  return code;
465 }
466 
467 mcl_error_t string_util_concatenate(const char *string_1, const char *string_2, char **result)
468 {
469  mcl_error_t code = MCL_OK;
470  mcl_size_t string_1_length;
471  mcl_size_t string_2_length;
472 
473  MCL_DEBUG_ENTRY("const char *string_1 = <%p>, const char *string_2 = <%p>, char **result = <%p>", string_1, string_2, result);
474 
475  string_1_length = string_util_strlen(string_1);
476  string_2_length = string_util_strlen(string_2);
477 
478  if (MCL_NULL != (*result = MCL_MALLOC(string_1_length + string_2_length + MCL_NULL_CHAR_SIZE)))
479  {
480  string_util_memcpy(*result, string_1, string_1_length);
481  string_util_memcpy((*result) + string_1_length, string_2, string_2_length + MCL_NULL_CHAR_SIZE);
482  }
483  else
484  {
485  code = MCL_OUT_OF_MEMORY;
486  }
487 
488  MCL_DEBUG_LEAVE("retVal = <%d>", code);
489  return code;
490 }
491 
492 static mcl_error_t _print_formatted_string(char *string, mcl_size_t length, const char *format, va_list args)
493 {
494  mcl_error_t code;
495  mcl_error_t count;
496 
497  MCL_DEBUG_ENTRY("char *string = <%p>, mcl_size_t length = <%lu>, const char *format = <%p>, va_list args = <%p>", string, length, format, args);
498 
499  count = vsnprintf(string, length, format, args);
500 
501  if ((count > 0) && (((mcl_size_t) count) <= length))
502  {
503  code = MCL_OK;
504  }
505  else
506  {
507  MCL_ERROR("Couldn't write the string!");
508  code = MCL_FAIL;
509  }
510 
511  MCL_DEBUG_LEAVE("retVal = <%d>", code);
512  return code;
513 }
mcl_size_t mcl_string_util_strlen(const char *buffer)
Definition: string_util.c:23
void string_util_strncat(char *destination, const char *source, mcl_size_t count)
Definition: string_util.c:105
#define MCL_FUNCTION_LEAVE_LABEL
mcl_error_t mcl_string_util_concatenate(const char *string_1, const char *string_2, char **result)
Definition: string_util.c:452
mcl_error_t mcl_string_util_snprintf(char *string, mcl_size_t length, const char *format,...)
Definition: string_util.c:158
size_t mcl_size_t
mcl_size_t string_util_strnlen(const char *buffer, mcl_size_t maximum_length)
Definition: string_util.c:59
char * string_util_strdup(const char *string)
Definition: string_util.c:274
long string_util_strtol(const char *source, int base, char **end_pointer)
Definition: string_util.c:402
Assert module header file.
Success.
Received parameter is null.
mcl_int32_t mcl_error_t
mcl_bool_t string_util_find(const char *source, const char *target, mcl_size_t *start_index)
Definition: string_util.c:308
void string_util_memset(void *destination, mcl_uint8_t value, mcl_size_t count)
Definition: string_util.c:250
#define MCL_DEBUG_ENTRY(...)
Definition: mcl_log_util.h:115
void string_util_strncpy(char *destination, const char *source, mcl_size_t count)
Definition: string_util.c:83
#define MCL_FALSE
mcl_error_t mcl_string_util_reset(const void *value, char **target)
Definition: string_util.c:414
mcl_bool_t string_util_find_case_insensitive(const char *source, const char *target, mcl_size_t *start_index)
Definition: string_util.c:357
String utility module header file.
#define MCL_NULL
void mcl_string_util_memset(void *destination, mcl_uint8_t value, mcl_size_t count)
Definition: string_util.c:238
#define MCL_ERROR(...)
Definition: mcl_log_util.h:142
mcl_bool_t mcl_string_util_find_case_insensitive(const char *source, const char *target, mcl_size_t *start_index)
Definition: string_util.c:342
mcl_error_t string_util_concatenate(const char *string_1, const char *string_2, char **result)
Definition: string_util.c:467
mcl_size_t mcl_string_util_strnlen(const char *buffer, mcl_size_t maximum_length)
Definition: string_util.c:47
#define MCL_FREE(p)
Definition: mcl_memory.h:59
void mcl_string_util_strncat(char *destination, const char *source, mcl_size_t count)
Definition: string_util.c:96
void string_util_memcpy(void *destination, const void *source, mcl_size_t count)
Definition: string_util.c:229
mcl_error_t mcl_string_util_strncmp(const char *string_1, const char *string_2, mcl_size_t count)
Definition: string_util.c:118
uint8_t mcl_uint8_t
#define MCL_ASSERT_NOT_NULL(argument, return_variable)
Definition: mcl_assert.h:38
mcl_error_t string_util_snprintf(char *string, mcl_size_t length, const char *format,...)
Definition: string_util.c:177
mcl_error_t string_util_reset(const void *value, char **target)
Definition: string_util.c:431
#define LOWERCASE(n)
Definition: string_util.c:18
mcl_uint8_t mcl_bool_t
String utility module interface header file.
mcl_bool_t mcl_string_util_memcmp(const void *block_1, const void *block_2, mcl_size_t count)
Definition: string_util.c:196
mcl_bool_t string_util_memcmp(const void *block_1, const void *block_2, mcl_size_t count)
Definition: string_util.c:208
Memory allocation fail.
#define MCL_NULL_CHAR_SIZE
#define MCL_MALLOC(bytes)
Definition: mcl_memory.h:54
char * mcl_string_util_strdup(const char *string)
Definition: string_util.c:259
mcl_error_t string_util_strncmp(const char *string_1, const char *string_2, mcl_size_t count)
Definition: string_util.c:135
void mcl_string_util_memcpy(void *destination, const void *source, mcl_size_t count)
Definition: string_util.c:220
#define MCL_DEBUG_LEAVE(...)
Definition: mcl_log_util.h:116
#define MCL_TRUE
static mcl_error_t _print_formatted_string(char *string, mcl_size_t length, const char *format, va_list args)
Definition: string_util.c:492
Internal failure in MCL.
mcl_size_t string_util_strlen(const char *buffer)
Definition: string_util.c:35
long mcl_string_util_strtol(const char *source, int base, char **end_pointer)
Definition: string_util.c:390
#define MCL_NULL_CHAR
mcl_bool_t mcl_string_util_find(const char *source, const char *target, mcl_size_t *start_index)
Definition: string_util.c:293
void mcl_string_util_strncpy(char *destination, const char *source, mcl_size_t count)
Definition: string_util.c:74
Memory module interface header file.