Replace SQLite3 with TinyCDB; javascript compile output

This commit is contained in:
John Alanbrook 2023-09-05 15:44:52 +00:00
parent a9468d0e95
commit 075b9950e0
24 changed files with 1434 additions and 250816 deletions

View file

@ -16,6 +16,10 @@ OPT ?= 0
INFO := INFO :=
LD = $(CC) LD = $(CC)
ifeq ($(CC), clang)
AR = llvm-ar
endif
ifeq ($(DBG),1) ifeq ($(DBG),1)
CFLAGS += -g CFLAGS += -g
INFO += dbg INFO += dbg
@ -94,7 +98,7 @@ OBJS := $(addprefix $(BIN)/obj/, $(OBJS))
engineincs != find source/engine -maxdepth 1 -type d engineincs != find source/engine -maxdepth 1 -type d
includeflag != find source -type d -name include includeflag != find source -type d -name include
includeflag += $(engineincs) source/engine/thirdparty/Nuklear includeflag += $(engineincs) source/engine/thirdparty/Nuklear source/engine/thirdparty/tinycdb-0.78
includeflag := $(addprefix -I, $(includeflag)) includeflag := $(addprefix -I, $(includeflag))
WARNING_FLAGS = -Wno-incompatible-function-pointer-types -Wno-incompatible-pointer-types #-Wall -Wno-incompatible-function-pointer-types -Wno-unused-function# -pedantic -Wextra -Wwrite-strings -Wno-incompatible-function-pointer-types -Wno-incompatible-pointer-types -Wno-unused-function -Wno-int-conversion WARNING_FLAGS = -Wno-incompatible-function-pointer-types -Wno-incompatible-pointer-types #-Wall -Wno-incompatible-function-pointer-types -Wno-unused-function# -pedantic -Wextra -Wwrite-strings -Wno-incompatible-function-pointer-types -Wno-incompatible-pointer-types -Wno-unused-function -Wno-int-conversion
@ -126,9 +130,9 @@ install: $(DISTDIR)/$(DIST)
# @unzip $(DISTDIR)/$(DIST) -d $(DESTDIR) # @unzip $(DISTDIR)/$(DIST) -d $(DESTDIR)
@$(UNZIP) @$(UNZIP)
$(BIN)/$(NAME): $(BIN)/libengine.a $(BIN)/libquickjs.lto.a $(BIN)/$(NAME): $(BIN)/libengine.a $(BIN)/libquickjs.a
@echo Linking $(NAME) @echo Linking $(NAME)
$(LD) $^ $(LDFLAGS) $(LDLIBS) -o $@ $(LD) $^ $(LDFLAGS) -L$(BIN) $(LDLIBS) -o $@
@echo Finished build @echo Finished build
$(DISTDIR)/$(DIST): $(BIN)/$(NAME) source/shaders/* $(SCRIPTS) assets/* $(DISTDIR)/$(DIST): $(BIN)/$(NAME) source/shaders/* $(SCRIPTS) assets/*
@ -142,7 +146,7 @@ $(DISTDIR)/$(DIST): $(BIN)/$(NAME) source/shaders/* $(SCRIPTS) assets/*
$(BIN)/libengine.a: $(OBJS) $(BIN)/libengine.a: $(OBJS)
@$(AR) r $@ $^ @$(AR) r $@ $^
$(BIN)/libquickjs.lto.a: $(BIN)/libquickjs.a:
make -C quickjs clean make -C quickjs clean
make -C quickjs libquickjs.a libquickjs.lto.a CC=$(CC) make -C quickjs libquickjs.a libquickjs.lto.a CC=$(CC)
cp quickjs/libquickjs.* $(BIN) cp quickjs/libquickjs.* $(BIN)
@ -150,7 +154,7 @@ $(BIN)/libquickjs.lto.a:
$(OBJDIR)/%.o:%.c $(OBJDIR)/%.o:%.c
@mkdir -p $(@D) @mkdir -p $(@D)
@echo Making C object $@ @echo Making C object $@
@$(CC) $(CFLAGS) -c $^ -o $@ @$(CC) $(CFLAGS) -c $< -o $@
clean: clean:
@echo Cleaning project @echo Cleaning project

View file

@ -13,7 +13,8 @@
#include <unistd.h> #include <unistd.h>
#include "font.h" #include "font.h"
#include <sqlite3.h> #include <fcntl.h>
#include "cdb.h"
#ifndef __EMSCRIPTEN__ #ifndef __EMSCRIPTEN__
#include <ftw.h> #include <ftw.h>
@ -34,10 +35,9 @@ struct dirent *c_dirent = NULL;
char pathbuf[MAXPATH + 1]; char pathbuf[MAXPATH + 1];
const char *DB_NAME = "test.db"; const char *DB_NAME = "test.db";
static sqlite3 *game_db = NULL;
static sqlite3_stmt *fopen_stmt;
#define sqlite_perr(db) YughError("Database error code %d, %s: %s", sqlite3_errcode(db), sqlite3_errstr(sqlite3_errcode(db)), sqlite3_errmsg(db)); static struct cdb game_cdb;
static int loaded_cdb = 0;
void resources_init() { void resources_init() {
DATA_PATH = malloc(MAXPATH); DATA_PATH = malloc(MAXPATH);
@ -47,17 +47,10 @@ void resources_init() {
if (!PREF_PATH) if (!PREF_PATH)
PREF_PATH = strdup("./tmp/"); PREF_PATH = strdup("./tmp/");
if (sqlite3_open_v2("test.db", &game_db, SQLITE_OPEN_READONLY, NULL)) { int fd;
sqlite_perr(game_db); fd = open("test.cdb", O_RDONLY);
sqlite3_close(game_db); cdb_init(&game_cdb, fd);
game_db = NULL; loaded_cdb = 1;
return;
}
if (sqlite3_prepare_v2(game_db, "select data from files where path=?1", -1, &fopen_stmt, NULL)) {
sqlite_perr(game_db);
}
} }
char *get_filename_from_path(char *path, int extension) { char *get_filename_from_path(char *path, int extension) {
@ -155,25 +148,15 @@ char *strdup(const char *s) {
unsigned char *slurp_file(const char *filename, long *size) unsigned char *slurp_file(const char *filename, long *size)
{ {
if (game_db) { if (cdb_find(&game_cdb, filename, strlen(filename))) {
sqlite3_reset(fopen_stmt); unsigned vlen, vpos;
vpos = cdb_datapos(&game_cdb);
if (sqlite3_bind_text(fopen_stmt, 1, filename, -1, NULL)) { vlen = cdb_datalen(&game_cdb);
sqlite_perr(game_db); char *data = malloc(vlen);
goto jump; cdb_read(&game_cdb, data, vlen, vpos);
}
if (sqlite3_step(fopen_stmt) == SQLITE_ERROR) {
sqlite_perr(game_db);
goto jump;
}
char *data = sqlite3_column_blob(fopen_stmt,0);
if (!data)
goto jump;
return strdup(data); return strdup(data);
} }
FILE *f; FILE *f;
jump: jump:
@ -193,27 +176,14 @@ unsigned char *slurp_file(const char *filename, long *size)
return slurp; return slurp;
} }
char *slurp_text(const char *filename) { char *slurp_text(const char *filename)
if (game_db) { {
if (sqlite3_reset(fopen_stmt)) { if (cdb_find(&game_cdb, filename, strlen(filename))) {
sqlite_perr(game_db); unsigned vlen, vpos;
goto jump; vpos = cdb_datapos(&game_cdb);
} vlen = cdb_datalen(&game_cdb);
char *data = malloc(vlen);
if (sqlite3_bind_text(fopen_stmt, 1, filename, -1, NULL)) { cdb_read(&game_cdb, data, vlen, vpos);
sqlite_perr(game_db);
goto jump;
}
if (sqlite3_step(fopen_stmt) == SQLITE_ERROR) {
sqlite_perr(game_db);
goto jump;
}
char *data = sqlite3_column_text(fopen_stmt,0);
if (!data)
goto jump;
return strdup(data); return strdup(data);
} }
@ -251,8 +221,7 @@ int slurp_write(const char *txt, const char *filename) {
} }
#ifndef __EMSCRIPTEN__ #ifndef __EMSCRIPTEN__
static sqlite3 *pack_db = NULL; static struct cdb_make cdbm;
static sqlite3_stmt *pack_stmt;
static const char *pack_ext[] = {".qoi", ".qoa", ".js", ".wav", ".mp3", ".png", ".sf2", ".midi", ".lvl", ".glsl"}; static const char *pack_ext[] = {".qoi", ".qoa", ".js", ".wav", ".mp3", ".png", ".sf2", ".midi", ".lvl", ".glsl"};
@ -274,48 +243,26 @@ static int ftw_pack(const char *path, const struct stat *sb, int flag)
} }
if (!pack) return 0; if (!pack) return 0;
printf("Packing file %s\n", path);
long len; long len;
void *file = slurp_file(path, &len); void *file = slurp_file(path, &len);
if (sqlite3_bind_text(pack_stmt, 1, &path[2], -1, NULL)) cdb_make_add(&cdbm, &path[2], strlen(&path[2]), file, len);
sqlite_perr(pack_db);
if (sqlite3_bind_blob(pack_stmt, 2, file, len, NULL))
sqlite_perr(pack_db);
if (sqlite3_step(pack_stmt) != SQLITE_DONE)
sqlite_perr(pack_db);
free(file); free(file);
if (sqlite3_reset(pack_stmt))
sqlite_perr(pack_db);
return 0; return 0;
} }
void pack_engine() void pack_engine()
{ {
sqlite3 *db; int fd;
char *zErr = 0; char *key, *va;
if (sqlite3_open("test.db", &db)) { unsigned klen, vlen;
sqlite_perr(db); fd = open("test.cdb", O_RDWR|O_CREAT);
sqlite3_close(db); cdb_make_start(&cdbm, fd);
return;
}
if(sqlite3_exec(db, "create table files ( path text, data blob);", NULL, NULL, NULL))
sqlite_perr(db);
pack_db = db;
if(sqlite3_prepare_v2(db, "insert into files (path, data) values (?1, ?2)", -1, &pack_stmt, NULL)) {
sqlite_perr(db);
sqlite3_close(db);
return;
}
ftw(".", ftw_pack, 20); ftw(".", ftw_pack, 20);
cdb_make_finish(&cdbm);
sqlite3_close(db);
} }
#else #else
void pack_engine(){ void pack_engine(){

View file

@ -1,7 +1,5 @@
#include "script.h" #include "script.h"
#include "stdarg.h"
#include "log.h" #include "log.h"
#include "stdio.h" #include "stdio.h"
@ -42,6 +40,7 @@ void script_startup() {
rt = JS_NewRuntime(); rt = JS_NewRuntime();
JS_SetMaxStackSize(rt, 0); JS_SetMaxStackSize(rt, 0);
js = JS_NewContext(rt); js = JS_NewContext(rt);
ffi_load(); ffi_load();
for (int i = 0; i < 100; i++) for (int i = 0; i < 100; i++)
@ -98,16 +97,12 @@ void script_evalf(const char *format, ...)
JS_FreeValue(js,obj); JS_FreeValue(js,obj);
} }
void compile_script(const char *file) { uint8_t *compile_script(const char *file) {
const char *script = slurp_text(file); const char *script = slurp_text(file);
JSValue obj = JS_Eval(js, script, strlen(script), file, JS_EVAL_FLAG_COMPILE_ONLY | JS_EVAL_TYPE_GLOBAL | JS_EVAL_FLAGS); JSValue obj = JS_Eval(js, script, strlen(script), file, JS_EVAL_FLAG_COMPILE_ONLY | JS_EVAL_TYPE_GLOBAL | JS_EVAL_FLAGS);
size_t out_len; size_t out_len;
uint8_t *out; uint8_t *out;
out = JS_WriteObject(js, &out_len, obj, JS_WRITE_OBJ_BYTECODE); return JS_WriteObject(js, &out_len, obj, JS_WRITE_OBJ_BYTECODE);
FILE *f = fopen("out.jsc", "w");
fwrite(out, sizeof out[0], out_len, f);
fclose(f);
} }
struct callee stacktrace_callee; struct callee stacktrace_callee;

View file

@ -58,6 +58,6 @@ void call_physics(double dt);
void register_draw(struct callee c); void register_draw(struct callee c);
void call_draw(); void call_draw();
void compile_script(const char *file); uint8_t *compile_script(const char *file);
#endif #endif

View file

@ -1,113 +0,0 @@
This package contains:
* the SQLite library amalgamation source code file: sqlite3.c
* the sqlite3.h and sqlite3ext.h header files that define the C-language
interface to the sqlite3.c library file
* the shell.c file used to build the sqlite3 command-line shell program
* autoconf/automake installation infrastucture for building on POSIX
compliant systems
* a Makefile.msc, sqlite3.rc, and Replace.cs for building with Microsoft
Visual C++ on Windows
SUMMARY OF HOW TO BUILD
=======================
Unix: ./configure; make
Windows: nmake /f Makefile.msc
BUILDING ON POSIX
=================
The generic installation instructions for autoconf/automake are found
in the INSTALL file.
The following SQLite specific boolean options are supported:
--enable-readline use readline in shell tool [default=yes]
--enable-threadsafe build a thread-safe library [default=yes]
--enable-dynamic-extensions support loadable extensions [default=yes]
The default value for the CFLAGS variable (options passed to the C
compiler) includes debugging symbols in the build, resulting in larger
binaries than are necessary. Override it on the configure command
line like this:
$ CFLAGS="-Os" ./configure
to produce a smaller installation footprint.
Other SQLite compilation parameters can also be set using CFLAGS. For
example:
$ CFLAGS="-Os -DSQLITE_THREADSAFE=0" ./configure
BUILDING WITH MICROSOFT VISUAL C++
==================================
To compile for Windows using Microsoft Visual C++:
$ nmake /f Makefile.msc
Using Microsoft Visual C++ 2005 (or later) is recommended. Several Windows
platform variants may be built by adding additional macros to the NMAKE
command line.
Building for WinRT 8.0
----------------------
FOR_WINRT=1
Using Microsoft Visual C++ 2012 (or later) is required. When using the
above, something like the following macro will need to be added to the
NMAKE command line as well:
"NSDKLIBPATH=%WindowsSdkDir%\..\8.0\lib\win8\um\x86"
Building for WinRT 8.1
----------------------
FOR_WINRT=1
Using Microsoft Visual C++ 2013 (or later) is required. When using the
above, something like the following macro will need to be added to the
NMAKE command line as well:
"NSDKLIBPATH=%WindowsSdkDir%\..\8.1\lib\winv6.3\um\x86"
Building for UWP 10.0
---------------------
FOR_WINRT=1 FOR_UWP=1
Using Microsoft Visual C++ 2015 (or later) is required. When using the
above, something like the following macros will need to be added to the
NMAKE command line as well:
"NSDKLIBPATH=%WindowsSdkDir%\..\10\lib\10.0.10586.0\um\x86"
"PSDKLIBPATH=%WindowsSdkDir%\..\10\lib\10.0.10586.0\um\x86"
"NUCRTLIBPATH=%UniversalCRTSdkDir%\..\10\lib\10.0.10586.0\ucrt\x86"
Building for the Windows 10 SDK
-------------------------------
FOR_WIN10=1
Using Microsoft Visual C++ 2015 (or later) is required. When using the
above, no other macros should be needed on the NMAKE command line.
Other preprocessor defines
--------------------------
Additionally, preprocessor defines may be specified by using the OPTS macro
on the NMAKE command line. However, not all possible preprocessor defines
may be specified in this manner as some require the amalgamation to be built
with them enabled (see http://www.sqlite.org/compile.html). For example, the
following will work:
"OPTS=-DSQLITE_ENABLE_STAT4=1 -DSQLITE_ENABLE_JSON1=1"
However, the following will not compile unless the amalgamation was built
with it enabled:
"OPTS=-DSQLITE_ENABLE_UPDATE_DELETE_LIMIT=1"

File diff suppressed because it is too large Load diff

View file

@ -1,675 +0,0 @@
/*
** 2006 June 7
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
*************************************************************************
** This header file defines the SQLite interface for use by
** shared libraries that want to be imported as extensions into
** an SQLite instance. Shared libraries that intend to be loaded
** as extensions by SQLite should #include this file instead of
** sqlite3.h.
*/
#ifndef SQLITE3EXT_H
#define SQLITE3EXT_H
#include "sqlite3.h"
/*
** The following structure holds pointers to all of the SQLite API
** routines.
**
** WARNING: In order to maintain backwards compatibility, add new
** interfaces to the end of this structure only. If you insert new
** interfaces in the middle of this structure, then older different
** versions of SQLite will not be able to load each other's shared
** libraries!
*/
struct sqlite3_api_routines {
void * (*aggregate_context)(sqlite3_context*,int nBytes);
int (*aggregate_count)(sqlite3_context*);
int (*bind_blob)(sqlite3_stmt*,int,const void*,int n,void(*)(void*));
int (*bind_double)(sqlite3_stmt*,int,double);
int (*bind_int)(sqlite3_stmt*,int,int);
int (*bind_int64)(sqlite3_stmt*,int,sqlite_int64);
int (*bind_null)(sqlite3_stmt*,int);
int (*bind_parameter_count)(sqlite3_stmt*);
int (*bind_parameter_index)(sqlite3_stmt*,const char*zName);
const char * (*bind_parameter_name)(sqlite3_stmt*,int);
int (*bind_text)(sqlite3_stmt*,int,const char*,int n,void(*)(void*));
int (*bind_text16)(sqlite3_stmt*,int,const void*,int,void(*)(void*));
int (*bind_value)(sqlite3_stmt*,int,const sqlite3_value*);
int (*busy_handler)(sqlite3*,int(*)(void*,int),void*);
int (*busy_timeout)(sqlite3*,int ms);
int (*changes)(sqlite3*);
int (*close)(sqlite3*);
int (*collation_needed)(sqlite3*,void*,void(*)(void*,sqlite3*,
int eTextRep,const char*));
int (*collation_needed16)(sqlite3*,void*,void(*)(void*,sqlite3*,
int eTextRep,const void*));
const void * (*column_blob)(sqlite3_stmt*,int iCol);
int (*column_bytes)(sqlite3_stmt*,int iCol);
int (*column_bytes16)(sqlite3_stmt*,int iCol);
int (*column_count)(sqlite3_stmt*pStmt);
const char * (*column_database_name)(sqlite3_stmt*,int);
const void * (*column_database_name16)(sqlite3_stmt*,int);
const char * (*column_decltype)(sqlite3_stmt*,int i);
const void * (*column_decltype16)(sqlite3_stmt*,int);
double (*column_double)(sqlite3_stmt*,int iCol);
int (*column_int)(sqlite3_stmt*,int iCol);
sqlite_int64 (*column_int64)(sqlite3_stmt*,int iCol);
const char * (*column_name)(sqlite3_stmt*,int);
const void * (*column_name16)(sqlite3_stmt*,int);
const char * (*column_origin_name)(sqlite3_stmt*,int);
const void * (*column_origin_name16)(sqlite3_stmt*,int);
const char * (*column_table_name)(sqlite3_stmt*,int);
const void * (*column_table_name16)(sqlite3_stmt*,int);
const unsigned char * (*column_text)(sqlite3_stmt*,int iCol);
const void * (*column_text16)(sqlite3_stmt*,int iCol);
int (*column_type)(sqlite3_stmt*,int iCol);
sqlite3_value* (*column_value)(sqlite3_stmt*,int iCol);
void * (*commit_hook)(sqlite3*,int(*)(void*),void*);
int (*complete)(const char*sql);
int (*complete16)(const void*sql);
int (*create_collation)(sqlite3*,const char*,int,void*,
int(*)(void*,int,const void*,int,const void*));
int (*create_collation16)(sqlite3*,const void*,int,void*,
int(*)(void*,int,const void*,int,const void*));
int (*create_function)(sqlite3*,const char*,int,int,void*,
void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
void (*xFinal)(sqlite3_context*));
int (*create_function16)(sqlite3*,const void*,int,int,void*,
void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
void (*xFinal)(sqlite3_context*));
int (*create_module)(sqlite3*,const char*,const sqlite3_module*,void*);
int (*data_count)(sqlite3_stmt*pStmt);
sqlite3 * (*db_handle)(sqlite3_stmt*);
int (*declare_vtab)(sqlite3*,const char*);
int (*enable_shared_cache)(int);
int (*errcode)(sqlite3*db);
const char * (*errmsg)(sqlite3*);
const void * (*errmsg16)(sqlite3*);
int (*exec)(sqlite3*,const char*,sqlite3_callback,void*,char**);
int (*expired)(sqlite3_stmt*);
int (*finalize)(sqlite3_stmt*pStmt);
void (*free)(void*);
void (*free_table)(char**result);
int (*get_autocommit)(sqlite3*);
void * (*get_auxdata)(sqlite3_context*,int);
int (*get_table)(sqlite3*,const char*,char***,int*,int*,char**);
int (*global_recover)(void);
void (*interruptx)(sqlite3*);
sqlite_int64 (*last_insert_rowid)(sqlite3*);
const char * (*libversion)(void);
int (*libversion_number)(void);
void *(*malloc)(int);
char * (*mprintf)(const char*,...);
int (*open)(const char*,sqlite3**);
int (*open16)(const void*,sqlite3**);
int (*prepare)(sqlite3*,const char*,int,sqlite3_stmt**,const char**);
int (*prepare16)(sqlite3*,const void*,int,sqlite3_stmt**,const void**);
void * (*profile)(sqlite3*,void(*)(void*,const char*,sqlite_uint64),void*);
void (*progress_handler)(sqlite3*,int,int(*)(void*),void*);
void *(*realloc)(void*,int);
int (*reset)(sqlite3_stmt*pStmt);
void (*result_blob)(sqlite3_context*,const void*,int,void(*)(void*));
void (*result_double)(sqlite3_context*,double);
void (*result_error)(sqlite3_context*,const char*,int);
void (*result_error16)(sqlite3_context*,const void*,int);
void (*result_int)(sqlite3_context*,int);
void (*result_int64)(sqlite3_context*,sqlite_int64);
void (*result_null)(sqlite3_context*);
void (*result_text)(sqlite3_context*,const char*,int,void(*)(void*));
void (*result_text16)(sqlite3_context*,const void*,int,void(*)(void*));
void (*result_text16be)(sqlite3_context*,const void*,int,void(*)(void*));
void (*result_text16le)(sqlite3_context*,const void*,int,void(*)(void*));
void (*result_value)(sqlite3_context*,sqlite3_value*);
void * (*rollback_hook)(sqlite3*,void(*)(void*),void*);
int (*set_authorizer)(sqlite3*,int(*)(void*,int,const char*,const char*,
const char*,const char*),void*);
void (*set_auxdata)(sqlite3_context*,int,void*,void (*)(void*));
char * (*xsnprintf)(int,char*,const char*,...);
int (*step)(sqlite3_stmt*);
int (*table_column_metadata)(sqlite3*,const char*,const char*,const char*,
char const**,char const**,int*,int*,int*);
void (*thread_cleanup)(void);
int (*total_changes)(sqlite3*);
void * (*trace)(sqlite3*,void(*xTrace)(void*,const char*),void*);
int (*transfer_bindings)(sqlite3_stmt*,sqlite3_stmt*);
void * (*update_hook)(sqlite3*,void(*)(void*,int ,char const*,char const*,
sqlite_int64),void*);
void * (*user_data)(sqlite3_context*);
const void * (*value_blob)(sqlite3_value*);
int (*value_bytes)(sqlite3_value*);
int (*value_bytes16)(sqlite3_value*);
double (*value_double)(sqlite3_value*);
int (*value_int)(sqlite3_value*);
sqlite_int64 (*value_int64)(sqlite3_value*);
int (*value_numeric_type)(sqlite3_value*);
const unsigned char * (*value_text)(sqlite3_value*);
const void * (*value_text16)(sqlite3_value*);
const void * (*value_text16be)(sqlite3_value*);
const void * (*value_text16le)(sqlite3_value*);
int (*value_type)(sqlite3_value*);
char *(*vmprintf)(const char*,va_list);
/* Added ??? */
int (*overload_function)(sqlite3*, const char *zFuncName, int nArg);
/* Added by 3.3.13 */
int (*prepare_v2)(sqlite3*,const char*,int,sqlite3_stmt**,const char**);
int (*prepare16_v2)(sqlite3*,const void*,int,sqlite3_stmt**,const void**);
int (*clear_bindings)(sqlite3_stmt*);
/* Added by 3.4.1 */
int (*create_module_v2)(sqlite3*,const char*,const sqlite3_module*,void*,
void (*xDestroy)(void *));
/* Added by 3.5.0 */
int (*bind_zeroblob)(sqlite3_stmt*,int,int);
int (*blob_bytes)(sqlite3_blob*);
int (*blob_close)(sqlite3_blob*);
int (*blob_open)(sqlite3*,const char*,const char*,const char*,sqlite3_int64,
int,sqlite3_blob**);
int (*blob_read)(sqlite3_blob*,void*,int,int);
int (*blob_write)(sqlite3_blob*,const void*,int,int);
int (*create_collation_v2)(sqlite3*,const char*,int,void*,
int(*)(void*,int,const void*,int,const void*),
void(*)(void*));
int (*file_control)(sqlite3*,const char*,int,void*);
sqlite3_int64 (*memory_highwater)(int);
sqlite3_int64 (*memory_used)(void);
sqlite3_mutex *(*mutex_alloc)(int);
void (*mutex_enter)(sqlite3_mutex*);
void (*mutex_free)(sqlite3_mutex*);
void (*mutex_leave)(sqlite3_mutex*);
int (*mutex_try)(sqlite3_mutex*);
int (*open_v2)(const char*,sqlite3**,int,const char*);
int (*release_memory)(int);
void (*result_error_nomem)(sqlite3_context*);
void (*result_error_toobig)(sqlite3_context*);
int (*sleep)(int);
void (*soft_heap_limit)(int);
sqlite3_vfs *(*vfs_find)(const char*);
int (*vfs_register)(sqlite3_vfs*,int);
int (*vfs_unregister)(sqlite3_vfs*);
int (*xthreadsafe)(void);
void (*result_zeroblob)(sqlite3_context*,int);
void (*result_error_code)(sqlite3_context*,int);
int (*test_control)(int, ...);
void (*randomness)(int,void*);
sqlite3 *(*context_db_handle)(sqlite3_context*);
int (*extended_result_codes)(sqlite3*,int);
int (*limit)(sqlite3*,int,int);
sqlite3_stmt *(*next_stmt)(sqlite3*,sqlite3_stmt*);
const char *(*sql)(sqlite3_stmt*);
int (*status)(int,int*,int*,int);
int (*backup_finish)(sqlite3_backup*);
sqlite3_backup *(*backup_init)(sqlite3*,const char*,sqlite3*,const char*);
int (*backup_pagecount)(sqlite3_backup*);
int (*backup_remaining)(sqlite3_backup*);
int (*backup_step)(sqlite3_backup*,int);
const char *(*compileoption_get)(int);
int (*compileoption_used)(const char*);
int (*create_function_v2)(sqlite3*,const char*,int,int,void*,
void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
void (*xFinal)(sqlite3_context*),
void(*xDestroy)(void*));
int (*db_config)(sqlite3*,int,...);
sqlite3_mutex *(*db_mutex)(sqlite3*);
int (*db_status)(sqlite3*,int,int*,int*,int);
int (*extended_errcode)(sqlite3*);
void (*log)(int,const char*,...);
sqlite3_int64 (*soft_heap_limit64)(sqlite3_int64);
const char *(*sourceid)(void);
int (*stmt_status)(sqlite3_stmt*,int,int);
int (*strnicmp)(const char*,const char*,int);
int (*unlock_notify)(sqlite3*,void(*)(void**,int),void*);
int (*wal_autocheckpoint)(sqlite3*,int);
int (*wal_checkpoint)(sqlite3*,const char*);
void *(*wal_hook)(sqlite3*,int(*)(void*,sqlite3*,const char*,int),void*);
int (*blob_reopen)(sqlite3_blob*,sqlite3_int64);
int (*vtab_config)(sqlite3*,int op,...);
int (*vtab_on_conflict)(sqlite3*);
/* Version 3.7.16 and later */
int (*close_v2)(sqlite3*);
const char *(*db_filename)(sqlite3*,const char*);
int (*db_readonly)(sqlite3*,const char*);
int (*db_release_memory)(sqlite3*);
const char *(*errstr)(int);
int (*stmt_busy)(sqlite3_stmt*);
int (*stmt_readonly)(sqlite3_stmt*);
int (*stricmp)(const char*,const char*);
int (*uri_boolean)(const char*,const char*,int);
sqlite3_int64 (*uri_int64)(const char*,const char*,sqlite3_int64);
const char *(*uri_parameter)(const char*,const char*);
char *(*xvsnprintf)(int,char*,const char*,va_list);
int (*wal_checkpoint_v2)(sqlite3*,const char*,int,int*,int*);
/* Version 3.8.7 and later */
int (*auto_extension)(void(*)(void));
int (*bind_blob64)(sqlite3_stmt*,int,const void*,sqlite3_uint64,
void(*)(void*));
int (*bind_text64)(sqlite3_stmt*,int,const char*,sqlite3_uint64,
void(*)(void*),unsigned char);
int (*cancel_auto_extension)(void(*)(void));
int (*load_extension)(sqlite3*,const char*,const char*,char**);
void *(*malloc64)(sqlite3_uint64);
sqlite3_uint64 (*msize)(void*);
void *(*realloc64)(void*,sqlite3_uint64);
void (*reset_auto_extension)(void);
void (*result_blob64)(sqlite3_context*,const void*,sqlite3_uint64,
void(*)(void*));
void (*result_text64)(sqlite3_context*,const char*,sqlite3_uint64,
void(*)(void*), unsigned char);
int (*strglob)(const char*,const char*);
/* Version 3.8.11 and later */
sqlite3_value *(*value_dup)(const sqlite3_value*);
void (*value_free)(sqlite3_value*);
int (*result_zeroblob64)(sqlite3_context*,sqlite3_uint64);
int (*bind_zeroblob64)(sqlite3_stmt*, int, sqlite3_uint64);
/* Version 3.9.0 and later */
unsigned int (*value_subtype)(sqlite3_value*);
void (*result_subtype)(sqlite3_context*,unsigned int);
/* Version 3.10.0 and later */
int (*status64)(int,sqlite3_int64*,sqlite3_int64*,int);
int (*strlike)(const char*,const char*,unsigned int);
int (*db_cacheflush)(sqlite3*);
/* Version 3.12.0 and later */
int (*system_errno)(sqlite3*);
/* Version 3.14.0 and later */
int (*trace_v2)(sqlite3*,unsigned,int(*)(unsigned,void*,void*,void*),void*);
char *(*expanded_sql)(sqlite3_stmt*);
/* Version 3.18.0 and later */
void (*set_last_insert_rowid)(sqlite3*,sqlite3_int64);
/* Version 3.20.0 and later */
int (*prepare_v3)(sqlite3*,const char*,int,unsigned int,
sqlite3_stmt**,const char**);
int (*prepare16_v3)(sqlite3*,const void*,int,unsigned int,
sqlite3_stmt**,const void**);
int (*bind_pointer)(sqlite3_stmt*,int,void*,const char*,void(*)(void*));
void (*result_pointer)(sqlite3_context*,void*,const char*,void(*)(void*));
void *(*value_pointer)(sqlite3_value*,const char*);
int (*vtab_nochange)(sqlite3_context*);
int (*value_nochange)(sqlite3_value*);
const char *(*vtab_collation)(sqlite3_index_info*,int);
/* Version 3.24.0 and later */
int (*keyword_count)(void);
int (*keyword_name)(int,const char**,int*);
int (*keyword_check)(const char*,int);
sqlite3_str *(*str_new)(sqlite3*);
char *(*str_finish)(sqlite3_str*);
void (*str_appendf)(sqlite3_str*, const char *zFormat, ...);
void (*str_vappendf)(sqlite3_str*, const char *zFormat, va_list);
void (*str_append)(sqlite3_str*, const char *zIn, int N);
void (*str_appendall)(sqlite3_str*, const char *zIn);
void (*str_appendchar)(sqlite3_str*, int N, char C);
void (*str_reset)(sqlite3_str*);
int (*str_errcode)(sqlite3_str*);
int (*str_length)(sqlite3_str*);
char *(*str_value)(sqlite3_str*);
/* Version 3.25.0 and later */
int (*create_window_function)(sqlite3*,const char*,int,int,void*,
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
void (*xFinal)(sqlite3_context*),
void (*xValue)(sqlite3_context*),
void (*xInv)(sqlite3_context*,int,sqlite3_value**),
void(*xDestroy)(void*));
/* Version 3.26.0 and later */
const char *(*normalized_sql)(sqlite3_stmt*);
/* Version 3.28.0 and later */
int (*stmt_isexplain)(sqlite3_stmt*);
int (*value_frombind)(sqlite3_value*);
/* Version 3.30.0 and later */
int (*drop_modules)(sqlite3*,const char**);
/* Version 3.31.0 and later */
sqlite3_int64 (*hard_heap_limit64)(sqlite3_int64);
const char *(*uri_key)(const char*,int);
const char *(*filename_database)(const char*);
const char *(*filename_journal)(const char*);
const char *(*filename_wal)(const char*);
/* Version 3.32.0 and later */
char *(*create_filename)(const char*,const char*,const char*,
int,const char**);
void (*free_filename)(char*);
sqlite3_file *(*database_file_object)(const char*);
/* Version 3.34.0 and later */
int (*txn_state)(sqlite3*,const char*);
/* Version 3.36.1 and later */
sqlite3_int64 (*changes64)(sqlite3*);
sqlite3_int64 (*total_changes64)(sqlite3*);
/* Version 3.37.0 and later */
int (*autovacuum_pages)(sqlite3*,
unsigned int(*)(void*,const char*,unsigned int,unsigned int,unsigned int),
void*, void(*)(void*));
};
/*
** This is the function signature used for all extension entry points. It
** is also defined in the file "loadext.c".
*/
typedef int (*sqlite3_loadext_entry)(
sqlite3 *db, /* Handle to the database. */
char **pzErrMsg, /* Used to set error string on failure. */
const sqlite3_api_routines *pThunk /* Extension API function pointers. */
);
/*
** The following macros redefine the API routines so that they are
** redirected through the global sqlite3_api structure.
**
** This header file is also used by the loadext.c source file
** (part of the main SQLite library - not an extension) so that
** it can get access to the sqlite3_api_routines structure
** definition. But the main library does not want to redefine
** the API. So the redefinition macros are only valid if the
** SQLITE_CORE macros is undefined.
*/
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
#define sqlite3_aggregate_context sqlite3_api->aggregate_context
#ifndef SQLITE_OMIT_DEPRECATED
#define sqlite3_aggregate_count sqlite3_api->aggregate_count
#endif
#define sqlite3_bind_blob sqlite3_api->bind_blob
#define sqlite3_bind_double sqlite3_api->bind_double
#define sqlite3_bind_int sqlite3_api->bind_int
#define sqlite3_bind_int64 sqlite3_api->bind_int64
#define sqlite3_bind_null sqlite3_api->bind_null
#define sqlite3_bind_parameter_count sqlite3_api->bind_parameter_count
#define sqlite3_bind_parameter_index sqlite3_api->bind_parameter_index
#define sqlite3_bind_parameter_name sqlite3_api->bind_parameter_name
#define sqlite3_bind_text sqlite3_api->bind_text
#define sqlite3_bind_text16 sqlite3_api->bind_text16
#define sqlite3_bind_value sqlite3_api->bind_value
#define sqlite3_busy_handler sqlite3_api->busy_handler
#define sqlite3_busy_timeout sqlite3_api->busy_timeout
#define sqlite3_changes sqlite3_api->changes
#define sqlite3_close sqlite3_api->close
#define sqlite3_collation_needed sqlite3_api->collation_needed
#define sqlite3_collation_needed16 sqlite3_api->collation_needed16
#define sqlite3_column_blob sqlite3_api->column_blob
#define sqlite3_column_bytes sqlite3_api->column_bytes
#define sqlite3_column_bytes16 sqlite3_api->column_bytes16
#define sqlite3_column_count sqlite3_api->column_count
#define sqlite3_column_database_name sqlite3_api->column_database_name
#define sqlite3_column_database_name16 sqlite3_api->column_database_name16
#define sqlite3_column_decltype sqlite3_api->column_decltype
#define sqlite3_column_decltype16 sqlite3_api->column_decltype16
#define sqlite3_column_double sqlite3_api->column_double
#define sqlite3_column_int sqlite3_api->column_int
#define sqlite3_column_int64 sqlite3_api->column_int64
#define sqlite3_column_name sqlite3_api->column_name
#define sqlite3_column_name16 sqlite3_api->column_name16
#define sqlite3_column_origin_name sqlite3_api->column_origin_name
#define sqlite3_column_origin_name16 sqlite3_api->column_origin_name16
#define sqlite3_column_table_name sqlite3_api->column_table_name
#define sqlite3_column_table_name16 sqlite3_api->column_table_name16
#define sqlite3_column_text sqlite3_api->column_text
#define sqlite3_column_text16 sqlite3_api->column_text16
#define sqlite3_column_type sqlite3_api->column_type
#define sqlite3_column_value sqlite3_api->column_value
#define sqlite3_commit_hook sqlite3_api->commit_hook
#define sqlite3_complete sqlite3_api->complete
#define sqlite3_complete16 sqlite3_api->complete16
#define sqlite3_create_collation sqlite3_api->create_collation
#define sqlite3_create_collation16 sqlite3_api->create_collation16
#define sqlite3_create_function sqlite3_api->create_function
#define sqlite3_create_function16 sqlite3_api->create_function16
#define sqlite3_create_module sqlite3_api->create_module
#define sqlite3_create_module_v2 sqlite3_api->create_module_v2
#define sqlite3_data_count sqlite3_api->data_count
#define sqlite3_db_handle sqlite3_api->db_handle
#define sqlite3_declare_vtab sqlite3_api->declare_vtab
#define sqlite3_enable_shared_cache sqlite3_api->enable_shared_cache
#define sqlite3_errcode sqlite3_api->errcode
#define sqlite3_errmsg sqlite3_api->errmsg
#define sqlite3_errmsg16 sqlite3_api->errmsg16
#define sqlite3_exec sqlite3_api->exec
#ifndef SQLITE_OMIT_DEPRECATED
#define sqlite3_expired sqlite3_api->expired
#endif
#define sqlite3_finalize sqlite3_api->finalize
#define sqlite3_free sqlite3_api->free
#define sqlite3_free_table sqlite3_api->free_table
#define sqlite3_get_autocommit sqlite3_api->get_autocommit
#define sqlite3_get_auxdata sqlite3_api->get_auxdata
#define sqlite3_get_table sqlite3_api->get_table
#ifndef SQLITE_OMIT_DEPRECATED
#define sqlite3_global_recover sqlite3_api->global_recover
#endif
#define sqlite3_interrupt sqlite3_api->interruptx
#define sqlite3_last_insert_rowid sqlite3_api->last_insert_rowid
#define sqlite3_libversion sqlite3_api->libversion
#define sqlite3_libversion_number sqlite3_api->libversion_number
#define sqlite3_malloc sqlite3_api->malloc
#define sqlite3_mprintf sqlite3_api->mprintf
#define sqlite3_open sqlite3_api->open
#define sqlite3_open16 sqlite3_api->open16
#define sqlite3_prepare sqlite3_api->prepare
#define sqlite3_prepare16 sqlite3_api->prepare16
#define sqlite3_prepare_v2 sqlite3_api->prepare_v2
#define sqlite3_prepare16_v2 sqlite3_api->prepare16_v2
#define sqlite3_profile sqlite3_api->profile
#define sqlite3_progress_handler sqlite3_api->progress_handler
#define sqlite3_realloc sqlite3_api->realloc
#define sqlite3_reset sqlite3_api->reset
#define sqlite3_result_blob sqlite3_api->result_blob
#define sqlite3_result_double sqlite3_api->result_double
#define sqlite3_result_error sqlite3_api->result_error
#define sqlite3_result_error16 sqlite3_api->result_error16
#define sqlite3_result_int sqlite3_api->result_int
#define sqlite3_result_int64 sqlite3_api->result_int64
#define sqlite3_result_null sqlite3_api->result_null
#define sqlite3_result_text sqlite3_api->result_text
#define sqlite3_result_text16 sqlite3_api->result_text16
#define sqlite3_result_text16be sqlite3_api->result_text16be
#define sqlite3_result_text16le sqlite3_api->result_text16le
#define sqlite3_result_value sqlite3_api->result_value
#define sqlite3_rollback_hook sqlite3_api->rollback_hook
#define sqlite3_set_authorizer sqlite3_api->set_authorizer
#define sqlite3_set_auxdata sqlite3_api->set_auxdata
#define sqlite3_snprintf sqlite3_api->xsnprintf
#define sqlite3_step sqlite3_api->step
#define sqlite3_table_column_metadata sqlite3_api->table_column_metadata
#define sqlite3_thread_cleanup sqlite3_api->thread_cleanup
#define sqlite3_total_changes sqlite3_api->total_changes
#define sqlite3_trace sqlite3_api->trace
#ifndef SQLITE_OMIT_DEPRECATED
#define sqlite3_transfer_bindings sqlite3_api->transfer_bindings
#endif
#define sqlite3_update_hook sqlite3_api->update_hook
#define sqlite3_user_data sqlite3_api->user_data
#define sqlite3_value_blob sqlite3_api->value_blob
#define sqlite3_value_bytes sqlite3_api->value_bytes
#define sqlite3_value_bytes16 sqlite3_api->value_bytes16
#define sqlite3_value_double sqlite3_api->value_double
#define sqlite3_value_int sqlite3_api->value_int
#define sqlite3_value_int64 sqlite3_api->value_int64
#define sqlite3_value_numeric_type sqlite3_api->value_numeric_type
#define sqlite3_value_text sqlite3_api->value_text
#define sqlite3_value_text16 sqlite3_api->value_text16
#define sqlite3_value_text16be sqlite3_api->value_text16be
#define sqlite3_value_text16le sqlite3_api->value_text16le
#define sqlite3_value_type sqlite3_api->value_type
#define sqlite3_vmprintf sqlite3_api->vmprintf
#define sqlite3_vsnprintf sqlite3_api->xvsnprintf
#define sqlite3_overload_function sqlite3_api->overload_function
#define sqlite3_prepare_v2 sqlite3_api->prepare_v2
#define sqlite3_prepare16_v2 sqlite3_api->prepare16_v2
#define sqlite3_clear_bindings sqlite3_api->clear_bindings
#define sqlite3_bind_zeroblob sqlite3_api->bind_zeroblob
#define sqlite3_blob_bytes sqlite3_api->blob_bytes
#define sqlite3_blob_close sqlite3_api->blob_close
#define sqlite3_blob_open sqlite3_api->blob_open
#define sqlite3_blob_read sqlite3_api->blob_read
#define sqlite3_blob_write sqlite3_api->blob_write
#define sqlite3_create_collation_v2 sqlite3_api->create_collation_v2
#define sqlite3_file_control sqlite3_api->file_control
#define sqlite3_memory_highwater sqlite3_api->memory_highwater
#define sqlite3_memory_used sqlite3_api->memory_used
#define sqlite3_mutex_alloc sqlite3_api->mutex_alloc
#define sqlite3_mutex_enter sqlite3_api->mutex_enter
#define sqlite3_mutex_free sqlite3_api->mutex_free
#define sqlite3_mutex_leave sqlite3_api->mutex_leave
#define sqlite3_mutex_try sqlite3_api->mutex_try
#define sqlite3_open_v2 sqlite3_api->open_v2
#define sqlite3_release_memory sqlite3_api->release_memory
#define sqlite3_result_error_nomem sqlite3_api->result_error_nomem
#define sqlite3_result_error_toobig sqlite3_api->result_error_toobig
#define sqlite3_sleep sqlite3_api->sleep
#define sqlite3_soft_heap_limit sqlite3_api->soft_heap_limit
#define sqlite3_vfs_find sqlite3_api->vfs_find
#define sqlite3_vfs_register sqlite3_api->vfs_register
#define sqlite3_vfs_unregister sqlite3_api->vfs_unregister
#define sqlite3_threadsafe sqlite3_api->xthreadsafe
#define sqlite3_result_zeroblob sqlite3_api->result_zeroblob
#define sqlite3_result_error_code sqlite3_api->result_error_code
#define sqlite3_test_control sqlite3_api->test_control
#define sqlite3_randomness sqlite3_api->randomness
#define sqlite3_context_db_handle sqlite3_api->context_db_handle
#define sqlite3_extended_result_codes sqlite3_api->extended_result_codes
#define sqlite3_limit sqlite3_api->limit
#define sqlite3_next_stmt sqlite3_api->next_stmt
#define sqlite3_sql sqlite3_api->sql
#define sqlite3_status sqlite3_api->status
#define sqlite3_backup_finish sqlite3_api->backup_finish
#define sqlite3_backup_init sqlite3_api->backup_init
#define sqlite3_backup_pagecount sqlite3_api->backup_pagecount
#define sqlite3_backup_remaining sqlite3_api->backup_remaining
#define sqlite3_backup_step sqlite3_api->backup_step
#define sqlite3_compileoption_get sqlite3_api->compileoption_get
#define sqlite3_compileoption_used sqlite3_api->compileoption_used
#define sqlite3_create_function_v2 sqlite3_api->create_function_v2
#define sqlite3_db_config sqlite3_api->db_config
#define sqlite3_db_mutex sqlite3_api->db_mutex
#define sqlite3_db_status sqlite3_api->db_status
#define sqlite3_extended_errcode sqlite3_api->extended_errcode
#define sqlite3_log sqlite3_api->log
#define sqlite3_soft_heap_limit64 sqlite3_api->soft_heap_limit64
#define sqlite3_sourceid sqlite3_api->sourceid
#define sqlite3_stmt_status sqlite3_api->stmt_status
#define sqlite3_strnicmp sqlite3_api->strnicmp
#define sqlite3_unlock_notify sqlite3_api->unlock_notify
#define sqlite3_wal_autocheckpoint sqlite3_api->wal_autocheckpoint
#define sqlite3_wal_checkpoint sqlite3_api->wal_checkpoint
#define sqlite3_wal_hook sqlite3_api->wal_hook
#define sqlite3_blob_reopen sqlite3_api->blob_reopen
#define sqlite3_vtab_config sqlite3_api->vtab_config
#define sqlite3_vtab_on_conflict sqlite3_api->vtab_on_conflict
/* Version 3.7.16 and later */
#define sqlite3_close_v2 sqlite3_api->close_v2
#define sqlite3_db_filename sqlite3_api->db_filename
#define sqlite3_db_readonly sqlite3_api->db_readonly
#define sqlite3_db_release_memory sqlite3_api->db_release_memory
#define sqlite3_errstr sqlite3_api->errstr
#define sqlite3_stmt_busy sqlite3_api->stmt_busy
#define sqlite3_stmt_readonly sqlite3_api->stmt_readonly
#define sqlite3_stricmp sqlite3_api->stricmp
#define sqlite3_uri_boolean sqlite3_api->uri_boolean
#define sqlite3_uri_int64 sqlite3_api->uri_int64
#define sqlite3_uri_parameter sqlite3_api->uri_parameter
#define sqlite3_uri_vsnprintf sqlite3_api->xvsnprintf
#define sqlite3_wal_checkpoint_v2 sqlite3_api->wal_checkpoint_v2
/* Version 3.8.7 and later */
#define sqlite3_auto_extension sqlite3_api->auto_extension
#define sqlite3_bind_blob64 sqlite3_api->bind_blob64
#define sqlite3_bind_text64 sqlite3_api->bind_text64
#define sqlite3_cancel_auto_extension sqlite3_api->cancel_auto_extension
#define sqlite3_load_extension sqlite3_api->load_extension
#define sqlite3_malloc64 sqlite3_api->malloc64
#define sqlite3_msize sqlite3_api->msize
#define sqlite3_realloc64 sqlite3_api->realloc64
#define sqlite3_reset_auto_extension sqlite3_api->reset_auto_extension
#define sqlite3_result_blob64 sqlite3_api->result_blob64
#define sqlite3_result_text64 sqlite3_api->result_text64
#define sqlite3_strglob sqlite3_api->strglob
/* Version 3.8.11 and later */
#define sqlite3_value_dup sqlite3_api->value_dup
#define sqlite3_value_free sqlite3_api->value_free
#define sqlite3_result_zeroblob64 sqlite3_api->result_zeroblob64
#define sqlite3_bind_zeroblob64 sqlite3_api->bind_zeroblob64
/* Version 3.9.0 and later */
#define sqlite3_value_subtype sqlite3_api->value_subtype
#define sqlite3_result_subtype sqlite3_api->result_subtype
/* Version 3.10.0 and later */
#define sqlite3_status64 sqlite3_api->status64
#define sqlite3_strlike sqlite3_api->strlike
#define sqlite3_db_cacheflush sqlite3_api->db_cacheflush
/* Version 3.12.0 and later */
#define sqlite3_system_errno sqlite3_api->system_errno
/* Version 3.14.0 and later */
#define sqlite3_trace_v2 sqlite3_api->trace_v2
#define sqlite3_expanded_sql sqlite3_api->expanded_sql
/* Version 3.18.0 and later */
#define sqlite3_set_last_insert_rowid sqlite3_api->set_last_insert_rowid
/* Version 3.20.0 and later */
#define sqlite3_prepare_v3 sqlite3_api->prepare_v3
#define sqlite3_prepare16_v3 sqlite3_api->prepare16_v3
#define sqlite3_bind_pointer sqlite3_api->bind_pointer
#define sqlite3_result_pointer sqlite3_api->result_pointer
#define sqlite3_value_pointer sqlite3_api->value_pointer
/* Version 3.22.0 and later */
#define sqlite3_vtab_nochange sqlite3_api->vtab_nochange
#define sqlite3_value_nochange sqlite3_api->value_nochange
#define sqlite3_vtab_collation sqlite3_api->vtab_collation
/* Version 3.24.0 and later */
#define sqlite3_keyword_count sqlite3_api->keyword_count
#define sqlite3_keyword_name sqlite3_api->keyword_name
#define sqlite3_keyword_check sqlite3_api->keyword_check
#define sqlite3_str_new sqlite3_api->str_new
#define sqlite3_str_finish sqlite3_api->str_finish
#define sqlite3_str_appendf sqlite3_api->str_appendf
#define sqlite3_str_vappendf sqlite3_api->str_vappendf
#define sqlite3_str_append sqlite3_api->str_append
#define sqlite3_str_appendall sqlite3_api->str_appendall
#define sqlite3_str_appendchar sqlite3_api->str_appendchar
#define sqlite3_str_reset sqlite3_api->str_reset
#define sqlite3_str_errcode sqlite3_api->str_errcode
#define sqlite3_str_length sqlite3_api->str_length
#define sqlite3_str_value sqlite3_api->str_value
/* Version 3.25.0 and later */
#define sqlite3_create_window_function sqlite3_api->create_window_function
/* Version 3.26.0 and later */
#define sqlite3_normalized_sql sqlite3_api->normalized_sql
/* Version 3.28.0 and later */
#define sqlite3_stmt_isexplain sqlite3_api->stmt_isexplain
#define sqlite3_value_frombind sqlite3_api->value_frombind
/* Version 3.30.0 and later */
#define sqlite3_drop_modules sqlite3_api->drop_modules
/* Version 3.31.0 and later */
#define sqlite3_hard_heap_limit64 sqlite3_api->hard_heap_limit64
#define sqlite3_uri_key sqlite3_api->uri_key
#define sqlite3_filename_database sqlite3_api->filename_database
#define sqlite3_filename_journal sqlite3_api->filename_journal
#define sqlite3_filename_wal sqlite3_api->filename_wal
/* Version 3.32.0 and later */
#define sqlite3_create_filename sqlite3_api->create_filename
#define sqlite3_free_filename sqlite3_api->free_filename
#define sqlite3_database_file_object sqlite3_api->database_file_object
/* Version 3.34.0 and later */
#define sqlite3_txn_state sqlite3_api->txn_state
/* Version 3.36.1 and later */
#define sqlite3_changes64 sqlite3_api->changes64
#define sqlite3_total_changes64 sqlite3_api->total_changes64
/* Version 3.37.0 and later */
#define sqlite3_autovacuum_pages sqlite3_api->autovacuum_pages
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
/* This case when the file really is being compiled as a loadable
** extension */
# define SQLITE_EXTENSION_INIT1 const sqlite3_api_routines *sqlite3_api=0;
# define SQLITE_EXTENSION_INIT2(v) sqlite3_api=v;
# define SQLITE_EXTENSION_INIT3 \
extern const sqlite3_api_routines *sqlite3_api;
#else
/* This case when the file is being statically linked into the
** application */
# define SQLITE_EXTENSION_INIT1 /*no-op*/
# define SQLITE_EXTENSION_INIT2(v) (void)v; /* unused parameter */
# define SQLITE_EXTENSION_INIT3 /*no-op*/
#endif
#endif /* SQLITE3EXT_H */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,184 @@
2006-06-29 Michael Tokarev <mjt@corpit.ru>
* see debian/changelog file for further changes.
2005-04-18 Michael Tokarev <mjt@corpit.ru>
* move cdb_make_find.c content into cdb_make_put.c
* introduce CDB_PUT_REPLACE0 - zerofill old duplicates
* allow usage of cdb.h in C++
2005-04-11 Michael Tokarev <mjt@corpit.ru>
* do not autogenerate files (cdb.h.in, cdb.3.in etc), but
use real files instead (only substituted VERSION and NAME)
* finally fixed the `!fputs()' condition to be `fputs() < 0'
as it should be in cdb.c (misbehaves on *bsd)
* kill cdbi_t usage in cdb_int.h
* export _cdb_make_fullwrite() (was ewrite()) and _cdb_make_flush()
and use them in cdb_make.c as appropriate
* almost completely rewrite _cdb_make_find() and friends:
- _cdb_make_find() now accepts new parameter, remove (bool), which,
if true, indicates all found records should be deleted from the
database.
- Call _cdb_make_find() with remove=0 from cdb_make_exists()
- Call _cdb_make_find() with appropriate arguments from
cdb_make_put(), and simplify the latter greatly (was too clumsy
anyway)
* rename `flags' parameter in cdb_make_put() to be `mode' which is
more appropriate
* change #if conditional in nss_cdb.c
from __GLIBC__ to __GNU_LIBRARY__
2003-11-04 Michael Tokarev <mjt@corpit.ru>
* added cdb_get() routine: tinycdb officially uses mmap.
* added cdb_{get,read}{data,key}() macros to read and get
current data and key.
* fixed bug in cdb_seek() - incorrect wrap, sometimes
cdb_seek()+cdb_bread() may return EIO instead of finding
correct record.
* added some tweaks to Makefile to build position-independent
libcdb_pic.a and shared libcdb.so libraries. Note that
using libcdb as shared library is probably not a good idea,
due to tiny size of the library.
* added initial nss_cdb module. Still not well-tested.
Probably will not build on non-GNU system.
* adjusted tests.{ok,sh} for latest cdb utility modifications
(-a mode in query by default)
* Victor Porton (porton at ex-code.com) provided a patch
to allow tinycdb to be built on win32 platform (cdb_init.c).
Completely untested.
2003-08-13 Michael Tokarev <mjt@corpit.ru>
* s/cdbi_t/unsigned/g. No need to keep this type.
* changed usage of cdb_findnext(): one need to pass
pointer to cdb structure to cdb_findnext() now,
and should use cdb_datapos(struct cdb_find *)
instead of cdb_datapos(struct cdb *)
* added cdb_seqinit() and cdb_seqnext() routines for sequential
record enumeration
* addded cdb_dend to the cdb structure: end of data
position. Use that in cdb_seq*().
* more strict checking: ensure data is within data section,
and hash tables are within hash section of a file.
* cdb_make.c (cdb_make_start): zerofill cdb_make structure
to shut valgrind up (writing uninitialized data to file)
* cdb.c (cmode): always open file in RDWR mode to allow
duplicate key detection
2002-12-08 Michael Tokarev <mjt+cdb@corpit.ru>
* version 0.73
* de-Debianization. Oh well... ;)
* no code changes, just like in 0.72
2002-10-13 Michael Tokarev <mjt+cdb@corpit.ru>
* version 0.72
* cleaned up debian packaging and made it actually work
* no code changes
2002-07-22 Michael Tokarev <mjt+cdb@corpit.ru>
* version 0.71
* rearranged object files to not depend on ranlib on
systems that requires it (i.e. OpenBSD)
* use ranlib but mark it's possible error as non-fatal
2001-12-10 Michael Tokarev <mjt+cdb@corpit.ru>
* version 0.7a
* converted to CVS, added two missing #include <stdlib.h> for
malloc declaration and spec target to the Makefile
2001-10-14 Michael Tokarev <mjt+cdb@corpit.ru>
* version 0.7
* added cdb_seek() and cdb_bread() routines as found
in freecdb/cdb-0.64
2001-07-26 Michael Tokarev <mjt+cdb@corpit.ru>
* version 0.6
* added another option, CDB_PUT_WARN, to cdb_make_put's flags
(to allow adding unconditionally but still warn about dups),
now cdb_make_put seems to be logically complete.
* added and documented -r and -u options for cdb(1) command,
and made them consistent with -w and -e also.
* reorganized cdb(1) manpage and added changes made to cdb
command.
* added version references to manpages (and make them autogenerated
to simplify maintenance).
* added cdb(5) manpage describing CDB file format.
2001-07-25 Michael Tokarev <mjt+cdb@corpit.ru>
* version 0.5
* added missing #include <sys/types.h> in cdb_init.c, thanks to
ppetru@ppetru.net (Petru Paler)
* removed usage of pread() in cdb_make_find() and friends,
suggested by Liviu Daia <Liviu.Daia@imar.ro>
* autogenerate tinycdb.spec file from template and debian/changelog
* autogenerate cdb.h from cdb.h.in (substituting version)
2001-06-29 Michael Tokarev <mjt+cdb@corpit.ru>
* version 0.4
* added cdb_make_put() routine to conditionnaly add a record
* split cdb library to more files (finer granularity)
* added cdb_findinit() and cdb_findnext() routines
* renamed cdbtool to cdb
* simplified cdb utility (dropped various format spec, changed
options parsing) and a manpage
* added small note and copyright to every file in package
* added some testsuite (make test)
2001-05-27 Michael Tokarev <mjt+cdb@corpit.ru>
* version 0.3
* Initial Release.

