aboutsummaryrefslogtreecommitdiff
path: root/gconf/wordsplit.c
diff options
context:
space:
mode:
Diffstat (limited to 'gconf/wordsplit.c')
-rw-r--r--gconf/wordsplit.c568
1 files changed, 0 insertions, 568 deletions
diff --git a/gconf/wordsplit.c b/gconf/wordsplit.c
deleted file mode 100644
index a5bb13e..0000000
--- a/gconf/wordsplit.c
+++ /dev/null
@@ -1,568 +0,0 @@
1/* wordsplit - a word splitter
2 Copyright (C) 2009 Sergey Poznyakoff
3
4 This program is free software; you can redistribute it and/or modify it
5 under the terms of the GNU General Public License as published by the
6 Free Software Foundation; either version 3 of the License, or (at your
7 option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License along
15 with this program. If not, see <http://www.gnu.org/licenses/>. */
16
17#ifdef HAVE_CONFIG_H
18# include <config.h>
19#endif
20
21#include <ctype.h>
22#include <c-ctype.h>
23#include <errno.h>
24#include <unistd.h>
25#include <string.h>
26#include <wordsplit.h>
27
28#include <error.h>
29#include <gettext.h>
30#define _(msgid) gettext (msgid)
31#include <xalloc.h>
32
33#define isws(c) ((c)==' '||(c)=='\t'||(c)=='\n')
34#define isdelim(c,delim) (strchr(delim,(c))!=NULL)
35
36#define _ARGCV_WORD_SED_EXPR 0x10000
37#define _ARGCV_WORD_MASK 0xf0000
38
39#define ALLOC_INIT 128
40#define ALLOC_INCR 128
41
42static int
43wordsplit_init (struct wordsplit *wsp, const char *input, size_t len,
44 int flags)
45{
46 wsp->ws_flags = flags;
47 if ((wsp->ws_flags & (WRDSF_NOVAR|WRDSF_NOCMD))
48 != (WRDSF_NOVAR|WRDSF_NOCMD))
49 {
50 if (wsp->ws_flags & WRDSF_SHOWERR)
51 error (0, 0,
52 _("variable expansion and command substitution "
53 "are not yet supported"));
54 errno = EINVAL;
55 return 1;
56 }
57
58 wsp->ws_input = input;
59 wsp->ws_len = len;
60
61 if (!(wsp->ws_flags & WRDSF_DOOFFS))
62 wsp->ws_offs = 0;
63
64 if (!(wsp->ws_flags & WRDSF_DELIM))
65 wsp->ws_delim = " ";
66
67 if (!(wsp->ws_flags & WRDSF_COMMENT))
68 wsp->ws_comment = NULL;
69
70 if (wsp->ws_flags & WRDSF_REUSE)
71 {
72 wsp->ws_wordn = wsp->ws_wordc + 1;
73 if (wsp->ws_flags & WRDSF_DOOFFS)
74 wsp->ws_wordn += wsp->ws_offs;
75 if (!(wsp->ws_flags & WRDSF_APPEND))
76 wsp->ws_wordc = 0;
77 }
78 else
79 {
80 wsp->ws_wordv = NULL;
81 wsp->ws_wordc = 0;
82 wsp->ws_wordn = 0;
83 }
84
85 wsp->ws_endp = 0;
86 return 0;
87}
88
89static int
90alloc_space (struct wordsplit *wsp)
91{
92 size_t offs = (wsp->ws_flags & WRDSF_DOOFFS) ? wsp->ws_offs : 0;
93 char **ptr;
94 size_t newalloc;
95
96 if (wsp->ws_wordv == NULL)
97 {
98 newalloc = offs + ALLOC_INIT;
99 ptr = calloc (newalloc, sizeof (ptr[0]));
100 }
101 else if (wsp->ws_wordn < offs + wsp->ws_wordc + 1)
102 {
103 newalloc = offs + wsp->ws_wordc + ALLOC_INCR;
104 ptr = realloc (wsp->ws_wordv, newalloc * sizeof (ptr[0]));
105 }
106 else
107 return 0;
108
109 if (ptr)
110 {
111 wsp->ws_wordn = newalloc;
112 wsp->ws_wordv = ptr;
113 }
114 else
115 {
116 if (wsp->ws_flags & WRDSF_ENOMEMABRT)
117 xalloc_die ();
118 else if (wsp->ws_flags & WRDSF_SHOWERR)
119 error (0, 0, _("memory exhausted"));
120 errno = ENOMEM;
121 return 1;
122 }
123 return 0;
124}
125
126static int
127skip_sed_expr(const char *command, size_t i, size_t len)
128{
129 int state;
130
131 do
132 {
133 int delim;
134
135 if (command[i] == ';')
136 i++;
137 if (!(command[i] == 's' && i + 3 < len && c_ispunct(command[i+1])))
138 break;
139
140 delim = command[++i];
141 state = 1;
142 for (i++; i < len; i++)
143 {
144 if (state == 3)
145 {
146 if (command[i] == delim || !c_isalnum(command[i]))
147 break;
148 }
149 else if (command[i] == '\\')
150 i++;
151 else if (command[i] == delim)
152 state++;
153 }
154 }
155 while (state == 3 && i < len && command[i] == ';');
156 return i;
157}
158
159static size_t
160skip_delim (struct wordsplit *wsp)
161{
162 size_t start = wsp->ws_endp;
163 if (wsp->ws_flags & WRDSF_SQUEEZE_DELIMS)
164 {
165 do
166 start++;
167 while (start < wsp->ws_len
168 && isdelim (wsp->ws_input[start], wsp->ws_delim));
169 start--;
170 }
171
172 if (!(wsp->ws_flags & WRDSF_RETURN_DELIMS))
173 start++;
174
175 return start;
176}
177
178#define _WRDS_WORD 1
179#define _WRDS_CONT 2
180
181static int
182scan_word (struct wordsplit *wsp, size_t *pstart, size_t *pend)
183{
184 size_t start = *pstart;
185 size_t len = wsp->ws_len;
186 const char *command = wsp->ws_input;
187 const char *delim = wsp->ws_delim;
188 const char *comment = wsp->ws_comment;
189
190 size_t i = start;
191
192 if (i >= len)
193 return WRDSE_EOF;
194
195 if (wsp->ws_flags & WRDSF_WS)
196 {
197 /* Skip initial whitespace */
198 while (i < len && isws (command[i]))
199 i++;
200 }
201
202 start = i;
203
204 wsp->ws_flags &= ~_ARGCV_WORD_MASK;
205
206 if (wsp->ws_flags & WRDSF_SED_EXPR
207 && command[i] == 's' && i + 3 < len && c_ispunct (command[i+1]))
208 {
209 wsp->ws_flags |= _ARGCV_WORD_SED_EXPR;
210 i = skip_sed_expr (command, i, len);
211 }
212 else if (!isdelim (command[i], delim))
213 {
214 while (i < len)
215 {
216 if (comment && strchr (comment, command[i]) != NULL)
217 {
218 size_t j;
219 for (j = i + 1; j < len && command[j] != '\n'; j++)
220 ;
221 *pstart = start;
222 *pend = i;
223 wsp->ws_endp = j;
224 return i > start ? _WRDS_WORD : _WRDS_CONT;
225 }
226
227 if (wsp->ws_flags & WRDSF_QUOTE)
228 {
229 if (command[i] == '\\')
230 {
231 if (++i == len)
232 break;
233 i++;
234 continue;
235 }
236
237 if (command[i] == '\'' || command[i] == '"')
238 {
239 size_t j;
240 for (j = i + 1; j < len && command[j] != command[i]; j++)
241 if (command[j] == '\\')
242 j++;
243 if (j < len && command[j] == command[i])
244 i = j + 1;
245 else
246 {