2021-07-16 18:46:36 +02:00
|
|
|
#include "easycsv_p.h"
|
|
|
|
#include "easycsv_error.h"
|
|
|
|
|
|
|
|
/* int */
|
|
|
|
/* _easycsv_update(_easycsv *csv) */
|
|
|
|
/* { */
|
|
|
|
/* /\* ARGS CHECK *\/ */
|
|
|
|
/* if (csv == NULL) { */
|
|
|
|
/* _easycsv_printerror(csv, EASYCSV_NULLCSV); */
|
|
|
|
/* return -1; */
|
|
|
|
/* } */
|
|
|
|
/* /\* ARGS CHECK *\/ */
|
|
|
|
|
|
|
|
/* /\* Set temp file to read binary *\/ */
|
|
|
|
/* if (freopen(csv->tmpfp, "rb", csv->temp) == NULL) { */
|
|
|
|
/* _easycsv_printerror(csv, EASYCSV_REOPENFAIL); */
|
|
|
|
/* easycsv_free(csv); */
|
|
|
|
/* return -1; */
|
|
|
|
/* } */
|
|
|
|
|
|
|
|
/* /\* Set file to write binary *\/ */
|
|
|
|
/* if (freopen(csv->fp, "wb", csv->file) == NULL) { */
|
|
|
|
/* _easycsv_printerror(csv, EASYCSV_REOPENFAIL); */
|
|
|
|
/* easycsv_free(csv); */
|
|
|
|
/* return -1; */
|
|
|
|
/* } */
|
|
|
|
|
|
|
|
/* /\* Copy entire file *\/ */
|
|
|
|
/* char buf[BUFSIZ]; */
|
|
|
|
/* size_t size; */
|
|
|
|
/* while (size = fread(buf, 1, BUFSIZ, csv->temp)) { */
|
|
|
|
/* fwrite(buf, 1, size, csv->file); */
|
|
|
|
/* } */
|
|
|
|
|
|
|
|
/* /\* Set temp file back to write *\/ */
|
|
|
|
/* if (freopen(csv->tmpfp, "w", csv->temp) == NULL) { */
|
|
|
|
/* _easycsv_printerror(csv, EASYCSV_REOPENFAIL); */
|
|
|
|
/* easycsv_free(csv); */
|
|
|
|
/* return -1; */
|
|
|
|
/* } */
|
|
|
|
|
|
|
|
/* /\* Set file back to read *\/ */
|
|
|
|
/* if (freopen(csv->fp, "r", csv->file) == NULL) { */
|
|
|
|
/* _easycsv_printerror(csv, EASYCSV_REOPENFAIL); */
|
|
|
|
/* easycsv_free(csv); */
|
|
|
|
/* return -1; */
|
|
|
|
/* } */
|
|
|
|
|
|
|
|
/* return 0; */
|
|
|
|
/* } */
|
|
|
|
|
|
|
|
/*** Accès ***/
|
|
|
|
|
|
|
|
int
|
|
|
|
easycsv_rows(const easycsv *csv)
|
|
|
|
{
|
|
|
|
if (easycsv_rewind(csv) < 0) return -1;
|
|
|
|
|
|
|
|
int rows = 1;
|
|
|
|
char c;
|
|
|
|
|
|
|
|
/* Go through each character in the file and count the number of new lines */
|
|
|
|
while ((c = fgetc(csv->file)) != EOF) {
|
|
|
|
if (c == '\n') rows++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return rows;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
easycsv_columns(const easycsv *csv)
|
|
|
|
{
|
|
|
|
if (easycsv_rewind(csv) < 0) return -1;
|
|
|
|
|
|
|
|
/*
|
|
|
|
1. check if empty file
|
|
|
|
2. check if only one column -> 0 commas
|
|
|
|
3. if >1 column, n commas = n+1 columns
|
|
|
|
*/
|
|
|
|
|
|
|
|
int col = 1;
|
|
|
|
char c;
|
|
|
|
|
|
|
|
while ((c = fgetc(csv->file)) != '\n') {
|
|
|
|
if (c == ',') col++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return col;
|
|
|
|
}
|
|
|
|
|
2021-07-17 16:46:19 +02:00
|
|
|
char*
|
|
|
|
easycsv_get_row(const easycsv *csv,
|
|
|
|
unsigned int row)
|
|
|
|
{
|
|
|
|
char *str = malloc(BUFSIZ);
|
|
|
|
easycsv_rewind(csv);
|
2021-07-16 18:46:36 +02:00
|
|
|
|
2021-07-17 16:46:19 +02:00
|
|
|
for (int i = 1; i < row; i++) {
|
|
|
|
fscanf(csv->file, "%*[^\n]\n", NULL);
|
|
|
|
}
|
2021-07-16 18:46:36 +02:00
|
|
|
|
2021-07-17 16:46:19 +02:00
|
|
|
fscanf(csv->file, "%s\n", str);
|
2021-07-16 18:46:36 +02:00
|
|
|
|
2021-07-17 16:46:19 +02:00
|
|
|
return str;
|
|
|
|
}
|
2021-07-16 18:46:36 +02:00
|
|
|
|
|
|
|
int
|
|
|
|
easycsv_rewind(const easycsv *csv)
|
|
|
|
{
|
|
|
|
/* Check if empty file */
|
|
|
|
if (fscanf(csv->file, "\n") == EOF) {
|
|
|
|
easycsv_error(EASYCSV_EMPTYCSV, NULL);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check if file is readable */
|
|
|
|
if (csv->mode != EASYCSV_R) {
|
|
|
|
easycsv_error(EASYCSV_UNREADABLE, NULL);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Set file pointer to the start */
|
|
|
|
rewind(csv->file);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* int */
|
|
|
|
/* _easycsv_getcolumn(const _easycsv *csv, */
|
|
|
|
/* const char *col) */
|
|
|
|
/* { */
|
|
|
|
/* /\* ARGS CHECK *\/ */
|
|
|
|
/* if (_easycsv_checkcsvandstring_one(csv, col) < 0) */
|
|
|
|
/* return -1; */
|
|
|
|
/* /\* ARGS CHECK *\/ */
|
|
|
|
|
|
|
|
/* /\* Grab str of row 1 *\/ */
|
|
|
|
/* char *firstrow = _easycsv_getrow(csv, 1); */
|
|
|
|
|
|
|
|
/* if (firstrow == NULL) { */
|
|
|
|
/* _easycsv_printerror(csv, EASYCSV_ROWNOTEXIST); */
|
|
|
|
/* return -1; */
|
|
|
|
/* } */
|
|
|
|
|
|
|
|
/* unsigned int commas = 0; */
|
|
|
|
|
|
|
|
/* // printf("FIRST COLUMN: %s\n", firstrow); */
|
|
|
|
|
|
|
|
/* /\* Find first occurance of col in firstrow *\/ */
|
|
|
|
/* char *str = strstr(firstrow, col); */
|
|
|
|
|
|
|
|
/* if (str == NULL) { */
|
|
|
|
/* _easycsv_printerror(csv, EASYCSV_COLNOTEXIST); */
|
|
|
|
/* return -1; */
|
|
|
|
/* } */
|
|
|
|
|
|
|
|
/* /\* Count numbers of commas following str *\/ */
|
|
|
|
/* char *c = strpbrk(str, ","); */
|
|
|
|
/* while (c != NULL) { */
|
|
|
|
/* commas++; */
|
|
|
|
/* c = strpbrk(c + 1, ","); */
|
|
|
|
/* } */
|
|
|
|
|
|
|
|
/* /\* no need to free c as it is already NULL at this point *\/ */
|
|
|
|
/* // free((char*) str); apparently invalid pointer */
|
|
|
|
|
|
|
|
/* // printf("ROW: %i\nCOL: %i\n", row, csv->cols - commas); */
|
|
|
|
/* /\* */
|
|
|
|
/* #ifdef EASYCSV_DEBUG */
|
|
|
|
/* printf("[%i] rcv_commas: %i\n", clock() - csv->start, commas); */
|
|
|
|
/* #endif */
|
|
|
|
/* *\/ */
|
|
|
|
/* free(firstrow); */
|
|
|
|
|
|
|
|
/* return csv->cols - commas; */
|
|
|
|
/* } */
|
|
|
|
|
|
|
|
/*
|
|
|
|
int _easycsv_checkifvalue(struct easycsv *csv, const int col, const int row)
|
|
|
|
{
|
|
|
|
const char *rowstr = _easycsv_getrow(csv, row);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* char* */
|
|
|
|
/* _easycsv_getvalueinrow(const _easycsv *_priv, */
|
|
|
|
/* const char *row, */
|
|
|
|
/* const unsigned int col) */
|
|
|
|
/* { */
|
|
|
|
/* size_t st; */
|
|
|
|
/* char *pch = NULL; */
|
|
|
|
|
|
|
|
/* /\* If not first column *\/ */
|
|
|
|
/* if (col != 1) { */
|
|
|
|
|
|
|
|
/* /\* Get first occurance of comma in str, */
|
|
|
|
/* the first value is ommited but not the comma *\/ */
|
|
|
|
/* char *pch = strpbrk(row, ","); */
|
|
|
|
|
|
|
|
/* /\* Repeat until desired col is found *\/ */
|
|
|
|
/* for (int i = 2; i < col; i++) { */
|
|
|
|
/* pch = strpbrk(pch + 1, ","); */
|
|
|
|
/* } */
|
|
|
|
/* } */
|
|
|
|
|
|
|
|
/* /\* Get span from start of string to first occurence */
|
|
|
|
/* of comma *\/ */
|
|
|
|
/* st = strcspn(pch + 1, ","); */
|
|
|
|
|
|
|
|
/* /\* If 0, no string exists! *\/ */
|
|
|
|
/* if (st == 0) { */
|
|
|
|
/* _easycsv_printerror(_priv, EASYCSV_EMPTYVALUE); */
|
|
|
|
/* return NULL; */
|
|
|
|
/* } */
|
|
|
|
|
|
|
|
/* char *val = malloc(st + 1); */
|
|
|
|
/* strncpy(val, pch + 1, st); */
|
|
|
|
/* strncat(val, "\0", 1); */
|
|
|
|
|
|
|
|
/* return val; */
|
|
|
|
/* } */
|
|
|
|
|
2021-07-17 16:46:19 +02:00
|
|
|
char*
|
|
|
|
easycsv_set_charp_to_value(const char *rowstr,
|
|
|
|
unsigned int col)
|
|
|
|
{
|
|
|
|
/* Get first occurance of comma in str, the first value is ommited but not the comma */
|
|
|
|
char *pch = (char*) rowstr;
|
|
|
|
/* Repeat until desired col is found */
|
|
|
|
for (unsigned int i = 1; i < col; i++) {
|
|
|
|
pch = strpbrk(pch + 1, ",");
|
|
|
|
}
|
2021-07-16 18:46:36 +02:00
|
|
|
|
2021-07-17 16:46:19 +02:00
|
|
|
return pch;
|
|
|
|
}
|
2021-07-16 18:46:36 +02:00
|
|
|
|
|
|
|
/* int */
|
|
|
|
/* _easycsv_checkcsvandstring_one(const _easycsv *csv, */
|
|
|
|
/* const char *one) */
|
|
|
|
/* { */
|
|
|
|
/* if (csv == NULL) { */
|
|
|
|
/* _easycsv_printerror(csv, EASYCSV_NULLCSV); */
|
|
|
|
/* return -1; */
|
|
|
|
/* } */
|
|
|
|
|
|
|
|
/* if (one == NULL) { */
|
|
|
|
/* _easycsv_printerror(csv, EASYCSV_EMPTYSTRING); */
|
|
|
|
/* return -1; */
|
|
|
|
/* } */
|
|
|
|
|
|
|
|
/* return 0; */
|
|
|
|
/* } */
|
|
|
|
|
|
|
|
/* int */
|
|
|
|
/* _easycsv_checkcsvandstring_two(const _easycsv *csv, */
|
|
|
|
/* const char *one, */
|
|
|
|
/* const char *two) */
|
|
|
|
/* { */
|
|
|
|
/* if (_easycsv_checkcsvandstring_one(csv, one) < 0) */
|
|
|
|
/* return -1; */
|
|
|
|
|
|
|
|
/* if (two == NULL) { */
|
|
|
|
/* _easycsv_printerror(csv, EASYCSV_EMPTYSTRING); */
|
|
|
|
/* return -1; */
|
|
|
|
/* } */
|
|
|
|
|
|
|
|
/* return 0; */
|
|
|
|
/* } */
|