Compare commits

..

No commits in common. "master" and "redesign" have entirely different histories.

12 changed files with 119 additions and 236 deletions

View File

@ -61,8 +61,8 @@ typedef struct _easycsv easycsv;
struct _easycsv { struct _easycsv {
FILE *file; ///< original CSV file FILE *file; ///< original CSV file
FILE *temp; ///< temporary CSV file for writing FILE *temp; ///< temporary CSV file for writing
char fp[BUFSIZ]; char *fp;
// char *tmpfp; char *tmpfp;
unsigned int rows; unsigned int rows;
unsigned int cols; unsigned int cols;
// EASYCSV_ERRORMSG error; // EASYCSV_ERRORMSG error;
@ -221,12 +221,12 @@ easycsv_sortcolumn(easycsv*,
/* int); */ /* int); */
/** /**
* Insert/replace string in a specific cell * Insert string in a specific cell
* @param[in] pointer to easycsv structure * @param[in] pointer to easycsv structure
* @param[in] cell value (cell value will not be modified if there is an error) * @param[in] cell value
* @param[in] column number
* @param[in] row number * @param[in] row number
* @return 0 if no error, -1 if error * @param[in] column number
* @return easycsv error code
*/ */
int int
easycsv_insertvalue(easycsv*, easycsv_insertvalue(easycsv*,

View File

@ -1,12 +1,8 @@
lib_LTLIBRARIES = libeasycsv.la libeasycsv_string.la lib_LTLIBRARIES = libeasycsv.la
libeasycsv_la_SOURCES = \ libeasycsv_la_SOURCES = \
easycsv.c \ easycsv.c \
easycsv_error.h \ easycsv_error.h \
easycsv_error.c \ easycsv_error.c \
easycsv_p.h \ easycsv_p.h \
easycsv_p.c easycsv_p.c
libeasycsv_la_LIBADD = libeasycsv_string.la
libeasycsv_string_la_SOURCES = \
easycsv_string.h \
easycsv_string.c
include_HEADERS = ../include/easycsv.h include_HEADERS = ../include/easycsv.h

View File

@ -11,40 +11,22 @@ easycsv_init(const char *fp,
int csv_exist = -1; int csv_exist = -1;
csv = malloc(sizeof(easycsv)); csv = malloc(sizeof(easycsv));
if (csv == NULL) {
easycsv_error(EASYCSV_MEMALLOC, NULL);
return NULL;
}
memset(csv, 0, sizeof(easycsv));
csv->mode = mode; csv->mode = mode;
csv->file = NULL; csv->file = NULL;
csv->temp = NULL; csv->temp = NULL;
strcpy(csv->fp, fp); csv->fp = NULL;
csv->tmpfp = NULL;
csv->rows = 0; csv->rows = 0;
csv->cols = 0; csv->cols = 0;
csv_exist = !access(csv->fp, F_OK);
/* Open file according to mode */ /* Open file according to mode */
switch (csv->mode) { switch (csv->mode) {
case EASYCSV_R: case EASYCSV_R:
if (csv_exist) { csv->file = fopen(fp, "r");
csv->file = fopen(csv->fp, "r");
}
else {
easycsv_error(EASYCSV_EMPTYCSV, NULL);
easycsv_free(csv);
return NULL;
}
break; break;
case EASYCSV_W: case EASYCSV_W:
if (csv_exist) { csv->file = fopen(fp, "w");
csv->file = fopen(csv->fp, "r+");
}
else {
csv->file = fopen(csv->fp, "w");
}
break; break;
default: default:
easycsv_error(EASYCSV_UNKNOWNIOMODE, NULL); easycsv_error(EASYCSV_UNKNOWNIOMODE, NULL);
@ -58,6 +40,15 @@ easycsv_init(const char *fp,
return NULL; 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 */ /* Calculate rows and cols if file exists */
if (csv_exist) { if (csv_exist) {
csv->rows = easycsv_rows(csv); csv->rows = easycsv_rows(csv);
@ -65,7 +56,33 @@ easycsv_init(const char *fp,
} }
if (mode == EASYCSV_W) { if (mode == EASYCSV_W) {
csv->temp = tmpfile();
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) { if (csv->temp == NULL) {
easycsv_error(EASYCSV_OPENFAIL, NULL); easycsv_error(EASYCSV_OPENFAIL, NULL);
easycsv_free(csv); easycsv_free(csv);
@ -79,11 +96,7 @@ easycsv_init(const char *fp,
void void
easycsv_free(easycsv *csv) easycsv_free(easycsv *csv)
{ {
if (csv != NULL) { if (csv == NULL) free(csv);
if (csv->file != NULL) fclose(csv->file);
if (csv->temp != NULL) fclose(csv->temp);
free(csv);
}
} }
/*** Acces, find ***/ /*** Acces, find ***/

View File

@ -31,8 +31,6 @@ easycsv_error(EASYCSV_ERROR error,
case EASYCSV_OVERMAXCOL: sprintf(s_error_msg, "int exceeds column 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_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_ZEROCOL: sprintf(s_error_msg, "parameterised column number is zero"); return;
case EASYCSV_MEMALLOC: sprintf(s_error_msg, "memory allocation failure"); return;
case EASYCSV_UNKNOWNIOMODE: sprintf(s_error_msg, "unknown file IO mode"); 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_OPENFAIL: sprintf(s_error_msg, "failed to open file"); return;
case EASYCSV_REOPENFAIL: sprintf(s_error_msg, "failed to reopen file"); return; case EASYCSV_REOPENFAIL: sprintf(s_error_msg, "failed to reopen file"); return;
@ -42,10 +40,8 @@ easycsv_error(EASYCSV_ERROR error,
case EASYCSV_UPDATEFAIL: sprintf(s_error_msg, "CSV file has failed to update"); 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_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_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_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_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_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; case EASYCSV_COLNUMFAIL: sprintf(s_error_msg, "failed to determine the column number of a value in the first row"); return;
case EASYCSV_FINDVALUEFAIL: sprintf(s_error_msg, "cannot find the value %s", error_msg); return; case EASYCSV_FINDVALUEFAIL: sprintf(s_error_msg, "cannot find the value %s", error_msg); return;

View File

@ -13,7 +13,6 @@ typedef enum EASYCSV_ERROR {
EASYCSV_OVERMAXCOL, // int exceeds col limit EASYCSV_OVERMAXCOL, // int exceeds col limit
EASYCSV_ZEROROW, EASYCSV_ZEROROW,
EASYCSV_ZEROCOL, EASYCSV_ZEROCOL,
EASYCSV_MEMALLOC, ///< memory allocation failure
/* File input/output errors */ /* File input/output errors */
EASYCSV_UNKNOWNIOMODE, // unknown file IO mode EASYCSV_UNKNOWNIOMODE, // unknown file IO mode

View File

@ -88,21 +88,46 @@ easycsv_columns(const easycsv *csv)
return col; return col;
} }
char* /* char* */
easycsv_get_row(const easycsv *csv, /* _easycsv_getrow(const _easycsv *csv, */
unsigned int row) /* const unsigned int row) */
{ /* { */
char *str = malloc(BUFSIZ); /* /\* ARGS CHECK *\/ */
easycsv_rewind(csv); /* if (csv == NULL) { */
/* _easycsv_printerror(csv, EASYCSV_NULLCSV); */
/* return NULL; */
/* } */
for (int i = 1; i < row; i++) { /* if (row > csv->rows) { */
fscanf(csv->file, "%*[^\n]\n", NULL); /* _easycsv_printerror(csv, EASYCSV_OVERMAXROW); */
} /* return NULL; */
/* } */
fscanf(csv->file, "%s\n", str); /* if (row == 0) { */
/* _easycsv_printerror(csv, EASYCSV_ZEROROW); */
/* return NULL; */
/* } */
/* /\* END ARGS CHECK *\/ */
return str; /* /\* 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 int
easycsv_rewind(const easycsv *csv) easycsv_rewind(const easycsv *csv)
@ -222,19 +247,24 @@ int _easycsv_checkifvalue(struct easycsv *csv, const int col, const int row)
/* return val; */ /* return val; */
/* } */ /* } */
char* /* char* */
easycsv_set_charp_to_value(const char *rowstr, /* _easycsv_setcharptovalue(const _easycsv *_priv, */
unsigned int col) /* const char *rowstr, */
{ /* const unsigned int col) */
/* Get first occurance of comma in str, the first value is ommited but not the comma */ /* { */
char *pch = (char*) rowstr; /* char *pch = rowstr; */
/* Repeat until desired col is found */
for (unsigned int i = 1; i < col; i++) {
pch = strpbrk(pch + 1, ",");
}
return pch; /* 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 */ /* int */
/* _easycsv_checkcsvandstring_one(const _easycsv *csv, */ /* _easycsv_checkcsvandstring_one(const _easycsv *csv, */

View File

@ -5,17 +5,15 @@
/*** Accès ***/ /*** Accès ***/
/** /* /\** */
* Returns string of a specific row, including '\n' character /* * Returns string of a specific row, including '\n' character */
* This function does not check parameters! /* * @param[in] const pointer to _easycsv structure */
* This function does not produce errors! /* * @param[in] row number */
* @param[in] const pointer to easycsv structure /* * @return string of row, NULL if error or none */
* @param[in] row number /* *\/ */
* @return string of row (heap-allocated) /* char* */
*/ /* _easycsv_getrow(const _easycsv*, */
char* /* unsigned int); */
easycsv_get_row(const easycsv*,
unsigned int);
/* /\** */ /* /\** */
/* * Returns column number of a named column *\/ */ /* * Returns column number of a named column *\/ */
@ -41,17 +39,11 @@ easycsv_get_row(const easycsv*,
/* const char*, */ /* const char*, */
/* const unsigned int); */ /* const unsigned int); */
/** /* /\* Returns char pointer to start of value in rowstr *\/ */
* Returns char pointer towards the n-th occurence of ',' in a given string /* char* */
* This function does not check parameters! /* _easycsv_setcharptovalue(const _easycsv*, */
* This function does not produce errors! /* const char*, */
* @param[in] string of row (string with multiple occurences of ',') /* const unsigned int); */
* @param[in] n-th occurence to place the char pointer
* @return char pointer towards the n-th occurence of ',' in a given string
*/
char*
easycsv_set_charp_to_value(const char*,
unsigned int);
/* /\* Insert value in row in specific column *\/ */ /* /\* Insert value in row in specific column *\/ */
/* char* */ /* char* */

View File

@ -1,67 +0,0 @@
#include <string.h>
#include <stdlib.h>
#include "string.h"
char*
easycsv_set_charp_to_value(const char *rowstr,
unsigned int col)
{
/* Get first occurance of comma in str, the first value is ommited but not the comma */
char *pch = (char*) rowstr;
/* Repeat until desired col is found */
for (unsigned int i = 1; i < col; i++) {
pch = strpbrk(pch + 1, ",");
}
return pch;
}
char*
easycsv_insert_string_row(const char* val,
const char* rowstr,
unsigned int col,
unsigned int col_max)
{
size_t rowstrst = strlen(rowstr);
size_t st = 0;
size_t commas = 0;
char *pch = NULL;
char *newstr = NULL;
/* column is within limit */
if (1 <= col && col <= col_max) {
/* Set pch to start of value in rowstr */
pch = easycsv_set_charp_to_value(rowstr, col);
/* Calculate size of existing value */
st = strcspn(pch, ",");
newstr = malloc(rowstrst - st + strlen(val) + 1);
/* Copy char to newstr before value (pch) */
strncpy(newstr, rowstr, pch - rowstr);
strcat(newstr, val);
/* Set pch to after value */
pch = strchr(rowstr, ',');
/* Calculate length of rest of string */
st = strlen(pch);
/* Concentate rest of string including NULL char */
strcat(newstr, pch);
}
else {
commas = col - col_max;
// 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
}
return newstr;
}

View File

@ -1,32 +0,0 @@
#ifndef EASYCSV_STRING_P_H
#define EASYCSV_STRING_P_H
/**
* Returns char pointer towards the n-th occurence of ',' in a given string
* This function does not check parameters!
* This function does not produce errors!
* @param[in] string of row (string with multiple occurences of ',')
* @param[in] n-th occurence to place the char pointer
* @return char pointer towards the n-th occurence of ',' in a given string
*/
char*
easycsv_set_charp_to_value(const char*,
unsigned int);
/**
* Insert a string in a comma-separated string of sub-strings in a specified position (by comma)
* @param[in] string to be inserted
* @param[in] comma-separated string
* @param[in] specified position of string
* @param[in] total number of sub-strings BEFORE manipulation
* @return heap-allocated string
*/
char*
easycsv_insert_string_row(const char*,
const char*,
unsigned int,
unsigned int);
#endif

View File

@ -1,19 +1,11 @@
TESTS = \ TESTS = \
check_easycsv \ check_easycsv
check_easycsv_string
noinst_PROGRAMS = \ noinst_PROGRAMS = \
check_easycsv \ check_easycsv
check_easycsv_string
check_easycsv_SOURCES = \ check_easycsv_SOURCES = \
check_easycsv.c check_easycsv.c
check_easycsv_CFLAGS = $(CHECK_CFLAGS) check_easycsv_CFLAGS = $(CHECK_CFLAGS)
check_easycsv_LDFLAGS = $(CHECK_LIBS) check_easycsv_LDFLAGS = $(CHECK_LIBS)
check_easycsv_LDADD = $(top_builddir)/src/libeasycsv.la check_easycsv_LDADD = $(top_builddir)/src/libeasycsv.la
check_easycsv_string_SOURCES = \
check_easycsv_string.c
check_easycsv_string_CFLAGS = $(CHECK_CFLAGS)
check_easycsv_string_LDFLAGS = $(CHECK_LIBS)
check_easycsv_string_LDADD = $(top_builddir)/src/libeasycsv_string.la

View File

@ -34,7 +34,6 @@ START_TEST(test_easycsv_init_write_2)
csv = easycsv_init(SAMPLE2_PATH, EASYCSV_W); csv = easycsv_init(SAMPLE2_PATH, EASYCSV_W);
ck_assert_ptr_nonnull(csv); ck_assert_ptr_nonnull(csv);
easycsv_free(csv); easycsv_free(csv);
remove(SAMPLE2_PATH);
} }
Suite* Suite*
@ -53,7 +52,7 @@ easycsv_constructor_suite(void)
tcase_add_test(tc_write, test_easycsv_init_write_2); tcase_add_test(tc_write, test_easycsv_init_write_2);
suite_add_tcase(s, tc_read); suite_add_tcase(s, tc_read);
suite_add_tcase(s, tc_write); //suite_add_tcase(s, tc_write);
return s; return s;
} }

View File

@ -1,35 +0,0 @@
#include <check.h>
#include "../src/easycsv_string.h"
START_TEST(test_easycsv_set_charp_to_value)
{
const char* str1 = "test,test,test,test";
char* c;
c = easycsv_set_charp_to_value(str1, 1);
ck_assert_ptr_eq(c, &str1[0]);
c = easycsv_set_charp_to_value(str1, 2);
ck_assert_ptr_eq(c, &str1[5]);
}
int
main(void)
{
int number_failed;
SRunner *sr;
Suite *s;
TCase *tc_string;
s = suite_create("string manipulation");
tc_string = tcase_create("string");
tcase_add_test(tc_string, test_easycsv_set_charp_to_value);
suite_add_tcase(s, tc_string);
sr = srunner_create(s);
srunner_run_all(sr, CK_VERBOSE);
number_failed = srunner_ntests_failed(sr);
srunner_free(sr);
return number_failed;
}