diff --git a/include/easycsv.h b/include/easycsv.h index 022ba7b..a46dbc4 100644 --- a/include/easycsv.h +++ b/include/easycsv.h @@ -1,13 +1,73 @@ #ifndef EASYCSV_H #define EASYCSV_H -#include "../src/_easycsv.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include -/** Public easycsv members */ -typedef struct easycsv { - EASYCSV_MODE mode; - _easycsv *_priv; -} easycsv; +/*** 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 ***/ + +/** 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 ***/ @@ -21,17 +81,17 @@ easycsv* easycsv_init(const char*, const EASYCSV_MODE); -/** - * Initialise easycsv structure with a given error message mode - * @param[in] relative path to CSV file - * @param[in] easycsv mode - * @param[in] easycsv error message mode - * @return pointer to easycsv structure - */ -easycsv* -easycsv_init_errormsg(const char*, - const EASYCSV_MODE, - const EASYCSV_ERRORMSG); +/* /\** */ +/* * Initialise easycsv structure with a given error message mode */ +/* * @param[in] relative path to CSV file */ +/* * @param[in] easycsv mode */ +/* * @param[in] easycsv error message mode */ +/* * @return pointer to easycsv structure */ +/* *\/ */ +/* easycsv* */ +/* easycsv_init_errormsg(const char*, */ +/* const EASYCSV_MODE, */ +/* const EASYCSV_ERRORMSG); */ /** * Destroy easycsv structure @@ -40,6 +100,15 @@ easycsv_init_errormsg(const char*, void easycsv_free(easycsv*); +/*** Error handling ***/ + +/** + * Get error message + * @return easycsv error message + */ +char* +easycsv_get_error(); + /*** Access, find ***/ /** @@ -51,7 +120,7 @@ easycsv_free(easycsv*); * @return easycsv error code */ int -easycsv_findvalue(const easycsv*, +easycsv_find_value(const easycsv*, const char*, unsigned int*, unsigned int*); @@ -63,7 +132,7 @@ easycsv_findvalue(const easycsv*, * @return number of instances */ int -easycsv_findnumvalue(const easycsv*, +easycsv_find_num_value(const easycsv*, const char*); /*** Access, read ***/ @@ -76,21 +145,21 @@ easycsv_findnumvalue(const easycsv*, * @return string value of cell, NULL if empty cell */ char* -easycsv_readvalue(const easycsv*, +easycsv_read_value(const easycsv*, unsigned int, unsigned int); -/** - * Read string in a specific cell with named column in row 1 - * @param[in] constant pointer to easycsv structure - * @param[in] row value - * @param[in] column number - * @return string value of cell, NULL if empty cell - */ -char* -easycsv_readcolumnvalue(const easycsv*, - const char*, - unsigned int); +/* /\** */ +/* * Read string in a specific cell with named column in row 1 */ +/* * @param[in] constant pointer to easycsv structure */ +/* * @param[in] row value */ +/* * @param[in] column number */ +/* * @return string value of cell, NULL if empty cell */ +/* *\/ */ +/* char* */ +/* easycsv_readcolumnvalue(const easycsv*, */ +/* const char*, */ +/* unsigned int); */ /*** Access, print ***/ @@ -100,7 +169,7 @@ easycsv_readcolumnvalue(const easycsv*, * @return number of rows */ int -easycsv_printrows(const easycsv*); +easycsv_print_rows(const easycsv*); /** * Return number of columns @@ -108,7 +177,7 @@ easycsv_printrows(const easycsv*); * @return number of columns */ int -easycsv_printcolumns(const easycsv*); +easycsv_print_columns(const easycsv*); /*** Modifications, sort ***/ @@ -138,17 +207,17 @@ easycsv_sortcolumn(easycsv*, /*** Modifications, insert ***/ -/** - * Insert row into CSV file - * @param[in] pointer to easycsv structure - * @param[in] cell value - * @param[in] row number - * @return easycsv error code - */ -int -easycsv_insertrow(easycsv*, - const char*, - int); +/* /\** */ +/* * Insert row into CSV file */ +/* * @param[in] pointer to easycsv structure */ +/* * @param[in] cell value */ +/* * @param[in] row number */ +/* * @return easycsv error code */ +/* *\/ */ +/* int */ +/* easycsv_insertrow(easycsv*, */ +/* const char*, */ +/* int); */ /** * Insert string in a specific cell @@ -164,75 +233,75 @@ easycsv_insertvalue(easycsv*, unsigned int, unsigned int); -/** - * Insert string in a specific cell with specific mode - * @param[in] pointer to easycsv structure - * @param[in] cell value - * @param[in] row number - * @param[in] column number - * @param[in] easycsv value mode - * @return easycsv error code - */ -int -easycsv_insertvaluemode(easycsv*, - const char*, - unsigned int, - unsigned int, - EASYCSV_VALMODE); +/* /\** */ +/* * Insert string in a specific cell with specific mode */ +/* * @param[in] pointer to easycsv structure */ +/* * @param[in] cell value */ +/* * @param[in] row number */ +/* * @param[in] column number */ +/* * @param[in] easycsv value mode */ +/* * @return easycsv error code */ +/* *\/ */ +/* int */ +/* easycsv_insertvaluemode(easycsv*, */ +/* const char*, */ +/* unsigned int, */ +/* unsigned int, */ +/* EASYCSV_VALMODE); */ -/** - * Insert string in a specific cell with named column in a given row - * @param[in] pointer to easycsv structure - * @param[in] cell value - * @param[in] row number - * @param[in] column value - * @return easycsv error code - */ -int -easycsv_insertcolumnvalue(easycsv*, - const char*, - unsigned int, - const char*); +/* /\** */ +/* * Insert string in a specific cell with named column in a given row */ +/* * @param[in] pointer to easycsv structure */ +/* * @param[in] cell value */ +/* * @param[in] row number */ +/* * @param[in] column value */ +/* * @return easycsv error code */ +/* *\/ */ +/* int */ +/* easycsv_insertcolumnvalue(easycsv*, */ +/* const char*, */ +/* unsigned int, */ +/* const char*); */ -/** - * Insert string in a specific cell with named column in a given row with specific mode - * @param[in] pointer to easycsv structure - * @param[in] cell value - * @param[in] row number - * @param[in] column value - * @param[in] easycsv value mode - * @return easycsv error code - */ -int -easycsv_insertcolumnvaluemode(easycsv*, - const char*, - unsigned int, - const char*, - EASYCSV_VALMODE); +/* /\** */ +/* * Insert string in a specific cell with named column in a given row with specific mode */ +/* * @param[in] pointer to easycsv structure */ +/* * @param[in] cell value */ +/* * @param[in] row number */ +/* * @param[in] column value */ +/* * @param[in] easycsv value mode */ +/* * @return easycsv error code */ +/* *\/ */ +/* int */ +/* easycsv_insertcolumnvaluemode(easycsv*, */ +/* const char*, */ +/* unsigned int, */ +/* const char*, */ +/* EASYCSV_VALMODE); */ /*** Modifications, push ***/ -/** - * Create new column on the right-hand side of an existing one - * @param[in] pointer to easycsv structure - * @param[in] column value - * @return easycsv error code - */ -int -easycsv_pushcolumn(easycsv*, - const char*); +/* /\** */ +/* * Create new column on the right-hand side of an existing one */ +/* * @param[in] pointer to easycsv structure */ +/* * @param[in] column value */ +/* * @return easycsv error code */ +/* *\/ */ +/* int */ +/* easycsv_pushcolumn(easycsv*, */ +/* const char*); */ -/** - * Insert string in a vacant cell under a named column - * @param[in] pointer to easycsv structure - * @param[in] column value - * @param[in] cell value - * @return easycsv error code - */ -int -easycsv_pushcolumnvalue(easycsv*, - const char*, - const char*); +/* /\** */ +/* * Insert string in a vacant cell under a named column */ +/* * @param[in] pointer to easycsv structure */ +/* * @param[in] column value */ +/* * @param[in] cell value */ +/* * @return easycsv error code */ +/* *\/ */ +/* int */ +/* easycsv_pushcolumnvalue(easycsv*, */ +/* const char*, */ +/* const char*); */ /*** Modifications, delete ***/ @@ -248,24 +317,24 @@ easycsv_deletevalue(easycsv*, unsigned int, unsigned int); -/** - * Delete numbered column - * @param[in] pointer to easycsv structure - * @param[in] column number - * @return easycsv error code - */ -int -easycsv_deletecolumnint(easycsv*, - unsigned int); +/* /\** */ +/* * Delete numbered column */ +/* * @param[in] pointer to easycsv structure */ +/* * @param[in] column number */ +/* * @return easycsv error code */ +/* *\/ */ +/* int */ +/* easycsv_deletecolumnint(easycsv*, */ +/* unsigned int); */ -/** Delete named column - * @param[in] pointer to easycsv structure - * @param[in] column value - * @return easycsv error code - */ -int -easycsv_deletecolumnstr(easycsv*, - const char*); +/* /\** Delete named column */ +/* * @param[in] pointer to easycsv structure */ +/* * @param[in] column value */ +/* * @return easycsv error code */ +/* *\/ */ +/* int */ +/* easycsv_deletecolumnstr(easycsv*, */ +/* const char*); */ /* Delete numered row */ @@ -273,24 +342,24 @@ easycsv_deletecolumnstr(easycsv*, /*** Modifications, append ***/ -/** - * Append two CSV files - * @param[in] destination CSV file - * @param[in] source CSV file - * @return easycsv error code - */ -int -easycsv_appendcsv(easycsv*, - easycsv*); +/* /\** */ +/* * Append two CSV files */ +/* * @param[in] destination CSV file */ +/* * @param[in] source CSV file */ +/* * @return easycsv error code */ +/* *\/ */ +/* int */ +/* easycsv_appendcsv(easycsv*, */ +/* easycsv*); */ /*** Modifications, miscellenaeous ***/ -/** - * Compress a CSV file - * @param[in] pointer to easycsv structure - * @return easycsv error code - */ -int -easycsv_compress(easycsv*); +/* /\** */ +/* * Compress a CSV file */ +/* * @param[in] pointer to easycsv structure */ +/* * @return easycsv error code */ +/* *\/ */ +/* int */ +/* easycsv_compress(easycsv*); */ #endif /* EASYCSV_H */ diff --git a/src/Makefile.am b/src/Makefile.am index e7a2f0d..b348054 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,6 +1,8 @@ lib_LTLIBRARIES = libeasycsv.la libeasycsv_la_SOURCES = \ - _easycsv.c \ - _easycsv.h \ - easycsv.c + easycsv.c \ + easycsv_error.h \ + easycsv_error.c \ + easycsv_p.h \ + easycsv_p.c include_HEADERS = ../include/easycsv.h diff --git a/src/_easycsv.c b/src/_easycsv.c deleted file mode 100644 index 454a17e..0000000 --- a/src/_easycsv.c +++ /dev/null @@ -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; -} diff --git a/src/_easycsv.h b/src/_easycsv.h deleted file mode 100644 index f42895e..0000000 --- a/src/_easycsv.h +++ /dev/null @@ -1,178 +0,0 @@ -#ifndef _EASYCSV -#define _EASYCSV - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#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 diff --git a/src/easycsv.c b/src/easycsv.c index e323e14..ec717da 100644 --- a/src/easycsv.c +++ b/src/easycsv.c @@ -1,504 +1,559 @@ -#include "_easycsv.h" -#include "../include/easycsv.h" +#include "easycsv_p.h" +#include "easycsv_error.h" -// typedef struct _easycsv _easycsv; -// _easycsv* _easycsv_priv_init(const char *fp, const EASYCSV_MODE mode, const EASYCSV_ERRORMSG error); +/*** Constructors ***/ -/* CONSTRUCTORS AND DESTRUCTORS */ - -/* (Constructor) Initialise easycsv */ easycsv* easycsv_init(const char *fp, - const EASYCSV_MODE mode) + EASYCSV_MODE mode) { - return easycsv_init_errormsg(fp, mode, EASYCSV_ERRORSTDERR); -} - -/* (Constructor) Initialise easycsv with error message option */ -easycsv* -easycsv_init_errormsg(const char *fp, - const EASYCSV_MODE mode, - const EASYCSV_ERRORMSG error) -{ -#ifdef EASYCSV_DEBUG - csv->start = clock(); -#endif + easycsv *csv = NULL; + int csv_exist = -1; + + csv = malloc(sizeof(easycsv)); - easycsv *csv = malloc(sizeof(easycsv)); 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); 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; } -/* (Destructor) Free easycsv memory */ void easycsv_free(easycsv *csv) { - /* ARGS CHECK */ - if (csv == NULL) - return; - /* END ARGS CHECK */ - - _easycsv_priv_free(csv->_priv); - free(csv); + if (csv == NULL) free(csv); } -/* GENERIC ALGORITHMS */ +/*** Acces, find ***/ -/* READ VALUE */ -char* -easycsv_readvalue(const easycsv *csv, - const unsigned int col, - const unsigned int row) +/*** Acces, read ***/ + +/* char* */ +/* easycsv_readvalue(const easycsv *csv, */ +/* 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 */ - 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); + return csv->rows; } int -easycsv_printrows(const easycsv *csv) +easycsv_print_columns(const easycsv *csv) { - return csv->_priv->rows; + return csv->cols; } -int -easycsv_printcolumns(const easycsv *csv) -{ - return csv->_priv->cols; -} +/*** Modifications, sort ***/ -/* INSERT VALUE -- AT SPECIFIC ROW AND COLUMN */ +/*** 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_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->_priv, val) < 0) - return -1; +/* 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->_priv, EASYCSV_ZEROCOL); - return -1; - } +/* if (col == 0) { */ +/* _easycsv_printerror(csv->csv, EASYCSV_ZEROCOL); */ +/* return -1; */ +/* } */ - if (row == 0) { - _easycsv_printerror(csv->_priv, EASYCSV_ZEROROW); - return -1; - } - /* END ARGS CHECK */ +/* if (row == 0) { */ +/* _easycsv_printerror(csv->csv, EASYCSV_ZEROROW); */ +/* return -1; */ +/* } */ +/* /\* END ARGS CHECK *\/ */ - /* row extends max */ - if (row > csv->_priv->rows) { - } +/* /\* row extends max *\/ */ +/* if (row > csv->csv->rows) { */ +/* } */ - char *rowstr = _easycsv_getrow(csv->_priv, row); - if (rowstr == NULL) - return -1; +/* char *rowstr = _easycsv_getrow(csv->csv, row); */ +/* if (rowstr == NULL) */ +/* return -1; */ - size_t rowstrst = strlen(rowstr); - size_t st = 0; - size_t commas = 0; - char *pch = NULL; - char *newstr = NULL; +/* 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->_priv->cols) { +/* /\* column is within limit *\/ */ +/* if (col <= csv->csv->cols) { */ - /* Set pch to start of value in rowstr */ - pch = _easycsv_setcharptovalue(csv->_priv, rowstr, col); - if (pch == NULL) - return -1; +/* /\* 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, ","); +/* /\* Calculate size of existing value *\/ */ +/* st = strcspn(pch, ","); */ - newstr = malloc(rowstrst - st + strlen(val) + 1); +/* newstr = malloc(rowstrst - st + strlen(val) + 1); */ - /* Copy char to newstr before value (pch) */ - strncpy(newstr, rowstr, pch - rowstr); +/* /\* 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); - } +/* /\* 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, ','); +/* /\* Set pch to after value *\/ */ +/* pch = strchr(rowstr, ','); */ - /* Calculate length of rest of string */ - st = strlen(pch); +/* /\* Calculate length of rest of string *\/ */ +/* st = strlen(pch); */ - /* Concentate rest of string including NULL char */ - strcat(newstr, pch); - } - else { - commas = col - csv->_priv->cols; - csv->_priv->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 - } +/* /\* 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 */ +/* } */ - /* UPDATE CSV */ +/* /\* UPDATE CSV *\/ */ - char *str = NULL; +/* char *str = NULL; */ - /* Row within limits */ - if (row <= csv->_priv->rows) { +/* /\* 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->_priv, i); - if (col > csv->_priv->cols) { - str = realloc(str, strlen(str) + commas + 1); - for (size_t j = 0; j < commas; j++) { - strncat(str, ",", 1); - } - } - fputs(str, csv->_priv->temp); +/* /\* 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); - } +/* free(str); */ +/* } */ - /* Print newstr into temp */ - fputs(newstr, csv->_priv->temp); +/* /\* Print newstr into temp *\/ */ +/* fputs(newstr, csv->csv->temp); */ - /* Copy the rest of rows */ - for (unsigned int i = row + 1; i <= csv->_priv->rows; i++) { - str = _easycsv_getrow(csv, i); - if (col > csv->_priv->cols) { - str = realloc(str, strlen(str) + commas + 1); - for (size_t j = 0; j < commas; j++) { - strncat(str, ",", 1); - } - } - fputs(str, csv->_priv->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 */ +/* free(str); */ +/* } */ +/* } */ +/* else { /\* Row exceeds limit *\/ */ - /* Copy entire file */ - char buf[BUFSIZ]; - size_t size; - while (size = fread(buf, 1, BUFSIZ, csv->_priv->file)) { - fwrite(buf, 1, size, csv->_priv->temp); - } +/* /\* 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->_priv->rows; i < row; i++) { - for (size_t j = 0; j < csv->_priv->cols; j++) - fputc(',', csv->_priv->temp); - fputc('\n', csv->_priv->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->_priv->temp); - } +/* fputs(newstr, csv->csv->temp); */ +/* } */ - /* Update csv */ - if (_easycsv_update(csv->_priv) < 0) - return -1; +/* /\* Update csv *\/ */ +/* if (_easycsv_update(csv->csv) < 0) */ +/* return -1; */ - /* END UPDATE CSV */ +/* /\* END UPDATE CSV *\/ */ - free(rowstr); // including pch - free(newstr); +/* free(rowstr); // including pch */ +/* free(newstr); */ - return 0; -} +/* 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_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->_priv, col, val) < 0) - return -1; +/* 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->_priv, EASYCSV_ZEROROW); - return -1; - } - /* END ARGS CHECK */ +/* if (row == 0) { */ +/* _easycsv_printerror(csv->csv, EASYCSV_ZEROROW); */ +/* return -1; */ +/* } */ +/* /\* END ARGS CHECK *\/ */ - int colnum = _easycsv_getcolumn(csv->_priv, col); - if (colnum < 0) { - _easycsv_printerror(csv->_priv, EASYCSV_COLNUMFAIL); - return -1; - } +/* int colnum = _easycsv_getcolumn(csv->csv, col); */ +/* if (colnum < 0) { */ +/* _easycsv_printerror(csv->csv, EASYCSV_COLNUMFAIL); */ +/* return -1; */ +/* } */ - return easycsv_insertvaluemode(csv, val, colnum, row, valmode); -} +/* return easycsv_insertvaluemode(csv, val, colnum, row, valmode); */ +/* } */ -/* PUSH VALUE */ +/*** Modifications, push ***/ -int -easycsv_pushcolumn(easycsv *csv, - const char *col) -{ - /* ARGS CHECK */ - if (_easycsv_checkcsvandstring_one(csv->_priv, col) < 0) - return -1; - /* END ARGS CHECK */ +/* int */ +/* easycsv_pushcolumn(easycsv *csv, */ +/* const char *col) */ +/* { */ +/* /\* ARGS CHECK *\/ */ +/* if (_easycsv_checkcsvandstring_one(csv->csv, col) < 0) */ +/* return -1; */ +/* /\* END ARGS CHECK *\/ */ - if (csv->mode == EASYCSV_R) { - _easycsv_printerror(csv->_priv, EASYCSV_UNWRITABLE); - return -1; - } +/* if (csv->mode == EASYCSV_R) { */ +/* _easycsv_printerror(csv->csv, EASYCSV_UNWRITABLE); */ +/* 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 - in the file */ - if (fputs(col, csv->_priv->file) < 0) { - _easycsv_printerror(csv->_priv, EASYCSV_PUSHCOLFAIL); - return -1; - } +/* /\* 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; - } +/* return 0; */ +/* } */ - /* Grab first row */ - char *str = _easycsv_getrow(csv->_priv, 1); - char *pch = NULL; - size_t i; +/* /\* 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->_priv->cols; i++) { - if (strcspn(pch, ",") == 0) - break; - pch = strchr(str, ','); - pch++; - } +/* /\* 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->_priv->cols) - i++; +/* /\* No empty columns in first row *\/ */ +/* if (i == csv->csv->cols) */ +/* i++; */ - return easycsv_insertvalue(csv, col, i, 1); +/* return easycsv_insertvalue(csv, col, i, 1); */ - /*size_t ststr = strlen(str); - size_t stcol = strlen(col); - realloc(str, ststr + stcol + 2); // 1 for null and 1 for comma +/* /\*size_t ststr = strlen(str); */ +/* size_t stcol = strlen(col); */ +/* realloc(str, ststr + stcol + 2); // 1 for null and 1 for comma */ - strncat(str + ststr, ",", 1); - strncat(str + ststr + 1, col, stcol); +/* strncat(str + ststr, ",", 1); */ +/* strncat(str + ststr + 1, col, stcol); */ - // Put str in temp file - if (fputs(str, csv->_priv->temp) < 0) { - _easycsv_printerror(csv->_priv, EASYCSV_PUSHCOLFAIL); - return -1; - } +/* // Put str in temp file */ +/* if (fputs(str, csv->csv->temp) < 0) { */ +/* _easycsv_printerror(csv->csv, EASYCSV_PUSHCOLFAIL); */ +/* return -1; */ +/* } */ - free(str); +/* free(str); */ - // Copy every row following the first into temp - for (int i = 2; i <= csv->_priv->rows; i++) { - char *row = _easycsv_getrow(csv, i); - fputs(row, csv->_priv->temp); - free(row); - }*/ -} +/* // 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->_priv, col, val) < 0) - return -1; - /* ARGS CHECK */ +/* 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 *\/ */ - int colnum = _easycsv_getcolumn(csv->_priv, col); - if (colnum < 0) { - _easycsv_printerror(csv->_priv, EASYCSV_COLNUMFAIL); - return -1; - } +/* 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->_priv->cols limits, - if there is none, generate a new row */ - unsigned int row; +/* /\* 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->_priv->error; - csv->_priv->error = EASYCSV_ERROROFF; - for (row = 2; row <= csv->_priv->cols; row++) - if (easycsv_readvalue(csv, colnum, row) != NULL) - break; - csv->_priv->error = temp_error; +/* 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->_priv->cols) - csv->_priv->rows++; +/* /\* All rows are filled, generate new row *\/ */ +/* if (row > csv->csv->cols) */ +/* 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 -easycsv_deletevalue(easycsv *csv, - const unsigned int col, - const unsigned int row) -{ - return easycsv_insertvalue(csv, "", col, row); -} +/* 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->_priv, EASYCSV_NULLCSV); - return -1; - } +/* 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->_priv, EASYCSV_ZEROCOL); - return -1; - } +/* if (col == 0) { */ +/* _easycsv_printerror(csv->csv, EASYCSV_ZEROCOL); */ +/* return -1; */ +/* } */ - if (col > csv->_priv->cols) { - _easycsv_printerror(csv->_priv, EASYCSV_OVERMAXCOL); - return -1; - } - /* END ARGS CHECK */ +/* if (col > csv->csv->cols) { */ +/* _easycsv_printerror(csv->csv, EASYCSV_OVERMAXCOL); */ +/* return -1; */ +/* } */ +/* /\* END ARGS CHECK *\/ */ - for (unsigned int i = 1; i <= csv->_priv->cols; i++) { - if (easycsv_readvalue(csv, col, i) == NULL) - break; - if (easycsv_deletevalue(csv, col, i) < 0) - return -1; - } +/* 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; */ +/* } */ - return 0; -} +/* return 0; */ +/* } */ -int -easycsv_deletecolumnstr(easycsv *csv, - const char *col) -{ - /* ARGS CHECK */ - if (_easycsv_checkcsvandstring_one(csv->_priv, col) < 0) - return -1; - /* END ARGS CHECK */ +/* int */ +/* easycsv_deletecolumnstr(easycsv *csv, */ +/* const char *col) */ +/* { */ +/* /\* ARGS CHECK *\/ */ +/* if (_easycsv_checkcsvandstring_one(csv->csv, col) < 0) */ +/* return -1; */ +/* /\* END ARGS CHECK *\/ */ - int colnum = _easycsv_getcolumn(csv->_priv, col); - if (colnum < 0) - return -1; +/* int colnum = _easycsv_getcolumn(csv->csv, col); */ +/* if (colnum < 0) */ +/* return -1; */ - return easycsv_deletecolumnint(csv, colnum); -} +/* return easycsv_deletecolumnint(csv, colnum); */ +/* } */ -int -easycsV_deleterowint(easycsv *csv, - const unsigned int row) -{ - return 0; -} +/* int */ +/* easycsV_deleterowint(easycsv *csv, */ +/* const unsigned int row) */ +/* { */ +/* return 0; */ +/* } */ diff --git a/src/easycsv_error.c b/src/easycsv_error.c new file mode 100644 index 0000000..7ef7710 --- /dev/null +++ b/src/easycsv_error.c @@ -0,0 +1,55 @@ +#include + +#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; +} diff --git a/src/easycsv_error.h b/src/easycsv_error.h index 8482aaf..16b7263 100644 --- a/src/easycsv_error.h +++ b/src/easycsv_error.h @@ -1,9 +1,8 @@ -#ifndef EASYCSV_ERROR -#define EASYCSV_ERROR +#ifndef EASYCSV_ERROR_H +#define EASYCSV_ERROR_H /* Error flags */ -typedef enum { - +typedef enum EASYCSV_ERROR { /* Generic errors */ EASYCSV_NOERROR, // no error EASYCSV_NULLCSV, // easycsv* is NULL @@ -36,4 +35,8 @@ typedef enum { EASYCSV_READVALUEFAIL, // read value fail } EASYCSV_ERROR; +void +easycsv_error(EASYCSV_ERROR, + const char*); + #endif diff --git a/src/easycsv_p.c b/src/easycsv_p.c new file mode 100644 index 0000000..39bc7af --- /dev/null +++ b/src/easycsv_p.c @@ -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; */ +/* } */ diff --git a/src/easycsv_p.h b/src/easycsv_p.h new file mode 100644 index 0000000..8bed55c --- /dev/null +++ b/src/easycsv_p.h @@ -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 diff --git a/tests/check_easycsv.c b/tests/check_easycsv.c index bcf604f..ebdbe2f 100644 --- a/tests/check_easycsv.c +++ b/tests/check_easycsv.c @@ -57,29 +57,29 @@ easycsv_constructor_suite(void) return s; } -START_TEST(test_easycsv_printcolumns) +START_TEST(test_easycsv_print_columns) { 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); } -START_TEST(test_easycsv_printrows) +START_TEST(test_easycsv_print_rows) { 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); } -START_TEST(test_easycsv_readcolumnvalue) -{ - 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", 2), "FILEPATHB1"); - ck_assert_str_eq(easycsv_readcolumnvalue(csv, "TEST1", 3), NULL); - ck_assert_str_eq(easycsv_readcolumnvalue(csv, "TEST2", 1), "FILEPATHA2"); - easycsv_free(csv); -} +/* START_TEST(test_easycsv_readcolumnvalue) */ +/* { */ +/* 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", 2), "FILEPATHB1"); */ +/* ck_assert_str_eq(easycsv_readcolumnvalue(csv, "TEST1", 3), NULL); */ +/* ck_assert_str_eq(easycsv_readcolumnvalue(csv, "TEST2", 1), "FILEPATHA2"); */ +/* easycsv_free(csv); */ +/* } */ Suite* easycsv_access_suite(void) @@ -87,14 +87,14 @@ easycsv_access_suite(void) Suite *s; TCase *tc_find, *tc_read, *tc_print; s = suite_create ("access"); - tc_read = tcase_create ("read"); - tcase_add_test(tc_read, test_easycsv_readcolumnvalue); + /* tc_read = tcase_create ("read"); */ + /* tcase_add_test(tc_read, test_easycsv_readcolumnvalue); */ tc_print = tcase_create ("print"); - tcase_add_test(tc_print, test_easycsv_printcolumns); - tcase_add_test(tc_print, test_easycsv_printrows); + tcase_add_test(tc_print, test_easycsv_print_columns); + 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); return s;