Change to the linux kernel coding style
[wmaker-crm.git] / WINGs / string.c
1
2 #include "wconfig.h"
3
4 #include <string.h>
5 #include <stdlib.h>
6 #include <ctype.h>
7
8 #include "WUtil.h"
9
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
16
17 typedef struct {
18         short nstate;
19         short output;
20 } DFA;
21
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 */
32 };
33
34 char *wtokennext(char *word, char **next)
35 {
36         char *ptr;
37         char *ret, *t;
38         int state, ctype;
39
40         t = ret = wmalloc(strlen(word) + 1);
41         ptr = word;
42
43         state = 0;
44         *t = 0;
45         while (1) {
46                 if (*ptr == 0)
47                         ctype = PRC_EOS;
48                 else if (*ptr == '\\')
49                         ctype = PRC_ESCAPE;
50                 else if (*ptr == '"')
51                         ctype = PRC_DQUOTE;
52                 else if (*ptr == '\'')
53                         ctype = PRC_SQUOTE;
54                 else if (*ptr == ' ' || *ptr == '\t')
55                         ctype = PRC_BLANK;
56                 else
57                         ctype = PRC_ALPHA;
58
59                 if (mtable[state][ctype].output) {
60                         *t = *ptr;
61                         t++;
62                         *t = 0;
63                 }
64                 state = mtable[state][ctype].nstate;
65                 ptr++;
66                 if (mtable[state][0].output < 0) {
67                         break;
68                 }
69         }
70
71         if (*ret == 0)
72                 t = NULL;
73         else
74                 t = wstrdup(ret);
75
76         wfree(ret);
77
78         if (ctype == PRC_EOS)
79                 *next = NULL;
80         else
81                 *next = ptr;
82
83         return t;
84 }
85
86 /* separate a string in tokens, taking " and ' into account */
87 void wtokensplit(char *command, char ***argv, int *argc)
88 {
89         char *token, *line;
90         int count;
91
92         count = 0;
93         line = command;
94         do {
95                 token = wtokennext(line, &line);
96                 if (token) {
97                         if (count == 0)
98                                 *argv = wmalloc(sizeof(char **));
99                         else
100                                 *argv = wrealloc(*argv, (count + 1) * sizeof(char **));
101                         (*argv)[count++] = token;
102                 }
103         } while (token != NULL && line != NULL);
104
105         *argc = count;
106 }
107
108 char *wtokenjoin(char **list, int count)
109 {
110         int i, j;
111         char *flat_string, *wspace;
112
113         j = 0;
114         for (i = 0; i < count; i++) {
115                 if (list[i] != NULL && list[i][0] != 0) {
116                         j += strlen(list[i]);
117                         if (strpbrk(list[i], " \t"))
118                                 j += 2;
119                 }
120         }
121
122         flat_string = wmalloc(j + count + 1);
123
124         *flat_string = 0;
125         for (i = 0; i < count; i++) {
126                 if (list[i] != NULL && list[i][0] != 0) {
127                         if (i > 0)
128                                 strcat(flat_string, " ");
129                         wspace = strpbrk(list[i], " \t");
130                         if (wspace)
131                                 strcat(flat_string, "\"");
132                         strcat(flat_string, list[i]);
133                         if (wspace)
134                                 strcat(flat_string, "\"");
135                 }
136         }
137
138         return flat_string;
139 }
140
141 void wtokenfree(char **tokens, int count)
142 {
143         while (--count)
144                 wfree(tokens[count]);
145         wfree(tokens);
146 }
147
148 char *wtrimspace(char *s)
149 {
150         char *t;
151         char *c;
152
153         while (isspace(*s) && *s)
154                 s++;
155         t = s + strlen(s) - 1;
156         while (t > s && isspace(*t))
157                 t--;
158
159         c = wmalloc(t - s + 2);
160         memcpy(c, s, t - s + 1);
161         c[t - s + 1] = 0;
162
163         return c;
164 }
165
166 char *wstrdup(char *str)
167 {
168         assert(str != NULL);
169
170         return strcpy(wmalloc(strlen(str) + 1), str);
171 }
172
173 char *wstrndup(char *str, size_t len)
174 {
175         char *copy;
176
177         assert(str != NULL);
178
179         len = WMIN(len, strlen(str));
180         copy = strncpy(wmalloc(len + 1), str, len);
181         copy[len] = 0;
182
183         return copy;
184 }
185
186 char *wstrconcat(char *str1, char *str2)
187 {
188         char *str;
189
190         if (!str1)
191                 return wstrdup(str2);
192         else if (!str2)
193                 return wstrdup(str1);
194
195         str = wmalloc(strlen(str1) + strlen(str2) + 1);
196         strcpy(str, str1);
197         strcat(str, str2);
198
199         return str;
200 }
201
202 char *wstrappend(char *dst, char *src)
203 {
204         if (!dst)
205                 return wstrdup(src);
206         else if (!src || *src == 0)
207                 return dst;
208
209         dst = wrealloc(dst, strlen(dst) + strlen(src) + 1);
210         strcat(dst, src);
211
212         return dst;
213 }
214
215 #ifndef HAVE_STRCASECMP
216 int strcasecmp(const char *s1, const char *s2)
217 {
218         while (*s1 && *s2 && (tolower(*s1) == tolower(*s2))) {
219                 s1++;
220                 s2++;
221         }
222
223         return (tolower(*s1) - tolower(*s2));
224 }
225 #endif