added wtokennext()
[wmaker-crm.git] / WINGs / string.c
blob172216ac9573b32faba18992529fcea7e805415f
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 char*
36 wtokennext(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 = wtokennext(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 = wmalloc(j+count+1);
132 *flat_string = 0;
133 for (i=0; i<count; i++) {
134 if (list[i]!=NULL && list[i][0]!=0) {
135 if (i>0)
136 strcat(flat_string, " ");
137 wspace = strpbrk(list[i], " \t");
138 if (wspace)
139 strcat(flat_string, "\"");
140 strcat(flat_string, list[i]);
141 if (wspace)
142 strcat(flat_string, "\"");
146 return flat_string;
151 void
152 wtokenfree(char **tokens, int count)
154 while (--count) free(tokens[count]);
155 free(tokens);
160 char*
161 wtrimspace(char *s)
163 char *t;
164 char *c;
166 while (isspace(*s) && *s) s++;
167 t = s+strlen(s);
168 while (t > s && isspace(*t)) t--;
170 c = wmalloc(t-s + 1);
171 memcpy(c, s, t-s);
172 c[t-s] = 0;
174 return c;