From 68da1ddec5515ea3b8823c04bf7e5aef0434ec45 Mon Sep 17 00:00:00 2001 From: Pradana Aumars Date: Thu, 22 Feb 2018 14:22:21 +0100 Subject: [PATCH] More features --- src/#easycsv.h# | 202 ++++++++++++++++++++++++++++++++++++++++++++++++ src/.#easycsv.h | 1 + src/easycsv.c | 129 +++++++++++++++++++------------ src/easycsv.h | 35 +++------ 4 files changed, 294 insertions(+), 73 deletions(-) create mode 100644 src/#easycsv.h# create mode 120000 src/.#easycsv.h diff --git a/src/#easycsv.h# b/src/#easycsv.h# new file mode 100644 index 0000000..08cfac4 --- /dev/null +++ b/src/#easycsv.h# @@ -0,0 +1,202 @@ +#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 new file mode 120000 index 0000000..4b90f17 --- /dev/null +++ b/src/.#easycsv.h @@ -0,0 +1 @@ +pradana@linux.home.2259:1519299316 \ No newline at end of file diff --git a/src/easycsv.c b/src/easycsv.c index 9079b2d..4354199 100644 --- a/src/easycsv.c +++ b/src/easycsv.c @@ -260,6 +260,7 @@ easycsv_readvalue(const easycsv *csv, _easycsv_printerror(csv->_priv, EASYCSV_READVALUEFAIL); return NULL; } + return val; } @@ -599,46 +600,85 @@ easycsv_pushcolumnvalue(easycsv *csv, if there is none, generate a new row */ unsigned int row; - for (row = 2; row <= csv->_priv->cols; 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; /* 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) { - _easycsv_printerror(csv->_priv, EASYCSV_FILEPTRFAIL); - return -1; - } - - char *rowstr = malloc(csv->_priv->cols + strlen(val) + 2); // 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); - + if (row > csv->_priv->cols) csv->_priv->rows++; - } + /* ROW WILL NOT BE GENERATED \\ row < csv->_priv->rows */ return easycsv_insertvalue(csv, val, colnum, row); } +/* DELETE VALUES */ + +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; + } + + if (col == 0) { + _easycsv_printerror(csv->_priv, EASYCSV_ZEROCOL); + return -1; + } + + if (col > csv->_priv->cols) { + _easycsv_printerror(csv->_priv, 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; + } + + return 0; +} + +int +easycsv_deletecolumnstr(easycsv *csv, + const char *col) +{ + /* ARGS CHECK */ + if (_easycsv_checkcsvandstring_one(csv, col) < 0) + return -1; + /* END ARGS CHECK */ + + int colnum = _easycsv_getcolumn(csv, col); + if (colnum < 0) + return -1; + + return easycsv_deletecolumnint(csv, colnum); +} + +int +easycsV_deleterowint(easycsv *csv, + const unsigned int row) +{ + return 0; +} /* PRIVATE FUNCTIONS */ /* (Constructor) Initialise _easycsv */ @@ -648,8 +688,7 @@ _easycsv_priv_init(const char *fp, const EASYCSV_ERRORMSG error) { _easycsv *_priv = malloc(sizeof *_priv); - calloc(_priv, sizeof(*_priv)); - memset(_priv, 0, sizeof(*_priv)); // set all members to NULL + memset(_priv, 0, sizeof(*_priv)); // set all members to NULL or 0 _priv->error = error; @@ -700,21 +739,15 @@ _easycsv_priv_init(const char *fp, /* 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 < 100) + strncat(buffer, "0", 1); - if (i < 10) { - strncpy(pbuffer, "0", 1); - pbuffer++; - } + if (i < 10) + strncat(buffer, "0", 1); - sprintf(pbuffer, "%i", i); - strncpy(++pbuffer, ".csv", 4); - buffer[20] = '\0'; + sprintf(buffer + strlen(buffer), "%i", i); + strcat(buffer, ".csv"); if (access(buffer, F_OK) < 0) { i++; @@ -868,10 +901,6 @@ _easycsv_columns(_easycsv *_priv, return col; } - - - - char* _easycsv_getrow(const easycsv *csv, const unsigned int row) @@ -1123,7 +1152,7 @@ _easycsv_checkcsvandstring_one(const easycsv *csv, return -1; } - if ((one == NULL) || (one[0] == '\0')) { + if (one == NULL) { _easycsv_printerror(csv->_priv, EASYCSV_EMPTYSTRING); return -1; } @@ -1139,7 +1168,7 @@ _easycsv_checkcsvandstringtwo(const easycsv *csv, if (_easycsv_checkcsvandstring_one(csv, one) < 0) return -1; - if ((two == NULL) || (two[0] == '\0')) { + if (two == NULL) { _easycsv_printerror(csv->_priv, EASYCSV_EMPTYSTRING); return -1; } diff --git a/src/easycsv.h b/src/easycsv.h index f8eb9d8..f5d4d2c 100644 --- a/src/easycsv.h +++ b/src/easycsv.h @@ -85,20 +85,23 @@ easycsv_findnumvalue(const easycsv*, const char*); int -easycsv_sortrow(const easycsv*, +easycsv_sortrow(easycsv*, const char*, const EASYCSV_SORT); int -easycsv_sortcolumn(const easycsv*, - const char*, const - EASYCSV_SORT); +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 */ @@ -168,18 +171,6 @@ easycsv_pushcolumnvalue(easycsv*, const char*, const char*); -/* Insert array of string pointers */ -int -easycsv_pushcolumnstrarr(easycsv*, - const char*[], - const char*); - -/* Insert array of void pointers */ -int -easycsv_pushcolumnvoidarr(easycsv*, - const void*[], - const char*); - /* DELETE VALUES -- use INSERT VALUE with empty string*/ /* Delete CSV value */ @@ -190,18 +181,16 @@ easycsv_deletevalue(easycsv*, /* Delete numbered column */ int -easycsv_deletecolumnint(const easycsv*, +easycsv_deletecolumnint(easycsv*, const unsigned int); /* Delete named column */ int -easycsv_deletecolumnstr(const easycsv*, +easycsv_deletecolumnstr(easycsv*, const char*); -/* Delete column value with str */ -int -easycsv_deletecolumnstrvalue(const easycsv*, - const char*, - const char*); +/* Delete numered row */ + +/* Delete named row */ #endif /* EASYCSV_H */