GCC Code Coverage Report


Directory: ./
File: src/string_utils.c
Date: 2024-08-06 23:19:24
Exec Total Coverage
Lines: 78 79 98.7%
Functions: 5 5 100.0%
Branches: 24 26 92.3%

Line Branch Exec Source
1 // SPDX-License-Identifier: GPL-3.0-or-later
2 // Copyright (C) 2020 Omar Castro
3
4 #include <stdlib.h>
5 #include <stdio.h>
6 #include <string.h>
7 #include "string_utils.h"
8
9 //// private method references
10
11
12 static void str_escape_for_json_string(const char *in, char *out);
13
14
15 //// public method references
16
17
18 // Result is an allocated a new string
19 30 char *str_replace(const char *orig, const char *rep, const char *with) {
20 char *result; // the return string
21 char *ins; // the next insert point
22 char *remainder; // remainder point
23 char *tmp; // varies
24 int len_rep; // length of rep (the string to remove)
25 int len_with; // length of with (the string to replace rep with)
26 int len_front; // distance between rep and end of last rep
27 int count; // number of replacements
28
29 // sanity checks and initialization
30
4/4
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 28 times.
30 if (!orig || !rep)
31 2 return NULL;
32 28 len_rep = strlen(rep);
33
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 27 times.
28 if (len_rep == 0)
34 1 return NULL; // empty rep causes infinite loop during count
35
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 26 times.
27 if (!with)
36 1 with = "";
37 27 len_with = strlen(with);
38
39 // count the number of replacements needed
40 27 ins = remainder = (char *) orig;
41 27 count = 0;
42 27 tmp = strstr(ins, rep);
43
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 27 times.
42 while(tmp){
44 15 ins = tmp + len_rep;
45 15 tmp = strstr(ins, rep);
46 15 count++;
47 }
48
49 27 tmp = result = malloc(strlen(orig) + (len_with - len_rep) * count + 1);
50
51
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 27 times.
27 if (!result)
52 return NULL;
53
54
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 27 times.
42 while (count--) {
55 15 ins = strstr(remainder, rep);
56 15 len_front = ins - remainder;
57 15 tmp = strncpy(tmp, remainder, len_front) + len_front;
58 15 tmp = strcpy(tmp, with) + len_with;
59 15 remainder += len_front + len_rep; // move to next "end of rep"
60 }
61 27 strcpy(tmp, remainder);
62 27 return result;
63 }
64
65 20 char *str_replace_in(char **orig, const char *rep, const char *with) {
66 20 char * result = str_replace(*orig, rep, with);
67
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
20 if( result != NULL ){
68 20 free(*orig);
69 20 *orig = result;
70 }
71 20 return *orig;
72 }
73
74 10 char *str_replace_in_escaped(char **orig, const char *rep, const char *with) {
75 10 char * escaped_with = str_new_escaped_for_json_string(with);
76 10 char * result = str_replace_in(orig, rep, escaped_with);
77 10 free(escaped_with);
78 10 return result;
79 }
80
81 10 char * str_new_escaped_for_json_string(const char *str_to_escape){
82 10 int len = strlen(str_to_escape);
83 10 char * result = (char*)calloc(len*2, sizeof(char));
84 10 str_escape_for_json_string(str_to_escape, result);
85 10 return result;
86 }
87
88
89 //// private method definitions
90
91
92 10 static void str_escape_for_json_string(const char *in, char *out) {
93
2/2
✓ Branch 0 taken 58 times.
✓ Branch 1 taken 10 times.
68 while (*in) {
94
8/8
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 1 times.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 51 times.
58 switch (*in) {
95 1 case '\\':
96 1 *(out++) = '\\';
97 1 *(out++) = *in;
98 1 break;
99 1 case '"':
100 1 *(out++) = '\\';
101 1 *(out++) = '"';
102 1 break;
103 1 case '\t':
104 1 *(out++) = '\\';
105 1 *(out++) = 't';
106 1 break;
107 1 case '\r':
108 1 *(out++) = '\\';
109 1 *(out++) = 'r';
110 1 break;
111 1 case '\f':
112 1 *(out++) = '\\';
113 1 *(out++) = 'f';
114 1 break;
115 1 case '\b':
116 1 *(out++) = '\\';
117 1 *(out++) = 'b';
118 1 break;
119 1 case '\n':
120 1 *(out++) = '\\';
121 1 *(out++) = 'n';
122 1 break;
123 51 default:
124 51 *(out++) = *in;
125 51 break;
126 }
127 58 in++;
128 }
129 10 }
130