blob: 6feefcbe2f7b72cac64ebbcfa32b57f6632ac5b2 (
plain)
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
#include "csv-parse.h"
token *tokens = 0;
token *last_tok = 0;
line *lines = 0;
line *last_line = 0;
inline int iseol(char c) {
return (c == '\n' || c == '\0');
}
token *make_token(char *value) {
token *new_tok = malloc(sizeof(token));
(last_tok) ? (last_tok->next = new_tok) : (tokens = new_tok);
new_tok->value = value;
new_tok->next = NULL;
last_tok = new_tok;
return new_tok;
}
line *get_line(char *str) {
token *t = NULL;
int skip = 0;
int isblank = 0;
int i = 0;
while (!iseol(str[i])) {
char *value = NULL;
switch (str[i]) {
case '\"': for (++str; str[i] != '\"' && !iseol(str[i]); i++); break;
default : for ( ; str[i] != ',' && !iseol(str[i]); i++); break;
}
if (i) {
value = malloc(i+1);
memcpy(value, str, i);
value[i] = '\0';
t = make_token(value);
t->skip = skip;
skip = 0;
t = t->next;
} else {
value = NULL;
skip += (t == NULL);
}
str += i+1;
i = 0;
}
isblank = (tokens == NULL && last_tok == NULL);
if (!isblank) {
line *l = malloc(sizeof(line));
(last_line) ? (last_line->next = l) : (lines = l);
l->tok = tokens;
l->last_tok = last_tok;
tokens = NULL;
last_tok = NULL;
l->next = NULL;
last_line = l;
return l;
} else {
return NULL;
}
}
void parse_csv(FILE *fp) {
char buf[0x1000];
int blank_lines = 0;
line *l;
while (fgets(buf, sizeof(buf), fp) != NULL && !feof(fp)) {
l = get_line(buf);
blank_lines += (l == NULL);
if (l != NULL) {
l->skip = blank_lines;
blank_lines = 0;
}
}
}
void free_tokens(token *t, token *lt, int row) {
token *tok;
int i = 0;
int skip = 0;
while (t != NULL) {
tok = t;
free(tok->value);
t = t->next;
i++;
free(tok);
}
}
void free_lines() {
line *l = lines;
line *ln;
int i = 0;
while (l != NULL) {
free_tokens(l->tok, l->last_tok, i);
i++;
ln = l;
l = l->next;
free(ln);
}
}
|