-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsplit_input.c
More file actions
138 lines (122 loc) · 4.13 KB
/
split_input.c
File metadata and controls
138 lines (122 loc) · 4.13 KB
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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include "misc.h"
#include "hashdb.h"
//uncomment the next line when you want to use your routine
#define MYCODE
#ifndef MYCODE
TODO(USING THE SOLUTION FUNCTION NOT MY CODE)
#else
/*
* split_input
*
* usage: input buffer csv format, builds table of pointers to each column
* assumes: input buffer has at least one char in it (not counting the '\0')
* returns: 0 if all the columns were found, -1 otherwise
*/
int
split_input(char *buf, char delim, int cnt, char **table, unsigned long lineno,
char **argv)
{
int idx = 0; /* index for table */
int fldof = 0; /* indicates if we have an overflow of fields */
/*
* walk through buffer, validating fields and directing table pointers to
* them
*/
while (*buf != '\0') {
/* checks that we are not trying to add more fields than allowed */
if (idx >= cnt) {
fldof = 1;
break;
}
/*
* point next text table slot to start of next field before validating
* that this field is valid. If it is not valid, record is dropped from
* output
*/
*(table + idx++) = buf;
if (*buf == '"') {
/*
* if we have a quoted field, loop over field looking for invalid
* character sequences. Invalid character sequences includes \0
* before a terminating "; a " not followed by the delimiter, \n, or
* another ".
*/
while (*buf != '\0') {
/* update buffer */
buf++;
/*
* if we have \0 before closing ", the quoted field was not
* properly terminated
*/
if (*buf == '\0') {
dropmsg("Quoted field missing final quote", lineno,
argv);
return -1;
}
/*
* if we hit a ", we must have it followed by the delimiter, a
* \n, or another ". Otherwise, it is an invalid field
*/
if (*buf == '"') {
if ((*(buf + 1) == delim) || (*(buf + 1) == '\n')) {
buf++;
*buf = '\0';
break;
} else if (*(buf + 1) == '"') {
buf++;
} else {
dropmsg("Quoted field not terminated properly", lineno,
argv);
return -1;
}
}
}
} else {
/*
* if not a quoted field first make sure it isn't an elmpty field.
* If it is an empty field, then add null terminator and continue to
* next field
*/
if (*buf == delim || *buf == '\n') {
*buf = '\0';
} else {
/*
* if we have an unquoted field, loop over field looking for
* invalid character sequences. The only invalid character
* sequence in this case is having " anywhere in the field
*/
while (*(buf++) != '\0') {
if (*buf == '"') {
dropmsg("A \" is not allowed inside unquoted field",
lineno, argv);
return -1;
} else if (*buf == '\n' || *buf == delim) {
*buf = '\0';
break;
}
}
}
}
/* moves to next field */
buf++;
}
/*
* make sure we have the correct number of fields read. If we have too many
* or too few, prints corresponding error message
*/
if (idx < cnt) {
dropmsg("too few columns", lineno, argv);
return -1;
} else if (fldof) {
dropmsg("too many columns", lineno, argv);
return -1;
}
return 0;
}
#endif