From e69ecdac9ef4cfaaebbcd2ec26c24465cfae912e Mon Sep 17 00:00:00 2001 From: Pradana AUMARS Date: Sun, 27 Jun 2021 18:21:23 +0200 Subject: [PATCH] Remove temporary files --- src/#easycsv.h# | 202 ----------- src/.#easycsv.h | 1 - src/easycsv.c~ | 878 ------------------------------------------------ src/easycsv.h~ | 90 ----- 4 files changed, 1171 deletions(-) delete mode 100644 src/#easycsv.h# delete mode 120000 src/.#easycsv.h delete mode 100644 src/easycsv.c~ delete mode 100644 src/easycsv.h~ diff --git a/src/#easycsv.h# b/src/#easycsv.h# deleted file mode 100644 index 08cfac4..0000000 --- a/src/#easycsv.h# +++ /dev/null @@ -1,202 +0,0 @@ -#ifndef EASYCSV_H -#define EASYCSV_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Flags for error messages */ -typedef enum { - EASYCSV_ERRORSTDERR = 0, // default - 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; - -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; - -typedef struct _easycsv _easycsv; - -/* Public easycsv members */ -typedef struct easycsv { - EASYCSV_MODE mode; // end users able to easily modify mode to their needs - _easycsv *_priv; // private members -} easycsv; - -/* - * ============================ - * FUNCTION PROTOTYPES - PUBLIC - * ============================ - */ - -/* CONSTRUCTORS AND DESTRUCTORS */ - -/* (Constructor) Initialise easycsv */ -easycsv* -easycsv_init(const char*, - const EASYCSV_MODE); - -/* (Constructor) Initialise easycsv with error message option */ -easycsv* -easycsv_init_errormsg(const char*, - const EASYCSV_MODE, - const EASYCSV_ERRORMSG); - -/* (Destructor) Free easycsv memory */ -void -easycsv_free(easycsv*); - -/* GENERIC ALGORITHMS */ - -/* Find value and returns row and column in unsigned int pointers */ -int -easycsv_findvalue(const easycsv*, - const char*, - unsigned int*, - unsigned int*); - -/* Find number of instances of value */ -int -easycsv_findnumvalue(const easycsv*, - const char*); - -int -easycsv_sortrow(easycsv*, - const char*, - const EASYCSV_SORT); - -int -easycsv_sortcolumn(easycsv*, - const char*, - const EASYCSV_SORT); - -/* Append to CSV files */ -int -easycsv_appendcsv(easycsv*, - easycsv*); - -int -easycsv_compress(easycsv*); - -/* READ VALUE */ - -/* Read string in a specific cell */ -char* -easycsv_readvalue(const easycsv*, - const unsigned int, - const unsigned int); - -/* Read string in a specific cell with named column in row 1 */ -char* -easycsv_readcolumnvalue(const easycsv*, - const char*, - const unsigned int); - -/* Number of rows in entire CSV file */ -int -easycsv_printrows(const easycsv*); - -/* Number of columns in entire CSV file */ -int -easycsv_printcolumns(const easycsv*); - -/* INSERT VALUE -- AT SPECIFIC ROW AND COLUMN */ - -// int easycsv_insertrow(struct easycsv*, const char*, const int); - -/* Insert string in a specific cell */ -int -easycsv_insertvalue(easycsv*, - const char*, - const unsigned int, - const unsigned int); - -/* Insert string in a specific cell with specific mode */ -int -easycsv_insertvaluemode(easycsv*, - const char*, - const unsigned int, - const unsigned int, - const EASYCSV_VALMODE); - -/* Insert string in a specific cell with named column in row 1 */ -int -easycsv_insertcolumnvalue(easycsv*, - const char*, - const unsigned int, - const char*); - -/* Insert string in a specific cell with named column in row 1 with specific mode */ -int -easycsv_insertcolumnvaluemode(easycsv*, - const char*, - const unsigned int, - const char*, - const EASYCSV_VALMODE); - -/* PUSH VALUE */ - -/* Create new column on the RHS of an existing one */ -int -easycsv_pushcolumn(easycsv*, - const char*); - -/* Insert string in a vacant cell under a named column */ -int -easycsv_pushcolumnvalue(easycsv*, - const char*, - const char*); - -/* DELETE VALUES -- use INSERT VALUE with empty string*/ - -/* Delete CSV value */ -int -easycsv_deletevalue(easycsv*, - const unsigned int, - const unsigned int); - -/* Delete numbered column */ -int -easycsv_deletecolumnint(easycsv*, - const unsigned int); - -/* Delete named column */ -int -easycsv_deletecolumnstr(easycsv*, - const char*); - -/* Delete numered row */ -int -easycsv_deleterowint(easycsv*, - const unsigned int); - -/* Delete named row */ -int -easycsv_deleterowstr(easycsv*, - const char*); - -#endif /* EASYCSV_H */ diff --git a/src/.#easycsv.h b/src/.#easycsv.h deleted file mode 120000 index 4b90f17..0000000 --- a/src/.#easycsv.h +++ /dev/null @@ -1 +0,0 @@ -pradana@linux.home.2259:1519299316 \ No newline at end of file diff --git a/src/easycsv.c~ b/src/easycsv.c~ deleted file mode 100644 index 774e08f..0000000 --- a/src/easycsv.c~ +++ /dev/null @@ -1,878 +0,0 @@ -#include "easycsv.h" - -/* Flags */ -typedef enum { - EASYCSV_NULL, - EASYCSV_STRING, - EASYCSV_INT -} _EASYCSV_TYPE; - -typedef enum { - - /* Generic errors */ - EASYCSV_NOERROR = 0, // no error - EASYCSV_NULLPTR, // pointer is NULL - EASYCSV_EMPTYSTRING, // empty string - EASYCSV_OVERMAXROW, // int exceeds row limit - EASYCSV_OVERMAXCOL, // int exceeds col limit - - /* File input/output errors */ - EASYCSV_UNKNOWNMODE, // unknown file IO mode - EASYCSV_OPENFAIL, // fail to open - EASYCSV_REOPENFAIL, // fail to reopen - EASYCSV_EMPTYCSV, // csv is empty or does not exist - EASYCSV_UNWRITABLE, // csv mode not at EASYCSV_W - EASYCSV_UNREADABLE, // csv mode not at EASYCSV_R - EASYCSV_UPDATEFAIL, // update file fail - EASYCSV_FILEPTRFAIL, // move file pointer fail - - /* Non-existant elements */ - EASYCSV_ROWNOTEXIST, // row does not exist - EASYCSV_COLNOTEXIST, // column does not exist - - /* Subroutine failure */ - EASYCSV_PUSHCOLFAIL, // push column value fail - EASYCSV_COLNUMFAIL // column number retrieval fail -} EASYCSV_ERROR; - -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; - -/* PRIVATE FUNCTIONS */ - -/* Constructor of private members */ -static _easycsv *_easycsv_priv_init(const char*, const EASYCSV_MODE, const EASYCSV_ERRORMSG); - -/* Destructor of private members */ -static void _easycsv_priv_free(_easycsv*); - -/* Verifies mode of file */ -// static int _easycsv_checkmode(struct easycsv*, const char); - -/* Copies data from temp FILE to file FILE */ -static int _easycsv_update(easycsv*); - -/* Rewind easycsv, checks for readability */ -static int _easycsv_rewind(_easycsv*, const EASYCSV_MODE); - -/* Returns string of a specific row */ -static char *_easycsv_getrow(const easycsv*, const unsigned int); - -/* Return column number of a named column */ -static int _easycsv_getcolumn(const easycsv*, const char*); - -/* Verifies the type of the value (eg: string or int) */ -static int _easycsv_checktype(const easycsv*, const int, const int); - -/* Verifies if there is a value or not */ -static int _easycsv_checkifvalue(const easycsv*, const int, const int); - -/* */ -// static char *_easycsv_getvalueinrow(const int, const char*); - -/* Calculate rows */ -static int _easycsv_rows(_easycsv*, const EASYCSV_MODE); - -/* Calculate columns*/ -static int _easycsv_columns(_easycsv*, const EASYCSV_MODE); - -static void _easycsv_printerror(const _easycsv*, const EASYCSV_ERROR); - -/* Print error from _easycsv struct in stderr */ -static void _easycsv_geterror(const _easycsv*, const EASYCSV_ERROR, FILE*); - -/* Verifies if the string is not NULL or empty, returns 0 on success and -1 on failure */ -// static int _easycsv_checkstring(const char*); - -/* Verifies if easycsv is not NULL or unallocated */ -// static int _easycsv_checkeasycsv(const struct easycsv*); - -/* Verifies if int is */ -// static int _easycsv_checkunsigned(const int); - -/* - * ==================== - * FUNCTION DEFINITIONS - * ==================== - */ - -/* PUBLIC FUNCTIONS */ - -easycsv* -easycsv_init(const char *fp, const EASYCSV_MODE mode) -{ - return easycsv_init_errormsg(fp, mode, EASYCSV_ERRORSTDERR); -} - -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 *csv); - csv->mode = mode; - csv->_priv = _easycsv_priv_init(fp, mode, error); - - if (csv->_priv == NULL) { - easycsv_free(csv); - return NULL; - } - - return csv; -} - -void -easycsv_free(easycsv *csv) -{ - if (csv == NULL) return; - _easycsv_priv_free(csv->_priv); - free(csv); -} - -_easycsv* -_easycsv_priv_init(const char *fp, const EASYCSV_MODE mode, const EASYCSV_ERRORMSG error) -{ - _easycsv *_priv = malloc(sizeof *_priv); - memset(_priv, 0, sizeof(*_priv)); // set all members to NULL - - _priv->error = error; - - /* Open file according to mode */ - switch (mode) { - case EASYCSV_R: - case EASYCSV_W: { - _priv->file = fopen(fp, "r"); - break; - } - default: { - _easycsv_printerror(_priv, EASYCSV_UNKNOWNMODE); - _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 - - strncpy(_priv->fp, fp, stfp); - - /* 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); - } - else { - _priv->rows = 0; - _priv->cols = 0; - } - - 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 - char *pbuffer = &buffer[13]; // don't free, is used for digit con - - if (i < 100) { - strncpy(pbuffer, "0", 1); - pbuffer++; - } - - if (i < 10) { - strncpy(pbuffer, "0", 1); - pbuffer++; - } - - sprintf(pbuffer, "%i", i); - strncpy(++pbuffer, ".csv", 4); - buffer[20] = '\0'; - - 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_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; -} - -void -_easycsv_priv_free(_easycsv *_priv) -{ - if (_priv == NULL) return; - 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_pushcolumn(easycsv *csv, const char *col) -{ - if (csv == NULL) { - fprintf(stderr, "easycsv: csv is NULL in %s\n", csv->_priv->fp); - return -1; - } - - if ((col == NULL) || (col[0] == '\0')) { - fprintf(stderr, "easycsv: col is either NULL or empty in %s\n", csv->_priv->fp); - return -1; - } - - if (csv->mode == EASYCSV_R) { -#ifdef EASYCSV_DEBUG - fprintf(stderr, "[%i] ", clock() - csv->_priv->start); -#endif - fprintf(stderr, "easycsv: %s set to read\n", csv->_priv->fp); - return -1; - } - - if ((csv->mode == EASYCSV_W) && (access(csv->_priv->fp, F_OK) == 0)) { - /* If the file doesn't exist, just put the col in the file */ - - if (fputs(col, csv->_priv->file) < 0) { -#ifdef EASYCSV_DEBUG - fprintf(stderr, "[%i] ", clock() - csv->_priv->start); -#endif - fprintf(stderr, "easycsv: failed to push column %s in %s\n", col, csv->_priv->fp); - return -1; - } - - return 0; - } - - char *str = _easycsv_getrow(csv, 1); - 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); - -#ifdef EASYCSV_DEBUG - printf("[%i] easycsv_debug: push column str: %s", clock() - csv->_priv->start, str); -#endif - - /* Put str in temp file */ - if (fputs(str, csv->_priv->temp) < 0) { -#ifdef EASYCSV_DEBUG - fprintf(stderr, "[%i] ", clock() - csv->_priv->start); -#endif - fprintf(stderr, "easycsv: failed to push column %s in %s\n", col, csv->_priv->tmpfp); - return -1; - } - - 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); - } - - /* Update the file */ - if (_easycsv_update(csv) < 0) { -#ifdef EASYCSV_DEBUG - fprintf(stderr, "[%i] ", clock() - csv->_priv->start); -#endif - fprintf(stderr, "easycsv: failed to update %s\n", csv->_priv->fp); - return -1; - } - - return 0; -} - -int -easycsv_pushcolumnvalue(const easycsv *csv, const char *col, const char *val) -{ - if (csv == NULL) { - fprintf(stderr, "easycsv: csv is NULL in %s\n", csv->_priv->fp); - return -1; - } - - if ((col == NULL) || (col[0] == '\0')) { - fprintf(stderr, "easycsv: col is either NULL or empty in %s\n", csv->_priv->fp); - return -1; - } - - if ((val == NULL) || (val[0] == '\0')) { - fprintf(stderr, "easycsv: val is either NULL or empty in %s\n", csv->_priv->fp); - return -1; - } - - int colnum = _easycsv_getcolumn(csv, col); - - if (colnum < 0) { - fprintf(stderr, "easycsv: error occured when fetcing col number in %s", csv->_priv->fp); - return -1; - } - - /* Find a free cell under col within csv->_priv->cols limits, if there is none, generate a new - row */ - unsigned int row; - - for (row = 2; row <= csv->_priv->cols; row++) { - if (easycsv_readvalue(csv, colnum, row) != NULL) break; - } - - /* All rows are filled, generate new row */ - if (row == csv->_priv->cols) { - row++; - - /* Set file pointer to end */ - if (fseek(csv->_priv->file, 0L, SEEK_END) < 0) { - fprintf(stderr, "easycsv: failed to set file pointer to end in %s", csv->_priv->fp); - return -1; - } - - char *rowstr = malloc(csv->_priv->cols + strlen(val) + 2); // 1 extra for '\n' - - strncpy(rowstr, "\n", 1); - - for (unsigned int i = 1; i < colnum; i++) { - strncpy(rowstr, ",", 1); - } - - strncpy(rowstr, val, strlen(val)); - - unsigned int colsleft = csv->_priv->cols - colnum; - - for (unsigned i = 1; i < colsleft; i++) { - strncpy(rowstr, ",", 1); - } - - strncpy(rowstr, "/0", 1); - - csv->_priv->rows++; - } - - /* Fill in rows before */ - - for (unsigned int i = 1; i < row; i++) { - char *str = _easycsv_getrow(csv, i); - if (fputs(str, csv->_priv->temp) == EOF) { - fprintf(stderr, "easycsv: failed to write \"%s\" in temporary file %s for %s\n", str, csv->_priv->tmpfp, csv->_priv->fp); - return -1; - } - - free(str); - } - - return 0; -} - -int -easycsv_insertcolumnvalue(const easycsv *csv, const char *col, const unsigned int row, const char *val, const EASYCSV_VALMODE valmode) -{ - if (csv == NULL) { - fprintf(stderr, "easycsv: csv is NULL in %s\n", csv->_priv->fp); - return -1; - } - - if ((col == NULL) || (col[0] == '\0')) { - fprintf(stderr, "easycsv: col is either NULL or empty in %s\n", csv->_priv->fp); - return -1; - } - - if ((val == NULL) || (val[0] == '\0')) { - fprintf(stderr, "easycsv: val is either NULL or empty in %s\n", csv->_priv->fp); - return -1; - } - - int colnum = _easycsv_getcolumn(csv, col); - if (colnum < 0) { - fprintf(stderr, "easycsv: failed to get colnum of %s in %s", col, csv->_priv->fp); - return -1; - } - - char *rowstr = _easycsv_getrow(csv, row); - char *pch = rowstr; - - for (unsigned int i = 1; i < colnum; i++) { - pch = strchr(pch, ','); - pch++; - } - - size_t st = strcspn(pch, ','); - - /* Empty cell */ - if (st == 0) { - - } - - return 0; -} - -int -easycsv_printrows(const easycsv *csv) -{ - return csv->_priv->rows; -} - -int -easycsv_printcolumns(const easycsv *csv) -{ - return csv->_priv->cols; -} - -int -_easycsv_rows(_easycsv *_priv, const EASYCSV_MODE mode) -{ - if (_priv == NULL) { - fprintf(stderr, "easycsv: csv is NULL in %s\n", _priv->fp); - return -1; - } - - /* Prepare it for reading */ - 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) -{ - if (_priv == NULL) { - fprintf(stderr, "easycsv: csv is NULL in %s\n", _priv->fp); - return -1; - } - - /* 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 - */ - - unsigned int col = 1; - char c; - - while ((c = fgetc(_priv->file)) != '\n') { - if (c == ',') col++; - } - - return col; -} - -const char* -easycsv_readcolumnvalue(const easycsv *csv, const char *col, const unsigned int row) -{ - if (csv == NULL) { - fprintf(stderr, "easycsv: csv is NULL in %s\n", csv->_priv->fp); - return NULL; - } - - if (row > csv->_priv->rows) { - fprintf(stderr, "easycsv: row exceeds max in %s\n", csv->_priv->fp); - return NULL; - } - - int i = _easycsv_getcolumn(csv, col); - if (i < 1) { - return NULL; - } - - return easycsv_readvalue(csv, i, row); -} - -const char* -easycsv_readvalue(const easycsv *csv, const unsigned int col, const unsigned int row) -{ - if (col == 0 || row == 0) { - fputs("easycsv: row or col is 0\n", stderr); - return NULL; - } - - char *str = _easycsv_getrow(csv, row); - if (str == NULL) { - fprintf(stderr, "easycsv: row %i does not exist in %s\n", row, csv->_priv->fp); - return NULL; - } - -#ifdef EASYCSV_DEBUG - printf("[%i] rv_col: %i\nstr: %s\n", clock() - csv->_priv->start, col, str); -#endif - - /* Return if first col */ - if (col == 1) { - size_t st = strcspn(str, ","); - if (st == 0) { - free(str); - return NULL; - } - char *pch = malloc(st); - strncpy(pch, str, st); - free(str); - return pch; - } - - /* Get first occurance of comma in str, - the first value is ommited but not the comma */ - char *pch = strpbrk(str, ","); - - /* 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 */ - size_t st = strcspn(pch + 1, ","); - - /* If 0, no string exists! */ - if (st == 0) { - free(str); - return NULL; - } - - char *val = malloc(st + 1); - strncpy(val, pch + 1, st); - strncat(val, "\0", 1); - free(str); - - return val; -} - -void -easycsv_geterror(const easycsv *csv) -{ - _easycsv_pgeterror(csv->_priv); -} - -void -easycsv_fgeterror(const easycsv *csv, FILE *fs) -{ - _easycsv_fpgeterror(csv->_priv, fs); -} - -/* PRIVATE FUNCTIONS */ - -/* -static int _easycsv_checkmode(struct easycsv *csv, const char mode) -{ - if (strchr(csv->mode, mode) == NULL) - { - return -1; - } -} -*/ - -int -_easycsv_update(easycsv *csv) -{ - if (csv == NULL) { - fputs("easycsv: csv is NULL\n", stderr); - return -1; - } - - /* Set temp file to read binary */ - if (freopen(csv->_priv->tmpfp, "rb", csv->_priv->temp) == NULL) { -#ifdef EASYCSV_DEBUG - fprintf(stderr, "[%i] ", clock() - csv->_priv->start); -#endif - fprintf(stderr, "easycsv: failed to reopen temp file %s in read binary mode\n", csv->_priv->fp); - easycsv_free(csv); - return -1; - } - - /* Set file to write binary */ - if (freopen(csv->_priv->fp, "wb", csv->_priv->file) == NULL) { -#ifdef EASYCSV_DEBUG - fprintf(stderr, "[%i] ", clock() - csv->_priv->start); -#endif - fprintf(stderr, "easycsv: failed to reopen file %s in write binary mode\n", csv->_priv->tmpfp); - easycsv_free(csv); - return -1; - } - - char buf[BUFSIZ]; - size_t size; - while (size = fread(buf, 1, BUFSIZ, csv->_priv->temp)) { - fwrite(buf, 1, size, csv->_priv->file); - } - - /* Set temp file back to write */ - if (freopen(csv->_priv->tmpfp, "w", csv->_priv->temp) == NULL) { -#ifdef EASYCSV_DEBUG - fprintf(stderr, "[%i] ", clock() - csv->_priv->start); -#endif - fprintf(stderr, "easycsv: failed to reopen temp file %s in write mode\n", csv->_priv->fp); - easycsv_free(csv); - return -1; - } - - /* Set file back to read */ - if (freopen(csv->_priv->fp, "r", csv->_priv->file) == NULL) { -#ifdef EASYCSV_DEBUG - fprintf(stderr, "[%i] ", clock() - csv->_priv->start); -#endif - fprintf(stderr, "easycsv: failed to reopen file %s in read mode\n", csv->_priv->tmpfp); - easycsv_free(csv); - return -1; - } - - return 0; -} - -char* -_easycsv_getrow(const easycsv *csv, const unsigned int row) -{ - if (csv == NULL) { - fputs("easycsv: csv is NULL\n", stderr); - return NULL; - } - - if (row > csv->_priv->rows) { - fputs("easycsv: row overflow\n", stderr); - return NULL; - } - - if (row == 0) { - fputs("easycsv: row is 0\n", stderr); - return NULL; - } - - /* Allocate memory */ - char *str = malloc(BUFSIZ); - - /* Set file pointer to start */ - rewind(csv->_priv->file); - - for (int i = 1; i < row; i++) - { - /* skip until row is reached */ - fscanf(csv->_priv->file, "%*[^\n]\n", NULL); - } - - /* Grab the row and store it in str */ - fscanf(csv->_priv->file, "%s\n", str); - - // printf("row: %s\n", str); - - return str; -} - -int -_easycsv_rewind(_easycsv *_priv, const EASYCSV_MODE mode) -{ - if (_priv == NULL) { - fprintf(stderr, "easycsv: csv is NULL in %s\n", _priv->fp); - return -1; - } - - /* Check if file is readable */ - if (mode == EASYCSV_R) { -#ifdef EASYCSV_DEBUG - fprintf(stderr, "[%i] ", clock() - _priv->start); -#endif - fprintf(stderr, "easycsv: %s is not be readable\n", _priv->fp); - return -1; - } - - /* Set file pointer to the start */ - rewind(_priv->file); - - /* Check if empty file */ - if (fscanf(_priv->file, "\n") == EOF) { -#ifdef EASYCSV_DEBUG - fprintf(stderr, "[%i] ", clock() - _priv->start); -#endif - fprintf(stderr, "easycsv: %s is empty\n", _priv->fp); - return -1; - } - - return 0; -} - -int -_easycsv_getcolumn(const easycsv *csv, const char *col) -{ - if (csv == NULL) { - fputs("easycsv: csv is NULL\n", stderr); - return -1; - } - - if ((col == NULL) || (col[0] == '\0')) { - fputs("easycsv: col is either NULL or empty\n", stderr); - return -1; - } - - /* Grab str of row 1 */ - char *firstrow = _easycsv_getrow(csv, 1); - - if (firstrow == NULL) { -#ifdef EASYCSV_DEBUG - fprintf(stderr, "[%i] ", clock() - csv->_priv->start); -#endif - fprintf(stderr, "easycsv: row 1 does not exist in %s\n", csv->_priv->fp); - 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) { -#ifdef EASYCSV_DEBUG - fprintf(stderr, "[%i] ", clock() - csv->_priv->start); -#endif - fprintf(stderr, "easycsv: column %s not found in %s\n", col, csv->_priv->fp); - 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->_priv->cols - commas); -#ifdef EASYCSV_DEBUG - printf("[%i] rcv_commas: %i\n", clock() - csv->_priv->start, commas); -#endif - - free(firstrow); - - return csv->_priv->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 int col, const char *row) -{ - char *pbrk = strchr(row, ','); - for (unsigned int i = 1; i < col; i++) { - - } -} -*/ - -void -_easycsv_printerror(const _easycsv *_priv, const EASYCSV_ERROR error) -{ - switch (_priv->error) { - case EASYCSV_ERROROFF: return; - case EASYCSV_ERRORSTDERR: _easycsv_geterror(_priv, error, stderr); break; - case EASYCSV_ERRORSTDOUT: _easycsv_geterror(_priv, error, stdout); break; - default: 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) { - case EASYCSV_NOERROR: fputs("no error", fs); break; - case EASYCSV_NULLPTR: fputs("pointer is NULL", fs); break; - case EASYCSV_EMPTYSTRING: fputs("string 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_UNKNOWNMODE: 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_FILEPTRFAIL: fputs("failed to move FILE pointer", fs); break; - - case EASYCSV_ROWNOTEXIST: fputs("given row does not exist", fs); break; - case EASYCSV_COLNOTEXIST: fputs("given column does not exist", fs); break; - - 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", fs); break; - } - - if (_priv->fp != NULL) { - fprintf(fs, " in %s", _priv->fp); - } -} diff --git a/src/easycsv.h~ b/src/easycsv.h~ deleted file mode 100644 index da73b12..0000000 --- a/src/easycsv.h~ +++ /dev/null @@ -1,90 +0,0 @@ -#ifndef EASYCSV_H -#define EASYCSV_H - -#include -#include -#include -#include -#include -#include -#include -#include - -/* Flags for error messages */ -typedef enum { - EASYCSV_ERROROFF, - EASYCSV_ERRORSTDERR, - EASYCSV_ERRORSTDOUT -} EASYCSV_ERRORMSG; - -/* Using our own flags to facilitate changing modes during file copying phases */ -typedef enum { - EASYCSV_R, - EASYCSV_W -} EASYCSV_MODE; - -typedef enum { - EASYCSV_REPLACE, - EASYCSV_APPEND, - EASYCSV_APPEND_R, -} EASYCSV_VALMODE; - -typedef struct _easycsv _easycsv; - -typedef struct easycsv { - EASYCSV_MODE mode; - _easycsv *_priv; // private members -} easycsv; - -/* - * ============================ - * FUNCTION PROTOTYPES - PUBLIC - * ============================ - */ - -/* (Constructor) Initialise easycsv */ -easycsv* easycsv_init(const char*, const EASYCSV_MODE); - -/* (Constructor) Initialise easycsv with error message option */ -easycsv* easycsv_init_errormsg(const char*, const EASYCSV_MODE, const EASYCSV_ERRORMSG); - -/* (Destructor) Free easycsv memory */ -void easycsv_free(easycsv*); - -/* Insert in */ -// int easycsv_insertrow(struct easycsv*, const char*, const int); - -/* Create new column on the RHS of an existing one */ -int easycsv_pushcolumn(easycsv*, const char*); - -/* Insert string in a specific cell */ -int easycsv_insertvalue(const easycsv*, const char*, const unsigned int, const unsigned int); - -/* Insert string in a vacant cell under a named column */ -int easycsv_pushcolumnvalue(const easycsv*, const char*, const char*); - -/* Insert string in a specific cell with named column in row 1 */ -int easycsv_insertcolumnvalue(const easycsv*, const char*, const unsigned int, const char*, const EASYCSV_VALMODE); - -/* Insert array of string pointers */ -int easycsv_pushcolumnstrarray(const easycsv*, const char*[], const char*); - -/* Insert array of void pointers */ -int easycsv_pushcolumnvoidarray(const easycsv*, const void*[], const char*); - -/* Append to CSV files */ -int easycsv_appendcsv(easycsv*, easycsv*); - -/* Read string in a specific cell */ -const char *easycsv_readvalue(const easycsv*, const unsigned int, const unsigned int); - -/* Read string in a specific cell with named column in row 1 */ -const char *easycsv_readcolumnvalue(const easycsv*, const char*, const unsigned int); - -/* Number of rows in entire CSV file */ -int easycsv_printrows(const easycsv*); - -/* Number of columns in entire CSV file */ -int easycsv_printcolumns(const easycsv*); - -#endif /* EASYCSV_H */