2021-07-16 18:46:36 +02:00
|
|
|
#include "easycsv_p.h"
|
|
|
|
#include "easycsv_error.h"
|
2018-02-11 18:14:34 +01:00
|
|
|
|
2021-07-16 18:46:36 +02:00
|
|
|
/*** Constructors ***/
|
2018-02-21 20:40:51 +01:00
|
|
|
|
2018-02-11 18:14:34 +01:00
|
|
|
easycsv*
|
2018-02-21 20:40:51 +01:00
|
|
|
easycsv_init(const char *fp,
|
2021-07-16 18:46:36 +02:00
|
|
|
EASYCSV_MODE mode)
|
2018-02-11 18:14:34 +01:00
|
|
|
{
|
2021-07-16 18:46:36 +02:00
|
|
|
easycsv *csv = NULL;
|
|
|
|
int csv_exist = -1;
|
|
|
|
|
|
|
|
csv = malloc(sizeof(easycsv));
|
2021-07-17 15:11:57 +02:00
|
|
|
if (csv == NULL) {
|
|
|
|
easycsv_error(EASYCSV_MEMALLOC, NULL);
|
|
|
|
return NULL;
|
|
|
|
}
|
2018-02-11 18:14:34 +01:00
|
|
|
|
2021-07-17 15:11:57 +02:00
|
|
|
memset(csv, 0, sizeof(easycsv));
|
2018-02-11 18:14:34 +01:00
|
|
|
csv->mode = mode;
|
2021-07-16 18:46:36 +02:00
|
|
|
csv->file = NULL;
|
|
|
|
csv->temp = NULL;
|
2021-07-17 15:11:57 +02:00
|
|
|
strcpy(csv->fp, fp);
|
2021-07-16 18:46:36 +02:00
|
|
|
csv->rows = 0;
|
|
|
|
csv->cols = 0;
|
2018-02-11 18:14:34 +01:00
|
|
|
|
2021-07-17 15:11:57 +02:00
|
|
|
csv_exist = !access(csv->fp, F_OK);
|
|
|
|
|
2021-07-16 18:46:36 +02:00
|
|
|
/* Open file according to mode */
|
|
|
|
switch (csv->mode) {
|
|
|
|
case EASYCSV_R:
|
2021-07-17 15:11:57 +02:00
|
|
|
if (csv_exist) {
|
|
|
|
csv->file = fopen(csv->fp, "r");
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
easycsv_error(EASYCSV_EMPTYCSV, NULL);
|
|
|
|
easycsv_free(csv);
|
|
|
|
return NULL;
|
|
|
|
}
|
2021-07-16 18:46:36 +02:00
|
|
|
break;
|
|
|
|
case EASYCSV_W:
|
2021-07-17 15:11:57 +02:00
|
|
|
if (csv_exist) {
|
|
|
|
csv->file = fopen(csv->fp, "r+");
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
csv->file = fopen(csv->fp, "w");
|
|
|
|
}
|
2021-07-16 18:46:36 +02:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
easycsv_error(EASYCSV_UNKNOWNIOMODE, NULL);
|
2018-02-11 18:14:34 +01:00
|
|
|
easycsv_free(csv);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2021-07-16 18:46:36 +02:00
|
|
|
if (csv->file == NULL) {
|
|
|
|
easycsv_error(EASYCSV_OPENFAIL, NULL);
|
|
|
|
easycsv_free(csv);
|
2018-02-21 20:40:51 +01:00
|
|
|
return NULL;
|
2018-02-11 18:14:34 +01:00
|
|
|
}
|
2021-07-16 18:46:36 +02:00
|
|
|
|
|
|
|
/* Calculate rows and cols if file exists */
|
|
|
|
if (csv_exist) {
|
|
|
|
csv->rows = easycsv_rows(csv);
|
|
|
|
csv->cols = easycsv_columns(csv);
|
2018-02-11 18:14:34 +01:00
|
|
|
}
|
|
|
|
|
2021-07-16 18:46:36 +02:00
|
|
|
if (mode == EASYCSV_W) {
|
2021-07-17 15:11:57 +02:00
|
|
|
csv->temp = tmpfile();
|
2021-07-16 18:46:36 +02:00
|
|
|
if (csv->temp == NULL) {
|
|
|
|
easycsv_error(EASYCSV_OPENFAIL, NULL);
|
|
|
|
easycsv_free(csv);
|
|
|
|
return NULL;
|
|
|
|
}
|
2018-02-21 20:40:51 +01:00
|
|
|
}
|
2018-02-22 14:23:23 +01:00
|
|
|
|
2021-07-16 18:46:36 +02:00
|
|
|
return csv;
|
2018-02-21 20:40:51 +01:00
|
|
|
}
|
|
|
|
|
2021-07-16 18:46:36 +02:00
|
|
|
void
|
|
|
|
easycsv_free(easycsv *csv)
|
2018-02-21 20:40:51 +01:00
|
|
|
{
|
2021-07-17 15:11:57 +02:00
|
|
|
if (csv != NULL) {
|
|
|
|
if (csv->file != NULL) fclose(csv->file);
|
|
|
|
if (csv->temp != NULL) fclose(csv->temp);
|
|
|
|
free(csv);
|
|
|
|
}
|
2021-07-16 18:46:36 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*** Acces, find ***/
|
|
|
|
|
2021-07-16 21:31:51 +02:00
|
|
|
int
|
|
|
|
easycsv_find_value(const easycsv* csv,
|
|
|
|
const char* value,
|
|
|
|
unsigned int* col,
|
|
|
|
unsigned int* row)
|
|
|
|
{
|
|
|
|
char *str;
|
|
|
|
const unsigned int cols = easycsv_print_columns(csv);
|
|
|
|
const unsigned int rows = easycsv_print_rows(csv);
|
|
|
|
|
2021-07-16 22:59:42 +02:00
|
|
|
for (unsigned int row_l = 1; row_l <= rows; row_l++) {
|
|
|
|
for (unsigned int col_l = 1; col_l <= cols; col_l++) {
|
2021-07-16 21:31:51 +02:00
|
|
|
str = easycsv_read_value(csv, col_l, row_l);
|
|
|
|
if (strcmp(str, value) == 0) {
|
|
|
|
*col = col_l;
|
|
|
|
*row = row_l;
|
|
|
|
free(str);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
free(str);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
easycsv_error(EASYCSV_FINDVALUEFAIL, value);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2021-07-16 22:59:42 +02:00
|
|
|
int
|
|
|
|
easycsv_find_num_value(const easycsv* csv,
|
|
|
|
const char* value)
|
|
|
|
{
|
|
|
|
char *str;
|
|
|
|
int num = 0;
|
|
|
|
const unsigned int cols = easycsv_print_columns(csv);
|
|
|
|
const unsigned int rows = easycsv_print_rows(csv);
|
|
|
|
|
|
|
|
for (unsigned int row_l = 1; row_l <= rows; row_l++) {
|
2021-07-17 13:43:25 +02:00
|
|
|
for (unsigned int col_l = 1; col_l < cols; col_l++) {
|
2021-07-16 22:59:42 +02:00
|
|
|
str = easycsv_read_value(csv, col_l, row_l);
|
|
|
|
if (strcmp(str, value) == 0) {
|
|
|
|
num++;
|
|
|
|
}
|
|
|
|
free(str);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return num;
|
|
|
|
}
|
|
|
|
|
2021-07-16 18:46:36 +02:00
|
|
|
/*** Acces, read ***/
|
|
|
|
|
2021-07-16 20:25:30 +02:00
|
|
|
char*
|
|
|
|
easycsv_read_value(const easycsv *csv,
|
|
|
|
unsigned int col,
|
|
|
|
unsigned int row)
|
|
|
|
{
|
|
|
|
char str_row[BUFSIZ];
|
2021-07-16 20:57:46 +02:00
|
|
|
size_t st;
|
|
|
|
char *pch, *val;
|
2021-07-16 20:25:30 +02:00
|
|
|
if (row == 0) {
|
|
|
|
easycsv_error(EASYCSV_ZEROROW, NULL);
|
|
|
|
return NULL;
|
|
|
|
}
|
2021-07-17 13:36:09 +02:00
|
|
|
|
|
|
|
if (row > easycsv_print_rows(csv)) {
|
|
|
|
easycsv_error(EASYCSV_ROWNOTEXIST, NULL);
|
|
|
|
return NULL;
|
|
|
|
}
|
2018-02-11 18:14:34 +01:00
|
|
|
|
2021-07-16 20:25:30 +02:00
|
|
|
if (col == 0) {
|
|
|
|
easycsv_error(EASYCSV_ZEROCOL, NULL);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2021-07-17 13:36:09 +02:00
|
|
|
if (col > easycsv_print_columns(csv)) {
|
|
|
|
easycsv_error(EASYCSV_COLNOTEXIST, NULL);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2021-07-16 20:25:30 +02:00
|
|
|
/* Set file pointer to start */
|
|
|
|
easycsv_rewind(csv);
|
2021-07-16 18:46:36 +02:00
|
|
|
|
2021-07-16 20:25:30 +02:00
|
|
|
for (unsigned int i = 1; i < row; i++) {
|
|
|
|
fscanf(csv->file, "%*[^\n]\n", NULL);
|
|
|
|
}
|
|
|
|
fscanf(csv->file, "%s\n", str_row);
|
|
|
|
|
2021-07-16 20:57:03 +02:00
|
|
|
/* Get first occurance of comma in str, the first value is ommited but not the comma */
|
2021-07-16 20:25:30 +02:00
|
|
|
pch = str_row;
|
|
|
|
/* Repeat until desired col is found */
|
2021-07-16 20:57:03 +02:00
|
|
|
for (unsigned int i = 1; i < col; i++) {
|
|
|
|
pch = strpbrk(pch + 1, ",");
|
|
|
|
}
|
2021-07-16 18:46:36 +02:00
|
|
|
|
2021-07-16 20:25:30 +02:00
|
|
|
val = malloc(BUFSIZ);
|
2021-07-16 22:59:42 +02:00
|
|
|
if (pch == NULL) {
|
|
|
|
st = 0;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* Get span from start of string to first occurence of comma */
|
|
|
|
if (col > 1) pch++;
|
|
|
|
st = strcspn(pch, ",");
|
|
|
|
// If 0, no string exists!
|
|
|
|
if (st > 0) {
|
|
|
|
strncpy(val, pch, st + 1);
|
|
|
|
}
|
2021-07-16 20:25:30 +02:00
|
|
|
}
|
2021-07-16 20:57:03 +02:00
|
|
|
val[st] = '\0';
|
|
|
|
|
2021-07-16 20:25:30 +02:00
|
|
|
return val;
|
|
|
|
}
|
2021-07-16 18:46:36 +02:00
|
|
|
|
|
|
|
/* char* */
|
|
|
|
/* easycsv_readcolumnvalue(const easycsv *csv, */
|
|
|
|
/* const char *col, */
|
|
|
|
/* const unsigned int row) */
|
|
|
|
/* { */
|
|
|
|
/* /\* ARGS CHECK *\/ */
|
|
|
|
/* if (_easycsv_checkcsvandstring_one(csv->csv, col) < 0) */
|
|
|
|
/* return NULL; */
|
|
|
|
|
|
|
|
/* if (row > csv->csv->rows) { */
|
|
|
|
/* _easycsv_printerror(csv->csv, EASYCSV_OVERMAXROW); */
|
|
|
|
/* return NULL; */
|
|
|
|
/* } */
|
|
|
|
/* /\* END ARGS CHECK *\/ */
|
2018-02-11 18:14:34 +01:00
|
|
|
|
2021-07-16 18:46:36 +02:00
|
|
|
/* int i = _easycsv_getcolumn(csv->csv, col); */
|
|
|
|
/* if (i < 1) { */
|
|
|
|
/* _easycsv_printerror(csv->csv, EASYCSV_COLNUMFAIL); */
|
|
|
|
/* return NULL; */
|
|
|
|
/* } */
|
2018-02-21 20:40:51 +01:00
|
|
|
|
2021-07-16 18:46:36 +02:00
|
|
|
/* return easycsv_readvalue(csv, i, row); */
|
|
|
|
/* } */
|
2018-02-21 20:40:51 +01:00
|
|
|
|
2021-07-16 18:46:36 +02:00
|
|
|
/*** Acces, print ***/
|
2018-02-21 20:40:51 +01:00
|
|
|
|
|
|
|
int
|
2021-07-16 18:46:36 +02:00
|
|
|
easycsv_print_rows(const easycsv *csv)
|
2018-02-21 20:40:51 +01:00
|
|
|
{
|
2021-07-17 13:50:54 +02:00
|
|
|
if (csv != NULL) {
|
|
|
|
return csv->rows;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return -1;
|
|
|
|
}
|
2018-02-21 20:40:51 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2021-07-16 18:46:36 +02:00
|
|
|
easycsv_print_columns(const easycsv *csv)
|
2018-02-21 20:40:51 +01:00
|
|
|
{
|
2021-07-17 13:50:54 +02:00
|
|
|
if (csv != NULL) {
|
|
|
|
return csv->cols;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return -1;
|
|
|
|
}
|
2018-02-21 20:40:51 +01:00
|
|
|
}
|
|
|
|
|
2021-07-16 18:46:36 +02:00
|
|
|
/*** Modifications, sort ***/
|
|
|
|
|
|
|
|
/*** Modifications, insert ***/
|
|
|
|
|
|
|
|
/* int */
|
|
|
|
/* easycsv_insertvalue(easycsv *csv, */
|
|
|
|
/* const char *val, */
|
|
|
|
/* const unsigned int col, */
|
|
|
|
/* const unsigned int row) */
|
|
|
|
/* { */
|
|
|
|
/* return easycsv_insertvaluemode(csv, val, col, row, EASYCSV_REPLACE); */
|
|
|
|
/* } */
|
|
|
|
|
|
|
|
/* int */
|
|
|
|
/* easycsv_insertvaluemode(easycsv *csv, */
|
|
|
|
/* const char *val, */
|
|
|
|
/* const unsigned int col, */
|
|
|
|
/* const unsigned int row, */
|
|
|
|
/* const EASYCSV_VALMODE valmode) */
|
|
|
|
/* { */
|
|
|
|
/* /\* ARGS CHECK *\/ */
|
|
|
|
/* if (_easycsv_checkcsvandstring_one(csv->csv, val) < 0) */
|
|
|
|
/* return -1; */
|
|
|
|
|
|
|
|
/* if (col == 0) { */
|
|
|
|
/* _easycsv_printerror(csv->csv, EASYCSV_ZEROCOL); */
|
|
|
|
/* return -1; */
|
|
|
|
/* } */
|
|
|
|
|
|
|
|
/* if (row == 0) { */
|
|
|
|
/* _easycsv_printerror(csv->csv, EASYCSV_ZEROROW); */
|
|
|
|
/* return -1; */
|
|
|
|
/* } */
|
|
|
|
/* /\* END ARGS CHECK *\/ */
|
|
|
|
|
|
|
|
/* /\* row extends max *\/ */
|
|
|
|
/* if (row > csv->csv->rows) { */
|
|
|
|
/* } */
|
2018-02-21 20:40:51 +01:00
|
|
|
|
2021-07-16 18:46:36 +02:00
|
|
|
/* char *rowstr = _easycsv_getrow(csv->csv, row); */
|
|
|
|
/* if (rowstr == NULL) */
|
|
|
|
/* return -1; */
|
2018-02-21 20:40:51 +01:00
|
|
|
|
2021-07-16 18:46:36 +02:00
|
|
|
/* size_t rowstrst = strlen(rowstr); */
|
|
|
|
/* size_t st = 0; */
|
|
|
|
/* size_t commas = 0; */
|
|
|
|
/* char *pch = NULL; */
|
|
|
|
/* char *newstr = NULL; */
|
|
|
|
|
|
|
|
/* /\* column is within limit *\/ */
|
|
|
|
/* if (col <= csv->csv->cols) { */
|
|
|
|
|
|
|
|
/* /\* Set pch to start of value in rowstr *\/ */
|
|
|
|
/* pch = _easycsv_setcharptovalue(csv->csv, rowstr, col); */
|
|
|
|
/* if (pch == NULL) */
|
|
|
|
/* return -1; */
|
|
|
|
|
|
|
|
/* /\* Calculate size of existing value *\/ */
|
|
|
|
/* st = strcspn(pch, ","); */
|
2018-02-11 18:14:34 +01:00
|
|
|
|
2021-07-16 18:46:36 +02:00
|
|
|
/* newstr = malloc(rowstrst - st + strlen(val) + 1); */
|
|
|
|
|
|
|
|
/* /\* Copy char to newstr before value (pch) *\/ */
|
|
|
|
/* strncpy(newstr, rowstr, pch - rowstr); */
|
|
|
|
|
|
|
|
/* /\* Insert value *\/ */
|
|
|
|
/* if (st != 0) { /\* Occupied cell *\/ */
|
|
|
|
/* switch (valmode) { */
|
|
|
|
/* case EASYCSV_CONCAT: { */
|
|
|
|
/* strncat(newstr, pch, st); */
|
|
|
|
/* strcat(newstr, val); */
|
|
|
|
/* break; */
|
|
|
|
/* } */
|
|
|
|
/* case EASYCSV_RCONCAT: { */
|
|
|
|
/* strcat(newstr, val); */
|
|
|
|
/* strncat(newstr, pch, st); */
|
|
|
|
/* break; */
|
|
|
|
/* } */
|
|
|
|
/* case EASYCSV_REPLACE: */
|
|
|
|
/* default: { */
|
|
|
|
/* strcat(newstr, val); */
|
|
|
|
/* break; */
|
|
|
|
/* } */
|
|
|
|
/* } */
|
|
|
|
/* } */
|
|
|
|
/* else { /\* Empty cell *\/ */
|
|
|
|
/* strcat(newstr, val); */
|
|
|
|
/* } */
|
|
|
|
|
|
|
|
/* /\* Set pch to after value *\/ */
|
|
|
|
/* pch = strchr(rowstr, ','); */
|
|
|
|
|
|
|
|
/* /\* Calculate length of rest of string *\/ */
|
|
|
|
/* st = strlen(pch); */
|
|
|
|
|
|
|
|
/* /\* Concentate rest of string including NULL char *\/ */
|
|
|
|
/* strcat(newstr, pch); */
|
|
|
|
/* } */
|
|
|
|
/* else { */
|
|
|
|
/* commas = col - csv->csv->cols; */
|
|
|
|
/* csv->csv->cols = col; */
|
|
|
|
/* newstr = malloc(rowstrst + commas + strlen(val) + 1); */
|
|
|
|
/* strncpy(newstr, rowstr, rowstrst); */
|
|
|
|
/* for (size_t i = 0; i < commas; i++) */
|
|
|
|
/* strncat(newstr, ",", 1); */
|
|
|
|
/* strcat(newstr, val); // append \0 */
|
|
|
|
/* } */
|
2018-02-21 20:40:51 +01:00
|
|
|
|
2021-07-16 18:46:36 +02:00
|
|
|
/* /\* UPDATE CSV *\/ */
|
2018-02-21 20:40:51 +01:00
|
|
|
|
2021-07-16 18:46:36 +02:00
|
|
|
/* char *str = NULL; */
|
|
|
|
|
|
|
|
/* /\* Row within limits *\/ */
|
|
|
|
/* if (row <= csv->csv->rows) { */
|
|
|
|
|
|
|
|
/* /\* Copy rows before newstr in csv to temp *\/ */
|
|
|
|
/* for (unsigned int i = 1; i < row; i++) { */
|
|
|
|
/* str = _easycsv_getrow(csv->csv, i); */
|
|
|
|
/* if (col > csv->csv->cols) { */
|
|
|
|
/* str = realloc(str, strlen(str) + commas + 1); */
|
|
|
|
/* for (size_t j = 0; j < commas; j++) { */
|
|
|
|
/* strncat(str, ",", 1); */
|
|
|
|
/* } */
|
|
|
|
/* } */
|
|
|
|
/* fputs(str, csv->csv->temp); */
|
|
|
|
|
|
|
|
/* free(str); */
|
|
|
|
/* } */
|
|
|
|
|
|
|
|
/* /\* Print newstr into temp *\/ */
|
|
|
|
/* fputs(newstr, csv->csv->temp); */
|
|
|
|
|
|
|
|
/* /\* Copy the rest of rows *\/ */
|
|
|
|
/* for (unsigned int i = row + 1; i <= csv->csv->rows; i++) { */
|
|
|
|
/* str = _easycsv_getrow(csv, i); */
|
|
|
|
/* if (col > csv->csv->cols) { */
|
|
|
|
/* str = realloc(str, strlen(str) + commas + 1); */
|
|
|
|
/* for (size_t j = 0; j < commas; j++) { */
|
|
|
|
/* strncat(str, ",", 1); */
|
|
|
|
/* } */
|
|
|
|
/* } */
|
|
|
|
/* fputs(str, csv->csv->temp); */
|
|
|
|
|
|
|
|
/* free(str); */
|
|
|
|
/* } */
|
|
|
|
/* } */
|
|
|
|
/* else { /\* Row exceeds limit *\/ */
|
2018-02-21 20:40:51 +01:00
|
|
|
|
2021-07-16 18:46:36 +02:00
|
|
|
/* /\* Copy entire file *\/ */
|
|
|
|
/* char buf[BUFSIZ]; */
|
|
|
|
/* size_t size; */
|
|
|
|
/* while (size = fread(buf, 1, BUFSIZ, csv->csv->file)) { */
|
|
|
|
/* fwrite(buf, 1, size, csv->csv->temp); */
|
|
|
|
/* } */
|
|
|
|
|
|
|
|
/* /\* Print out commas on rows before newstr *\/ */
|
|
|
|
/* for (size_t i = csv->csv->rows; i < row; i++) { */
|
|
|
|
/* for (size_t j = 0; j < csv->csv->cols; j++) */
|
|
|
|
/* fputc(',', csv->csv->temp); */
|
|
|
|
/* fputc('\n', csv->csv->temp); */
|
|
|
|
/* } */
|
|
|
|
|
|
|
|
/* fputs(newstr, csv->csv->temp); */
|
|
|
|
/* } */
|
|
|
|
|
|
|
|
/* /\* Update csv *\/ */
|
|
|
|
/* if (_easycsv_update(csv->csv) < 0) */
|
|
|
|
/* return -1; */
|
|
|
|
|
|
|
|
/* /\* END UPDATE CSV *\/ */
|
2018-02-11 18:14:34 +01:00
|
|
|
|
2021-07-16 18:46:36 +02:00
|
|
|
/* free(rowstr); // including pch */
|
|
|
|
/* free(newstr); */
|
2018-02-21 20:40:51 +01:00
|
|
|
|
2021-07-16 18:46:36 +02:00
|
|
|
/* return 0; */
|
|
|
|
/* } */
|
|
|
|
|
|
|
|
/* int */
|
|
|
|
/* easycsv_insertcolumnvalue(easycsv *csv, */
|
|
|
|
/* const char *col, */
|
|
|
|
/* const unsigned int row, */
|
|
|
|
/* const char *val) */
|
|
|
|
/* { */
|
|
|
|
/* return easycsv_insertcolumnvaluemode(csv, col, row, val, EASYCSV_REPLACE); */
|
|
|
|
/* } */
|
|
|
|
|
|
|
|
/* int */
|
|
|
|
/* easycsv_insertcolumnvaluemode(easycsv *csv, */
|
|
|
|
/* const char *col, */
|
|
|
|
/* const unsigned int row, */
|
|
|
|
/* const char *val, */
|
|
|
|
/* const EASYCSV_VALMODE valmode) */
|
|
|
|
/* { */
|
|
|
|
/* /\* ARGS CHECK *\/ */
|
|
|
|
/* if (_easycsv_checkcsvandstring_two(csv->csv, col, val) < 0) */
|
|
|
|
/* return -1; */
|
|
|
|
|
|
|
|
/* if (row == 0) { */
|
|
|
|
/* _easycsv_printerror(csv->csv, EASYCSV_ZEROROW); */
|
|
|
|
/* return -1; */
|
|
|
|
/* } */
|
|
|
|
/* /\* END ARGS CHECK *\/ */
|
2018-02-11 18:14:34 +01:00
|
|
|
|
2021-07-16 18:46:36 +02:00
|
|
|
/* int colnum = _easycsv_getcolumn(csv->csv, col); */
|
|
|
|
/* if (colnum < 0) { */
|
|
|
|
/* _easycsv_printerror(csv->csv, EASYCSV_COLNUMFAIL); */
|
|
|
|
/* return -1; */
|
|
|
|
/* } */
|
2018-02-21 20:40:51 +01:00
|
|
|
|
2021-07-16 18:46:36 +02:00
|
|
|
/* return easycsv_insertvaluemode(csv, val, colnum, row, valmode); */
|
|
|
|
/* } */
|
|
|
|
|
|
|
|
/*** Modifications, push ***/
|
|
|
|
|
|
|
|
/* int */
|
|
|
|
/* easycsv_pushcolumn(easycsv *csv, */
|
|
|
|
/* const char *col) */
|
|
|
|
/* { */
|
|
|
|
/* /\* ARGS CHECK *\/ */
|
|
|
|
/* if (_easycsv_checkcsvandstring_one(csv->csv, col) < 0) */
|
|
|
|
/* return -1; */
|
|
|
|
/* /\* END ARGS CHECK *\/ */
|
2018-02-11 18:14:34 +01:00
|
|
|
|
2021-07-16 18:46:36 +02:00
|
|
|
/* if (csv->mode == EASYCSV_R) { */
|
|
|
|
/* _easycsv_printerror(csv->csv, EASYCSV_UNWRITABLE); */
|
|
|
|
/* return -1; */
|
|
|
|
/* } */
|
2018-02-11 18:14:34 +01:00
|
|
|
|
2021-07-16 18:46:36 +02:00
|
|
|
/* if ((csv->mode == EASYCSV_W) && (access(csv->csv->fp, F_OK) < 0)) { */
|
2018-02-21 20:40:51 +01:00
|
|
|
|
2021-07-16 18:46:36 +02:00
|
|
|
/* /\* If the file doesn't exist, just put the col */
|
|
|
|
/* in the file *\/ */
|
|
|
|
/* if (fputs(col, csv->csv->file) < 0) { */
|
|
|
|
/* _easycsv_printerror(csv->csv, EASYCSV_PUSHCOLFAIL); */
|
|
|
|
/* return -1; */
|
|
|
|
/* } */
|
|
|
|
|
|
|
|
/* return 0; */
|
|
|
|
/* } */
|
2018-02-21 20:40:51 +01:00
|
|
|
|
2021-07-16 18:46:36 +02:00
|
|
|
/* /\* Grab first row *\/ */
|
|
|
|
/* char *str = _easycsv_getrow(csv->csv, 1); */
|
|
|
|
/* char *pch = NULL; */
|
|
|
|
/* size_t i; */
|
|
|
|
|
|
|
|
/* /\* Find empty column in first row *\/ */
|
|
|
|
/* for (i = 1; i < csv->csv->cols; i++) { */
|
|
|
|
/* if (strcspn(pch, ",") == 0) */
|
|
|
|
/* break; */
|
|
|
|
/* pch = strchr(str, ','); */
|
|
|
|
/* pch++; */
|
|
|
|
/* } */
|
|
|
|
|
|
|
|
/* /\* No empty columns in first row *\/ */
|
|
|
|
/* if (i == csv->csv->cols) */
|
|
|
|
/* i++; */
|
2018-02-21 20:40:51 +01:00
|
|
|
|
2021-07-16 18:46:36 +02:00
|
|
|
/* return easycsv_insertvalue(csv, col, i, 1); */
|
2018-02-21 20:40:51 +01:00
|
|
|
|
2021-07-16 18:46:36 +02:00
|
|
|
/* /\*size_t ststr = strlen(str); */
|
|
|
|
/* size_t stcol = strlen(col); */
|
|
|
|
/* realloc(str, ststr + stcol + 2); // 1 for null and 1 for comma */
|
2018-02-11 18:14:34 +01:00
|
|
|
|
2021-07-16 18:46:36 +02:00
|
|
|
/* strncat(str + ststr, ",", 1); */
|
|
|
|
/* strncat(str + ststr + 1, col, stcol); */
|
2018-02-21 20:40:51 +01:00
|
|
|
|
2021-07-16 18:46:36 +02:00
|
|
|
/* // Put str in temp file */
|
|
|
|
/* if (fputs(str, csv->csv->temp) < 0) { */
|
|
|
|
/* _easycsv_printerror(csv->csv, EASYCSV_PUSHCOLFAIL); */
|
|
|
|
/* return -1; */
|
|
|
|
/* } */
|
|
|
|
|
|
|
|
/* free(str); */
|
|
|
|
|
|
|
|
/* // Copy every row following the first into temp */
|
|
|
|
/* for (int i = 2; i <= csv->csv->rows; i++) { */
|
|
|
|
/* char *row = _easycsv_getrow(csv, i); */
|
|
|
|
/* fputs(row, csv->csv->temp); */
|
|
|
|
/* free(row); */
|
|
|
|
/* }*\/ */
|
|
|
|
/* } */
|
|
|
|
|
|
|
|
/* int */
|
|
|
|
/* easycsv_pushcolumnvalue(easycsv *csv, */
|
|
|
|
/* const char *col, */
|
|
|
|
/* const char *val) */
|
|
|
|
/* { */
|
|
|
|
/* /\* ARGS CHECK *\/ */
|
|
|
|
/* if (_easycsv_checkcsvandstring_two(csv->csv, col, val) < 0) */
|
|
|
|
/* return -1; */
|
|
|
|
/* /\* ARGS CHECK *\/ */
|
2018-02-11 18:14:34 +01:00
|
|
|
|
2021-07-16 18:46:36 +02:00
|
|
|
/* int colnum = _easycsv_getcolumn(csv->csv, col); */
|
|
|
|
/* if (colnum < 0) { */
|
|
|
|
/* _easycsv_printerror(csv->csv, EASYCSV_COLNUMFAIL); */
|
|
|
|
/* return -1; */
|
|
|
|
/* } */
|
|
|
|
|
|
|
|
/* /\* Find a free cell under col within csv->csv->cols limits, */
|
|
|
|
/* if there is none, generate a new row *\/ */
|
|
|
|
/* unsigned int row; */
|
|
|
|
|
|
|
|
/* EASYCSV_ERRORMSG temp_error = csv->csv->error; */
|
|
|
|
/* csv->csv->error = EASYCSV_ERROROFF; */
|
|
|
|
/* for (row = 2; row <= csv->csv->cols; row++) */
|
|
|
|
/* if (easycsv_readvalue(csv, colnum, row) != NULL) */
|
|
|
|
/* break; */
|
|
|
|
/* csv->csv->error = temp_error; */
|
|
|
|
|
|
|
|
/* /\* All rows are filled, generate new row *\/ */
|
|
|
|
/* if (row > csv->csv->cols) */
|
|
|
|
/* csv->csv->rows++; */
|
2018-02-22 14:23:23 +01:00
|
|
|
|
2021-07-16 18:46:36 +02:00
|
|
|
/* /\* ROW WILL NOT BE GENERATED \\ row < csv->csv->rows *\/ */
|
|
|
|
|
|
|
|
/* return easycsv_insertvalue(csv, val, colnum, row); */
|
|
|
|
/* } */
|
|
|
|
|
|
|
|
/*** Modifications, delete ***/
|
|
|
|
|
|
|
|
/* int */
|
|
|
|
/* easycsv_deletevalue(easycsv *csv, */
|
|
|
|
/* const unsigned int col, */
|
|
|
|
/* const unsigned int row) */
|
|
|
|
/* { */
|
|
|
|
/* return easycsv_insertvalue(csv, "", col, row); */
|
|
|
|
/* } */
|
|
|
|
|
|
|
|
/* int */
|
|
|
|
/* easycsv_deletecolumnint(easycsv *csv, */
|
|
|
|
/* const unsigned int col) */
|
|
|
|
/* { */
|
|
|
|
/* /\* ARGS CHECK *\/ */
|
|
|
|
/* if (csv == NULL) { */
|
|
|
|
/* _easycsv_printerror(csv->csv, EASYCSV_NULLCSV); */
|
|
|
|
/* return -1; */
|
|
|
|
/* } */
|
|
|
|
|
|
|
|
/* if (col == 0) { */
|
|
|
|
/* _easycsv_printerror(csv->csv, EASYCSV_ZEROCOL); */
|
|
|
|
/* return -1; */
|
|
|
|
/* } */
|
|
|
|
|
|
|
|
/* if (col > csv->csv->cols) { */
|
|
|
|
/* _easycsv_printerror(csv->csv, EASYCSV_OVERMAXCOL); */
|
|
|
|
/* return -1; */
|
|
|
|
/* } */
|
|
|
|
/* /\* END ARGS CHECK *\/ */
|
|
|
|
|
|
|
|
/* for (unsigned int i = 1; i <= csv->csv->cols; i++) { */
|
|
|
|
/* if (easycsv_readvalue(csv, col, i) == NULL) */
|
|
|
|
/* break; */
|
|
|
|
/* if (easycsv_deletevalue(csv, col, i) < 0) */
|
|
|
|
/* return -1; */
|
|
|
|
/* } */
|
2018-02-22 14:23:23 +01:00
|
|
|
|
2021-07-16 18:46:36 +02:00
|
|
|
/* return 0; */
|
|
|
|
/* } */
|
|
|
|
|
|
|
|
/* int */
|
|
|
|
/* easycsv_deletecolumnstr(easycsv *csv, */
|
|
|
|
/* const char *col) */
|
|
|
|
/* { */
|
|
|
|
/* /\* ARGS CHECK *\/ */
|
|
|
|
/* if (_easycsv_checkcsvandstring_one(csv->csv, col) < 0) */
|
|
|
|
/* return -1; */
|
|
|
|
/* /\* END ARGS CHECK *\/ */
|
2018-02-22 14:23:23 +01:00
|
|
|
|
2021-07-16 18:46:36 +02:00
|
|
|
/* int colnum = _easycsv_getcolumn(csv->csv, col); */
|
|
|
|
/* if (colnum < 0) */
|
|
|
|
/* return -1; */
|
2018-02-22 14:23:23 +01:00
|
|
|
|
2021-07-16 18:46:36 +02:00
|
|
|
/* return easycsv_deletecolumnint(csv, colnum); */
|
|
|
|
/* } */
|
|
|
|
|
|
|
|
/* int */
|
|
|
|
/* easycsV_deleterowint(easycsv *csv, */
|
|
|
|
/* const unsigned int row) */
|
|
|
|
/* { */
|
|
|
|
/* return 0; */
|
|
|
|
/* } */
|