diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/wordsplit.c | 30 |
1 files changed, 28 insertions, 2 deletions
diff --git a/src/wordsplit.c b/src/wordsplit.c index f563725..4e633fa 100644 --- a/src/wordsplit.c +++ b/src/wordsplit.c | |||
@@ -253,12 +253,15 @@ wordsplit_init (struct wordsplit *wsp, const char *input, size_t len, | |||
253 | if (!(wsp->ws_flags & WRDSF_DOOFFS)) | 253 | if (!(wsp->ws_flags & WRDSF_DOOFFS)) |
254 | wsp->ws_offs = 0; | 254 | wsp->ws_offs = 0; |
255 | 255 | ||
256 | if (!(wsp->ws_flags & WRDSF_DELIM)) | 256 | if (!(wsp->ws_flags & WRDSF_DELIM)) |
257 | wsp->ws_delim = " \t\n"; | 257 | wsp->ws_delim = " \t\n"; |
258 | 258 | ||
259 | wsp->ws_sep[0] = wsp->ws_delim[0]; | ||
260 | wsp->ws_sep[1] = 0; | ||
261 | |||
259 | if (!(wsp->ws_flags & WRDSF_COMMENT)) | 262 | if (!(wsp->ws_flags & WRDSF_COMMENT)) |
260 | wsp->ws_comment = NULL; | 263 | wsp->ws_comment = NULL; |
261 | 264 | ||
262 | if (!(wsp->ws_flags & WRDSF_CLOSURE)) | 265 | if (!(wsp->ws_flags & WRDSF_CLOSURE)) |
263 | wsp->ws_closure = NULL; | 266 | wsp->ws_closure = NULL; |
264 | 267 | ||
@@ -346,13 +349,13 @@ alloc_space (struct wordsplit *wsp, size_t count) | |||
346 | #define _WSNF_WORD 0x02 /* node contains word in v.word */ | 349 | #define _WSNF_WORD 0x02 /* node contains word in v.word */ |
347 | #define _WSNF_QUOTE 0x04 /* text is quoted */ | 350 | #define _WSNF_QUOTE 0x04 /* text is quoted */ |
348 | #define _WSNF_NOEXPAND 0x08 /* text is not subject to expansion */ | 351 | #define _WSNF_NOEXPAND 0x08 /* text is not subject to expansion */ |
349 | #define _WSNF_JOIN 0x10 /* node must be joined with the next node */ | 352 | #define _WSNF_JOIN 0x10 /* node must be joined with the next node */ |
350 | #define _WSNF_SEXP 0x20 /* is a sed expression */ | 353 | #define _WSNF_SEXP 0x20 /* is a sed expression */ |
351 | #define _WSNF_DELIM 0x40 /* node is a delimiter */ | 354 | #define _WSNF_DELIM 0x40 /* node is a delimiter */ |
352 | 355 | #define _WSNF_CONST 0x80 /* with _WSNF_WORD: v.word is constant */ | |
353 | #define _WSNF_EMPTYOK 0x0100 /* special flag indicating that | 356 | #define _WSNF_EMPTYOK 0x0100 /* special flag indicating that |
354 | wordsplit_add_segm must add the | 357 | wordsplit_add_segm must add the |
355 | segment even if it is empty */ | 358 | segment even if it is empty */ |
356 | 359 | ||
357 | struct wordsplit_node | 360 | struct wordsplit_node |
358 | { | 361 | { |
@@ -438,13 +441,13 @@ wsnode_new (struct wordsplit *wsp, struct wordsplit_node **pnode) | |||
438 | return 0; | 441 | return 0; |
439 | } | 442 | } |
440 | 443 | ||
441 | static void | 444 | static void |
442 | wsnode_free (struct wordsplit_node *p) | 445 | wsnode_free (struct wordsplit_node *p) |
443 | { | 446 | { |
444 | if (p->flags & _WSNF_WORD) | 447 | if ((p->flags & (_WSNF_WORD|_WSNF_CONST)) == _WSNF_WORD) |
445 | free (p->v.word); | 448 | free (p->v.word); |
446 | free (p); | 449 | free (p); |
447 | } | 450 | } |
448 | 451 | ||
449 | static void | 452 | static void |
450 | wsnode_append (struct wordsplit *wsp, struct wordsplit_node *node) | 453 | wsnode_append (struct wordsplit *wsp, struct wordsplit_node *node) |
@@ -1247,12 +1250,13 @@ expand_paramv (struct wordsplit *wsp, struct wordsplit_node **ptail, int flg, | |||
1247 | { | 1250 | { |
1248 | struct wordsplit ws; | 1251 | struct wordsplit ws; |
1249 | int wsflags = WRDSF_NOVAR | WRDSF_NOCMD | WRDSF_QUOTE | 1252 | int wsflags = WRDSF_NOVAR | WRDSF_NOCMD | WRDSF_QUOTE |
1250 | | (WSP_RETURN_DELIMS (wsp) ? WRDSF_RETURN_DELIMS : 0) | 1253 | | (WSP_RETURN_DELIMS (wsp) ? WRDSF_RETURN_DELIMS : 0) |
1251 | | (q ? WRDSF_NOSPLIT : 0); | 1254 | | (q ? WRDSF_NOSPLIT : 0); |
1252 | size_t i; | 1255 | size_t i; |
1256 | struct wordsplit_node *tail = *ptail; | ||
1253 | 1257 | ||
1254 | for (i = 0; i < wsp->ws_paramc; i++) | 1258 | for (i = 0; i < wsp->ws_paramc; i++) |
1255 | { | 1259 | { |
1256 | struct wordsplit_node *np; | 1260 | struct wordsplit_node *np; |
1257 | int rc = _wsplt_subsplit (wsp, &ws, | 1261 | int rc = _wsplt_subsplit (wsp, &ws, |
1258 | wsp->ws_paramv[i], strlen (wsp->ws_paramv[i]), | 1262 | wsp->ws_paramv[i], strlen (wsp->ws_paramv[i]), |
@@ -1285,12 +1289,34 @@ expand_paramv (struct wordsplit *wsp, struct wordsplit_node **ptail, int flg, | |||
1285 | } | 1289 | } |
1286 | 1290 | ||
1287 | wsflags |= WRDSF_REUSE; | 1291 | wsflags |= WRDSF_REUSE; |
1288 | } | 1292 | } |
1289 | if (wsflags & WRDSF_REUSE) | 1293 | if (wsflags & WRDSF_REUSE) |
1290 | wordsplit_free (&ws); | 1294 | wordsplit_free (&ws); |
1295 | |||
1296 | if (flg & _WSNF_QUOTE) | ||
1297 | { | ||
1298 | tail = tail->next; | ||
1299 | /* Insert delimiters, mark nodes as joinable */ | ||
1300 | while (tail != *ptail) | ||
1301 | { | ||
1302 | struct wordsplit_node *next = tail->next; | ||
1303 | struct wordsplit_node *newnode; | ||
1304 | |||
1305 | tail->flags |= _WSNF_JOIN; | ||
1306 | |||
1307 | if (wsnode_new (wsp, &newnode)) | ||
1308 | return 1; | ||
1309 | newnode->flags = _WSNF_WORD | _WSNF_CONST | _WSNF_NOEXPAND | _WSNF_JOIN; | ||
1310 | newnode->v.word = wsp->ws_sep; | ||
1311 | |||
1312 | wsnode_insert (wsp, newnode, tail, 0); | ||
1313 | tail = next; | ||
1314 | } | ||
1315 | } | ||
1316 | |||
1291 | return 0; | 1317 | return 0; |
1292 | } | 1318 | } |
1293 | 1319 | ||
1294 | static int | 1320 | static int |
1295 | expvar (struct wordsplit *wsp, const char *str, size_t len, | 1321 | expvar (struct wordsplit *wsp, const char *str, size_t len, |
1296 | struct wordsplit_node **ptail, const char **pend, int flg) | 1322 | struct wordsplit_node **ptail, const char **pend, int flg) |