- -- strip away dquotes; assume first and last chars contain quotes.
- stripQuotes :: String -> String
- stripQuotes ('"':xs) = init xs
- stripQuotes xs = xs
+ -- Grab a token off the string, given that the first character exists and
+ -- isn't whitespace. The second argument is an accumulator which has to be
+ -- reversed at the end.
+ token [] acc = (reverse acc,[]) -- out of characters
+ token ('\\':c:aft) acc -- escapes
+ = token aft ((escape c) : acc)
+ token (q:aft) acc | q == '"' || q == '\'' -- open quotes
+ = let (aft',acc') = quote q aft acc in token aft' acc'
+ token (c:aft) acc | isSpace c -- unescaped, unquoted spacing
+ = (reverse acc,aft)
+ token (c:aft) acc -- anything else goes in the token
+ = token aft (c:acc)
+
+ -- Get the appropriate character for a single-character escape.
+ escape 'n' = '\n'
+ escape 't' = '\t'
+ escape 'r' = '\r'
+ escape c = c
+
+ -- Read into accumulator until a quote character is found.
+ quote qc =
+ let quote' [] acc = ([],acc)
+ quote' ('\\':c:aft) acc = quote' aft ((escape c) : acc)
+ quote' (c:aft) acc | c == qc = (aft,acc)
+ quote' (c:aft) acc = quote' aft (c:acc)
+ in quote'