array decompose(regexp DELIMITER, string LINE, int PIECES,
bool KEEP, hashref QUOTINGPAIRS,
scalarref UNMATCHED_QUOTE)
decompose is a cross between split() and
Text::ParseWords::parse_line: it breaks LINE into at most PIECES pieces
separated by DELIMITER, except that the hash given by the reference
QUOTINGPAIRS specifies pairs of quotes (each key is an open quote which
matches the corresponding value) which prevent splitting on internal
instances of DELIMITER, and negate the effect of other quotes. The
quoting characters are retained if KEEP is true, discarded otherwise.
Matches to the regexp METACHARACTERS (outside quotes) are their own
words, regardless of being delimited. Backslashes escape the meanings of
characters that might match delimiters, quotes, or metacharacters.
Initial unquoted empty pieces are suppressed.
The regexp DELIMITER may contain a single back-reference
parenthesis construct, in which case the matches to the parenthesized
subexpression are also placed among the pieces, as with the built-in
split. METACHARACTERS may not contain any parenthesized
subexpression.
decompose returns the array of pieces. If UNMATCHED_QUOTE is
specified, 1 will be placed in the scalar referred to if LINE contained
an unmatched quote, 0 otherwise.
If PIECES is undefined, as many pieces as necessary are used.
KEEP defaults to 1. If QUOTINGPAIRS is undefined, {"'" =>
"'", "\"" => "\""} is used,
i.e. single and double quotes are recognized. Supply a reference to an
empty hash to have no quoting characters. METACHARACTERS defaults to a
regexp that never matches.
EXAMPLE: if $line is exactly
echo fred(joe, "Happy Days", ' steve"jan ',
"\"Oh, no!\"")
then decompose(' ', $line) should
break it at the following places marked by vertical bars:
echo|fred(joe,|"Happy Days",|'
steve"jan',|"\"Oh, no!\"")
int incomplete_expr(string LINE)
Returns 2 if LINE has unmatched quotations. Returns -1 if LINE
has mismatched parens. Otherwise, returns 1 if LINE has an unmatched
open brace, parenthesis, or square bracket and 0 in all other cases.
Summing up, negative is a mismatch, 0 is all OK, and positive is
unfinished business. (Reasonably good, can be fooled with some effort. I
therefore have deliberately not taken comments into account, which means
you can use them to "unfool" this function, but also that
unmatched stuff in comments WILL fool this function.)