static int scan_qstring (struct wordsplit *wsp, size_t start, size_t * end) { size_t j; const char *command = wsp->ws_input; size_t len = wsp->ws_len; char q = command[start]; for (j = start + 1; j < len && command[j] != q; j++) if (q == '"' && command[j] == '\\') j++; if (j < len && command[j] == q) { int flags = _WSNF_QUOTE | _WSNF_EMPTYOK; if (q == '\'') flags |= _WSNF_NOEXPAND; if (wordsplit_add_segm (wsp, start + 1, j, flags)) return _WRDS_ERR; *end = j; } else { wsp->ws_endp = start; wsp->ws_errno = WRDSE_QUOTE; if (wsp->ws_flags & WRDSF_SHOWERR) wordsplit_perror (wsp); return _WRDS_ERR; } return 0; }
static int wordsplit_process_list (struct wordsplit *wsp, size_t start) { struct exptab *p; if (wsp->ws_flags & WRDSF_NOSPLIT) { /* Treat entire input as a quoted argument */ if (wordsplit_add_segm (wsp, start, wsp->ws_len, _WSNF_QUOTE)) return wsp->ws_errno; } else { int rc; while ((rc = scan_word (wsp, start)) == _WRDS_OK) start = skip_delim (wsp); /* Make sure tail element is not joinable */ if (wsp->ws_tail) wsp->ws_tail->flags &= ~_WSNF_JOIN; if (rc == _WRDS_ERR) return wsp->ws_errno; } if (wsp->ws_flags & WRDSF_SHOWDBG) { wsp->ws_debug ("(%02d) %s", wsp->ws_lvl, _("Initial list:")); wordsplit_dump_nodes (wsp); } for (p = exptab; p->descr; p++) { if ((p->opt & EXPOPT_NEG) ? !(wsp->ws_flags & p->flag) : (wsp->ws_flags & p->flag)) { if (p->opt & EXPOPT_COALESCE) { if (wsnode_coalesce (wsp)) break; if (wsp->ws_flags & WRDSF_SHOWDBG) { wsp->ws_debug ("(%02d) %s", wsp->ws_lvl, _("Coalesced list:")); wordsplit_dump_nodes (wsp); } } if (p->expansion) { if (p->expansion (wsp)) break; if (wsp->ws_flags & WRDSF_SHOWDBG) { wsp->ws_debug ("(%02d) %s", wsp->ws_lvl, _(p->descr)); wordsplit_dump_nodes (wsp); } } } } return wsp->ws_errno; }
static int wordsplit_process_list (struct wordsplit *wsp, size_t start) { if (wsp->ws_flags & WRDSF_NOSPLIT) { /* Treat entire input as a quoted argument */ if (wordsplit_add_segm (wsp, start, wsp->ws_len, _WSNF_QUOTE)) return wsp->ws_errno; } else { int rc; while ((rc = scan_word (wsp, start)) == _WRDS_OK) start = skip_delim (wsp); /* Make sure tail element is not joinable */ if (wsp->ws_tail) wsp->ws_tail->flags &= ~_WSNF_JOIN; if (rc == _WRDS_ERR) return wsp->ws_errno; } if (wsp->ws_flags & WRDSF_SHOWDBG) { wsp->ws_debug ("Initial list:"); wordsplit_dump_nodes (wsp); } if (wsp->ws_flags & WRDSF_WS) { /* Trim leading and trailing whitespace */ wordsplit_trimws (wsp); if (wsp->ws_flags & WRDSF_SHOWDBG) { wsp->ws_debug ("After WS trimming:"); wordsplit_dump_nodes (wsp); } } /* Expand variables (FIXME: & commands) */ if (!(wsp->ws_flags & WRDSF_NOVAR)) { if (wordsplit_varexp (wsp)) { wordsplit_free_nodes (wsp); return wsp->ws_errno; } if (wsp->ws_flags & WRDSF_SHOWDBG) { wsp->ws_debug ("Expanded list:"); wordsplit_dump_nodes (wsp); } } do { if (wsnode_quoteremoval (wsp)) break; if (wsp->ws_flags & WRDSF_SHOWDBG) { wsp->ws_debug ("After quote removal:"); wordsplit_dump_nodes (wsp); } if (wsnode_coalesce (wsp)) break; if (wsp->ws_flags & WRDSF_SHOWDBG) { wsp->ws_debug ("Coalesced list:"); wordsplit_dump_nodes (wsp); } } while (0); return wsp->ws_errno; }
static int scan_word (struct wordsplit *wsp, size_t start) { size_t len = wsp->ws_len; const char *command = wsp->ws_input; const char *comment = wsp->ws_comment; int join = 0; int flags = 0; size_t i = start; if (i >= len) { wsp->ws_errno = WRDSE_EOF; return _WRDS_EOF; } start = i; if (wsp->ws_flags & WRDSF_SED_EXPR && command[i] == 's' && i + 3 < len && ISPUNCT (command[i + 1])) { flags = _WSNF_SEXP; i = skip_sed_expr (command, i, len); } else if (!ISDELIM (wsp, command[i])) { while (i < len) { if (comment && strchr (comment, command[i]) != NULL) { size_t j; for (j = i + 1; j < len && command[j] != '\n'; j++) ; if (wordsplit_add_segm (wsp, start, i, 0)) return _WRDS_ERR; wsp->ws_endp = j; return _WRDS_OK; } if (wsp->ws_flags & WRDSF_QUOTE) { if (command[i] == '\\') { if (++i == len) break; i++; continue; } if (((wsp->ws_flags & WRDSF_SQUOTE) && command[i] == '\'') || ((wsp->ws_flags & WRDSF_DQUOTE) && command[i] == '"')) { if (join && wsp->ws_tail) wsp->ws_tail->flags |= _WSNF_JOIN; if (wordsplit_add_segm (wsp, start, i, _WSNF_JOIN)) return _WRDS_ERR; if (scan_qstring (wsp, i, &i)) return _WRDS_ERR; start = i + 1; join = 1; } } if (ISDELIM (wsp, command[i])) break; else i++; } } else if (wsp->ws_flags & WRDSF_RETURN_DELIMS) { i++; } else if (!(wsp->ws_flags & WRDSF_SQUEEZE_DELIMS)) flags |= _WSNF_EMPTYOK; if (join && i > start && wsp->ws_tail) wsp->ws_tail->flags |= _WSNF_JOIN; if (wordsplit_add_segm (wsp, start, i, flags)) return _WRDS_ERR; wsp->ws_endp = i; if (wsp->ws_flags & WRDSF_INCREMENTAL) return _WRDS_EOF; return _WRDS_OK; }