Fri, 26 Mar 2010 01:30:24 +0000
Initial commit
0 | 1 | |
2 | local lpeg = require "lpeg" | |
3 | local setmetatable, tonumber = | |
4 | setmetatable, tonumber; | |
5 | local s_char = string.char; | |
6 | ||
7 | module("csv"); | |
8 | ||
9 | local delim = lpeg.P","; | |
10 | ||
11 | local char_escape = lpeg.R"az" + lpeg.S"\\\r\n" + delim; | |
12 | local numeric_escape = (lpeg.R"09"^1)^-3; | |
13 | local escape = (lpeg.P"\\" * (char_escape + numeric_escape)); | |
14 | ||
15 | local value = (escape + (1-delim))^0; | |
16 | ||
17 | local escape_map = setmetatable({ | |
18 | t = "\t", b = "\b", f = "\f"; | |
19 | n = "\n", r = "\r", v = "\v"; }, | |
20 | { __index = function (_, n) | |
21 | if tonumber(n) then | |
22 | print"n" | |
23 | return s_char(tonumber(n)); | |
24 | else | |
25 | return n; | |
26 | end | |
27 | end | |
28 | }); | |
29 | ||
30 | function read_record(line, value_callback) | |
31 | local fieldpos = 0; | |
32 | local callback = function (v) | |
33 | return value_callback(v:gsub("\\(.)", escape_map)); | |
34 | end; | |
35 | repeat | |
36 | fieldpos = lpeg.match(value / callback, line, fieldpos+1); | |
37 | until fieldpos >= #line; | |
38 | end | |
39 | ||
40 | return _M; |