diff options
Diffstat (limited to 'src/wordsplit.c')
-rw-r--r-- | src/wordsplit.c | 2892 |
1 files changed, 0 insertions, 2892 deletions
diff --git a/src/wordsplit.c b/src/wordsplit.c deleted file mode 100644 index 9179a87..0000000 --- a/src/wordsplit.c +++ /dev/null | |||
@@ -1,2892 +0,0 @@ | |||
1 | /* wordsplit - a word splitter | ||
2 | Copyright (C) 2009-2019 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 <errno.h> | ||
22 | #include <ctype.h> | ||
23 | #include <unistd.h> | ||
24 | #include <stdlib.h> | ||
25 | #include <string.h> | ||
26 | #include <stdio.h> | ||
27 | #include <stdarg.h> | ||
28 | #include <pwd.h> | ||
29 | #include <glob.h> | ||
30 | #include <limits.h> | ||
31 | |||
32 | #if ENABLE_NLS | ||
33 | # include <gettext.h> | ||
34 | #else | ||
35 | # define gettext(msgid) msgid | ||
36 | #endif | ||
37 | #define _(msgid) gettext (msgid) | ||
38 | #define N_(msgid) msgid | ||
39 | |||
40 | #include <wordsplit.h> | ||
41 | |||
42 | #define ISWS(c) ((c)==' '||(c)=='\t'||(c)=='\n') | ||
43 | #define ISDELIM(ws,c) \ | ||
44 | (strchr ((ws)->ws_delim, (c)) != NULL) | ||
45 | #define ISPUNCT(c) (strchr("!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",(c))!=NULL) | ||
46 | #define ISUPPER(c) ('A' <= ((unsigned) (c)) && ((unsigned) (c)) <= 'Z') | ||
47 | #define ISLOWER(c) ('a' <= ((unsigned) (c)) && ((unsigned) (c)) <= 'z') | ||
48 | #define ISALPHA(c) (ISUPPER(c) || ISLOWER(c)) | ||
49 | #define ISDIGIT(c) ('0' <= ((unsigned) (c)) && ((unsigned) (c)) <= '9') | ||
50 | #define ISXDIGIT(c) (strchr("abcdefABCDEF", c)!=NULL) | ||
51 | #define ISALNUM(c) (ISALPHA(c) || ISDIGIT(c)) | ||
52 | #define ISPRINT(c) (' ' <= ((unsigned) (c)) && ((unsigned) (c)) <= 127) | ||
53 | |||
54 | #define ISVARBEG(c) (ISALPHA(c) || c == '_') | ||
55 | #define ISVARCHR(c) (ISALNUM(c) || c == '_') | ||
56 | |||
57 | #define WSP_RETURN_DELIMS(wsp) \ | ||
58 | ((wsp)->ws_flags & WRDSF_RETURN_DELIMS || ((wsp)->ws_options & WRDSO_MAXWORDS)) | ||
59 | |||
60 | #define to_num(c) \ | ||
61 | (ISDIGIT(c) ? c - '0' : (ISXDIGIT(c) ? toupper(c) - 'A' + 10 : 255 )) | ||
62 | |||
63 | #define ALLOC_INIT 128 | ||
64 | #define ALLOC_INCR 128 | ||
65 | |||
66 | static void | ||
67 | _wsplt_alloc_die (struct wordsplit *wsp) | ||
68 | { | ||
69 | wsp->ws_error ("%s", _("memory exhausted")); | ||
70 | abort (); | ||
71 | } | ||
72 | |||
73 | static void | ||
74 | _wsplt_error (const char *fmt, ...) | ||
75 | { | ||
76 | va_list ap; | ||
77 | |||
78 | va_start (ap, fmt); | ||
79 | vfprintf (stderr, fmt, ap); | ||
80 | va_end (ap); | ||
81 | fputc ('\n', stderr); | ||
82 | } | ||
83 | |||
84 | static void wordsplit_free_nodes (struct wordsplit *); | ||
85 | |||
86 | static int | ||
87 | _wsplt_seterr (struct wordsplit *wsp, int ec) | ||
88 | { | ||
89 | wsp->ws_errno = ec; | ||
90 | if (wsp->ws_flags & WRDSF_SHOWERR) | ||
91 | wordsplit_perror (wsp); | ||
92 | return ec; | ||
93 | } | ||
94 | |||
95 | static int | ||
96 | _wsplt_nomem (struct wordsplit *wsp) | ||
97 | { | ||
98 | errno = ENOMEM; | ||
99 | wsp->ws_errno = WRDSE_NOSPACE; | ||
100 | if (wsp->ws_flags & WRDSF_ENOMEMABRT) | ||
101 | wsp->ws_alloc_die (wsp); | ||
102 | if (wsp->ws_flags & WRDSF_SHOWERR) | ||
103 | wordsplit_perror (wsp); | ||
104 | if (!(wsp->ws_flags & WRDSF_REUSE)) | ||
105 | wordsplit_free (wsp); | ||
106 | wordsplit_free_nodes (wsp); | ||
107 | return wsp->ws_errno; | ||
108 | } | ||
109 | |||
110 | static void | ||
111 | _wsplt_store_errctx (struct wordsplit *wsp, char const *str, size_t len) | ||
112 | { | ||
113 | free (wsp->ws_errctx); | ||
114 | wsp->ws_errctx = malloc (len + 1); | ||
115 | if (!wsp->ws_errctx) | ||
116 | { | ||
117 | wsp->ws_error ("%s", | ||
118 | _("memory exhausted while trying to store error context")); | ||
119 | } | ||
120 | else | ||
121 | { | ||
122 | memcpy (wsp->ws_errctx, str, len); | ||
123 | wsp->ws_errctx[len] = 0; | ||
124 | } | ||
125 | } | ||
126 | |||
127 | static inline int | ||
128 | _wsplt_setctxerr (struct wordsplit *wsp, int ec, char const *str, size_t len) | ||
129 | { | ||
130 | _wsplt_store_errctx (wsp, str, len); | ||
131 | return _wsplt_seterr (wsp, ec); | ||
132 | } | ||
133 | |||
134 | static int wordsplit_run (const char *command, size_t length, | ||
135 | struct wordsplit *wsp, | ||
136 | int flags, int lvl); | ||
137 | |||
138 | static int wordsplit_init (struct wordsplit *wsp, const char *input, size_t len, | ||
139 | int flags); | ||
140 | static int wordsplit_process_list (struct wordsplit *wsp, size_t start); | ||
141 | static int wordsplit_finish (struct wordsplit *wsp); | ||
142 | |||
143 | static int | ||
144 | _wsplt_subsplit (struct wordsplit *wsp, struct wordsplit *wss, | ||
145 | char const *str, int len, | ||
146 | int flags, int finalize) | ||
147 | { | ||
148 | int rc; | ||
149 | |||
150 | wss->ws_delim = wsp->ws_delim; | ||
151 | wss->ws_debug = wsp->ws_debug; | ||
152 | wss->ws_error = wsp->ws_error; | ||
153 | wss->ws_alloc_die = wsp->ws_alloc_die; | ||
154 | |||
155 | if (!(flags & WRDSF_NOVAR)) | ||
156 | { | ||
157 | wss->ws_env = wsp->ws_env; | ||
158 | wss->ws_getvar = wsp->ws_getvar; | ||
159 | flags |= wsp->ws_flags & (WRDSF_ENV | WRDSF_ENV_KV | WRDSF_GETVAR); | ||
160 | } | ||
161 | if (!(flags & WRDSF_NOCMD)) | ||
162 | { | ||
163 | wss->ws_command = wsp->ws_command; | ||
164 | } | ||
165 | |||
166 | if ((flags & (WRDSF_NOVAR|WRDSF_NOCMD)) != (WRDSF_NOVAR|WRDSF_NOCMD)) | ||
167 | { | ||
168 | wss->ws_closure = wsp->ws_closure; | ||
169 | flags |= wsp->ws_flags & WRDSF_CLOSURE; | ||
170 | } | ||
171 | |||
172 | wss->ws_options = wsp->ws_options; | ||
173 | |||
174 | flags |= WRDSF_DELIM | ||
175 | | WRDSF_ALLOC_DIE | ||
176 | | WRDSF_ERROR | ||
177 | | WRDSF_DEBUG | ||
178 | | (wsp->ws_flags & (WRDSF_SHOWDBG | WRDSF_SHOWERR | WRDSF_OPTIONS)); | ||
179 | |||
180 | rc = wordsplit_init (wss, str, len, flags); | ||
181 | if (rc) | ||
182 | return rc; | ||
183 | wss->ws_lvl = wsp->ws_lvl + 1; | ||
184 | rc = wordsplit_process_list (wss, 0); | ||
185 | if (rc) | ||
186 | { | ||
187 | wordsplit_free_nodes (wss); | ||
188 | return rc; | ||
189 | } | ||
190 | if (finalize) | ||
191 | { | ||
192 | rc = wordsplit_finish (wss); | ||
193 | wordsplit_free_nodes (wss); | ||
194 | } | ||
195 | return rc; | ||
196 | } | ||
197 | |||
198 | static void | ||
199 | _wsplt_seterr_sub (struct wordsplit *wsp, struct wordsplit *wss) | ||
200 | { | ||
201 | /* Clear user-defined error */ | ||
202 | if (wsp->ws_errno == WRDSE_USERERR) | ||
203 | free (wsp->ws_usererr); | ||
204 | /* Copy error state */ | ||
205 | wsp->ws_errno = wss->ws_errno; | ||
206 | if (wss->ws_errno == WRDSE_USERERR) | ||
207 | { | ||
208 | wsp->ws_usererr = wss->ws_usererr; | ||
209 | wss->ws_errno = WRDSE_EOF; | ||
210 | wss->ws_usererr = NULL; | ||
211 | } | ||
212 | /* Copy error context */ | ||
213 | free (wsp->ws_errctx); | ||
214 | wsp->ws_errctx = wss->ws_errctx; | ||
215 | wss->ws_errctx = NULL; | ||
216 | } | ||
217 | |||
218 | static void | ||
219 | wordsplit_init0 (struct wordsplit *wsp) | ||
220 | { | ||
221 | if (wsp->ws_flags & WRDSF_REUSE) | ||
222 | { | ||
223 | if (!(wsp->ws_flags & WRDSF_APPEND)) | ||
224 | wordsplit_free_words (wsp); | ||
225 | wordsplit_clearerr (wsp); | ||
226 | } | ||
227 | else | ||
228 | { | ||
229 | wsp->ws_wordv = NULL; | ||
230 | wsp->ws_wordc = 0; | ||
231 | wsp->ws_wordn = 0; | ||
232 | } | ||
233 | |||
234 | wsp->ws_errno = 0; | ||
235 | } | ||
236 | |||
237 | char wordsplit_c_escape_tab[] = "\\\\\"\"a\ab\bf\fn\nr\rt\tv\v"; | ||
238 | |||
239 | static int | ||
240 | wordsplit_init (struct wordsplit *wsp, const char *input, size_t len, | ||
241 | int flags) | ||
242 | { | ||
243 | wsp->ws_flags = flags; | ||
244 | |||
245 | if (!(wsp->ws_flags & WRDSF_ALLOC_DIE)) | ||
246 | wsp->ws_alloc_die = _wsplt_alloc_die; | ||
247 | if (!(wsp->ws_flags & WRDSF_ERROR)) | ||
248 | wsp->ws_error = _wsplt_error; | ||
249 | |||
250 | if (!(wsp->ws_flags & WRDSF_NOVAR)) | ||