changed indentation to use spaces only
[wmaker-crm.git] / WINGs / string.c
blobe9f9ed3c1d2971c5d37226e8fc5aed941eb0a9e3
2 #include "wconfig.h"
4 #include <string.h>
5 #include <stdlib.h>
6 #include <ctype.h>
8 #include "WUtil.h"
12 #define PRC_ALPHA 0
13 #define PRC_BLANK 1
14 #define PRC_ESCAPE 2
15 #define PRC_DQUOTE 3
16 #define PRC_EOS 4
17 #define PRC_SQUOTE 5
19 typedef struct {
20 short nstate;
21 short output;
22 } DFA;
25 static DFA mtable[9][6] = {
26 {{3,1},{0,0},{4,0},{1,0},{8,0},{6,0}},
27 {{1,1},{1,1},{2,0},{3,0},{5,0},{1,1}},
28 {{1,1},{1,1},{1,1},{1,1},{5,0},{1,1}},
29 {{3,1},{5,0},{4,0},{1,0},{5,0},{6,0}},
30 {{3,1},{3,1},{3,1},{3,1},{5,0},{3,1}},
31 {{-1,-1},{0,0},{0,0},{0,0},{0,0},{0,0}}, /* final state */
32 {{6,1},{6,1},{7,0},{6,1},{5,0},{3,0}},
33 {{6,1},{6,1},{6,1},{6,1},{5,0},{6,1}},
34 {{-1,-1},{0,0},{0,0},{0,0},{0,0},{0,0}}, /* final state */
37 char*
38 wtokennext(char *word, char **next)
40 char *ptr;
41 char *ret, *t;
42 int state, ctype;
44 t = ret = wmalloc(strlen(word)+1);
45 ptr = word;
47 state = 0;
48 *t = 0;
49 while (1) {
50 if (*ptr==0)
51 ctype = PRC_EOS;
52 else if (*ptr=='\\')
53 ctype = PRC_ESCAPE;
54 else if (*ptr=='"')
55 ctype = PRC_DQUOTE;
56 else if (*ptr=='\'')
57 ctype = PRC_SQUOTE;
58 else if (*ptr==' ' || *ptr=='\t')
59 ctype = PRC_BLANK;
60 else
61 ctype = PRC_ALPHA;
63 if (mtable[state][ctype].output) {
64 *t = *ptr; t++;
65 *t = 0;
67 state = mtable[state][ctype].nstate;
68 ptr++;
69 if (mtable[state][0].output<0) {
70 break;
74 if (*ret==0)
75 t = NULL;
76 else
77 t = wstrdup(ret);
79 wfree(ret);
81 if (ctype==PRC_EOS)
82 *next = NULL;
83 else
84 *next = ptr;
86 return t;
90 /* separate a string in tokens, taking " and ' into account */
91 void
92 wtokensplit(char *command, char ***argv, int *argc)
94 char *token, *line;
95 int count;
97 count = 0;
98 line = command;
99 do {
100 token = wtokennext(line, &line);
101 if (token) {
102 if (count == 0)
103 *argv = wmalloc(sizeof(char**));
104 else
105 *argv = wrealloc(*argv, (count+1)*sizeof(char**));
106 (*argv)[count++] = token;
108 } while (token!=NULL && line!=NULL);
110 *argc = count;
117 char*
118 wtokenjoin(char **list, int count)
120 int i, j;
121 char *flat_string, *wspace;
123 j = 0;
124 for (i=0; i<count; i++) {
125 if (list[i]!=NULL && list[i][0]!=0) {
126 j += strlen(list[i]);
127 if (strpbrk(list[i], " \t"))
128 j += 2;
132 flat_string = wmalloc(j+count+1);
134 *flat_string = 0;
135 for (i=0; i<count; i++) {
136 if (list[i]!=NULL && list[i][0]!=0) {
137 if (i>0)
138 strcat(flat_string, " ");
139 wspace = strpbrk(list[i], " \t");
140 if (wspace)
141 strcat(flat_string, "\"");
142 strcat(flat_string, list[i]);
143 if (wspace)
144 strcat(flat_string, "\"");
148 return flat_string;
153 void
154 wtokenfree(char **tokens, int count)
156 while (--count) wfree(tokens[count]);
157 wfree(tokens);
162 char*
163 wtrimspace(char *s)
165 char *t;
166 char *c;
168 while (isspace(*s) && *s) s++;
169 t = s+strlen(s)-1;
170 while (t > s && isspace(*t)) t--;
172 c = wmalloc(t-s+2);
173 memcpy(c, s, t-s+1);
174 c[t-s+1] = 0;
176 return c;
180 char*
181 wstrdup(char *str)
183 assert(str!=NULL);
185 return strcpy(wmalloc(strlen(str)+1), str);
189 char*
190 wstrndup(char *str, size_t len)
192 char *copy;
194 assert(str!=NULL);
196 len = WMIN(len, strlen(str));
197 copy = strncpy(wmalloc(len+1), str, len);
198 copy[len] = 0;
200 return copy;
204 char*
205 wstrconcat(char *str1, char *str2)
207 char *str;
209 if (!str1)
210 return wstrdup(str2);
211 else if (!str2)
212 return wstrdup(str1);
214 str = wmalloc(strlen(str1)+strlen(str2)+1);
215 strcpy(str, str1);
216 strcat(str, str2);
218 return str;
222 char*
223 wstrappend(char *dst, char *src)
225 if (!dst)
226 return wstrdup(src);
227 else if (!src || *src==0)
228 return dst;
230 dst = wrealloc(dst, strlen(dst)+strlen(src)+1);
231 strcat(dst, src);
233 return dst;
237 #ifndef HAVE_STRCASECMP
239 strcasecmp(const char *s1, const char *s2)
241 while (*s1 && *s2 && (tolower(*s1)==tolower(*s2))) {
242 s1++;
243 s2++;
246 return (tolower(*s1) - tolower(*s2));
248 #endif