-
Notifications
You must be signed in to change notification settings - Fork 0
/
csv.a68
98 lines (80 loc) · 2.01 KB
/
csv.a68
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# -*- coding: utf-8 -*- #
MODE FLEXCSVFIELD = STRING;
MODE CSVFIELDS = [0] FLEXCSVFIELD;
MODE FLEXCSVFIELDS = REF CSVFIELDS;
OP +:= = (REF FLEXCSVFIELDS in out, FLEXCSVFIELD item) REF FLEXCSVFIELDS: (
HEAP [UPB in out + 1] FLEXCSVFIELD new;
new[:UPB in out] := in out;
new[UPB new] := item;
in out := new
);
CHAR nl = REPR 10;
PROC read csv = (REF FILE csv, PROC (FLEXCSVFIELDS) VOID callback) VOID: (
FLEXCSVFIELD chunk := "";
INT chunk counter := 0;
INT fields count := 0;
INT line count := 0;
BOOL finished := FALSE;
PROC current = CHAR: chunk[chunk counter];
PROC next = CHAR: (
IF chunk counter = 0 OR chunk counter + 1 > UPB chunk THEN
getf(csv, ($gl$, chunk));
chunk +:= nl;
chunk counter := 0;
line count +:= 1
FI;
chunk counter +:= 1;
chunk[chunk counter]
);
next;
PROC parse = FLEXCSVFIELDS: (
on logical file end(csv, (REF FILE eof csv) BOOL: ( done eof; TRUE ));
FLEXCSVFIELDS fields := HEAP CSVFIELDS := "";
BOOL in quotes := FALSE;
INT quote start := 0;
DO
IF in quotes THEN
IF current = """" THEN
# This probably would generate an error if eof
but I couldn't check it #
IF next = """" THEN
fields[UPB fields] +:= """";
next
ELSE
in quotes := FALSE
FI
ELSE
fields[UPB fields] +:= current;
next
FI
ELIF current = "," THEN
fields +:= "";
next
ELIF current = """" THEN
in quotes := TRUE;
next
ELIF current = nl THEN
next;
GOTO done
ELSE
fields[UPB fields] +:= current;
next
FI
OD;
done eof:
finished := TRUE;
done:
IF fields count > 0 AND UPB fields /= fields count THEN
printf(($"Error: unexpected number of fields ("g(-0)") in line "g(-0)" (expected "g(-0)")"l$, UPB fields, line count, fields count))
FI;
IF in quotes THEN
printf(($"Error: unclosed quotes starting in line "g(-0)" column "g(-0)l$, line count, quote start))
FI;
fields
);
FLEXCSVFIELDS header = parse;
fields count := UPB header;
WHILE NOT finished DO
callback(parse)
OD
)