WINGs: Make wmalloc() intialize allocated memory to 0
[wmaker-crm.git] / WINGs / string.c
blob5dbba85fd8a795ef16f2f515d51acaa82a8ac83c
2 #include "wconfig.h"
4 #include <string.h>
5 #include <stdlib.h>
6 #include <ctype.h>
8 #include "WUtil.h"
10 #define PRC_ALPHA 0
11 #define PRC_BLANK 1
12 #define PRC_ESCAPE 2
13 #define PRC_DQUOTE 3
14 #define PRC_EOS 4
15 #define PRC_SQUOTE 5
17 typedef struct {
18 short nstate;
19 short output;
20 } DFA;
22 static DFA mtable[9][6] = {
23 {{3, 1}, {0, 0}, {4, 0}, {1, 0}, {8, 0}, {6, 0}},
24 {{1, 1}, {1, 1}, {2, 0}, {3, 0}, {5, 0}, {1, 1}},
25 {{1, 1}, {1, 1}, {1, 1}, {1, 1}, {5, 0}, {1, 1}},
26 {{3, 1}, {5, 0}, {4, 0}, {1, 0}, {5, 0}, {6, 0}},
27 {{3, 1}, {3, 1}, {3, 1}, {3, 1}, {5, 0}, {3, 1}},
28 {{-1, -1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, /* final state */
29 {{6, 1}, {6, 1}, {7, 0}, {6, 1}, {5, 0}, {3, 0}},
30 {{6, 1}, {6, 1}, {6, 1}, {6, 1}, {5, 0}, {6, 1}},
31 {{-1, -1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, /* final state */
34 char *wtokennext(char *word, char **next)
36 char *ptr;
37 char *ret, *t;
38 int state, ctype;
40 t = ret = wmalloc(strlen(word) + 1);
41 ptr = word;
43 state = 0;
44 while (1) {
45 if (*ptr == 0)
46 ctype = PRC_EOS;
47 else if (*ptr == '\\')
48 ctype = PRC_ESCAPE;
49 else if (*ptr == '"')
50 ctype = PRC_DQUOTE;
51 else if (*ptr == '\'')
52 ctype = PRC_SQUOTE;
53 else if (*ptr == ' ' || *ptr == '\t')
54 ctype = PRC_BLANK;
55 else
56 ctype = PRC_ALPHA;
58 if (mtable[state][ctype].output) {
59 *t = *ptr;
60 t++;
61 *t = 0;
63 state = mtable[state][ctype].nstate;
64 ptr++;
65 if (mtable[state][0].output < 0) {
66 break;
70 if (*ret == 0)
71 t = NULL;
72 else
73 t = wstrdup(ret);
75 wfree(ret);
77 if (ctype == PRC_EOS)
78 *next = NULL;
79 else
80 *next = ptr;
82 return t;
85 /* separate a string in tokens, taking " and ' into account */
86 void wtokensplit(char *command, char ***argv, int *argc)
88 char *token, *line;
89 int count;
91 count = 0;
92 line = command;
93 do {
94 token = wtokennext(line, &line);
95 if (token) {
96 if (count == 0)
97 *argv = wmalloc(sizeof(char **));
98 else
99 *argv = wrealloc(*argv, (count + 1) * sizeof(char **));
100 (*argv)[count++] = token;
102 } while (token != NULL && line != NULL);
104 *argc = count;
107 char *wtokenjoin(char **list, int count)
109 int i, j;
110 char *flat_string, *wspace;
112 j = 0;
113 for (i = 0; i < count; i++) {
114 if (list[i] != NULL && list[i][0] != 0) {
115 j += strlen(list[i]);
116 if (strpbrk(list[i], " \t"))
117 j += 2;
121 flat_string = wmalloc(j + count + 1);
123 for (i = 0; i < count; i++) {
124 if (list[i] != NULL && list[i][0] != 0) {
125 if (i > 0)
126 strcat(flat_string, " ");
127 wspace = strpbrk(list[i], " \t");
128 if (wspace)
129 strcat(flat_string, "\"");
130 strcat(flat_string, list[i]);
131 if (wspace)
132 strcat(flat_string, "\"");
136 return flat_string;
139 void wtokenfree(char **tokens, int count)
141 while (count--)
142 wfree(tokens[count]);
143 wfree(tokens);
146 char *wtrimspace(const char *s)
148 char *t;
150 if (s == NULL)
151 return NULL;
153 while (isspace(*s) && *s)
154 s++;
155 t = (char *)s + strlen(s) - 1;
156 while (t > s && isspace(*t))
157 t--;
159 return wstrndup(s, t - s + 1);
162 char *wstrdup(const char *str)
164 assert(str != NULL);
166 return strcpy(wmalloc(strlen(str) + 1), str);
169 char *wstrndup(const char *str, size_t len)
171 char *copy;
173 assert(str != NULL);
175 len = WMIN(len, strlen(str));
176 copy = strncpy(wmalloc(len + 1), str, len);
177 copy[len] = 0;
179 return copy;
182 char *wstrconcat(char *str1, char *str2)
184 char *str;
186 if (!str1)
187 return wstrdup(str2);
188 else if (!str2)
189 return wstrdup(str1);
191 str = wmalloc(strlen(str1) + strlen(str2) + 1);
192 strcpy(str, str1);
193 strcat(str, str2);
195 return str;
198 char *wstrappend(char *dst, char *src)
200 if (!dst)
201 return wstrdup(src);
202 else if (!src || *src == 0)
203 return dst;
205 dst = wrealloc(dst, strlen(dst) + strlen(src) + 1);
206 strcat(dst, src);
208 return dst;