All private members are now public members.

* Construction, destruction, print row, print columns all work in READ mode

Signed-off-by: Pradana AUMARS <paumars@courrier.dev>
This commit is contained in:
Pradana AUMARS 2021-07-16 18:46:36 +02:00
parent 1156c9debf
commit d4b53ede9b
10 changed files with 1160 additions and 1255 deletions

View File

@ -1,13 +1,73 @@
#ifndef EASYCSV_H #ifndef EASYCSV_H
#define EASYCSV_H #define EASYCSV_H
#include "../src/_easycsv.h" #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/sendfile.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <time.h>
#include <stdint.h>
/** Public easycsv members */ /*** Generic type definitions for internal use ***/
typedef struct easycsv {
EASYCSV_MODE mode; typedef uint32_t row_t; // max length of 2^32 - 1
_easycsv *_priv; typedef uint32_t column_t;
} easycsv; typedef char* rowstr; // non-const, to free it after usage
/*** Flags ***/
/** Flags to facilitate changing modes during file copying phases */
typedef enum {
EASYCSV_UNKNOWNMODE = 0,
EASYCSV_R,
EASYCSV_W
} EASYCSV_MODE;
/** Flags to parameterise the easycsv_insertvalue */
typedef enum {
EASYCSV_REPLACE, ///< (default) replaces word
EASYCSV_CONCAT, ///< concantates word at the end
EASYCSV_RCONCAT, ///< concantates word from the start
} EASYCSV_VALMODE;
/** Flags to parameterise sorting */
typedef enum {
EASYCSV_ALPHA, ///< sort alphabetically
EASYCSV_RALPHA, ///< sort reverse alphabetically
EASYCSV_NUMER, ///< sort numerically, from lowest value to highest
EASYCSV_RNUMER ///< sort from highest value to lowest
} EASYCSV_SORT;
/** Flags denoting cell type */
typedef enum {
EASYCSV_NONE,
EASYCSV_STRING,
EASYCSV_INT,
EASYCSV_FLOAT,
EASYCSV_UNKNOWNTYPE
} _EASYCSV_TYPE;
/*** Structures ***/
/**
* easycsv:
*
* A CSV file.
*/
typedef struct _easycsv easycsv;
struct _easycsv {
FILE *file; ///< original CSV file
FILE *temp; ///< temporary CSV file for writing
char *fp;
char *tmpfp;
unsigned int rows;
unsigned int cols;
// EASYCSV_ERRORMSG error;
EASYCSV_MODE mode;
};
/*** Constructors ***/ /*** Constructors ***/
@ -21,17 +81,17 @@ easycsv*
easycsv_init(const char*, easycsv_init(const char*,
const EASYCSV_MODE); const EASYCSV_MODE);
/** /* /\** */
* Initialise easycsv structure with a given error message mode /* * Initialise easycsv structure with a given error message mode */
* @param[in] relative path to CSV file /* * @param[in] relative path to CSV file */
* @param[in] easycsv mode /* * @param[in] easycsv mode */
* @param[in] easycsv error message mode /* * @param[in] easycsv error message mode */
* @return pointer to easycsv structure /* * @return pointer to easycsv structure */
*/ /* *\/ */
easycsv* /* easycsv* */
easycsv_init_errormsg(const char*, /* easycsv_init_errormsg(const char*, */
const EASYCSV_MODE, /* const EASYCSV_MODE, */
const EASYCSV_ERRORMSG); /* const EASYCSV_ERRORMSG); */
/** /**
* Destroy easycsv structure * Destroy easycsv structure
@ -40,6 +100,15 @@ easycsv_init_errormsg(const char*,
void void
easycsv_free(easycsv*); easycsv_free(easycsv*);
/*** Error handling ***/
/**
* Get error message
* @return easycsv error message
*/
char*
easycsv_get_error();
/*** Access, find ***/ /*** Access, find ***/
/** /**
@ -51,7 +120,7 @@ easycsv_free(easycsv*);
* @return easycsv error code * @return easycsv error code
*/ */
int int
easycsv_findvalue(const easycsv*, easycsv_find_value(const easycsv*,
const char*, const char*,
unsigned int*, unsigned int*,
unsigned int*); unsigned int*);
@ -63,7 +132,7 @@ easycsv_findvalue(const easycsv*,
* @return number of instances * @return number of instances
*/ */
int int
easycsv_findnumvalue(const easycsv*, easycsv_find_num_value(const easycsv*,
const char*); const char*);
/*** Access, read ***/ /*** Access, read ***/
@ -76,21 +145,21 @@ easycsv_findnumvalue(const easycsv*,
* @return string value of cell, NULL if empty cell * @return string value of cell, NULL if empty cell
*/ */
char* char*
easycsv_readvalue(const easycsv*, easycsv_read_value(const easycsv*,
unsigned int, unsigned int,
unsigned int); unsigned int);
/** /* /\** */
* Read string in a specific cell with named column in row 1 /* * Read string in a specific cell with named column in row 1 */
* @param[in] constant pointer to easycsv structure /* * @param[in] constant pointer to easycsv structure */
* @param[in] row value /* * @param[in] row value */
* @param[in] column number /* * @param[in] column number */
* @return string value of cell, NULL if empty cell /* * @return string value of cell, NULL if empty cell */
*/ /* *\/ */
char* /* char* */
easycsv_readcolumnvalue(const easycsv*, /* easycsv_readcolumnvalue(const easycsv*, */
const char*, /* const char*, */
unsigned int); /* unsigned int); */
/*** Access, print ***/ /*** Access, print ***/
@ -100,7 +169,7 @@ easycsv_readcolumnvalue(const easycsv*,
* @return number of rows * @return number of rows
*/ */
int int
easycsv_printrows(const easycsv*); easycsv_print_rows(const easycsv*);
/** /**
* Return number of columns * Return number of columns
@ -108,7 +177,7 @@ easycsv_printrows(const easycsv*);
* @return number of columns * @return number of columns
*/ */
int int
easycsv_printcolumns(const easycsv*); easycsv_print_columns(const easycsv*);
/*** Modifications, sort ***/ /*** Modifications, sort ***/
@ -138,17 +207,17 @@ easycsv_sortcolumn(easycsv*,
/*** Modifications, insert ***/ /*** Modifications, insert ***/
/** /* /\** */
* Insert row into CSV file /* * Insert row into CSV file */
* @param[in] pointer to easycsv structure /* * @param[in] pointer to easycsv structure */
* @param[in] cell value /* * @param[in] cell value */
* @param[in] row number /* * @param[in] row number */
* @return easycsv error code /* * @return easycsv error code */
*/ /* *\/ */
int /* int */
easycsv_insertrow(easycsv*, /* easycsv_insertrow(easycsv*, */
const char*, /* const char*, */
int); /* int); */
/** /**
* Insert string in a specific cell * Insert string in a specific cell
@ -164,75 +233,75 @@ easycsv_insertvalue(easycsv*,
unsigned int, unsigned int,
unsigned int); unsigned int);
/** /* /\** */
* Insert string in a specific cell with specific mode /* * Insert string in a specific cell with specific mode */
* @param[in] pointer to easycsv structure /* * @param[in] pointer to easycsv structure */
* @param[in] cell value /* * @param[in] cell value */
* @param[in] row number /* * @param[in] row number */
* @param[in] column number /* * @param[in] column number */
* @param[in] easycsv value mode /* * @param[in] easycsv value mode */
* @return easycsv error code /* * @return easycsv error code */
*/ /* *\/ */
int /* int */
easycsv_insertvaluemode(easycsv*, /* easycsv_insertvaluemode(easycsv*, */
const char*, /* const char*, */
unsigned int, /* unsigned int, */
unsigned int, /* unsigned int, */
EASYCSV_VALMODE); /* EASYCSV_VALMODE); */
/** /* /\** */
* Insert string in a specific cell with named column in a given row /* * Insert string in a specific cell with named column in a given row */
* @param[in] pointer to easycsv structure /* * @param[in] pointer to easycsv structure */
* @param[in] cell value /* * @param[in] cell value */
* @param[in] row number /* * @param[in] row number */
* @param[in] column value /* * @param[in] column value */
* @return easycsv error code /* * @return easycsv error code */
*/ /* *\/ */
int /* int */
easycsv_insertcolumnvalue(easycsv*, /* easycsv_insertcolumnvalue(easycsv*, */
const char*, /* const char*, */
unsigned int, /* unsigned int, */
const char*); /* const char*); */
/** /* /\** */
* Insert string in a specific cell with named column in a given row with specific mode /* * Insert string in a specific cell with named column in a given row with specific mode */
* @param[in] pointer to easycsv structure /* * @param[in] pointer to easycsv structure */
* @param[in] cell value /* * @param[in] cell value */
* @param[in] row number /* * @param[in] row number */
* @param[in] column value /* * @param[in] column value */
* @param[in] easycsv value mode /* * @param[in] easycsv value mode */
* @return easycsv error code /* * @return easycsv error code */
*/ /* *\/ */
int /* int */
easycsv_insertcolumnvaluemode(easycsv*, /* easycsv_insertcolumnvaluemode(easycsv*, */
const char*, /* const char*, */
unsigned int, /* unsigned int, */
const char*, /* const char*, */
EASYCSV_VALMODE); /* EASYCSV_VALMODE); */
/*** Modifications, push ***/ /*** Modifications, push ***/
/** /* /\** */
* Create new column on the right-hand side of an existing one /* * Create new column on the right-hand side of an existing one */
* @param[in] pointer to easycsv structure /* * @param[in] pointer to easycsv structure */
* @param[in] column value /* * @param[in] column value */
* @return easycsv error code /* * @return easycsv error code */
*/ /* *\/ */
int /* int */
easycsv_pushcolumn(easycsv*, /* easycsv_pushcolumn(easycsv*, */
const char*); /* const char*); */
/** /* /\** */
* Insert string in a vacant cell under a named column /* * Insert string in a vacant cell under a named column */
* @param[in] pointer to easycsv structure /* * @param[in] pointer to easycsv structure */
* @param[in] column value /* * @param[in] column value */
* @param[in] cell value /* * @param[in] cell value */
* @return easycsv error code /* * @return easycsv error code */
*/ /* *\/ */
int /* int */
easycsv_pushcolumnvalue(easycsv*, /* easycsv_pushcolumnvalue(easycsv*, */
const char*, /* const char*, */
const char*); /* const char*); */
/*** Modifications, delete ***/ /*** Modifications, delete ***/
@ -248,24 +317,24 @@ easycsv_deletevalue(easycsv*,
unsigned int, unsigned int,
unsigned int); unsigned int);
/** /* /\** */
* Delete numbered column /* * Delete numbered column */
* @param[in] pointer to easycsv structure /* * @param[in] pointer to easycsv structure */
* @param[in] column number /* * @param[in] column number */
* @return easycsv error code /* * @return easycsv error code */
*/ /* *\/ */
int /* int */
easycsv_deletecolumnint(easycsv*, /* easycsv_deletecolumnint(easycsv*, */
unsigned int); /* unsigned int); */
/** Delete named column /* /\** Delete named column */
* @param[in] pointer to easycsv structure /* * @param[in] pointer to easycsv structure */
* @param[in] column value /* * @param[in] column value */
* @return easycsv error code /* * @return easycsv error code */
*/ /* *\/ */
int /* int */
easycsv_deletecolumnstr(easycsv*, /* easycsv_deletecolumnstr(easycsv*, */
const char*); /* const char*); */
/* Delete numered row */ /* Delete numered row */
@ -273,24 +342,24 @@ easycsv_deletecolumnstr(easycsv*,
/*** Modifications, append ***/ /*** Modifications, append ***/
/** /* /\** */
* Append two CSV files /* * Append two CSV files */
* @param[in] destination CSV file /* * @param[in] destination CSV file */
* @param[in] source CSV file /* * @param[in] source CSV file */
* @return easycsv error code /* * @return easycsv error code */
*/ /* *\/ */
int /* int */
easycsv_appendcsv(easycsv*, /* easycsv_appendcsv(easycsv*, */
easycsv*); /* easycsv*); */
/*** Modifications, miscellenaeous ***/ /*** Modifications, miscellenaeous ***/
/** /* /\** */
* Compress a CSV file /* * Compress a CSV file */
* @param[in] pointer to easycsv structure /* * @param[in] pointer to easycsv structure */
* @return easycsv error code /* * @return easycsv error code */
*/ /* *\/ */
int /* int */
easycsv_compress(easycsv*); /* easycsv_compress(easycsv*); */
#endif /* EASYCSV_H */ #endif /* EASYCSV_H */

View File

@ -1,6 +1,8 @@
lib_LTLIBRARIES = libeasycsv.la lib_LTLIBRARIES = libeasycsv.la
libeasycsv_la_SOURCES = \ libeasycsv_la_SOURCES = \
_easycsv.c \ easycsv.c \
_easycsv.h \ easycsv_error.h \
easycsv.c easycsv_error.c \
easycsv_p.h \
easycsv_p.c
include_HEADERS = ../include/easycsv.h include_HEADERS = ../include/easycsv.h

View File

@ -1,506 +0,0 @@
#include "_easycsv.h"
/* (Constructor) Initialise _easycsv */
_easycsv*
_easycsv_priv_init(const char *fp,
const EASYCSV_MODE mode,
const EASYCSV_ERRORMSG error)
{
_easycsv *_priv = malloc(sizeof(_easycsv));
_priv->file = NULL;
_priv->temp = NULL;
_priv->fp = NULL;
_priv->tmpfp = NULL;
_priv->rows = 0;
_priv->cols = 0;
#ifdef EASYCSV_DEBUG
_priv->start = 0;
#endif
_priv->error = error;
/* Open file according to mode */
switch (mode) {
case EASYCSV_R: {
_priv->file = fopen(fp, "r");
break;
}
case EASYCSV_W: {
_priv->file = fopen(fp, "w");
break;
}
default: {
_easycsv_printerror(_priv, EASYCSV_UNKNOWNIOMODE);
_easycsv_priv_free(_priv);
return NULL;
}
}
if (_priv->file == NULL)
{
_easycsv_printerror(_priv, EASYCSV_OPENFAIL);
_easycsv_priv_free(_priv);
return NULL;
}
size_t stfp = strlen(fp);
/* Allocate memory for char* */
_priv->fp = malloc(stfp + 1); // + 1 for null
strcpy(_priv->fp, fp);
/* Calculate rows and cols if file exists */
if (access(_priv->fp, F_OK) == 0) {
_priv->rows = _easycsv_rows(_priv, mode);
_priv->cols = _easycsv_columns(_priv, mode);
}
if (mode == EASYCSV_W) {
/* csv->tmpfp = malloc(16 + stfp + 1); */
/* strncpy(csv->tmpfp, prefix, 16); */
/* strncat(csv->tmpfp, fp, stfp); */
do {
/* Write to temporary file */
unsigned int i = 1;
char buffer[21] = "/tmp/easycsv-"; // 13 char, 3 for digits, 4 for .csv, 1 for NULL
if (i < 100)
strncat(buffer, "0", 1);
if (i < 10)
strncat(buffer, "0", 1);
sprintf(buffer + strlen(buffer), "%i", i);
strcat(buffer, ".csv");
if (access(buffer, F_OK) < 0) {
i++;
}
else {
_priv->tmpfp = malloc(21);
strncpy(_priv->tmpfp, buffer, 21);
break;
}
} while (1);
_priv->temp = fopen(_priv->tmpfp, "w");
if (_priv->temp == NULL) {
_easycsv_printerror(_priv, EASYCSV_OPENFAIL);
_easycsv_priv_free(_priv);
return NULL;
}
/*
#ifdef EASYCSV_DEBUG
printf("[%i] easycsv_debug: temp file %s opened\n", clock() - csv->start, csv->tmpfp);
#endif*/
/*
if (freopen(csv->fp, csv->mode, csv->file) == NULL) {
fprintf(stderr, "easycsv: failed to set temporary file %s to %s mode\n", csv->tmpfp, csv->mode);
return NULL;
}
if (freopen(csv->tmpfp, csv->mode, csv->temp) == NULL) {
fprintf(stderr, "easycsv: failed to set temporary file %s to %s mode\n", csv->tmpfp, csv->mode);
return NULL;
}
*/
}
return _priv;
}
/* (Destructor) Free _easycsv memory */
void
_easycsv_priv_free(_easycsv *_priv)
{
/* ARGS CHECK */
if (_priv == NULL)
return;
/* ARGS CHECK */
if (_priv->file != NULL)
fclose(_priv->file);
if (_priv->temp != NULL)
fclose(_priv->temp);
if (_priv->fp != NULL)
free(_priv->fp);
if (_priv->tmpfp != NULL)
free(_priv->tmpfp);
free(_priv);
}
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;
}
int
_easycsv_rows(_easycsv *_priv,
const EASYCSV_MODE mode)
{
// no need to check _priv for NULL
if (_easycsv_rewind(_priv, mode) < 0)
return -1;
int rows = 1;
char c;
/* Go through each character in the file and count the number of \n
in it */
while ((c = fgetc(_priv->file)) != EOF) {
if (c == '\n') rows++;
}
return rows;
}
int
_easycsv_columns(_easycsv *_priv,
const EASYCSV_MODE mode)
{
// no need to check _priv for NULL
/* Prepare it for reading */
if (_easycsv_rewind(_priv, mode) < 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(_priv->file)) != '\n') {
if (c == ',') col++;
}
return col;
}
char*
_easycsv_getrow(const _easycsv *csv,
const unsigned int row)
{
/* ARGS CHECK */
if (csv == NULL) {
_easycsv_printerror(csv, EASYCSV_NULLCSV);
return NULL;
}
if (row > csv->rows) {
_easycsv_printerror(csv, EASYCSV_OVERMAXROW);
return NULL;
}
if (row == 0) {
_easycsv_printerror(csv, EASYCSV_ZEROROW);
return NULL;
}
/* END ARGS CHECK */
/* Allocate memory */
char *str = malloc(BUFSIZ);
/* Set file pointer to start */
rewind(csv->file);
for (int i = 1; i < row; i++)
{
/* skip until row is reached */
fscanf(csv->file, "%*[^\n]\n", NULL);
}
/* Grab the row and store it in str */
fscanf(csv->file, "%s\n", str);
// printf("row: %s\n", str);
return str;
}
int
_easycsv_rewind(_easycsv *_priv,
const EASYCSV_MODE mode)
{
/* Check if empty file */
if (fscanf(_priv->file, "\n") == EOF) {
_easycsv_printerror(_priv, EASYCSV_EMPTYCSV);
return -1;
}
/* Check if file is readable */
if (mode != EASYCSV_R) {
_easycsv_printerror(_priv, EASYCSV_UNREADABLE);
return -1;
}
/* Set file pointer to the start */
rewind(_priv->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;
}
char*
_easycsv_setcharptovalue(const _easycsv *_priv,
const char *rowstr,
const unsigned int col)
{
char *pch = rowstr;
for (unsigned int i = 1; i < col; i++) {
pch = strchr(rowstr, ',');
if (pch == NULL) {
_easycsv_printerror(_priv, EASYCSV_NULLPTR);
return NULL;
}
pch++;
}
return pch;
}
void
_easycsv_printerror(const _easycsv *_priv,
const EASYCSV_ERROR error)
{
switch (_priv->error) {
case EASYCSV_ERROROFF: return;
case EASYCSV_ERRORSTDOUT: _easycsv_geterror(_priv, error, stdout); break;
case EASYCSV_ERRORSTDERR:
default: _easycsv_geterror(_priv, error, stderr); return;
}
}
void
_easycsv_geterror(const _easycsv *_priv,
const EASYCSV_ERROR error,
FILE *fs)
{
#ifdef EASYCSV_DEBUG
fprintf(stderr, "[%i] ", clock() - _priv->start);
#endif
fputs("easycsv: ", fs);
switch (error) {
/* Generic errors */
case EASYCSV_NOERROR: fputs("no error", fs); break;
case EASYCSV_NULLCSV: fputs("easycsv pointer is NULL", fs); break;
case EASYCSV_NULLPTR: fputs("pointer is NULL", fs); break;
case EASYCSV_EMPTYSTRING: fputs("string is empty", fs); break;
case EASYCSV_EMPTYVALUE: fputs("value in CSV file is empty", fs); break;
case EASYCSV_OVERMAXROW: fprintf(fs, "int exceeds row limit %i", _priv->rows); break;
case EASYCSV_OVERMAXCOL: fprintf(fs, "int exceeds column limit %i", _priv->cols); break;
case EASYCSV_ZEROROW: fputs("parameterised row number is zero", fs); break;
case EASYCSV_ZEROCOL: fputs("parameterised column number is zero", fs); break;
/* File input/output errors */
case EASYCSV_UNKNOWNIOMODE: fputs("unknown file IO mode", fs); break;
case EASYCSV_OPENFAIL: fputs("failed to open file", fs); break;
case EASYCSV_REOPENFAIL: fputs("failed to reopen file", fs); break;
case EASYCSV_EMPTYCSV: fputs("CSV file is empty", fs); break;
case EASYCSV_UNWRITABLE: fputs("CSV file is not in a writable mode", fs); break;
case EASYCSV_UNREADABLE: fputs("CSV file is not in a readable mode", fs); break;
case EASYCSV_UPDATEFAIL: fputs("CSV file has failed to update", fs); break;
case EASYCSV_UPDATETEMPFAIL: fputs("failed to update temp CSV file", fs); break;
case EASYCSV_FILEPTRFAIL: fputs("failed to move FILE pointer", fs); break;
/* Non-existant elements */
case EASYCSV_ROWNOTEXIST: fputs("given row does not exist", fs); break;
case EASYCSV_COLNOTEXIST: fputs("given column does not exist", fs); break;
/* User-facing failure */
case EASYCSV_PUSHCOLFAIL: fputs("failed to push value under column", fs); break;
case EASYCSV_COLNUMFAIL: fputs("failed to determine the column number of a value in the first row", fs); break;
default: fputs("unknown error, easycsv* is possibly NULL", fs); break;
}
if (_priv->fp != NULL)
fprintf(fs, " in %s", _priv->fp);
fputc('\n', fs);
}
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;
}

View File

@ -1,178 +0,0 @@
#ifndef _EASYCSV
#define _EASYCSV
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/sendfile.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <time.h>
#include <stdint.h>
#include "easycsv_error.h"
/* Generic type definitions for internal use */
typedef uint32_t row_t; // max length of 2^32 - 1
typedef uint32_t column_t;
typedef char* rowstr; // non-const, to free it after usage
/** Flags for error messages */
typedef enum {
EASYCSV_ERRORSTDERR = 0,
EASYCSV_ERROROFF,
EASYCSV_ERRORSTDOUT
} EASYCSV_ERRORMSG;
/** Flags to facilitate changing modes during file copying phases */
typedef enum {
EASYCSV_UNKNOWNMODE = 0,
EASYCSV_R,
EASYCSV_W
} EASYCSV_MODE;
/** Flags to parameterise the easycsv_insertvalue */
typedef enum {
EASYCSV_REPLACE, ///< (default) replaces word
EASYCSV_CONCAT, ///< concantates word at the end
EASYCSV_RCONCAT, ///< concantates word from the start
} EASYCSV_VALMODE;
/** Flags to parameterise sorting */
typedef enum {
EASYCSV_ALPHA, ///< sort alphabetically
EASYCSV_RALPHA, ///< sort reverse alphabetically
EASYCSV_NUMER, ///< sort numerically, from lowest value to highest
EASYCSV_RNUMER ///< sort from highest value to lowest
} EASYCSV_SORT;
/* Flags denoting cell type */
typedef enum {
EASYCSV_NONE,
EASYCSV_STRING,
EASYCSV_INT,
EASYCSV_FLOAT,
EASYCSV_UNKNOWNTYPE
} _EASYCSV_TYPE;
/* Private easycsv members */
typedef struct _easycsv {
FILE *file; // original CSV file
FILE *temp; // temporary CSV file for writing
char *fp;
char *tmpfp;
unsigned int rows;
unsigned int cols;
EASYCSV_ERRORMSG error;
#ifdef EASYCSV_DEBUG
clock_t start;
#endif
} _easycsv;
/* (Constructor) Initialise _easycsv */
_easycsv*
_easycsv_priv_init(const char*,
const EASYCSV_MODE,
const EASYCSV_ERRORMSG);
/* (Destructor) Free _easycsv memory */
void
_easycsv_priv_free(_easycsv*);
/* Verifies mode of file */
// int _easycsv_checkmode(struct easycsv*, const char);
/* Copies data from temp FILE to file FILE */
int
_easycsv_update(_easycsv*);
/* Rewind easycsv, checks for readability */
int
_easycsv_rewind(_easycsv*,
const EASYCSV_MODE);
/* Returns string of a specific row,
includes the '\n' character as well! */
char*
_easycsv_getrow(const _easycsv*,
const unsigned int);
/* Return column number of a named column */
int
_easycsv_getcolumn(const _easycsv*,
const char*);
/* Verifies the type of the value (eg: string or int) */
_EASYCSV_TYPE
_easycsv_checktype(const _easycsv*,
const int,
const int);
/* Verifies if there is a value or not */
int
_easycsv_checkifvalue(const _easycsv*,
const int,
const int);
/* Grab const char* in row */
char*
_easycsv_getvalueinrow(const _easycsv*,
const char*,
const unsigned int);
/* Returns char pointer to start of value in rowstr */
char*
_easycsv_setcharptovalue(const _easycsv*,
const char*,
const unsigned int);
/* Insert value in row in specific column */
char*
_easycsv_insertvalueinrow(const _easycsv*,
const char*,
const char*,
const unsigned int);
/* Calculate rows */
int
_easycsv_rows(_easycsv*,
const EASYCSV_MODE);
/* Calculate columns*/
int
_easycsv_columns(_easycsv*,
const EASYCSV_MODE);
void
_easycsv_printerror(const _easycsv*,
const EASYCSV_ERROR);
/* Print error from _easycsv struct in stderr */
void
_easycsv_geterror(const _easycsv*,
const EASYCSV_ERROR,
FILE*);
/* Check if easycsv* and const char* are NULL */
int
_easycsv_checkcsvandstring_one(const _easycsv*,
const char*);
/* Check if easycsv* and two const char* are NULL*/
int
_easycsv_checkcsvandstring_two(const _easycsv*,
const char*,
const char*);
/* Verifies if the string is not NULL or empty, returns 0 on success and -1 on failure */
// int _easycsv_checkstring(const char*);
/* Verifies if easycsv is not NULL or unallocated */
// int _easycsv_checkeasycsv(const struct easycsv*);
/* Verifies if int is */
// int _easycsv_checkunsigned(const int);
#endif

View File

@ -1,504 +1,559 @@
#include "_easycsv.h" #include "easycsv_p.h"
#include "../include/easycsv.h" #include "easycsv_error.h"
// typedef struct _easycsv _easycsv; /*** Constructors ***/
// _easycsv* _easycsv_priv_init(const char *fp, const EASYCSV_MODE mode, const EASYCSV_ERRORMSG error);
/* CONSTRUCTORS AND DESTRUCTORS */
/* (Constructor) Initialise easycsv */
easycsv* easycsv*
easycsv_init(const char *fp, easycsv_init(const char *fp,
const EASYCSV_MODE mode) EASYCSV_MODE mode)
{ {
return easycsv_init_errormsg(fp, mode, EASYCSV_ERRORSTDERR); easycsv *csv = NULL;
} int csv_exist = -1;
/* (Constructor) Initialise easycsv with error message option */ csv = malloc(sizeof(easycsv));
easycsv*
easycsv_init_errormsg(const char *fp,
const EASYCSV_MODE mode,
const EASYCSV_ERRORMSG error)
{
#ifdef EASYCSV_DEBUG
csv->start = clock();
#endif
easycsv *csv = malloc(sizeof(easycsv));
csv->mode = mode; csv->mode = mode;
csv->_priv = _easycsv_priv_init(fp, mode, error); csv->file = NULL;
csv->temp = NULL;
csv->fp = NULL;
csv->tmpfp = NULL;
csv->rows = 0;
csv->cols = 0;
if (csv->_priv == NULL) { /* Open file according to mode */
switch (csv->mode) {
case EASYCSV_R:
csv->file = fopen(fp, "r");
break;
case EASYCSV_W:
csv->file = fopen(fp, "w");
break;
default:
easycsv_error(EASYCSV_UNKNOWNIOMODE, NULL);
easycsv_free(csv); easycsv_free(csv);
return NULL; return NULL;
} }
if (csv->file == NULL) {
easycsv_error(EASYCSV_OPENFAIL, NULL);
easycsv_free(csv);
return NULL;
}
csv_exist = access(csv->fp, F_OK);
size_t stfp = strlen(fp);
/* Allocate memory for char* */
csv->fp = malloc(stfp + 1); // + 1 for null
strcpy(csv->fp, fp);
/* Calculate rows and cols if file exists */
if (csv_exist) {
csv->rows = easycsv_rows(csv);
csv->cols = easycsv_columns(csv);
}
if (mode == EASYCSV_W) {
do {
/* Write to temporary file */
unsigned int i = 1;
char buffer[21] = "/tmp/easycsv-"; // 13 char, 3 for digits, 4 for .csv, 1 for NULL
if (i < 100)
strncat(buffer, "0", 1);
if (i < 10)
strncat(buffer, "0", 1);
sprintf(buffer + strlen(buffer), "%i", i);
strcat(buffer, ".csv");
if (access(buffer, F_OK) < 0) {
i++;
}
else {
csv->tmpfp = malloc(21);
strncpy(csv->tmpfp, buffer, 21);
break;
}
} while (1);
csv->temp = fopen(csv->tmpfp, "w");
if (csv->temp == NULL) {
easycsv_error(EASYCSV_OPENFAIL, NULL);
easycsv_free(csv);
return NULL;
}
}
return csv; return csv;
} }
/* (Destructor) Free easycsv memory */
void void
easycsv_free(easycsv *csv) easycsv_free(easycsv *csv)
{ {
/* ARGS CHECK */ if (csv == NULL) free(csv);
if (csv == NULL)
return;
/* END ARGS CHECK */
_easycsv_priv_free(csv->_priv);
free(csv);
} }
/* GENERIC ALGORITHMS */ /*** Acces, find ***/
/* READ VALUE */ /*** Acces, read ***/
char*
easycsv_readvalue(const easycsv *csv, /* char* */
const unsigned int col, /* easycsv_readvalue(const easycsv *csv, */
const unsigned int row) /* const unsigned int col, */
/* const unsigned int row) */
/* { */
/* /\* ARGS CHECK *\/ */
/* if (row == 0) { */
/* _easycsv_printerror(csv->csv, EASYCSV_ZEROROW); */
/* _easycsv_printerror(csv->csv, EASYCSV_READVALUEFAIL); */
/* return NULL; */
/* } */
/* if (col == 0) { */
/* _easycsv_printerror(csv->csv, EASYCSV_ZEROCOL); */
/* _easycsv_printerror(csv->csv, EASYCSV_READVALUEFAIL); */
/* return NULL; */
/* } */
/* /\* END ARGS CHECK *\/ */
/* char *str = _easycsv_getrow(csv->csv, row); */
/* if (str == NULL) { */
/* _easycsv_printerror(csv->csv, EASYCSV_ROWNOTEXIST); */
/* _easycsv_printerror(csv->csv, EASYCSV_READVALUEFAIL); */
/* return NULL; */
/* } */
/* char *val = _easycsv_getvalueinrow(csv->csv, str, col); */
/* if (val == NULL) { */
/* _easycsv_printerror(csv->csv, EASYCSV_READVALUEFAIL); */
/* return NULL; */
/* } */
/* return val; */
/* } */
/* 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 *\/ */
/* int i = _easycsv_getcolumn(csv->csv, col); */
/* if (i < 1) { */
/* _easycsv_printerror(csv->csv, EASYCSV_COLNUMFAIL); */
/* return NULL; */
/* } */
/* return easycsv_readvalue(csv, i, row); */
/* } */
/*** Acces, print ***/
int
easycsv_print_rows(const easycsv *csv)
{ {
/* ARGS CHECK */ return csv->rows;
if (row == 0) {
_easycsv_printerror(csv->_priv, EASYCSV_ZEROROW);
_easycsv_printerror(csv->_priv, EASYCSV_READVALUEFAIL);
return NULL;
}
if (col == 0) {
_easycsv_printerror(csv->_priv, EASYCSV_ZEROCOL);
_easycsv_printerror(csv->_priv, EASYCSV_READVALUEFAIL);
return NULL;
}
/* END ARGS CHECK */
char *str = _easycsv_getrow(csv->_priv, row);
if (str == NULL) {
_easycsv_printerror(csv->_priv, EASYCSV_ROWNOTEXIST);
_easycsv_printerror(csv->_priv, EASYCSV_READVALUEFAIL);
return NULL;
}
char *val = _easycsv_getvalueinrow(csv->_priv, str, col);
if (val == NULL) {
_easycsv_printerror(csv->_priv, EASYCSV_READVALUEFAIL);
return NULL;
}
return val;
}
char*
easycsv_readcolumnvalue(const easycsv *csv,
const char *col,
const unsigned int row)
{
/* ARGS CHECK */
if (_easycsv_checkcsvandstring_one(csv->_priv, col) < 0)
return NULL;
if (row > csv->_priv->rows) {
_easycsv_printerror(csv->_priv, EASYCSV_OVERMAXROW);
return NULL;
}
/* END ARGS CHECK */
int i = _easycsv_getcolumn(csv->_priv, col);
if (i < 1) {
_easycsv_printerror(csv->_priv, EASYCSV_COLNUMFAIL);
return NULL;
}
return easycsv_readvalue(csv, i, row);
} }
int int
easycsv_printrows(const easycsv *csv) easycsv_print_columns(const easycsv *csv)
{ {
return csv->_priv->rows; return csv->cols;
} }
int /*** Modifications, sort ***/
easycsv_printcolumns(const easycsv *csv)
{
return csv->_priv->cols;
}
/* INSERT VALUE -- AT SPECIFIC ROW AND COLUMN */ /*** Modifications, insert ***/
int /* int */
easycsv_insertvalue(easycsv *csv, /* easycsv_insertvalue(easycsv *csv, */
const char *val, /* const char *val, */
const unsigned int col, /* const unsigned int col, */
const unsigned int row) /* const unsigned int row) */
{ /* { */
return easycsv_insertvaluemode(csv, val, col, row, EASYCSV_REPLACE); /* return easycsv_insertvaluemode(csv, val, col, row, EASYCSV_REPLACE); */
} /* } */
int /* int */
easycsv_insertvaluemode(easycsv *csv, /* easycsv_insertvaluemode(easycsv *csv, */
const char *val, /* const char *val, */
const unsigned int col, /* const unsigned int col, */
const unsigned int row, /* const unsigned int row, */
const EASYCSV_VALMODE valmode) /* const EASYCSV_VALMODE valmode) */
{ /* { */
/* ARGS CHECK */ /* /\* ARGS CHECK *\/ */
if (_easycsv_checkcsvandstring_one(csv->_priv, val) < 0) /* if (_easycsv_checkcsvandstring_one(csv->csv, val) < 0) */
return -1; /* return -1; */
if (col == 0) { /* if (col == 0) { */
_easycsv_printerror(csv->_priv, EASYCSV_ZEROCOL); /* _easycsv_printerror(csv->csv, EASYCSV_ZEROCOL); */
return -1; /* return -1; */
} /* } */
if (row == 0) { /* if (row == 0) { */
_easycsv_printerror(csv->_priv, EASYCSV_ZEROROW); /* _easycsv_printerror(csv->csv, EASYCSV_ZEROROW); */
return -1; /* return -1; */
} /* } */
/* END ARGS CHECK */ /* /\* END ARGS CHECK *\/ */
/* row extends max */ /* /\* row extends max *\/ */
if (row > csv->_priv->rows) { /* if (row > csv->csv->rows) { */
} /* } */
char *rowstr = _easycsv_getrow(csv->_priv, row); /* char *rowstr = _easycsv_getrow(csv->csv, row); */
if (rowstr == NULL) /* if (rowstr == NULL) */
return -1; /* return -1; */
size_t rowstrst = strlen(rowstr); /* size_t rowstrst = strlen(rowstr); */
size_t st = 0; /* size_t st = 0; */
size_t commas = 0; /* size_t commas = 0; */
char *pch = NULL; /* char *pch = NULL; */
char *newstr = NULL; /* char *newstr = NULL; */
/* column is within limit */ /* /\* column is within limit *\/ */
if (col <= csv->_priv->cols) { /* if (col <= csv->csv->cols) { */
/* Set pch to start of value in rowstr */ /* /\* Set pch to start of value in rowstr *\/ */
pch = _easycsv_setcharptovalue(csv->_priv, rowstr, col); /* pch = _easycsv_setcharptovalue(csv->csv, rowstr, col); */
if (pch == NULL) /* if (pch == NULL) */
return -1; /* return -1; */
/* Calculate size of existing value */ /* /\* Calculate size of existing value *\/ */
st = strcspn(pch, ","); /* st = strcspn(pch, ","); */
newstr = malloc(rowstrst - st + strlen(val) + 1); /* newstr = malloc(rowstrst - st + strlen(val) + 1); */
/* Copy char to newstr before value (pch) */ /* /\* Copy char to newstr before value (pch) *\/ */
strncpy(newstr, rowstr, pch - rowstr); /* strncpy(newstr, rowstr, pch - rowstr); */
/* Insert value */ /* /\* Insert value *\/ */
if (st != 0) { /* Occupied cell */ /* if (st != 0) { /\* Occupied cell *\/ */
switch (valmode) { /* switch (valmode) { */
case EASYCSV_CONCAT: { /* case EASYCSV_CONCAT: { */
strncat(newstr, pch, st); /* strncat(newstr, pch, st); */
strcat(newstr, val); /* strcat(newstr, val); */
break; /* break; */
} /* } */
case EASYCSV_RCONCAT: { /* case EASYCSV_RCONCAT: { */
strcat(newstr, val); /* strcat(newstr, val); */
strncat(newstr, pch, st); /* strncat(newstr, pch, st); */
break; /* break; */
} /* } */
case EASYCSV_REPLACE: /* case EASYCSV_REPLACE: */
default: { /* default: { */
strcat(newstr, val); /* strcat(newstr, val); */
break; /* break; */
} /* } */
} /* } */
} /* } */
else { /* Empty cell */ /* else { /\* Empty cell *\/ */
strcat(newstr, val); /* strcat(newstr, val); */
} /* } */
/* Set pch to after value */ /* /\* Set pch to after value *\/ */
pch = strchr(rowstr, ','); /* pch = strchr(rowstr, ','); */
/* Calculate length of rest of string */ /* /\* Calculate length of rest of string *\/ */
st = strlen(pch); /* st = strlen(pch); */
/* Concentate rest of string including NULL char */ /* /\* Concentate rest of string including NULL char *\/ */
strcat(newstr, pch); /* strcat(newstr, pch); */
} /* } */
else { /* else { */
commas = col - csv->_priv->cols; /* commas = col - csv->csv->cols; */
csv->_priv->cols = col; /* csv->csv->cols = col; */
newstr = malloc(rowstrst + commas + strlen(val) + 1); /* newstr = malloc(rowstrst + commas + strlen(val) + 1); */
strncpy(newstr, rowstr, rowstrst); /* strncpy(newstr, rowstr, rowstrst); */
for (size_t i = 0; i < commas; i++) /* for (size_t i = 0; i < commas; i++) */
strncat(newstr, ",", 1); /* strncat(newstr, ",", 1); */
strcat(newstr, val); // append \0 /* strcat(newstr, val); // append \0 */
} /* } */
/* UPDATE CSV */ /* /\* UPDATE CSV *\/ */
char *str = NULL; /* char *str = NULL; */
/* Row within limits */ /* /\* Row within limits *\/ */
if (row <= csv->_priv->rows) { /* if (row <= csv->csv->rows) { */
/* Copy rows before newstr in csv to temp */ /* /\* Copy rows before newstr in csv to temp *\/ */
for (unsigned int i = 1; i < row; i++) { /* for (unsigned int i = 1; i < row; i++) { */
str = _easycsv_getrow(csv->_priv, i); /* str = _easycsv_getrow(csv->csv, i); */
if (col > csv->_priv->cols) { /* if (col > csv->csv->cols) { */
str = realloc(str, strlen(str) + commas + 1); /* str = realloc(str, strlen(str) + commas + 1); */
for (size_t j = 0; j < commas; j++) { /* for (size_t j = 0; j < commas; j++) { */
strncat(str, ",", 1); /* strncat(str, ",", 1); */
} /* } */
} /* } */
fputs(str, csv->_priv->temp); /* fputs(str, csv->csv->temp); */
free(str); /* free(str); */
} /* } */
/* Print newstr into temp */ /* /\* Print newstr into temp *\/ */
fputs(newstr, csv->_priv->temp); /* fputs(newstr, csv->csv->temp); */
/* Copy the rest of rows */ /* /\* Copy the rest of rows *\/ */
for (unsigned int i = row + 1; i <= csv->_priv->rows; i++) { /* for (unsigned int i = row + 1; i <= csv->csv->rows; i++) { */
str = _easycsv_getrow(csv, i); /* str = _easycsv_getrow(csv, i); */
if (col > csv->_priv->cols) { /* if (col > csv->csv->cols) { */
str = realloc(str, strlen(str) + commas + 1); /* str = realloc(str, strlen(str) + commas + 1); */
for (size_t j = 0; j < commas; j++) { /* for (size_t j = 0; j < commas; j++) { */
strncat(str, ",", 1); /* strncat(str, ",", 1); */
} /* } */
} /* } */
fputs(str, csv->_priv->temp); /* fputs(str, csv->csv->temp); */
free(str); /* free(str); */
} /* } */
} /* } */
else { /* Row exceeds limit */ /* else { /\* Row exceeds limit *\/ */
/* Copy entire file */ /* /\* Copy entire file *\/ */
char buf[BUFSIZ]; /* char buf[BUFSIZ]; */
size_t size; /* size_t size; */
while (size = fread(buf, 1, BUFSIZ, csv->_priv->file)) { /* while (size = fread(buf, 1, BUFSIZ, csv->csv->file)) { */
fwrite(buf, 1, size, csv->_priv->temp); /* fwrite(buf, 1, size, csv->csv->temp); */
} /* } */
/* Print out commas on rows before newstr */ /* /\* Print out commas on rows before newstr *\/ */
for (size_t i = csv->_priv->rows; i < row; i++) { /* for (size_t i = csv->csv->rows; i < row; i++) { */
for (size_t j = 0; j < csv->_priv->cols; j++) /* for (size_t j = 0; j < csv->csv->cols; j++) */
fputc(',', csv->_priv->temp); /* fputc(',', csv->csv->temp); */
fputc('\n', csv->_priv->temp); /* fputc('\n', csv->csv->temp); */
} /* } */
fputs(newstr, csv->_priv->temp); /* fputs(newstr, csv->csv->temp); */
} /* } */
/* Update csv */ /* /\* Update csv *\/ */
if (_easycsv_update(csv->_priv) < 0) /* if (_easycsv_update(csv->csv) < 0) */
return -1; /* return -1; */
/* END UPDATE CSV */ /* /\* END UPDATE CSV *\/ */
free(rowstr); // including pch /* free(rowstr); // including pch */
free(newstr); /* free(newstr); */
return 0; /* return 0; */
} /* } */
int /* int */
easycsv_insertcolumnvalue(easycsv *csv, /* easycsv_insertcolumnvalue(easycsv *csv, */
const char *col, /* const char *col, */
const unsigned int row, /* const unsigned int row, */
const char *val) /* const char *val) */
{ /* { */
return easycsv_insertcolumnvaluemode(csv, col, row, val, EASYCSV_REPLACE); /* return easycsv_insertcolumnvaluemode(csv, col, row, val, EASYCSV_REPLACE); */
} /* } */
int /* int */
easycsv_insertcolumnvaluemode(easycsv *csv, /* easycsv_insertcolumnvaluemode(easycsv *csv, */
const char *col, /* const char *col, */
const unsigned int row, /* const unsigned int row, */
const char *val, /* const char *val, */
const EASYCSV_VALMODE valmode) /* const EASYCSV_VALMODE valmode) */
{ /* { */
/* ARGS CHECK */ /* /\* ARGS CHECK *\/ */
if (_easycsv_checkcsvandstring_two(csv->_priv, col, val) < 0) /* if (_easycsv_checkcsvandstring_two(csv->csv, col, val) < 0) */
return -1; /* return -1; */
if (row == 0) { /* if (row == 0) { */
_easycsv_printerror(csv->_priv, EASYCSV_ZEROROW); /* _easycsv_printerror(csv->csv, EASYCSV_ZEROROW); */
return -1; /* return -1; */
} /* } */
/* END ARGS CHECK */ /* /\* END ARGS CHECK *\/ */
int colnum = _easycsv_getcolumn(csv->_priv, col); /* int colnum = _easycsv_getcolumn(csv->csv, col); */
if (colnum < 0) { /* if (colnum < 0) { */
_easycsv_printerror(csv->_priv, EASYCSV_COLNUMFAIL); /* _easycsv_printerror(csv->csv, EASYCSV_COLNUMFAIL); */
return -1; /* return -1; */
} /* } */
return easycsv_insertvaluemode(csv, val, colnum, row, valmode); /* return easycsv_insertvaluemode(csv, val, colnum, row, valmode); */
} /* } */
/* PUSH VALUE */ /*** Modifications, push ***/
int /* int */
easycsv_pushcolumn(easycsv *csv, /* easycsv_pushcolumn(easycsv *csv, */
const char *col) /* const char *col) */
{ /* { */
/* ARGS CHECK */ /* /\* ARGS CHECK *\/ */
if (_easycsv_checkcsvandstring_one(csv->_priv, col) < 0) /* if (_easycsv_checkcsvandstring_one(csv->csv, col) < 0) */
return -1; /* return -1; */
/* END ARGS CHECK */ /* /\* END ARGS CHECK *\/ */
if (csv->mode == EASYCSV_R) { /* if (csv->mode == EASYCSV_R) { */
_easycsv_printerror(csv->_priv, EASYCSV_UNWRITABLE); /* _easycsv_printerror(csv->csv, EASYCSV_UNWRITABLE); */
return -1; /* return -1; */
} /* } */
if ((csv->mode == EASYCSV_W) && (access(csv->_priv->fp, F_OK) < 0)) { /* if ((csv->mode == EASYCSV_W) && (access(csv->csv->fp, F_OK) < 0)) { */
/* If the file doesn't exist, just put the col /* /\* If the file doesn't exist, just put the col */
in the file */ /* in the file *\/ */
if (fputs(col, csv->_priv->file) < 0) { /* if (fputs(col, csv->csv->file) < 0) { */
_easycsv_printerror(csv->_priv, EASYCSV_PUSHCOLFAIL); /* _easycsv_printerror(csv->csv, EASYCSV_PUSHCOLFAIL); */
return -1; /* return -1; */
} /* } */
return 0; /* return 0; */
} /* } */
/* Grab first row */ /* /\* Grab first row *\/ */
char *str = _easycsv_getrow(csv->_priv, 1); /* char *str = _easycsv_getrow(csv->csv, 1); */
char *pch = NULL; /* char *pch = NULL; */
size_t i; /* size_t i; */
/* Find empty column in first row */ /* /\* Find empty column in first row *\/ */
for (i = 1; i < csv->_priv->cols; i++) { /* for (i = 1; i < csv->csv->cols; i++) { */
if (strcspn(pch, ",") == 0) /* if (strcspn(pch, ",") == 0) */
break; /* break; */
pch = strchr(str, ','); /* pch = strchr(str, ','); */
pch++; /* pch++; */
} /* } */
/* No empty columns in first row */ /* /\* No empty columns in first row *\/ */
if (i == csv->_priv->cols) /* if (i == csv->csv->cols) */
i++; /* i++; */
return easycsv_insertvalue(csv, col, i, 1); /* return easycsv_insertvalue(csv, col, i, 1); */
/*size_t ststr = strlen(str); /* /\*size_t ststr = strlen(str); */
size_t stcol = strlen(col); /* size_t stcol = strlen(col); */
realloc(str, ststr + stcol + 2); // 1 for null and 1 for comma /* realloc(str, ststr + stcol + 2); // 1 for null and 1 for comma */
strncat(str + ststr, ",", 1); /* strncat(str + ststr, ",", 1); */
strncat(str + ststr + 1, col, stcol); /* strncat(str + ststr + 1, col, stcol); */
// Put str in temp file /* // Put str in temp file */
if (fputs(str, csv->_priv->temp) < 0) { /* if (fputs(str, csv->csv->temp) < 0) { */
_easycsv_printerror(csv->_priv, EASYCSV_PUSHCOLFAIL); /* _easycsv_printerror(csv->csv, EASYCSV_PUSHCOLFAIL); */
return -1; /* return -1; */
} /* } */
free(str); /* free(str); */
// Copy every row following the first into temp /* // Copy every row following the first into temp */
for (int i = 2; i <= csv->_priv->rows; i++) { /* for (int i = 2; i <= csv->csv->rows; i++) { */
char *row = _easycsv_getrow(csv, i); /* char *row = _easycsv_getrow(csv, i); */
fputs(row, csv->_priv->temp); /* fputs(row, csv->csv->temp); */
free(row); /* free(row); */
}*/ /* }*\/ */
} /* } */
int /* int */
easycsv_pushcolumnvalue(easycsv *csv, /* easycsv_pushcolumnvalue(easycsv *csv, */
const char *col, /* const char *col, */
const char *val) /* const char *val) */
{ /* { */
/* ARGS CHECK */ /* /\* ARGS CHECK *\/ */
if (_easycsv_checkcsvandstring_two(csv->_priv, col, val) < 0) /* if (_easycsv_checkcsvandstring_two(csv->csv, col, val) < 0) */
return -1; /* return -1; */
/* ARGS CHECK */ /* /\* ARGS CHECK *\/ */
int colnum = _easycsv_getcolumn(csv->_priv, col); /* int colnum = _easycsv_getcolumn(csv->csv, col); */
if (colnum < 0) { /* if (colnum < 0) { */
_easycsv_printerror(csv->_priv, EASYCSV_COLNUMFAIL); /* _easycsv_printerror(csv->csv, EASYCSV_COLNUMFAIL); */
return -1; /* return -1; */
} /* } */
/* Find a free cell under col within csv->_priv->cols limits, /* /\* Find a free cell under col within csv->csv->cols limits, */
if there is none, generate a new row */ /* if there is none, generate a new row *\/ */
unsigned int row; /* unsigned int row; */
EASYCSV_ERRORMSG temp_error = csv->_priv->error; /* EASYCSV_ERRORMSG temp_error = csv->csv->error; */
csv->_priv->error = EASYCSV_ERROROFF; /* csv->csv->error = EASYCSV_ERROROFF; */
for (row = 2; row <= csv->_priv->cols; row++) /* for (row = 2; row <= csv->csv->cols; row++) */
if (easycsv_readvalue(csv, colnum, row) != NULL) /* if (easycsv_readvalue(csv, colnum, row) != NULL) */
break; /* break; */
csv->_priv->error = temp_error; /* csv->csv->error = temp_error; */
/* All rows are filled, generate new row */ /* /\* All rows are filled, generate new row *\/ */
if (row > csv->_priv->cols) /* if (row > csv->csv->cols) */
csv->_priv->rows++; /* csv->csv->rows++; */
/* ROW WILL NOT BE GENERATED \\ row < csv->_priv->rows */ /* /\* ROW WILL NOT BE GENERATED \\ row < csv->csv->rows *\/ */
return easycsv_insertvalue(csv, val, colnum, row); /* return easycsv_insertvalue(csv, val, colnum, row); */
} /* } */
/* DELETE VALUES */ /*** Modifications, delete ***/
int /* int */
easycsv_deletevalue(easycsv *csv, /* easycsv_deletevalue(easycsv *csv, */
const unsigned int col, /* const unsigned int col, */
const unsigned int row) /* const unsigned int row) */
{ /* { */
return easycsv_insertvalue(csv, "", col, row); /* return easycsv_insertvalue(csv, "", col, row); */
} /* } */
int /* int */
easycsv_deletecolumnint(easycsv *csv, /* easycsv_deletecolumnint(easycsv *csv, */
const unsigned int col) /* const unsigned int col) */
{ /* { */
/* ARGS CHECK */ /* /\* ARGS CHECK *\/ */
if (csv == NULL) { /* if (csv == NULL) { */
_easycsv_printerror(csv->_priv, EASYCSV_NULLCSV); /* _easycsv_printerror(csv->csv, EASYCSV_NULLCSV); */
return -1; /* return -1; */
} /* } */
if (col == 0) { /* if (col == 0) { */
_easycsv_printerror(csv->_priv, EASYCSV_ZEROCOL); /* _easycsv_printerror(csv->csv, EASYCSV_ZEROCOL); */
return -1; /* return -1; */
} /* } */
if (col > csv->_priv->cols) { /* if (col > csv->csv->cols) { */
_easycsv_printerror(csv->_priv, EASYCSV_OVERMAXCOL); /* _easycsv_printerror(csv->csv, EASYCSV_OVERMAXCOL); */
return -1; /* return -1; */
} /* } */
/* END ARGS CHECK */ /* /\* END ARGS CHECK *\/ */
for (unsigned int i = 1; i <= csv->_priv->cols; i++) { /* for (unsigned int i = 1; i <= csv->csv->cols; i++) { */
if (easycsv_readvalue(csv, col, i) == NULL) /* if (easycsv_readvalue(csv, col, i) == NULL) */
break; /* break; */
if (easycsv_deletevalue(csv, col, i) < 0) /* if (easycsv_deletevalue(csv, col, i) < 0) */
return -1; /* return -1; */
} /* } */
return 0; /* return 0; */
} /* } */
int /* int */
easycsv_deletecolumnstr(easycsv *csv, /* easycsv_deletecolumnstr(easycsv *csv, */
const char *col) /* const char *col) */
{ /* { */
/* ARGS CHECK */ /* /\* ARGS CHECK *\/ */
if (_easycsv_checkcsvandstring_one(csv->_priv, col) < 0) /* if (_easycsv_checkcsvandstring_one(csv->csv, col) < 0) */
return -1; /* return -1; */
/* END ARGS CHECK */ /* /\* END ARGS CHECK *\/ */
int colnum = _easycsv_getcolumn(csv->_priv, col); /* int colnum = _easycsv_getcolumn(csv->csv, col); */
if (colnum < 0) /* if (colnum < 0) */
return -1; /* return -1; */
return easycsv_deletecolumnint(csv, colnum); /* return easycsv_deletecolumnint(csv, colnum); */
} /* } */
int /* int */
easycsV_deleterowint(easycsv *csv, /* easycsV_deleterowint(easycsv *csv, */
const unsigned int row) /* const unsigned int row) */
{ /* { */
return 0; /* return 0; */
} /* } */

55
src/easycsv_error.c Normal file
View File

@ -0,0 +1,55 @@
#include <limits.h>
#include "../include/easycsv.h"
#include "easycsv_error.h"
/* void */
/* _easycsv_printerror(const _easycsv *_priv, */
/* const EASYCSV_ERROR error) */
/* { */
/* switch (_priv->error) { */
/* case EASYCSV_ERROROFF: return; */
/* case EASYCSV_ERRORSTDOUT: _easycsv_geterror(_priv, error, stdout); break; */
/* case EASYCSV_ERRORSTDERR: */
/* default: _easycsv_geterror(_priv, error, stderr); return; */
/* } */
/* } */
static char s_error_msg[SCHAR_MAX];
void
easycsv_error(EASYCSV_ERROR error,
const char *error_msg)
{
switch (error) {
case EASYCSV_NOERROR: sprintf(s_error_msg, "no error"); return;
case EASYCSV_NULLCSV: sprintf(s_error_msg, "easycsv pointer is NULL"); return;
case EASYCSV_NULLPTR: sprintf(s_error_msg, "pointer is NULL"); return;
case EASYCSV_EMPTYSTRING: sprintf(s_error_msg, "string is empty"); return;
case EASYCSV_EMPTYVALUE: sprintf(s_error_msg, "value in CSV file is empty"); return;
case EASYCSV_OVERMAXROW: sprintf(s_error_msg, "int exceeds row limit of %s", error_msg); return;
case EASYCSV_OVERMAXCOL: sprintf(s_error_msg, "int exceeds column limit of %s", error_msg); return;
case EASYCSV_ZEROROW: sprintf(s_error_msg, "parameterised row number is zero"); return;
case EASYCSV_ZEROCOL: sprintf(s_error_msg, "parameterised column number is zero"); return;
case EASYCSV_UNKNOWNIOMODE: sprintf(s_error_msg, "unknown file IO mode"); return;
case EASYCSV_OPENFAIL: sprintf(s_error_msg, "failed to open file"); return;
case EASYCSV_REOPENFAIL: sprintf(s_error_msg, "failed to reopen file"); return;
case EASYCSV_EMPTYCSV: sprintf(s_error_msg, "CSV file is empty"); return;
case EASYCSV_UNWRITABLE: sprintf(s_error_msg, "CSV file is not in a writable mode"); return;
case EASYCSV_UNREADABLE: sprintf(s_error_msg, "CSV file is not in a readable mode"); return;
case EASYCSV_UPDATEFAIL: sprintf(s_error_msg, "CSV file has failed to update"); return;
case EASYCSV_UPDATETEMPFAIL: sprintf(s_error_msg, "failed to update temp CSV file"); return;
case EASYCSV_FILEPTRFAIL: sprintf(s_error_msg, "failed to move FILE pointer"); return;
case EASYCSV_ROWNOTEXIST: sprintf(s_error_msg, "given row does not exist"); return;
case EASYCSV_COLNOTEXIST: sprintf(s_error_msg, "given column does not exist"); return;
case EASYCSV_PUSHCOLFAIL: sprintf(s_error_msg, "failed to push value under column"); return;
case EASYCSV_COLNUMFAIL: sprintf(s_error_msg, "failed to determine the column number of a value in the first row"); return;
default: sprintf(s_error_msg, "unknown error"); return;
}
}
char*
easycsv_get_error()
{
return s_error_msg;
}

View File

@ -1,9 +1,8 @@
#ifndef EASYCSV_ERROR #ifndef EASYCSV_ERROR_H
#define EASYCSV_ERROR #define EASYCSV_ERROR_H
/* Error flags */ /* Error flags */
typedef enum { typedef enum EASYCSV_ERROR {
/* Generic errors */ /* Generic errors */
EASYCSV_NOERROR, // no error EASYCSV_NOERROR, // no error
EASYCSV_NULLCSV, // easycsv* is NULL EASYCSV_NULLCSV, // easycsv* is NULL
@ -36,4 +35,8 @@ typedef enum {
EASYCSV_READVALUEFAIL, // read value fail EASYCSV_READVALUEFAIL, // read value fail
} EASYCSV_ERROR; } EASYCSV_ERROR;
void
easycsv_error(EASYCSV_ERROR,
const char*);
#endif #endif

300
src/easycsv_p.c Normal file
View File

@ -0,0 +1,300 @@
#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;
}
/* char* */
/* _easycsv_getrow(const _easycsv *csv, */
/* const unsigned int row) */
/* { */
/* /\* ARGS CHECK *\/ */
/* if (csv == NULL) { */
/* _easycsv_printerror(csv, EASYCSV_NULLCSV); */
/* return NULL; */
/* } */
/* if (row > csv->rows) { */
/* _easycsv_printerror(csv, EASYCSV_OVERMAXROW); */
/* return NULL; */
/* } */
/* if (row == 0) { */
/* _easycsv_printerror(csv, EASYCSV_ZEROROW); */
/* return NULL; */
/* } */
/* /\* END ARGS CHECK *\/ */
/* /\* Allocate memory *\/ */
/* char *str = malloc(BUFSIZ); */
/* /\* Set file pointer to start *\/ */
/* rewind(csv->file); */
/* for (int i = 1; i < row; i++) */
/* { */
/* /\* skip until row is reached *\/ */
/* fscanf(csv->file, "%*[^\n]\n", NULL); */
/* } */
/* /\* Grab the row and store it in str *\/ */
/* fscanf(csv->file, "%s\n", str); */
/* // printf("row: %s\n", str); */
/* return str; */
/* } */
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; */
/* } */
/* char* */
/* _easycsv_setcharptovalue(const _easycsv *_priv, */
/* const char *rowstr, */
/* const unsigned int col) */
/* { */
/* char *pch = rowstr; */
/* for (unsigned int i = 1; i < col; i++) { */
/* pch = strchr(rowstr, ','); */
/* if (pch == NULL) { */
/* _easycsv_printerror(_priv, EASYCSV_NULLPTR); */
/* return NULL; */
/* } */
/* pch++; */
/* } */
/* return pch; */
/* } */
/* 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; */
/* } */

105
src/easycsv_p.h Normal file
View File

@ -0,0 +1,105 @@
#ifndef EASYCSV_P_H
#define EASYCSV_P_H
#include "../include/easycsv.h"
/*** Accès ***/
/* /\** */
/* * Returns string of a specific row, including '\n' character */
/* * @param[in] const pointer to _easycsv structure */
/* * @param[in] row number */
/* * @return string of row, NULL if error or none */
/* *\/ */
/* char* */
/* _easycsv_getrow(const _easycsv*, */
/* unsigned int); */
/* /\** */
/* * Returns column number of a named column *\/ */
/* int */
/* _easycsv_getcolumn(const _easycsv*, */
/* const char*); */
/* /\* Verifies the type of the value (eg: string or int) *\/ */
/* _EASYCSV_TYPE */
/* _easycsv_checktype(const _easycsv*, */
/* const int, */
/* const int); */
/* /\* Verifies if there is a value or not *\/ */
/* int */
/* _easycsv_checkifvalue(const _easycsv*, */
/* const int, */
/* const int); */
/* /\* Grab const char* in row *\/ */
/* char* */
/* _easycsv_getvalueinrow(const _easycsv*, */
/* const char*, */
/* const unsigned int); */
/* /\* Returns char pointer to start of value in rowstr *\/ */
/* char* */
/* _easycsv_setcharptovalue(const _easycsv*, */
/* const char*, */
/* const unsigned int); */
/* /\* Insert value in row in specific column *\/ */
/* char* */
/* _easycsv_insertvalueinrow(const _easycsv*, */
/* const char*, */
/* const char*, */
/* const unsigned int); */
/**
* Calculate rows of easycsv
* @param[in] const pointer to easycsv structure
* @return number of rows in easycsv
*/
int
easycsv_rows(const easycsv*);
/**
* Calculate columns of easycsv
* @param[in] const pointer to easycsv structure
* @return number of columns in easycsv
*/
int
easycsv_columns(const easycsv*);
/**
* Rewind easycsv FILE pointer
* @param[in] const pointer to easycsv structure
* @return 0 if no error, -1 if fail
*/
int
easycsv_rewind(const easycsv*);
/* /\* Check if easycsv* and const char* are NULL *\/ */
/* int */
/* _easycsv_checkcsvandstring_one(const _easycsv*, */
/* const char*); */
/* /\* Check if easycsv* and two const char* are NULL*\/ */
/* int */
/* _easycsv_checkcsvandstring_two(const _easycsv*, */
/* const char*, */
/* const char*); */
/* Verifies if the string is not NULL or empty, returns 0 on success and -1 on failure */
// int _easycsv_checkstring(const char*);
/* Verifies if easycsv is not NULL or unallocated */
// int _easycsv_checkeasycsv(const struct easycsv*);
/* Verifies if int is */
// int _easycsv_checkunsigned(const int);
/*** Modifications ***/
/* Copies data from temp FILE to file FILE */
/* int */
/* _easycsv_update(_easycsv*); */
#endif

View File

@ -57,29 +57,29 @@ easycsv_constructor_suite(void)
return s; return s;
} }
START_TEST(test_easycsv_printcolumns) START_TEST(test_easycsv_print_columns)
{ {
easycsv *csv = easycsv_init(SAMPLE1_PATH, EASYCSV_R); easycsv *csv = easycsv_init(SAMPLE1_PATH, EASYCSV_R);
ck_assert_int_eq(easycsv_printcolumns(csv), 3); ck_assert_int_eq(easycsv_print_columns(csv), 3);
easycsv_free(csv); easycsv_free(csv);
} }
START_TEST(test_easycsv_printrows) START_TEST(test_easycsv_print_rows)
{ {
easycsv *csv = easycsv_init(SAMPLE1_PATH, EASYCSV_R); easycsv *csv = easycsv_init(SAMPLE1_PATH, EASYCSV_R);
ck_assert_int_eq(easycsv_printrows(csv), 5); ck_assert_int_eq(easycsv_print_rows(csv), 5);
easycsv_free(csv); easycsv_free(csv);
} }
START_TEST(test_easycsv_readcolumnvalue) /* START_TEST(test_easycsv_readcolumnvalue) */
{ /* { */
easycsv *csv = easycsv_init(SAMPLE1_PATH, EASYCSV_R); /* easycsv *csv = easycsv_init(SAMPLE1_PATH, EASYCSV_R); */
ck_assert_str_eq(easycsv_readcolumnvalue(csv, "TEST1", 1), "FILEPATHA1"); /* ck_assert_str_eq(easycsv_readcolumnvalue(csv, "TEST1", 1), "FILEPATHA1"); */
ck_assert_str_eq(easycsv_readcolumnvalue(csv, "TEST1", 2), "FILEPATHB1"); /* ck_assert_str_eq(easycsv_readcolumnvalue(csv, "TEST1", 2), "FILEPATHB1"); */
ck_assert_str_eq(easycsv_readcolumnvalue(csv, "TEST1", 3), NULL); /* ck_assert_str_eq(easycsv_readcolumnvalue(csv, "TEST1", 3), NULL); */
ck_assert_str_eq(easycsv_readcolumnvalue(csv, "TEST2", 1), "FILEPATHA2"); /* ck_assert_str_eq(easycsv_readcolumnvalue(csv, "TEST2", 1), "FILEPATHA2"); */
easycsv_free(csv); /* easycsv_free(csv); */
} /* } */
Suite* Suite*
easycsv_access_suite(void) easycsv_access_suite(void)
@ -87,14 +87,14 @@ easycsv_access_suite(void)
Suite *s; Suite *s;
TCase *tc_find, *tc_read, *tc_print; TCase *tc_find, *tc_read, *tc_print;
s = suite_create ("access"); s = suite_create ("access");
tc_read = tcase_create ("read"); /* tc_read = tcase_create ("read"); */
tcase_add_test(tc_read, test_easycsv_readcolumnvalue); /* tcase_add_test(tc_read, test_easycsv_readcolumnvalue); */
tc_print = tcase_create ("print"); tc_print = tcase_create ("print");
tcase_add_test(tc_print, test_easycsv_printcolumns); tcase_add_test(tc_print, test_easycsv_print_columns);
tcase_add_test(tc_print, test_easycsv_printrows); tcase_add_test(tc_print, test_easycsv_print_rows);
suite_add_tcase(s, tc_read); /* suite_add_tcase(s, tc_read); */
suite_add_tcase(s, tc_print); suite_add_tcase(s, tc_print);
return s; return s;