View file

@ -0,0 +1,87 @@
User-visible news. Latest at the top.
tinycdb-0.78 2012-05-11
- bugfix release:
o fixed >2Gb file size prob on 32bit platform
o fixed handling of files >=4Gb
o fixed a few compiler warnings
- introduce $(LD) and $(LDFLAGS), and also $(CDEFS) in Makefile
tinycdb-0.77
- bugfix release: manpage typos, portability fixes and the like
- bugfix: improper logic in EINTR handling in _cdb_make_full_write
routine which may lead to corruped .cdb file.
tinycdb-0.76
- new cdb utility option: -p permissions, to specify permission
bits for the newly created database file.
- cdb utility, when creating the database, does unlink() of the
(temp) db file and when opens it with O_CREAT|O_EXCL, instead
of previous O_CREAT|O_TRUNC w/o unlink() behaviour, and uses
O_NOFOLLOW flag if available. This avoids any possible symlink
race conditions, but is somewhat incompatible with previous
versions, where it was possible to create temp file beforehand
with proper permissions. Together with new -p option (above),
this isn't that big change.
- cdb utility now allows to omit temp file usage (with final rename())
when creating the database, by specifying -t- (`-' as temp file name)
(or -t the_same_name_as_the_db_file). Useful if the utility is called
from a script which does its own rename afterwards.
- alot of minor code changes to make modern compilers happy (mostly
signed char vs unsigned char "fixes"). Including additions of
`unsigned' into common structure definitions in cdb.h - the API
stays compatible still.
- several (spelling and other) fixes for manpages.
- tinycdb is, once again, maintained as a native Debian package.
Debian package has been split into 4 parts: libcdb1, libcdb-dev,
tinycdb (the utility) and libnss_cdb. RPM .spec file now builds
two packages as well: tinycdb (includes shared library, the utility,
and nss_cdb module) and tinycdb-devel (development files).
tinycdb-0.75 (2005-04-11)
- make cdb_make_put(CDB_PUT_REPLACE) to actually *remove*
all (was only first previously) matching records, by
rewriting the file.
- new mode CDB_PUT_REPLACE0, which zeroes out old duplicate
records
- fixed fputs() == NULL condition in cdb.c, finally
(should be < 0, not == NULL)
tinycdb-0.74 (2003-11-04)
- reworked cdb utility, see manpage for details. cdb -q now
prints all matching records by default (incompat change),
use cdb -q -n XX to return only XXth record if any.
-m works with -q.
- there are several new routines (and macros) in library.
- cdb_seqinit() and cdb_seqstart() to fetch all records
- cdb_get() to get a pointer to data in internal buffer
- cdb_{get,read}{data,key}()
- cdbi_t gone (but still defined). Use unsigned instead.
- cdb_findnext() changed
- fixed a bug in cdb_seek() (EIO instead of getting valid record)
- added nss_cdb (for passwd, group and shadow databases only)
- Makefile targets to build PIC code (libcdb_pic.a, required for
nss_cdb) and shared library (probably not a good idea)
- Modifications to allow tinycdb to compile under win32,
by Victor Porton (porton at ex-code.com).

View file

@ -0,0 +1,125 @@
/* cdb.h: public cdb include file
*
* This file is a part of tinycdb package by Michael Tokarev, mjt@corpit.ru.
* Public domain.
*/
#ifndef TINYCDB_VERSION
#define TINYCDB_VERSION 0.78
#ifdef __cplusplus
extern "C" {
#endif
typedef unsigned int cdbi_t; /* compatibility */
/* common routines */
unsigned cdb_hash(const void *buf, unsigned len);
unsigned cdb_unpack(const unsigned char buf[4]);
void cdb_pack(unsigned num, unsigned char buf[4]);
struct cdb {
int cdb_fd; /* file descriptor */
/* private members */
unsigned cdb_fsize; /* datafile size */
unsigned cdb_dend; /* end of data ptr */
const unsigned char *cdb_mem; /* mmap'ed file memory */
unsigned cdb_vpos, cdb_vlen; /* found data */
unsigned cdb_kpos, cdb_klen; /* found key */
};
#define CDB_STATIC_INIT {0,0,0,0,0,0,0,0}
#define cdb_datapos(c) ((c)->cdb_vpos)
#define cdb_datalen(c) ((c)->cdb_vlen)
#define cdb_keypos(c) ((c)->cdb_kpos)
#define cdb_keylen(c) ((c)->cdb_klen)
#define cdb_fileno(c) ((c)->cdb_fd)
int cdb_init(struct cdb *cdbp, int fd);
void cdb_free(struct cdb *cdbp);
int cdb_read(const struct cdb *cdbp,
void *buf, unsigned len, unsigned pos);
#define cdb_readdata(cdbp, buf) \
cdb_read((cdbp), (buf), cdb_datalen(cdbp), cdb_datapos(cdbp))
#define cdb_readkey(cdbp, buf) \
cdb_read((cdbp), (buf), cdb_keylen(cdbp), cdb_keypos(cdbp))
const void *cdb_get(const struct cdb *cdbp, unsigned len, unsigned pos);
#define cdb_getdata(cdbp) \
cdb_get((cdbp), cdb_datalen(cdbp), cdb_datapos(cdbp))
#define cdb_getkey(cdbp) \
cdb_get((cdbp), cdb_keylen(cdbp), cdb_keypos(cdbp))
int cdb_find(struct cdb *cdbp, const void *key, unsigned klen);
struct cdb_find {
struct cdb *cdb_cdbp;
unsigned cdb_hval;
const unsigned char *cdb_htp, *cdb_htab, *cdb_htend;
unsigned cdb_httodo;
const void *cdb_key;
unsigned cdb_klen;
};
int cdb_findinit(struct cdb_find *cdbfp, struct cdb *cdbp,
const void *key, unsigned klen);
int cdb_findnext(struct cdb_find *cdbfp);
#define cdb_seqinit(cptr, cdbp) ((*(cptr))=2048)
int cdb_seqnext(unsigned *cptr, struct cdb *cdbp);
/* old simple interface */
/* open file using standard routine, then: */
int cdb_seek(int fd, const void *key, unsigned klen, unsigned *dlenp);
int cdb_bread(int fd, void *buf, int len);
/* cdb_make */
struct cdb_make {
int cdb_fd; /* file descriptor */
/* private */
unsigned cdb_dpos; /* data position so far */
unsigned cdb_rcnt; /* record count so far */
unsigned char cdb_buf[4096]; /* write buffer */
unsigned char *cdb_bpos; /* current buf position */
struct cdb_rl *cdb_rec[256]; /* list of arrays of record infos */
};
enum cdb_put_mode {
CDB_PUT_ADD = 0, /* add unconditionnaly, like cdb_make_add() */
#define CDB_PUT_ADD CDB_PUT_ADD
CDB_FIND = CDB_PUT_ADD,
CDB_PUT_REPLACE, /* replace: do not place to index OLD record */
#define CDB_PUT_REPLACE CDB_PUT_REPLACE
CDB_FIND_REMOVE = CDB_PUT_REPLACE,
CDB_PUT_INSERT, /* add only if not already exists */
#define CDB_PUT_INSERT CDB_PUT_INSERT
CDB_PUT_WARN, /* add unconditionally but ret. 1 if exists */
#define CDB_PUT_WARN CDB_PUT_WARN
CDB_PUT_REPLACE0, /* if a record exists, fill old one with zeros */
#define CDB_PUT_REPLACE0 CDB_PUT_REPLACE0
CDB_FIND_FILL0 = CDB_PUT_REPLACE0
};
int cdb_make_start(struct cdb_make *cdbmp, int fd);
int cdb_make_add(struct cdb_make *cdbmp,
const void *key, unsigned klen,
const void *val, unsigned vlen);
int cdb_make_exists(struct cdb_make *cdbmp,
const void *key, unsigned klen);
int cdb_make_find(struct cdb_make *cdbmp,
const void *key, unsigned klen,
enum cdb_put_mode mode);
int cdb_make_put(struct cdb_make *cdbmp,
const void *key, unsigned klen,
const void *val, unsigned vlen,
enum cdb_put_mode mode);
int cdb_make_finish(struct cdb_make *cdbmp);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* include guard */

View file

@ -0,0 +1,75 @@
/* cdb_find.c: cdb_find routine
*
* This file is a part of tinycdb package by Michael Tokarev, mjt@corpit.ru.
* Public domain.
*/
#include "cdb_int.h"
int
cdb_find(struct cdb *cdbp, const void *key, unsigned klen)
{
const unsigned char *htp; /* hash table pointer */
const unsigned char *htab; /* hash table */
const unsigned char *htend; /* end of hash table */
unsigned httodo; /* ht bytes left to look */
unsigned pos, n;
unsigned hval;
if (klen >= cdbp->cdb_dend) /* if key size is too large */
return 0;
hval = cdb_hash(key, klen);
/* find (pos,n) hash table to use */
/* first 2048 bytes (toc) are always available */
/* (hval % 256) * 8 */
htp = cdbp->cdb_mem + ((hval << 3) & 2047); /* index in toc (256x8) */
n = cdb_unpack(htp + 4); /* table size */
if (!n) /* empty table */
return 0; /* not found */
httodo = n << 3; /* bytes of htab to lookup */
pos = cdb_unpack(htp); /* htab position */
if (n > (cdbp->cdb_fsize >> 3) /* overflow of httodo ? */
|| pos < cdbp->cdb_dend /* is htab inside data section ? */
|| pos > cdbp->cdb_fsize /* htab start within file ? */
|| httodo > cdbp->cdb_fsize - pos) /* entrie htab within file ? */
return errno = EPROTO, -1;
htab = cdbp->cdb_mem + pos; /* htab pointer */
htend = htab + httodo; /* after end of htab */
/* htab starting position: rest of hval modulo htsize, 8bytes per elt */
htp = htab + (((hval >> 8) % n) << 3);
for(;;) {
pos = cdb_unpack(htp + 4); /* record position */
if (!pos)
return 0;
if (cdb_unpack(htp) == hval) {
if (pos > cdbp->cdb_dend - 8) /* key+val lengths */
return errno = EPROTO, -1;
if (cdb_unpack(cdbp->cdb_mem + pos) == klen) {
if (cdbp->cdb_dend - klen < pos + 8)
return errno = EPROTO, -1;
if (memcmp(key, cdbp->cdb_mem + pos + 8, klen) == 0) {
n = cdb_unpack(cdbp->cdb_mem + pos + 4);
pos += 8;
if (cdbp->cdb_dend < n || cdbp->cdb_dend - n < pos + klen)
return errno = EPROTO, -1;
cdbp->cdb_kpos = pos;
cdbp->cdb_klen = klen;
cdbp->cdb_vpos = pos + klen;
cdbp->cdb_vlen = n;
return 1;
}
}
}
httodo -= 8;
if (!httodo)
return 0;
if ((htp += 8) >= htend)
htp = htab;
}
}

View file

@ -0,0 +1,80 @@
/* cdb_findnext.c: sequential cdb_find routines
*
* This file is a part of tinycdb package by Michael Tokarev, mjt@corpit.ru.
* Public domain.
*/
/* see cdb_find.c for comments */
#include "cdb_int.h"
int
cdb_findinit(struct cdb_find *cdbfp, struct cdb *cdbp,
const void *key, unsigned klen)
{
unsigned n, pos;
cdbfp->cdb_cdbp = cdbp;
cdbfp->cdb_key = key;
cdbfp->cdb_klen = klen;
cdbfp->cdb_hval = cdb_hash(key, klen);
cdbfp->cdb_htp = cdbp->cdb_mem + ((cdbfp->cdb_hval << 3) & 2047);
n = cdb_unpack(cdbfp->cdb_htp + 4);
cdbfp->cdb_httodo = n << 3;
if (!n)
return 0;
pos = cdb_unpack(cdbfp->cdb_htp);
if (n > (cdbp->cdb_fsize >> 3)
|| pos < cdbp->cdb_dend
|| pos > cdbp->cdb_fsize
|| cdbfp->cdb_httodo > cdbp->cdb_fsize - pos)
return errno = EPROTO, -1;
cdbfp->cdb_htab = cdbp->cdb_mem + pos;
cdbfp->cdb_htend = cdbfp->cdb_htab + cdbfp->cdb_httodo;
cdbfp->cdb_htp = cdbfp->cdb_htab + (((cdbfp->cdb_hval >> 8) % n) << 3);
return 1;
}
int
cdb_findnext(struct cdb_find *cdbfp) {
struct cdb *cdbp = cdbfp->cdb_cdbp;
unsigned pos, n;
unsigned klen = cdbfp->cdb_klen;
while(cdbfp->cdb_httodo) {
pos = cdb_unpack(cdbfp->cdb_htp + 4);
if (!pos)
return 0;
n = cdb_unpack(cdbfp->cdb_htp) == cdbfp->cdb_hval;
if ((cdbfp->cdb_htp += 8) >= cdbfp->cdb_htend)
cdbfp->cdb_htp = cdbfp->cdb_htab;
cdbfp->cdb_httodo -= 8;
if (n) {
if (pos > cdbp->cdb_fsize - 8)
return errno = EPROTO, -1;
if (cdb_unpack(cdbp->cdb_mem + pos) == klen) {
if (cdbp->cdb_fsize - klen < pos + 8)
return errno = EPROTO, -1;
if (memcmp(cdbfp->cdb_key,
cdbp->cdb_mem + pos + 8, klen) == 0) {
n = cdb_unpack(cdbp->cdb_mem + pos + 4);
pos += 8;
if (cdbp->cdb_fsize < n ||
cdbp->cdb_fsize - n < pos + klen)
return errno = EPROTO, -1;
cdbp->cdb_kpos = pos;
cdbp->cdb_klen = klen;
cdbp->cdb_vpos = pos + klen;
cdbp->cdb_vlen = n;
return 1;
}
}
}
}
return 0;
}

View file

@ -0,0 +1,18 @@
/* cdb_hash.c: cdb hashing routine
*
* This file is a part of tinycdb package by Michael Tokarev, mjt@corpit.ru.
* Public domain.
*/
#include "cdb.h"
unsigned
cdb_hash(const void *buf, unsigned len)
{
register const unsigned char *p = (const unsigned char *)buf;
register const unsigned char *end = p + len;
register unsigned hash = 5381; /* start value */
while (p < end)
hash = (hash + (hash << 5)) ^ *p++;
return hash;
}

View file

@ -0,0 +1,112 @@
/* cdb_init.c: cdb_init, cdb_free and cdb_read routines
*
* This file is a part of tinycdb package by Michael Tokarev, mjt@corpit.ru.
* Public domain.
*/
#include <sys/types.h>
#ifdef _WIN32
# include <windows.h>
#else
# include <sys/mman.h>
# ifndef MAP_FAILED
# define MAP_FAILED ((void*)-1)
# endif
#endif
#include <sys/stat.h>
#include "cdb_int.h"
int
cdb_init(struct cdb *cdbp, int fd)
{
struct stat st;
unsigned char *mem;
unsigned fsize, dend;
#ifdef _WIN32
HANDLE hFile, hMapping;
#endif
/* get file size */
if (fstat(fd, &st) < 0)
return -1;
/* trivial sanity check: at least toc should be here */
if (st.st_size < 2048)
return errno = EPROTO, -1;
fsize = st.st_size < 0xffffffffu ? st.st_size : 0xffffffffu;
/* memory-map file */
#ifdef _WIN32
hFile = (HANDLE) _get_osfhandle(fd);
if (hFile == (HANDLE) -1)
return -1;
hMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
if (!hMapping)
return -1;
mem = (unsigned char *)MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0);
CloseHandle(hMapping);
if (!mem)
return -1;
#else
mem = (unsigned char*)mmap(NULL, fsize, PROT_READ, MAP_SHARED, fd, 0);
if (mem == MAP_FAILED)
return -1;
#endif /* _WIN32 */
cdbp->cdb_fd = fd;
cdbp->cdb_fsize = fsize;
cdbp->cdb_mem = mem;
#if 0
/* XXX don't know well about madvise syscall -- is it legal
to set different options for parts of one mmap() region?
There is also posix_madvise() exist, with POSIX_MADV_RANDOM etc...
*/
#ifdef MADV_RANDOM
/* set madvise() parameters. Ignore errors for now if system
doesn't support it */
madvise(mem, 2048, MADV_WILLNEED);
madvise(mem + 2048, cdbp->cdb_fsize - 2048, MADV_RANDOM);
#endif
#endif
cdbp->cdb_vpos = cdbp->cdb_vlen = 0;
cdbp->cdb_kpos = cdbp->cdb_klen = 0;
dend = cdb_unpack(mem);
if (dend < 2048) dend = 2048;
else if (dend >= fsize) dend = fsize;
cdbp->cdb_dend = dend;
return 0;
}
void
cdb_free(struct cdb *cdbp)
{
if (cdbp->cdb_mem) {
#ifdef _WIN32
UnmapViewOfFile((void*) cdbp->cdb_mem);
#else
munmap((void*)cdbp->cdb_mem, cdbp->cdb_fsize);
#endif /* _WIN32 */
cdbp->cdb_mem = NULL;
}
cdbp->cdb_fsize = 0;
}
const void *
cdb_get(const struct cdb *cdbp, unsigned len, unsigned pos)
{
if (pos > cdbp->cdb_fsize || cdbp->cdb_fsize - pos < len) {
errno = EPROTO;
return NULL;
}
return cdbp->cdb_mem + pos;
}
int
cdb_read(const struct cdb *cdbp, void *buf, unsigned len, unsigned pos)
{
const void *data = cdb_get(cdbp, len, pos);
if (!data) return -1;
memcpy(buf, data, len);
return 0;
}

View file

@ -0,0 +1,40 @@
/* cdb_int.h: internal cdb library declarations
*
* This file is a part of tinycdb package by Michael Tokarev, mjt@corpit.ru.
* Public domain.
*/
#include "cdb.h"
#include <errno.h>
#include <string.h>
#ifndef EPROTO
# define EPROTO EINVAL
#endif
#ifndef internal_function
# ifdef __GNUC__
# define internal_function __attribute__((visibility("hidden")))
# else
# define internal_function
# endif
#endif
struct cdb_rec {
unsigned hval;
unsigned rpos;
};
struct cdb_rl {
struct cdb_rl *next;
unsigned cnt;
struct cdb_rec rec[254];
};
int _cdb_make_write(struct cdb_make *cdbmp,
const unsigned char *ptr, unsigned len);
int _cdb_make_fullwrite(int fd, const unsigned char *buf, unsigned len);
int _cdb_make_flush(struct cdb_make *cdbmp);
int _cdb_make_add(struct cdb_make *cdbmp, unsigned hval,
const void *key, unsigned klen,
const void *val, unsigned vlen);

View file

@ -0,0 +1,183 @@
/* cdb_make.c: basic cdb creation routines
*
* This file is a part of tinycdb package by Michael Tokarev, mjt@corpit.ru.
* Public domain.
*/
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include "cdb_int.h"
void
cdb_pack(unsigned num, unsigned char buf[4])
{
buf[0] = num & 255; num >>= 8;
buf[1] = num & 255; num >>= 8;
buf[2] = num & 255;
buf[3] = num >> 8;
}
int
cdb_make_start(struct cdb_make *cdbmp, int fd)
{
memset(cdbmp, 0, sizeof(*cdbmp));
cdbmp->cdb_fd = fd;
cdbmp->cdb_dpos = 2048;
cdbmp->cdb_bpos = cdbmp->cdb_buf + 2048;
return 0;
}
int internal_function
_cdb_make_fullwrite(int fd, const unsigned char *buf, unsigned len)
{
while(len) {
int l = write(fd, buf, len);
if (l > 0) {
len -= l;
buf += l;
}
else if (l < 0 && errno != EINTR)
return -1;
}
return 0;
}
int internal_function
_cdb_make_flush(struct cdb_make *cdbmp) {
unsigned len = cdbmp->cdb_bpos - cdbmp->cdb_buf;
if (len) {
if (_cdb_make_fullwrite(cdbmp->cdb_fd, cdbmp->cdb_buf, len) < 0)
return -1;
cdbmp->cdb_bpos = cdbmp->cdb_buf;
}
return 0;
}
int internal_function
_cdb_make_write(struct cdb_make *cdbmp, const unsigned char *ptr, unsigned len)
{
unsigned l = sizeof(cdbmp->cdb_buf) - (cdbmp->cdb_bpos - cdbmp->cdb_buf);
cdbmp->cdb_dpos += len;
if (len > l) {
memcpy(cdbmp->cdb_bpos, ptr, l);
cdbmp->cdb_bpos += l;
if (_cdb_make_flush(cdbmp) < 0)
return -1;
ptr += l; len -= l;
l = len / sizeof(cdbmp->cdb_buf);
if (l) {
l *= sizeof(cdbmp->cdb_buf);
if (_cdb_make_fullwrite(cdbmp->cdb_fd, ptr, l) < 0)
return -1;
ptr += l; len -= l;
}
}
if (len) {
memcpy(cdbmp->cdb_bpos, ptr, len);
cdbmp->cdb_bpos += len;
}
return 0;
}
static int
cdb_make_finish_internal(struct cdb_make *cdbmp)
{
unsigned hcnt[256]; /* hash table counts */
unsigned hpos[256]; /* hash table positions */
struct cdb_rec *htab;
unsigned char *p;
struct cdb_rl *rl;
unsigned hsize;
unsigned t, i;
if (((0xffffffff - cdbmp->cdb_dpos) >> 3) < cdbmp->cdb_rcnt)
return errno = ENOMEM, -1;
/* count htab sizes and reorder reclists */
hsize = 0;
for (t = 0; t < 256; ++t) {
struct cdb_rl *rlt = NULL;
i = 0;
rl = cdbmp->cdb_rec[t];
while(rl) {
struct cdb_rl *rln = rl->next;
rl->next = rlt;
rlt = rl;
i += rl->cnt;
rl = rln;
}
cdbmp->cdb_rec[t] = rlt;
if (hsize < (hcnt[t] = i << 1))
hsize = hcnt[t];
}
/* allocate memory to hold max htable */
htab = (struct cdb_rec*)malloc((hsize + 2) * sizeof(struct cdb_rec));
if (!htab)
return errno = ENOENT, -1;
p = (unsigned char *)htab;
htab += 2;
/* build hash tables */
for (t = 0; t < 256; ++t) {
unsigned len, hi;
hpos[t] = cdbmp->cdb_dpos;
if ((len = hcnt[t]) == 0)
continue;
for (i = 0; i < len; ++i)
htab[i].hval = htab[i].rpos = 0;
for (rl = cdbmp->cdb_rec[t]; rl; rl = rl->next)
for (i = 0; i < rl->cnt; ++i) {
hi = (rl->rec[i].hval >> 8) % len;
while(htab[hi].rpos)
if (++hi == len)
hi = 0;
htab[hi] = rl->rec[i];
}
for (i = 0; i < len; ++i) {
cdb_pack(htab[i].hval, p + (i << 3));
cdb_pack(htab[i].rpos, p + (i << 3) + 4);
}
if (_cdb_make_write(cdbmp, p, len << 3) < 0) {
free(p);
return -1;
}
}
free(p);
if (_cdb_make_flush(cdbmp) < 0)
return -1;
p = cdbmp->cdb_buf;
for (t = 0; t < 256; ++t) {
cdb_pack(hpos[t], p + (t << 3));
cdb_pack(hcnt[t], p + (t << 3) + 4);
}
if (lseek(cdbmp->cdb_fd, 0, 0) != 0 ||
_cdb_make_fullwrite(cdbmp->cdb_fd, p, 2048) != 0)
return -1;
return 0;
}
static void
cdb_make_free(struct cdb_make *cdbmp)
{
unsigned t;
for(t = 0; t < 256; ++t) {
struct cdb_rl *rl = cdbmp->cdb_rec[t];
while(rl) {
struct cdb_rl *tm = rl;
rl = rl->next;
free(tm);
}
}
}
int
cdb_make_finish(struct cdb_make *cdbmp)
{
int r = cdb_make_finish_internal(cdbmp);
cdb_make_free(cdbmp);
return r;
}

View file

@ -0,0 +1,49 @@
/* cdb_make_add.c: basic cdb_make_add routine
*
* This file is a part of tinycdb package by Michael Tokarev, mjt@corpit.ru.
* Public domain.
*/
#include <stdlib.h> /* for malloc */
#include "cdb_int.h"
int internal_function
_cdb_make_add(struct cdb_make *cdbmp, unsigned hval,
const void *key, unsigned klen,
const void *val, unsigned vlen)
{
unsigned char rlen[8];
struct cdb_rl *rl;
unsigned i;
if (klen > 0xffffffff - (cdbmp->cdb_dpos + 8) ||
vlen > 0xffffffff - (cdbmp->cdb_dpos + klen + 8))
return errno = ENOMEM, -1;
i = hval & 255;
rl = cdbmp->cdb_rec[i];
if (!rl || rl->cnt >= sizeof(rl->rec)/sizeof(rl->rec[0])) {
rl = (struct cdb_rl*)malloc(sizeof(struct cdb_rl));
if (!rl)
return errno = ENOMEM, -1;
rl->cnt = 0;
rl->next = cdbmp->cdb_rec[i];
cdbmp->cdb_rec[i] = rl;
}
i = rl->cnt++;
rl->rec[i].hval = hval;
rl->rec[i].rpos = cdbmp->cdb_dpos;
++cdbmp->cdb_rcnt;
cdb_pack(klen, rlen);
cdb_pack(vlen, rlen + 4);
if (_cdb_make_write(cdbmp, rlen, 8) < 0 ||
_cdb_make_write(cdbmp, key, klen) < 0 ||
_cdb_make_write(cdbmp, val, vlen) < 0)
return -1;
return 0;
}
int
cdb_make_add(struct cdb_make *cdbmp,
const void *key, unsigned klen,
const void *val, unsigned vlen) {
return _cdb_make_add(cdbmp, cdb_hash(key, klen), key, klen, val, vlen);
}

View file

@ -0,0 +1,203 @@
/* cdb_make_put.c: "advanced" cdb_make_put routine
*
* This file is a part of tinycdb package by Michael Tokarev, mjt@corpit.ru.
* Public domain.
*/
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
#include "cdb_int.h"
static void
fixup_rpos(struct cdb_make *cdbmp, unsigned rpos, unsigned rlen) {
unsigned i;
struct cdb_rl *rl;
register struct cdb_rec *rp, *rs;
for (i = 0; i < 256; ++i) {
for (rl = cdbmp->cdb_rec[i]; rl; rl = rl->next)
for (rs = rl->rec, rp = rs + rl->cnt; --rp >= rs;)
if (rp->rpos <= rpos) goto nexthash;
else rp->rpos -= rlen;
nexthash:;
}
}
static int
remove_record(struct cdb_make *cdbmp, unsigned rpos, unsigned rlen) {
unsigned pos, len;
int r, fd;
len = cdbmp->cdb_dpos - rpos - rlen;
cdbmp->cdb_dpos -= rlen;
if (!len)
return 0; /* it was the last record, nothing to do */
pos = rpos;
fd = cdbmp->cdb_fd;
do {
r = len > sizeof(cdbmp->cdb_buf) ? sizeof(cdbmp->cdb_buf) : len;
if (lseek(fd, pos + rlen, SEEK_SET) < 0 ||
(r = read(fd, cdbmp->cdb_buf, r)) <= 0)
return -1;
if (lseek(fd, pos, SEEK_SET) < 0 ||
_cdb_make_fullwrite(fd, cdbmp->cdb_buf, r) < 0)
return -1;
pos += r;
len -= r;
} while(len);
assert(cdbmp->cdb_dpos == pos);
fixup_rpos(cdbmp, rpos, rlen);
return 0;
}
static int
zerofill_record(struct cdb_make *cdbmp, unsigned rpos, unsigned rlen) {
if (rpos + rlen == cdbmp->cdb_dpos) {
cdbmp->cdb_dpos = rpos;
return 0;
}
if (lseek(cdbmp->cdb_fd, rpos, SEEK_SET) < 0)
return -1;
memset(cdbmp->cdb_buf, 0, sizeof(cdbmp->cdb_buf));
cdb_pack(rlen - 8, cdbmp->cdb_buf + 4);
for(;;) {
rpos = rlen > sizeof(cdbmp->cdb_buf) ? sizeof(cdbmp->cdb_buf) : rlen;
if (_cdb_make_fullwrite(cdbmp->cdb_fd, cdbmp->cdb_buf, rpos) < 0)
return -1;
rlen -= rpos;
if (!rlen) return 0;
memset(cdbmp->cdb_buf + 4, 0, 4);
}
}
/* return: 0 = not found, 1 = error, or record length */
static unsigned
match(struct cdb_make *cdbmp, unsigned pos, const char *key, unsigned klen)
{
int len;
unsigned rlen;
if (lseek(cdbmp->cdb_fd, pos, SEEK_SET) < 0)
return 1;
if (read(cdbmp->cdb_fd, cdbmp->cdb_buf, 8) != 8)
return 1;
if (cdb_unpack(cdbmp->cdb_buf) != klen)
return 0;
/* record length; check its validity */
rlen = cdb_unpack(cdbmp->cdb_buf + 4);
if (rlen > cdbmp->cdb_dpos - pos - klen - 8)
return errno = EPROTO, 1; /* someone changed our file? */
rlen += klen + 8;
while(klen) {
len = klen > sizeof(cdbmp->cdb_buf) ? sizeof(cdbmp->cdb_buf) : klen;
len = read(cdbmp->cdb_fd, cdbmp->cdb_buf, len);
if (len <= 0)
return 1;
if (memcmp(cdbmp->cdb_buf, key, len) != 0)
return 0;
key += len;
klen -= len;
}
return rlen;
}
static int
findrec(struct cdb_make *cdbmp,
const void *key, unsigned klen, unsigned hval,
enum cdb_put_mode mode)
{
struct cdb_rl *rl;
struct cdb_rec *rp, *rs;
unsigned r;
int seeked = 0;
int ret = 0;
for(rl = cdbmp->cdb_rec[hval&255]; rl; rl = rl->next)
for(rs = rl->rec, rp = rs + rl->cnt; --rp >= rs;) {
if (rp->hval != hval)
continue;
/*XXX this explicit flush may be unnecessary having
* smarter match() that looks into cdb_buf too, but
* most of a time here spent in finding hash values
* (above), not keys */
if (!seeked && _cdb_make_flush(cdbmp) < 0)
return -1;
seeked = 1;
r = match(cdbmp, rp->rpos, key, klen);
if (!r)
continue;
if (r == 1)
return -1;
ret = 1;
switch(mode) {
case CDB_FIND_REMOVE:
if (remove_record(cdbmp, rp->rpos, r) < 0)
return -1;
break;
case CDB_FIND_FILL0:
if (zerofill_record(cdbmp, rp->rpos, r) < 0)
return -1;
break;
default: goto finish;
}
memmove(rp, rp + 1, (rs + rl->cnt - 1 - rp) * sizeof(*rp));
--rl->cnt;
--cdbmp->cdb_rcnt;
}
finish:
if (seeked && lseek(cdbmp->cdb_fd, cdbmp->cdb_dpos, SEEK_SET) < 0)
return -1;
return ret;
}
int
cdb_make_find(struct cdb_make *cdbmp,
const void *key, unsigned klen,
enum cdb_put_mode mode)
{
return findrec(cdbmp, key, klen, cdb_hash(key, klen), mode);
}
int
cdb_make_exists(struct cdb_make *cdbmp,
const void *key, unsigned klen)
{
return cdb_make_find(cdbmp, key, klen, CDB_FIND);
}
int
cdb_make_put(struct cdb_make *cdbmp,
const void *key, unsigned klen,
const void *val, unsigned vlen,
enum cdb_put_mode mode)
{
unsigned hval = cdb_hash(key, klen);
int r;
switch(mode) {
case CDB_PUT_REPLACE:
case CDB_PUT_INSERT:
case CDB_PUT_WARN:
case CDB_PUT_REPLACE0:
r = findrec(cdbmp, key, klen, hval, mode);
if (r < 0)
return -1;
if (r && mode == CDB_PUT_INSERT)
return errno = EEXIST, 1;
break;
case CDB_PUT_ADD:
r = 0;
break;
default:
return errno = EINVAL, -1;
}
if (_cdb_make_add(cdbmp, hval, key, klen, val, vlen) < 0)
return -1;
return r;
}

View file

@ -0,0 +1,99 @@
/* cdb_seek.c: old interface for reading cdb file
*
* This file is a part of tinycdb package by Michael Tokarev, mjt@corpit.ru.
* Public domain.
*/
#include <unistd.h>
#include "cdb_int.h"
#ifndef SEEK_SET
# define SEEK_SET 0
#endif
/* read a chunk from file, ignoring interrupts (EINTR) */
int
cdb_bread(int fd, void *buf, int len)
{
int l;
while(len > 0) {
do l = read(fd, buf, len);
while(l < 0 && errno == EINTR);
if (l <= 0) {
if (!l)
errno = EIO;
return -1;
}
buf = (char*)buf + l;
len -= l;
}
return 0;
}
/* find a given key in cdb file, seek a file pointer to it's value and
place data length to *dlenp. */
int
cdb_seek(int fd, const void *key, unsigned klen, unsigned *dlenp)
{
unsigned htstart; /* hash table start position */
unsigned htsize; /* number of elements in a hash table */
unsigned httodo; /* hash table elements left to look */
unsigned hti; /* hash table index */
unsigned pos; /* position in a file */
unsigned hval; /* key's hash value */
unsigned char rbuf[64]; /* read buffer */
int needseek = 1; /* if we should seek to a hash slot */
hval = cdb_hash(key, klen);
pos = (hval & 0xff) << 3; /* position in TOC */
/* read the hash table parameters */
if (lseek(fd, pos, SEEK_SET) < 0 || cdb_bread(fd, rbuf, 8) < 0)
return -1;
if ((htsize = cdb_unpack(rbuf + 4)) == 0)
return 0;
hti = (hval >> 8) % htsize; /* start position in hash table */
httodo = htsize;
htstart = cdb_unpack(rbuf);
for(;;) {
if (needseek && lseek(fd, htstart + (hti << 3), SEEK_SET) < 0)
return -1;
if (cdb_bread(fd, rbuf, 8) < 0)
return -1;
if ((pos = cdb_unpack(rbuf + 4)) == 0) /* not found */
return 0;
if (cdb_unpack(rbuf) != hval) /* hash value not matched */
needseek = 0;
else { /* hash value matched */
if (lseek(fd, pos, SEEK_SET) < 0 || cdb_bread(fd, rbuf, 8) < 0)
return -1;
if (cdb_unpack(rbuf) == klen) { /* key length matches */
/* read the key from file and compare with wanted */
unsigned l = klen, c;
const char *k = (const char*)key;
if (dlenp)
*dlenp = cdb_unpack(rbuf + 4); /* save value length */
for(;;) {
if (!l) /* the whole key read and matches, return */
return 1;
c = l > sizeof(rbuf) ? sizeof(rbuf) : l;
if (cdb_bread(fd, rbuf, c) < 0)
return -1;
if (memcmp(rbuf, k, c) != 0) /* no, it differs, stop here */
break;
k += c; l -= c;
}
}
needseek = 1; /* we're looked to other place, should seek back */
}
if (!--httodo)
return 0;
if (++hti == htsize) {
hti = 0;
needseek = 1;
}
}
}

View file

@ -0,0 +1,28 @@
/* cdb_seq.c: sequential record retrieval routines
*
* This file is a part of tinycdb package by Michael Tokarev, mjt@corpit.ru.
* Public domain.
*/
#include "cdb_int.h"
int
cdb_seqnext(unsigned *cptr, struct cdb *cdbp) {
unsigned klen, vlen;
unsigned pos = *cptr;
unsigned dend = cdbp->cdb_dend;
const unsigned char *mem = cdbp->cdb_mem;
if (pos > dend - 8)
return 0;
klen = cdb_unpack(mem + pos);
vlen = cdb_unpack(mem + pos + 4);
pos += 8;
if (dend - klen < pos || dend - vlen < pos + klen)
return errno = EPROTO, -1;
cdbp->cdb_kpos = pos;
cdbp->cdb_klen = klen;
cdbp->cdb_vpos = pos + klen;
cdbp->cdb_vlen = vlen;
*cptr = pos + klen + vlen;
return 1;
}

View file

@ -0,0 +1,17 @@
/* cdb_unpack.c: unpack 32bit integer
*
* This file is a part of tinycdb package by Michael Tokarev, mjt@corpit.ru.
* Public domain.
*/
#include "cdb.h"
unsigned
cdb_unpack(const unsigned char buf[4])
{
unsigned n = buf[3];
n <<= 8; n |= buf[2];
n <<= 8; n |= buf[1];
n <<= 8; n |= buf[0];
return n;
}

View file

@ -0,0 +1,88 @@
# tinycdb.spec: tinycdb RPM spec file.
#
# This file is a part of tinycdb package by Michael Tokarev, mjt@corpit.ru.
# Public domain.
Summary: A package for maintenance of constant databases
Name: tinycdb
Version: 0.78
Release: 1
Source: ftp://ftp.corpit.ru/pub/tinycdb/tinycdb_%version.tar.gz
License: Public Domain
Group: System Environment/Libraries
Prefix: %{_prefix}
BuildRoot: %{_tmppath}/%{name}-root
Summary: TinyCDB - a Constant DataBase
%description
tinycdb is a small, fast and reliable utility set and subroutine
library for creating and reading constant databases. The database
structure is tuned for fast reading:
+ Successful lookups take normally just two disk accesses.
+ Unsuccessful lookups take only one disk access.
+ Small disk space and memory size requirements; a database
uses 2048 bytes for the header and 24 bytes plus size of
(key,value) per record.
+ Maximum database size is 4GB; individual record size is not
otherwise limited.
+ Portable file format.
+ Fast creation of new databases.
+ No locking, updates are atomical.
This package contains both the utility and the development
files, together with nss_cdb module.
%package devel
Summary: Development files for the tinycdb library.
Group: System Environment/Libraries
Requires: %name = %version-%release
Summary: Development files for tinycdb
%description devel
tinycdb is a small, fast and reliable utility set and subroutine
library for creating and reading constant databases.
This package contains tinycdb development libraries and header files.
%prep
%setup -q
%build
make CFLAGS="$RPM_OPT_FLAGS" \
staticlib sharedlib cdb-shared nss \
sysconfdir=/etc
%install
rm -rf $RPM_BUILD_ROOT
mkdir -p $RPM_BUILD_ROOT
%makeinstall DESTDIR=$RPM_BUILD_ROOT \
libdir=%_libdir bindir=%_bindir mandir=%_mandir \
syslibdir=/%_lib sysconfdir=/etc \
includedir=%_includedir \
install-all install-nss install-piclib install-sharedlib \
INSTALLPROG=cdb-shared CP="cp -p"
%files
%defattr(-,root,root)
%_bindir/*
%_mandir/man1/*
%_mandir/man5/*
%_libdir/libcdb.so.*
/%_lib/libnss_cdb*
/etc/cdb-Makefile
%doc ChangeLog NEWS debian/changelog
%files devel
%defattr(-,root,root)
%_libdir/libcdb.a
%_libdir/libcdb_pic.a
%_libdir/libcdb.so
%_mandir/man3/*
%_includedir/*
%clean
rm -rf $RPM_BUILD_ROOT
%post -p /sbin/ldconfig
%postun -p /sbin/ldconfig
%changelog

View file

@ -324,7 +324,6 @@ sapp_desc sokol_main(int sargc, char **sargs) {
#endif #endif
#endif #endif
stm_setup(); /* time */ stm_setup(); /* time */
resources_init(); resources_init();