str.c (3776B)
1 /* See LICENSE file for copyright and license details. */ 2 #include <assert.h> 3 #include <ctype.h> 4 #include <stdio.h> 5 #include <stdlib.h> 6 #include <string.h> 7 8 #include "util.h" 9 10 /* compress array of strings to single string */ 11 char * 12 str_concat(char **s, int c) 13 { 14 if (!s) die("strconcat: given null pointer"); 15 16 int len = 0, i; 17 char *ret; 18 19 for (i = 0; i < c; i++) 20 len += strlen(s[i]) + 1; 21 ret = ecalloc(len, sizeof(char)); 22 23 strcpy(ret, s[0]); 24 strcat(ret, " "); 25 for (i = 1; i < c; i++) { 26 strcat(ret, s[i]); 27 strcat(ret, " "); 28 } 29 30 return ret; 31 } 32 33 /* split string s into muiltple strings by a_delim */ 34 char ** 35 str_split(const char *s, const char a_delim, int *c) 36 { 37 if (!s) die("strsplit: given null pointer"); 38 39 char **ret = 0; 40 size_t count = 0; 41 char *last_delim = 0; 42 char delim[2] = { a_delim, 0 }; /* converet a_delim into string for strtok */ 43 char *a_str = ecalloc(strlen(s)+1, sizeof(char)); 44 strcpy(a_str, s); 45 46 /* count number of elements that will be extracted. */ 47 for (char *tmp = a_str; *tmp; tmp++) 48 if (a_delim == *tmp) { 49 count++; 50 last_delim = tmp; 51 } 52 53 /* add space for trailing token. */ 54 count += last_delim < (a_str + strlen(a_str) - 1); 55 56 /* add space for terminating null string so caller 57 * knows where the list of returned strings ends. */ 58 count++; 59 60 ret = ecalloc(count, sizeof(char*)); 61 62 if (ret) { 63 size_t idx = 0; 64 char *token = strtok(a_str, delim); 65 66 while (token) { 67 assert(idx < count); 68 *(ret + idx++) = estrdup(token); 69 token = strtok(0, delim); 70 } 71 assert(idx == count - 1); 72 *(ret + idx) = 0; 73 } 74 75 *c = count - 1; 76 free(a_str); 77 return ret; 78 } 79 80 /* replace rep in orig with with */ 81 char * 82 str_replace(char *orig, char *rep, char *with) 83 { 84 char *ret, *tmp, *ins; /* ins: the next insert point */ 85 int len_rep, len_with, len_front, count; /* len_front: distance between rep and end of last rep */ 86 87 /* checks, set lens, and init */ 88 if (!orig || !rep) 89 return NULL; 90 len_rep = strlen(rep); 91 if (len_rep == 0) 92 return NULL; /* empty rep causes infinite loop during count */ 93 if (!with) 94 with = ""; 95 len_with = strlen(with); 96 97 /* count the number of replacements needed */ 98 ins = orig; 99 for (count = 0; (tmp = strstr(ins, rep)); ++count) 100 ins = tmp + len_rep; 101 102 tmp = ret = malloc(strlen(orig) + (len_with - len_rep) * count + 1); 103 104 if (!ret) 105 return NULL; 106 107 /* tmp: end of the ret string 108 * ins: next occurrence of rep in orig 109 * orig: remainder of orig after "end of rep" */ 110 while (count--) { 111 ins = strstr(orig, rep); 112 len_front = ins - orig; 113 tmp = strncpy(tmp, orig, len_front) + len_front; 114 tmp = strcpy(tmp, with) + len_with; 115 orig += len_front + len_rep; /* move to next "end of rep" */ 116 } 117 strcpy(tmp, orig); 118 119 return ret; 120 } 121 122 /* remove tailing or leading white space from s */ 123 char * 124 str_trim(char *s) 125 { 126 char *end; 127 128 /* trim leading space */ 129 while (isspace(*s)) s++; 130 131 if (*s == 0) /* all spaces? */ 132 return s; 133 134 /* trim trailing space */ 135 end = s + strlen(s) - 1; 136 while (end > s && isspace(*end)) end--; 137 138 /* write new null terminator */ 139 *(end+1) = 0; 140 141 return s; 142 } 143 144 char * 145 str_rmspaces(char *s) 146 { 147 int c = 0, d = 0; 148 char *start = emalloc(strlen(s)+1); 149 150 while (*(s+c) != '\0') { 151 if (*(s+c) == ' ') { 152 int temp = c + 1; 153 if (*(s+temp) != '\0') { 154 while (*(s+temp) == ' ' && *(s+temp) != '\0') { 155 if (*(s+temp) == ' ') c++; 156 temp++; 157 } 158 } 159 } 160 *(start+d) = *(s+c); 161 c++; 162 d++; 163 } 164 *(start+d)= '\0'; 165 166 return start; 167 } 168 169 /* return if str is in the list */ 170 int 171 strinlist(char *str, char **list, int listc) 172 { 173 if (!str || !list) return 0; 174 int i; 175 for (i = 0; i < listc; i++) 176 if (list[i] && strcmp(str, list[i]) == 0) 177 return 1; 178 return 0; 179 } 180 181 int 182 charinstr(char c, char *str) 183 { 184 if (!str) return 0; 185 for (; *str; str++) 186 if (*str == c) 187 return 1; 188 return 0; 189 }