added string utils
[wmaker-crm.git] / WINGs / string.c
blob01ea275c78b404bd0f8321bd2a994f7eb8d0c5f6
2 #include <string.h>
3 #include <stdlib.h>
4 #include <ctype.h>
6 #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;
23 static DFA mtable[9][6] = {
24 {{3,1},{0,0},{4,0},{1,0},{8,0},{6,0}},
25 {{1,1},{1,1},{2,0},{3,0},{5,0},{1,1}},
26 {{1,1},{1,1},{1,1},{1,1},{5,0},{1,1}},
27 {{3,1},{5,0},{4,0},{1,0},{5,0},{6,0}},
28 {{3,1},{3,1},{3,1},{3,1},{5,0},{3,1}},
29 {{-1,-1},{0,0},{0,0},{0,0},{0,0},{0,0}}, /* final state */
30 {{6,1},{6,1},{7,0},{6,1},{5,0},{3,0}},
31 {{6,1},{6,1},{6,1},{6,1},{5,0},{6,1}},
32 {{-1,-1},{0,0},{0,0},{0,0},{0,0},{0,0}}, /* final state */
35 static char*
36 next_token(char *word, char **next)
38 char *ptr;
39 char *ret, *t;
40 int state, ctype;
42 t = ret = wmalloc(strlen(word)+1);
43 ptr = word;
45 state = 0;
46 *t = 0;
47 while (1) {
48 if (*ptr==0)
49 ctype = PRC_EOS;
50 else if (*ptr=='\\')
51 ctype = PRC_ESCAPE;
52 else if (*ptr=='"')
53 ctype = PRC_DQUOTE;
54 else if (*ptr=='\'')
55 ctype = PRC_SQUOTE;
56 else if (*ptr==' ' || *ptr=='\t')
57 ctype = PRC_BLANK;
58 else
59 ctype = PRC_ALPHA;
61 if (mtable[state][ctype].output) {
62 *t = *ptr; t++;
63 *t = 0;
65 state = mtable[state][ctype].nstate;
66 ptr++;
67 if (mtable[state][0].output<0) {
68 break;
72 if (*ret==0)
73 t = NULL;
74 else
75 t = wstrdup(ret);
77 free(ret);
79 if (ctype==PRC_EOS)
80 *next = NULL;
81 else
82 *next = ptr;
84 return t;
88 /* separate a string in tokens, taking " and ' into account */
89 void
90 wtokensplit(char *command, char ***argv, int *argc)
92 char *token, *line;
93 int count;
95 count = 0;
96 line = command;
97 do {
98 token = next_token(line, &line);
99 if (token) {
100 if (count == 0)
101 *argv = wmalloc(sizeof(char**));
102 else
103 *argv = wrealloc(*argv, (count+1)*sizeof(char**));
104 (*argv)[count++] = token;
106 } while (token!=NULL && line!=NULL);
108 *argc = count;
115 char*
116 wtokenjoin(char **list, int count)
118 int i, j;
119 char *flat_string, *wspace;
121 j = 0;
122 for (i=0; i<count; i++) {
123 if (list[i]!=NULL && list[i][0]!=0) {
124 j += strlen(list[i]);
125 if (strpbrk(list[i], " \t"))
126 j += 2;
130 flat_string = malloc(j+count+1);
131 if (!flat_string) {
132 return NULL;
135 *flat_string = 0;
136 for (i=0; i<count; i++) {
137 if (list[i]!=NULL && list[i][0]!=0) {
138 if (i>0)
139 strcat(flat_string, " ");
140 wspace = strpbrk(list[i], " \t");
141 if (wspace)
142 strcat(flat_string, "\"");
143 strcat(flat_string, list[i]);
144 if (wspace)
145 strcat(flat_string, "\"");
149 return flat_string;
154 void
155 wtokenfree(char **tokens, int count)
157 while (--count) free(tokens[count]);
158 free(tokens);
163 char*
164 wtrimspace(char *s)
166 char *t;
167 char *c;
169 while (isspace(*s) && *s) s++;
170 t = s+strlen(s);
171 while (t > s && isspace(*t)) t--;
173 c = wmalloc(t-s + 1);
174 memcpy(c, s, t-s);
175 c[t-s] = 0;
177 return c;