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);
|
||||
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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user