From 0820036f56a497e5a51f2530cdbb4a0f603f78d1 Mon Sep 17 00:00:00 2001 From: vms Date: Mon, 12 Apr 2021 12:30:51 +0300 Subject: [PATCH] use cvector --- Makefile | 3 +- cvector/cvector.h | 197 ++++++++++++++++++++++++++++++++++++++++++++++ src/legacy.c | 4 +- src/main.c | 6 +- src/sqliteInt.h | 7 ++ src/wrapper.c | 24 +++--- 6 files changed, 225 insertions(+), 16 deletions(-) create mode 100644 cvector/cvector.h diff --git a/Makefile b/Makefile index dd7923c..6c13c0b 100644 --- a/Makefile +++ b/Makefile @@ -154,7 +154,8 @@ SQLITE_FLAGS = \ -DSQLITE_ENABLE_OFFSET_SQL_FUNC\ -DSQLITE_ENABLE_DESERIALIZE\ -DSQLITE_INTROSPECTION_PRAGMAS\ - -DSQLITE_OMIT_POPEN + -DSQLITE_OMIT_POPEN\ + -DCVECTOR_LOGARITHMIC_GROWTH .PHONY: default all clean diff --git a/cvector/cvector.h b/cvector/cvector.h new file mode 100644 index 0000000..ce3ce51 --- /dev/null +++ b/cvector/cvector.h @@ -0,0 +1,197 @@ +#ifndef CVECTOR_H_ +#define CVECTOR_H_ + +#include /* for assert */ +#include /* for malloc/realloc/free */ + +/** + * @brief cvector_vector_type - The vector type used in this library + */ +#define cvector_vector_type(type) type * + +/** + * @brief cvector_set_capacity - For internal use, sets the capacity variable of the vector + * @param vec - the vector + * @param size - the new capacity to set + * @return void + */ +#define cvector_set_capacity(vec, size) \ + do { \ + if (vec) { \ + ((size_t *)(vec))[-1] = (size); \ + } \ + } while (0) + +/** + * @brief cvector_set_size - For internal use, sets the size variable of the vector + * @param vec - the vector + * @param size - the new capacity to set + * @return void + */ +#define cvector_set_size(vec, size) \ + do { \ + if (vec) { \ + ((size_t *)(vec))[-2] = (size); \ + } \ + } while (0) + +/** + * @brief cvector_capacity - gets the current capacity of the vector + * @param vec - the vector + * @return the capacity as a size_t + */ +#define cvector_capacity(vec) \ + ((vec) ? ((size_t *)(vec))[-1] : (size_t)0) + +/** + * @brief cvector_size - gets the current size of the vector + * @param vec - the vector + * @return the size as a size_t + */ +#define cvector_size(vec) \ + ((vec) ? ((size_t *)(vec))[-2] : (size_t)0) + +/** + * @brief cvector_empty - returns non-zero if the vector is empty + * @param vec - the vector + * @return non-zero if empty, zero if non-empty + */ +#define cvector_empty(vec) \ + (cvector_size(vec) == 0) + +/** + * @brief cvector_grow - For internal use, ensures that the vector is at least elements big + * @param vec - the vector + * @param count - the new capacity to set + * @return void + */ +#define cvector_grow(vec, count) \ + do { \ + const size_t cv_sz = (count) * sizeof(*(vec)) + (sizeof(size_t) * 2); \ + if (!(vec)) { \ + size_t *cv_p = malloc(cv_sz); \ + assert(cv_p); \ + (vec) = (void *)(&cv_p[2]); \ + cvector_set_capacity((vec), (count)); \ + cvector_set_size((vec), 0); \ + } else { \ + size_t *cv_p1 = &((size_t *)(vec))[-2]; \ + size_t *cv_p2 = realloc(cv_p1, (cv_sz)); \ + assert(cv_p2); \ + (vec) = (void *)(&cv_p2[2]); \ + cvector_set_capacity((vec), (count)); \ + } \ + } while (0) + +/** + * @brief cvector_pop_back - removes the last element from the vector + * @param vec - the vector + * @return void + */ +#define cvector_pop_back(vec) \ + do { \ + cvector_set_size((vec), cvector_size(vec) - 1); \ + } while (0) + +/** + * @brief cvector_erase - removes the element at index i from the vector + * @param vec - the vector + * @param i - index of element to remove + * @return void + */ +#define cvector_erase(vec, i) \ + do { \ + if (vec) { \ + const size_t cv_sz = cvector_size(vec); \ + if ((i) < cv_sz) { \ + cvector_set_size((vec), cv_sz - 1); \ + size_t cv_x; \ + for (cv_x = (i); cv_x < (cv_sz - 1); ++cv_x) { \ + (vec)[cv_x] = (vec)[cv_x + 1]; \ + } \ + } \ + } \ + } while (0) + +/** + * @brief cvector_free - frees all memory associated with the vector + * @param vec - the vector + * @return void + */ +#define cvector_free(vec) \ + do { \ + if (vec) { \ + size_t *p1 = &((size_t *)(vec))[-2]; \ + free(p1); \ + } \ + } while (0) + +/** + * @brief cvector_begin - returns an iterator to first element of the vector + * @param vec - the vector + * @return a pointer to the first element (or NULL) + */ +#define cvector_begin(vec) \ + (vec) + +/** + * @brief cvector_end - returns an iterator to one past the last element of the vector + * @param vec - the vector + * @return a pointer to one past the last element (or NULL) + */ +#define cvector_end(vec) \ + ((vec) ? &((vec)[cvector_size(vec)]) : NULL) + +/* user request to use logarithmic growth algorithm */ +#ifdef CVECTOR_LOGARITHMIC_GROWTH + +/** + * @brief cvector_push_back - adds an element to the end of the vector + * @param vec - the vector + * @param value - the value to add + * @return void + */ +#define cvector_push_back(vec, value) \ + do { \ + size_t cv_cap = cvector_capacity(vec); \ + if (cv_cap <= cvector_size(vec)) { \ + cvector_grow((vec), !cv_cap ? cv_cap + 1 : cv_cap * 2); \ + } \ + vec[cvector_size(vec)] = (value); \ + cvector_set_size((vec), cvector_size(vec) + 1); \ + } while (0) + +#else + +/** + * @brief cvector_push_back - adds an element to the end of the vector + * @param vec - the vector + * @param value - the value to add + * @return void + */ +#define cvector_push_back(vec, value) \ + do { \ + size_t cv_cap = cvector_capacity(vec); \ + if (cv_cap <= cvector_size(vec)) { \ + cvector_grow((vec), cv_cap + 1); \ + } \ + vec[cvector_size(vec)] = (value); \ + cvector_set_size((vec), cvector_size(vec) + 1); \ + } while (0) + +#endif /* CVECTOR_LOGARITHMIC_GROWTH */ + +/** + * @brief cvector_copy - copy a vector + * @param from - the original vector + * @param to - destination to which the function copy to + * @return void + */ +#define cvector_copy(from, to) \ + do { \ + for(size_t i = 0; i < cvector_size(from); i++) { \ + cvector_push_back(to, from[i]); \ + } \ + } while (0) \ + +#endif /* CVECTOR_H_ */ diff --git a/src/legacy.c b/src/legacy.c index d3dcc94..4b77b81 100644 --- a/src/legacy.c +++ b/src/legacy.c @@ -30,7 +30,7 @@ */ void sqlite3_exec_( sqlite3 *db, /* The database on which the SQL executes */ - char *zSql, /* The SQL to be executed */ + char *zSql, /* The SQL to be executed */ int zSql_len, sqlite3_callback xCallback, /* Invoke this callback routine */ void *pArg /* First argument to xCallback() */ @@ -38,7 +38,7 @@ void sqlite3_exec_( zSql[zSql_len] = '\x00'; char *pzErrMsg = 0; - const int ret_code = sqlite3_exec(db, new_zSql, xCallback, pArg, &pzErrMsg); + const int ret_code = sqlite3_exec(db, zSql, xCallback, pArg, &pzErrMsg); free(zSql); int *result = malloc(3*8); diff --git a/src/main.c b/src/main.c index 072776b..f9490e1 100644 --- a/src/main.c +++ b/src/main.c @@ -3437,10 +3437,10 @@ int sqlite3_open( } void sqlite3_open_v2_( - const char *filename, /* Database filename (UTF-8) */ + char *filename, /* Database filename (UTF-8) */ int filename_len, int flags, /* Flags */ - const char *zVfs, /* Name of VFS module to use */ + char *zVfs, /* Name of VFS module to use */ int zVfs_len ) __EXPORT_NAME(sqlite3_open_v2) { // this strings were allocated by the allocate function that allocates 1 byte more for null character @@ -3449,7 +3449,7 @@ void sqlite3_open_v2_( sqlite3 *ppDb; - const int ret_code = sqlite3_open_v2(new_filename, &ppDb, (unsigned int)flags, new_zVfs); + const int ret_code = sqlite3_open_v2(filename, &ppDb, (unsigned int)flags, zVfs); // cleanup strings passed from the IT side free(filename); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 53e7095..f6cc172 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -4908,4 +4908,11 @@ void sqlite3VectorErrorMsg(Parse*, Expr*); const char **sqlite3CompileOptions(int *pnOpt); #endif +#ifndef __sqlite_unmodified_upstram +void add_object_to_release(void *object); + +void set_result_ptr(const char *ptr); +void set_result_size(int size); +#endif + #endif /* SQLITEINT_H */ diff --git a/src/wrapper.c b/src/wrapper.c index bf5899e..bdd7eaa 100644 --- a/src/wrapper.c +++ b/src/wrapper.c @@ -1,26 +1,30 @@ -#include #include "sqliteInt.h" +#include "../cvector/cvector.h" + +#include const char *RESULT_PTR; int RESULT_SIZE; -void* OBJECTS_TO_RELEASE[]; -unsigned int OBJECTS_TO_RELEASE_COUNT; +cvector_vector_type(void *) OBJECTS_TO_RELEASE; void* allocate(size_t size) { + // this +1 is needed to append then zero byte to strings passing to this module. return malloc(size + 1); } void release_objects() { - for(unsigned int i = 0; i < OBJECTS_TO_RELEASE_COUNT; ++i) { - free(OBJECTS_TO_RELEASE[i]); - } + const unsigned int objects_count = cvector_size(OBJECTS_TO_RELEASE); + for (unsigned int obj_id = objects_count; obj_id > 0; --obj_id) { + void *object = OBJECTS_TO_RELEASE[obj_id-1]; + free(object); - OBJECTS_TO_RELEASE_COUNT = 0; + cvector_pop_back(OBJECTS_TO_RELEASE); + } } void add_object_to_release(void *object) { - + cvector_push_back(OBJECTS_TO_RELEASE, object); } void set_result_ptr(const char *ptr) { @@ -40,6 +44,6 @@ const char *get_result_ptr() { } int main() { - // the main purpose of this empty main is to initialize WASi subsystem + // the main purpose of this empty main is to initialize WASI subsystem return 0; -} \ No newline at end of file +}