57 size += str.length; |
57 size += str.length; |
58 } |
58 } |
59 va_end(ap); |
59 va_end(ap); |
60 |
60 |
61 return size; |
61 return size; |
|
62 } |
|
63 |
|
64 static sstr_t sstrvcat_a( |
|
65 UcxAllocator *a, |
|
66 size_t count, |
|
67 sstr_t s1, |
|
68 sstr_t s2, |
|
69 va_list ap) { |
|
70 sstr_t str; |
|
71 str.ptr = NULL; |
|
72 str.length = 0; |
|
73 if(count < 2) { |
|
74 return str; |
|
75 } |
|
76 |
|
77 sstr_t *strings = calloc(count, sizeof(sstr_t)); |
|
78 if(!strings) { |
|
79 return str; |
|
80 } |
|
81 |
|
82 // get all args and overall length |
|
83 strings[0] = s1; |
|
84 strings[1] = s2; |
|
85 size_t strlen = s1.length + s2.length; |
|
86 for (size_t i=2;i<count;i++) { |
|
87 sstr_t s = va_arg (ap, sstr_t); |
|
88 strings[i] = s; |
|
89 strlen += s.length; |
|
90 } |
|
91 |
|
92 // create new string |
|
93 str.ptr = malloc(strlen + 1); |
|
94 str.length = strlen; |
|
95 if(!str.ptr) { |
|
96 free(strings); |
|
97 str.length = 0; |
|
98 return str; |
|
99 } |
|
100 |
|
101 // concatenate strings |
|
102 size_t pos = 0; |
|
103 for (size_t i=0;i<count;i++) { |
|
104 sstr_t s = strings[i]; |
|
105 memcpy(str.ptr + pos, s.ptr, s.length); |
|
106 pos += s.length; |
|
107 } |
|
108 |
|
109 str.ptr[str.length] = '\0'; |
|
110 |
|
111 free(strings); |
|
112 |
|
113 return str; |
|
114 } |
|
115 |
|
116 sstr_t sstrcat(size_t count, sstr_t s1, sstr_t s2, ...) { |
|
117 va_list ap; |
|
118 va_start(ap, s2); |
|
119 sstr_t s = sstrvcat_a(ucx_default_allocator(), count, s1, s2, ap); |
|
120 va_end(ap); |
|
121 return s; |
|
122 } |
|
123 |
|
124 sstr_t sstrcat_a(UcxAllocator *a, size_t count, sstr_t s1, sstr_t s2, ...) { |
|
125 va_list ap; |
|
126 va_start(ap, s2); |
|
127 sstr_t s = sstrvcat_a(a, count, s1, s2, ap); |
|
128 va_end(ap); |
|
129 return s; |
62 } |
130 } |
63 |
131 |
64 sstr_t sstrsubs(sstr_t s, size_t start) { |
132 sstr_t sstrsubs(sstr_t s, size_t start) { |
65 return sstrsubsl (s, start, s.length-start); |
133 return sstrsubsl (s, start, s.length-start); |
66 } |
134 } |