More features
This commit is contained in:
parent
217543cdea
commit
68da1ddec5
202
src/#easycsv.h#
Normal file
202
src/#easycsv.h#
Normal file
@ -0,0 +1,202 @@
|
|||||||
|
#ifndef EASYCSV_H
|
||||||
|
#define EASYCSV_H
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/sendfile.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/* 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 */
|
1
src/.#easycsv.h
Symbolic link
1
src/.#easycsv.h
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
pradana@linux.home.2259:1519299316
|
129
src/easycsv.c
129
src/easycsv.c
@ -260,6 +260,7 @@ easycsv_readvalue(const easycsv *csv,
|
|||||||
_easycsv_printerror(csv->_priv, EASYCSV_READVALUEFAIL);
|
_easycsv_printerror(csv->_priv, EASYCSV_READVALUEFAIL);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -599,46 +600,85 @@ easycsv_pushcolumnvalue(easycsv *csv,
|
|||||||
if there is none, generate a new row */
|
if there is none, generate a new row */
|
||||||
unsigned int 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)
|
if (easycsv_readvalue(csv, colnum, row) != NULL)
|
||||||
break;
|
break;
|
||||||
}
|
csv->_priv->error = temp_error;
|
||||||
|
|
||||||
/* All rows are filled, generate new row */
|
/* All rows are filled, generate new row */
|
||||||
if (row == csv->_priv->cols) {
|
if (row > csv->_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);
|
|
||||||
|
|
||||||
csv->_priv->rows++;
|
csv->_priv->rows++;
|
||||||
}
|
|
||||||
/* ROW WILL NOT BE GENERATED \\ row < csv->_priv->rows */
|
/* ROW WILL NOT BE GENERATED \\ row < csv->_priv->rows */
|
||||||
|
|
||||||
return easycsv_insertvalue(csv, val, colnum, row);
|
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 */
|
/* PRIVATE FUNCTIONS */
|
||||||
|
|
||||||
/* (Constructor) Initialise _easycsv */
|
/* (Constructor) Initialise _easycsv */
|
||||||
@ -648,8 +688,7 @@ _easycsv_priv_init(const char *fp,
|
|||||||
const EASYCSV_ERRORMSG error)
|
const EASYCSV_ERRORMSG error)
|
||||||
{
|
{
|
||||||
_easycsv *_priv = malloc(sizeof *_priv);
|
_easycsv *_priv = malloc(sizeof *_priv);
|
||||||
calloc(_priv, sizeof(*_priv));
|
memset(_priv, 0, sizeof(*_priv)); // set all members to NULL or 0
|
||||||
memset(_priv, 0, sizeof(*_priv)); // set all members to NULL
|
|
||||||
|
|
||||||
_priv->error = error;
|
_priv->error = error;
|
||||||
|
|
||||||
@ -700,21 +739,15 @@ _easycsv_priv_init(const char *fp,
|
|||||||
/* Write to temporary file */
|
/* Write to temporary file */
|
||||||
unsigned int i = 1;
|
unsigned int i = 1;
|
||||||
char buffer[21] = "/tmp/easycsv-"; // 13 char, 3 for digits, 4 for .csv, 1 for NULL
|
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) {
|
if (i < 100)
|
||||||
strncpy(pbuffer, "0", 1);
|
strncat(buffer, "0", 1);
|
||||||
pbuffer++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i < 10) {
|
if (i < 10)
|
||||||
strncpy(pbuffer, "0", 1);
|
strncat(buffer, "0", 1);
|
||||||
pbuffer++;
|
|
||||||
}
|
|
||||||
|
|
||||||
sprintf(pbuffer, "%i", i);
|
sprintf(buffer + strlen(buffer), "%i", i);
|
||||||
strncpy(++pbuffer, ".csv", 4);
|
strcat(buffer, ".csv");
|
||||||
buffer[20] = '\0';
|
|
||||||
|
|
||||||
if (access(buffer, F_OK) < 0) {
|
if (access(buffer, F_OK) < 0) {
|
||||||
i++;
|
i++;
|
||||||
@ -868,10 +901,6 @@ _easycsv_columns(_easycsv *_priv,
|
|||||||
return col;
|
return col;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
char*
|
char*
|
||||||
_easycsv_getrow(const easycsv *csv,
|
_easycsv_getrow(const easycsv *csv,
|
||||||
const unsigned int row)
|
const unsigned int row)
|
||||||
@ -1123,7 +1152,7 @@ _easycsv_checkcsvandstring_one(const easycsv *csv,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((one == NULL) || (one[0] == '\0')) {
|
if (one == NULL) {
|
||||||
_easycsv_printerror(csv->_priv, EASYCSV_EMPTYSTRING);
|
_easycsv_printerror(csv->_priv, EASYCSV_EMPTYSTRING);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -1139,7 +1168,7 @@ _easycsv_checkcsvandstringtwo(const easycsv *csv,
|
|||||||
if (_easycsv_checkcsvandstring_one(csv, one) < 0)
|
if (_easycsv_checkcsvandstring_one(csv, one) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if ((two == NULL) || (two[0] == '\0')) {
|
if (two == NULL) {
|
||||||
_easycsv_printerror(csv->_priv, EASYCSV_EMPTYSTRING);
|
_easycsv_printerror(csv->_priv, EASYCSV_EMPTYSTRING);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -85,20 +85,23 @@ easycsv_findnumvalue(const easycsv*,
|
|||||||
const char*);
|
const char*);
|
||||||
|
|
||||||
int
|
int
|
||||||
easycsv_sortrow(const easycsv*,
|
easycsv_sortrow(easycsv*,
|
||||||
const char*,
|
const char*,
|
||||||
const EASYCSV_SORT);
|
const EASYCSV_SORT);
|
||||||
|
|
||||||
int
|
int
|
||||||
easycsv_sortcolumn(const easycsv*,
|
easycsv_sortcolumn(easycsv*,
|
||||||
const char*, const
|
const char*,
|
||||||
EASYCSV_SORT);
|
const EASYCSV_SORT);
|
||||||
|
|
||||||
/* Append to CSV files */
|
/* Append to CSV files */
|
||||||
int
|
int
|
||||||
easycsv_appendcsv(easycsv*,
|
easycsv_appendcsv(easycsv*,
|
||||||
easycsv*);
|
easycsv*);
|
||||||
|
|
||||||
|
int
|
||||||
|
easycsv_compress(easycsv*);
|
||||||
|
|
||||||
/* READ VALUE */
|
/* READ VALUE */
|
||||||
|
|
||||||
/* Read string in a specific cell */
|
/* Read string in a specific cell */
|
||||||
@ -168,18 +171,6 @@ easycsv_pushcolumnvalue(easycsv*,
|
|||||||
const char*,
|
const char*,
|
||||||
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 VALUES -- use INSERT VALUE with empty string*/
|
||||||
|
|
||||||
/* Delete CSV value */
|
/* Delete CSV value */
|
||||||
@ -190,18 +181,16 @@ easycsv_deletevalue(easycsv*,
|
|||||||
|
|
||||||
/* Delete numbered column */
|
/* Delete numbered column */
|
||||||
int
|
int
|
||||||
easycsv_deletecolumnint(const easycsv*,
|
easycsv_deletecolumnint(easycsv*,
|
||||||
const unsigned int);
|
const unsigned int);
|
||||||
|
|
||||||
/* Delete named column */
|
/* Delete named column */
|
||||||
int
|
int
|
||||||
easycsv_deletecolumnstr(const easycsv*,
|
easycsv_deletecolumnstr(easycsv*,
|
||||||
const char*);
|
const char*);
|
||||||
|
|
||||||
/* Delete column value with str */
|
/* Delete numered row */
|
||||||
int
|
|
||||||
easycsv_deletecolumnstrvalue(const easycsv*,
|
/* Delete named row */
|
||||||
const char*,
|
|
||||||
const char*);
|
|
||||||
|
|
||||||
#endif /* EASYCSV_H */
|
#endif /* EASYCSV_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user