aboutsummaryrefslogtreecommitdiff
path: root/src/wordsplit.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/wordsplit.c')
-rw-r--r--src/wordsplit.c2892
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
66static void
67_wsplt_alloc_die (struct wordsplit *wsp)
68{
69 wsp->ws_error ("%s", _("memory exhausted"));
70 abort ();
71}
72
73static 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
84static void wordsplit_free_nodes (struct wordsplit *);
85
86static 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
95static 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
110static 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
127static 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
134static int wordsplit_run (const char *command, size_t length,
135 struct wordsplit *wsp,
136 int flags, int lvl);
137
138static int wordsplit_init (struct wordsplit *wsp, const char *input, size_t len,
139 int flags);
140static int wordsplit_process_list (struct wordsplit *wsp, size_t start);
141static int wordsplit_finish (struct wordsplit *wsp);
142
143static 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
198static 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
218static void
219wordsplit_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
237char wordsplit_c_escape_tab[] = "\\\\\"\"a\ab\bf\fn\nr\rt\tv\v";
238
239static int
240wordsplit_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))