51 static int _csv_create_tc_index(
CSVParser *csv)
61 "Could not create array of time column indexes\n"
62 " -> time column names have not been defined\n");
74 "Could not create array of time column indexes\n"
75 " -> column headers have not been defined\n");
90 "Could not create array of time column indexes\n"
91 " -> memory allocation error\n");
100 for (ti = 0; ti < csv->
ntc; ++ti) {
102 for (fi = 0; fi < csv->
nfields; ++fi) {
113 "Could not create array of time column indexes\n"
114 " -> time column '%s' not found in header fields\n",
139 int _csv_parse_record_time(
161 if (!_csv_create_tc_index(csv)) {
168 for (tci = 0; tci < csv->
ntc; ++tci) {
175 if (fi < 0 || fi > csv->
nfields) {
178 "Time column index '%d' is out of range [0, %d].\n",
186 time_string = csv->
values[fi][record_index];
195 "Time string pattern match failed for record %d.\n",
202 else if (status == 0) {
205 "Record time format '%s' does not match '%s'\n",
222 if (match.
min != -1) result.
min = match.
min;
223 if (match.
sec != -1) result.
sec = match.
sec;
226 if (match.
yy != -1) result.
yy = match.
yy;
230 if (match.
offset.tv_sec != 0)
233 if (match.
offset.tv_usec != 0)
246 csv->
tvs[record_index] = rec_time;
276 "Memory allocation error creating file name RETimeRes structure\n");
284 if (status < 0)
return(-1);
287 if (result.
year == -1) {
297 "Could not determine record time\n"
298 " -> year not found in record or file name time patterns\n");
306 if (result.
month == -1) {
308 if (result.
yday != -1) {
327 if (result.
mday == -1) {
339 if (result.
year == -1) {
342 "Could not determine record time\n"
343 " -> year not found in record time pattern\n");
357 if (used_file_date && record_index > 0) {
359 prev_time = csv->
tvs[record_index - 1];
361 if (
TV_LT(rec_time, prev_time)) {
363 switch (used_file_date) {
367 gmtime_r(&(prev_time.tv_sec), &gmt);
370 tro_interval = 366 * 86400;
373 tro_interval = 365 * 86400;
384 gmtime_r(&(prev_time.tv_sec), &gmt);
386 tro_interval =
days_in_month(gmt.tm_year + 1900, gmt.tm_mon + 1)
397 tro_interval = 86400;
408 rec_time.tv_sec += tro_interval;
414 csv->
tvs[record_index] = rec_time;
429 static int _csv_realloc_data(
CSVParser *csv,
int nfields,
int nrecs)
438 if (nrecs > prev_nrecs) {
440 nelems = nrecs - prev_nrecs;
444 for (fi = 0; fi < prev_nfields; ++fi) {
446 csv->
values[fi] = (
char **)realloc(csv->
values[fi], nrecs *
sizeof(
char *));
447 if (!csv->
values[fi])
return(0);
449 memset(csv->
values[fi] + prev_nrecs, 0, nelems *
sizeof(
char *));
457 if (!csv->
tvs)
return(0);
459 memset(csv->
tvs + prev_nrecs, 0, nelems *
sizeof(
timeval_t));
467 if (nfields > prev_nfields) {
469 nelems = nfields - prev_nfields;
478 csv->
headers = (
char **)realloc(csv->
headers, nfields *
sizeof(
char *));
481 memset(csv->
headers + prev_nfields, 0, nelems *
sizeof(
char *));
488 memset(csv->
free_header + prev_nfields, 0, nelems *
sizeof(
int));
492 csv->
values = (
char ***)realloc(csv->
values, nfields *
sizeof(
char **));
493 if (!csv->
values)
return(0);
495 for (fi = prev_nfields; fi < nfields; ++fi) {
498 if (!csv->
values[fi])
return(0);
556 for (i = 0; i < csv->
ntc; ++i) {
563 for (i = 0; i < csv->
ntc; ++i) {
571 if (csv->
tvs) free(csv->
tvs);
605 resultp = (result) ? result : &result_buffer;
610 "Could not get time from CSV file name: %s\n"
611 " -> no time string patterns have been defined\n",
624 "Could not get time from CSV file name: %s\n"
625 " -> time string pattern matching error occured\n",
632 else if (status == 0) {
635 "Could not get time from CSV file name: %s\n"
636 " -> file name format does not match time string pattern: '%s'\n",
647 if (secs1970 == -1) {
650 "Could not get time from CSV file name: %s\n"
651 " -> year not found in time string pattern\n",
676 if (nfields) *nfields = csv->
nfields;
678 return((
char **)NULL);
697 for (fi = 0; fi < csv->
nfields; ++fi) {
699 if (strcmp(csv->
headers[fi], name) == 0) {
700 return((
char **)csv->
values[fi]);
704 return((
char **)NULL);
721 if (nrecs) *nrecs = csv->
nrecs;
740 return((
char *)NULL);
778 csv->
linep = (
char *)NULL;
799 "Memory allocation error loading CSV file: %s\n",
830 char full_path[PATH_MAX];
852 csv->
lines = (
char **)malloc(nlines *
sizeof(
char *));
857 "Memory allocation error loading CSV file: %s\n",
874 "Memory allocation error loading CSV file: %s\n",
882 snprintf(full_path, PATH_MAX,
"%s/%s", path, name);
894 "Could not get file status for: %s\n"
895 " -> %s\n", full_path, strerror(errno));
905 if (nbytes == 0)
return(0);
913 "Memory allocation error loading CSV file: %s\n",
924 fp = fopen(full_path,
"r");
928 "Could not open file: %s\n"
929 " -> %s\n", csv->
file_name, strerror(errno));
936 nread = fread(csv->
file_data, 1, nbytes, fp);
939 if (nread != nbytes) {
942 "Could not read CSV file: %s\n"
943 " -> %s\n", csv->
file_name, strerror(errno));
955 csv->
lines[0] = chrp;
964 if (*(chrp - 1) ==
'\r') {
970 if (*chrp ==
'\0')
break;
979 nlines = (nbytes / (chrp - csv->
file_data)) * li
982 csv->
lines = (
char **)realloc(csv->
lines, nlines *
sizeof(
char *));
987 "Memory allocation error loading CSV file: %s\n",
998 csv->
lines[li++] = chrp;
1021 char delim = csv->
delim;
1050 "Memory allocation error parsing CSV header for file: %s\n",
1060 if (!_csv_realloc_data(csv, count, csv->
nlines)) {
1063 "Memory allocation error parsing CSV header for file: %s\n",
1077 csv->
headers[fi] = (
char *)NULL;
1087 if (nfields != count) {
1097 "Unknown error parsing CSV header line for file: %s\n",
1137 char delim = csv->
delim;
1161 if (!_csv_realloc_data(csv, csv->
nfields, csv->
nrecs * 1.5)) {
1164 "Memory allocation error parsing CSV record #%d for file: %s\n",
1180 if (nfields != csv->
nfields) {
1183 "Expected %d values but found %d\n",
1191 for (fi = 0; fi < nfields; ++fi) {
1199 status = _csv_parse_record_time(csv, csv->
nrecs);
1200 if (status < 0)
return(-1);
1201 if (status == 0)
return(0);
1241 while (max_fields <= index) max_fields += csv->
nfields_guess;
1243 if (!_csv_realloc_data(csv, max_fields, csv->
nlines)) {
1246 "Memory allocation error adding CSV column name:\n"
1247 " -> file name: %s\n"
1248 " -> column index: %d\n"
1249 " -> column name: %s\n",
1261 csv->
headers[index] = strdup(name);
1265 "Memory allocation error adding CSV column name:\n"
1266 " -> file name: %s\n"
1267 " -> column index: %d\n"
1268 " -> column name: %s\n",
1278 if (csv->
nfields < index + 1) {
1299 memset(&(csv->
base_tm), 0,
sizeof(
struct tm));
1301 if (!gmtime_r(&base_time, &(csv->
base_tm))) {
1304 "Could not set base time for CSV data records\n"
1305 " -> gmtime error: %s\n",
1358 const char **patterns)
1369 "Could not compile CSV file time pattern(s)\n");
1434 const char **patterns)
1452 for (tci = 0; tci < ncols; ++tci) {
1453 if (strcmp(csv->
tc_names[tci], name) == 0) {
1462 tc_names = (
char **)realloc(csv->
tc_names, (ncols + 1) *
sizeof(
char *));
1463 if (!tc_names)
goto MEMORY_ERROR;
1468 if (!tc_patterns)
goto MEMORY_ERROR;
1475 if (!csv->
tc_names[tci])
goto MEMORY_ERROR;
1495 "Memory allocation error adding CSV time column patterns\n");
1546 for (; *strp !=
'\0'; ++strp) {
1549 if (*strp == quote) {
1553 else if (*strp == delim) {
1554 return((
char *)strp);
1556 else if (*strp ==
'"' || *strp ==
'\'') {
1561 return((
char *)NULL);
1577 if (delim && delim !=
' ') {
1578 while (isspace(*strp) && *strp != delim) ++strp;
1581 while (isspace(*strp)) ++strp;
1584 return((
char *)strp);
1616 if (*startp ==
'\0')
return(0);
1622 if (delimp != startp) {
1627 while (endp > startp && isspace(*endp)) *endp-- =
'\0';
1631 if (endp > startp) {
1632 if (*endp ==
'"' || *endp ==
'\'') {
1633 if (*startp == *endp) {
1647 if (nfound < length) {
1648 list[nfound] = startp;
1660 endp = startp + strlen(startp) - 1;
1661 while (endp > startp && isspace(*endp)) *endp-- =
'\0';
1665 if (endp > startp) {
1666 if (*endp ==
'"' || *endp ==
'\'') {
1667 if (*startp == *endp) {
1674 if (nfound < length) {
1675 list[nfound] = startp;
1705 if (status != 1)
return(status);
1710 if (status != 1)
return(status);
1730 char delim = csv->
delim;
1734 fprintf(fp,
"No header stored in CSV Table\n");
1738 fprintf(fp,
"%s", csv->
headers[0]);
1739 for (fi = 1; fi < csv->
nfields; ++fi) {
1740 fprintf(fp,
"%c%s", delim, csv->
headers[fi]);
1746 "Could not write to CSV file\n"
1747 " -> %s\n", strerror(errno));
1772 char delim = csv->
delim;
1776 fprintf(fp,
"No fields stored in CSV Table\n");
1780 if (csv->
nrecs <= 0) {
1781 fprintf(fp,
"No records stored in CSV Table\n");
1785 for (ri = 0; ri < csv->
nrecs; ++ri) {
1787 fprintf(fp,
"%s", csv->
values[0][ri]);
1788 for (fi = 1; fi < csv->
nfields; ++fi) {
1789 fprintf(fp,
"%c%s", delim, csv->
values[fi][ri]);
1797 "Could not write to CSV file\n"
1798 " -> %s\n", strerror(errno));