modernc.org/cc@v1.0.1/v2/testdata/_sqlite/src/test_init.c (about)

     1  /*
     2  ** 2009 August 17
     3  **
     4  ** The author disclaims copyright to this source code.  In place of
     5  ** a legal notice, here is a blessing:
     6  **
     7  **    May you do good and not evil.
     8  **    May you find forgiveness for yourself and forgive others.
     9  **    May you share freely, never taking more than you give.
    10  **
    11  *************************************************************************
    12  **
    13  ** The code in this file is used for testing SQLite. It is not part of
    14  ** the source code used in production systems.
    15  **
    16  ** Specifically, this file tests the effect of errors while initializing
    17  ** the various pluggable sub-systems from within sqlite3_initialize().
    18  ** If an error occurs in sqlite3_initialize() the following should be
    19  ** true:
    20  **
    21  **   1) An error code is returned to the user, and
    22  **   2) A subsequent call to sqlite3_shutdown() calls the shutdown method
    23  **      of those subsystems that were initialized, and
    24  **   3) A subsequent call to sqlite3_initialize() attempts to initialize
    25  **      the remaining, uninitialized, subsystems.
    26  */
    27  
    28  #include "sqliteInt.h"
    29  #include <string.h>
    30  #if defined(INCLUDE_SQLITE_TCL_H)
    31  #  include "sqlite_tcl.h"
    32  #else
    33  #  include "tcl.h"
    34  #endif
    35  
    36  static struct Wrapped {
    37    sqlite3_pcache_methods2 pcache;
    38    sqlite3_mem_methods     mem;
    39    sqlite3_mutex_methods   mutex;
    40  
    41    int mem_init;                /* True if mem subsystem is initalized */
    42    int mem_fail;                /* True to fail mem subsystem inialization */
    43    int mutex_init;              /* True if mutex subsystem is initalized */
    44    int mutex_fail;              /* True to fail mutex subsystem inialization */
    45    int pcache_init;             /* True if pcache subsystem is initalized */
    46    int pcache_fail;             /* True to fail pcache subsystem inialization */
    47  } wrapped;
    48  
    49  static int wrMemInit(void *pAppData){
    50    int rc;
    51    if( wrapped.mem_fail ){
    52      rc = SQLITE_ERROR;
    53    }else{
    54      rc = wrapped.mem.xInit(wrapped.mem.pAppData);
    55    }
    56    if( rc==SQLITE_OK ){
    57      wrapped.mem_init = 1;
    58    }
    59    return rc;
    60  }
    61  static void wrMemShutdown(void *pAppData){
    62    wrapped.mem.xShutdown(wrapped.mem.pAppData);
    63    wrapped.mem_init = 0;
    64  }
    65  static void *wrMemMalloc(int n)           {return wrapped.mem.xMalloc(n);}
    66  static void wrMemFree(void *p)            {wrapped.mem.xFree(p);}
    67  static void *wrMemRealloc(void *p, int n) {return wrapped.mem.xRealloc(p, n);}
    68  static int wrMemSize(void *p)             {return wrapped.mem.xSize(p);}
    69  static int wrMemRoundup(int n)            {return wrapped.mem.xRoundup(n);}
    70  
    71  
    72  static int wrMutexInit(void){
    73    int rc;
    74    if( wrapped.mutex_fail ){
    75      rc = SQLITE_ERROR;
    76    }else{
    77      rc = wrapped.mutex.xMutexInit();
    78    }
    79    if( rc==SQLITE_OK ){
    80      wrapped.mutex_init = 1;
    81    }
    82    return rc;
    83  }
    84  static int wrMutexEnd(void){
    85    wrapped.mutex.xMutexEnd();
    86    wrapped.mutex_init = 0;
    87    return SQLITE_OK;
    88  }
    89  static sqlite3_mutex *wrMutexAlloc(int e){
    90    return wrapped.mutex.xMutexAlloc(e);
    91  }
    92  static void wrMutexFree(sqlite3_mutex *p){
    93    wrapped.mutex.xMutexFree(p);
    94  }
    95  static void wrMutexEnter(sqlite3_mutex *p){
    96    wrapped.mutex.xMutexEnter(p);
    97  }
    98  static int wrMutexTry(sqlite3_mutex *p){
    99    return wrapped.mutex.xMutexTry(p);
   100  }
   101  static void wrMutexLeave(sqlite3_mutex *p){
   102    wrapped.mutex.xMutexLeave(p);
   103  }
   104  static int wrMutexHeld(sqlite3_mutex *p){
   105    return wrapped.mutex.xMutexHeld(p);
   106  }
   107  static int wrMutexNotheld(sqlite3_mutex *p){
   108    return wrapped.mutex.xMutexNotheld(p);
   109  }
   110  
   111  
   112  
   113  static int wrPCacheInit(void *pArg){
   114    int rc;
   115    if( wrapped.pcache_fail ){
   116      rc = SQLITE_ERROR;
   117    }else{
   118      rc = wrapped.pcache.xInit(wrapped.pcache.pArg);
   119    }
   120    if( rc==SQLITE_OK ){
   121      wrapped.pcache_init = 1;
   122    }
   123    return rc;
   124  }
   125  static void wrPCacheShutdown(void *pArg){
   126    wrapped.pcache.xShutdown(wrapped.pcache.pArg);
   127    wrapped.pcache_init = 0;
   128  }
   129  
   130  static sqlite3_pcache *wrPCacheCreate(int a, int b, int c){
   131    return wrapped.pcache.xCreate(a, b, c);
   132  }  
   133  static void wrPCacheCachesize(sqlite3_pcache *p, int n){
   134    wrapped.pcache.xCachesize(p, n);
   135  }  
   136  static int wrPCachePagecount(sqlite3_pcache *p){
   137    return wrapped.pcache.xPagecount(p);
   138  }  
   139  static sqlite3_pcache_page *wrPCacheFetch(sqlite3_pcache *p, unsigned a, int b){
   140    return wrapped.pcache.xFetch(p, a, b);
   141  }  
   142  static void wrPCacheUnpin(sqlite3_pcache *p, sqlite3_pcache_page *a, int b){
   143    wrapped.pcache.xUnpin(p, a, b);
   144  }  
   145  static void wrPCacheRekey(
   146    sqlite3_pcache *p, 
   147    sqlite3_pcache_page *a, 
   148    unsigned b, 
   149    unsigned c
   150  ){
   151    wrapped.pcache.xRekey(p, a, b, c);
   152  }  
   153  static void wrPCacheTruncate(sqlite3_pcache *p, unsigned a){
   154    wrapped.pcache.xTruncate(p, a);
   155  }  
   156  static void wrPCacheDestroy(sqlite3_pcache *p){
   157    wrapped.pcache.xDestroy(p);
   158  }  
   159  
   160  static void installInitWrappers(void){
   161    sqlite3_mutex_methods mutexmethods = {
   162      wrMutexInit,  wrMutexEnd,   wrMutexAlloc,
   163      wrMutexFree,  wrMutexEnter, wrMutexTry,
   164      wrMutexLeave, wrMutexHeld,  wrMutexNotheld
   165    };
   166    sqlite3_pcache_methods2 pcachemethods = {
   167      1, 0,
   168      wrPCacheInit,      wrPCacheShutdown,  wrPCacheCreate, 
   169      wrPCacheCachesize, wrPCachePagecount, wrPCacheFetch,
   170      wrPCacheUnpin,     wrPCacheRekey,     wrPCacheTruncate,  
   171      wrPCacheDestroy
   172    };
   173    sqlite3_mem_methods memmethods = {
   174      wrMemMalloc,   wrMemFree,    wrMemRealloc,
   175      wrMemSize,     wrMemRoundup, wrMemInit,
   176      wrMemShutdown,
   177      0
   178    };
   179  
   180    memset(&wrapped, 0, sizeof(wrapped));
   181  
   182    sqlite3_shutdown();
   183    sqlite3_config(SQLITE_CONFIG_GETMUTEX, &wrapped.mutex);
   184    sqlite3_config(SQLITE_CONFIG_GETMALLOC, &wrapped.mem);
   185    sqlite3_config(SQLITE_CONFIG_GETPCACHE2, &wrapped.pcache);
   186    sqlite3_config(SQLITE_CONFIG_MUTEX, &mutexmethods);
   187    sqlite3_config(SQLITE_CONFIG_MALLOC, &memmethods);
   188    sqlite3_config(SQLITE_CONFIG_PCACHE2, &pcachemethods);
   189  }
   190  
   191  static int SQLITE_TCLAPI init_wrapper_install(
   192    ClientData clientData, /* Unused */
   193    Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
   194    int objc,              /* Number of arguments */
   195    Tcl_Obj *CONST objv[]  /* Command arguments */
   196  ){
   197    int i;
   198    installInitWrappers();
   199    for(i=1; i<objc; i++){
   200      char *z = Tcl_GetString(objv[i]);
   201      if( strcmp(z, "mem")==0 ){
   202        wrapped.mem_fail = 1;
   203      }else if( strcmp(z, "mutex")==0 ){
   204        wrapped.mutex_fail = 1;
   205      }else if( strcmp(z, "pcache")==0 ){
   206        wrapped.pcache_fail = 1;
   207      }else{
   208        Tcl_AppendResult(interp, "Unknown argument: \"", z, "\"");
   209        return TCL_ERROR;
   210      }
   211    }
   212    return TCL_OK;
   213  }
   214  
   215  static int SQLITE_TCLAPI init_wrapper_uninstall(
   216    ClientData clientData, /* Unused */
   217    Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
   218    int objc,              /* Number of arguments */
   219    Tcl_Obj *CONST objv[]  /* Command arguments */
   220  ){
   221    if( objc!=1 ){
   222      Tcl_WrongNumArgs(interp, 1, objv, "");
   223      return TCL_ERROR;
   224    }
   225  
   226    sqlite3_shutdown();
   227    sqlite3_config(SQLITE_CONFIG_MUTEX, &wrapped.mutex);
   228    sqlite3_config(SQLITE_CONFIG_MALLOC, &wrapped.mem);
   229    sqlite3_config(SQLITE_CONFIG_PCACHE2, &wrapped.pcache);
   230    return TCL_OK;
   231  }
   232  
   233  static int SQLITE_TCLAPI init_wrapper_clear(
   234    ClientData clientData, /* Unused */
   235    Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
   236    int objc,              /* Number of arguments */
   237    Tcl_Obj *CONST objv[]  /* Command arguments */
   238  ){
   239    if( objc!=1 ){
   240      Tcl_WrongNumArgs(interp, 1, objv, "");
   241      return TCL_ERROR;
   242    }
   243  
   244    wrapped.mem_fail = 0;
   245    wrapped.mutex_fail = 0;
   246    wrapped.pcache_fail = 0;
   247    return TCL_OK;
   248  }
   249  
   250  static int SQLITE_TCLAPI init_wrapper_query(
   251    ClientData clientData, /* Unused */
   252    Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
   253    int objc,              /* Number of arguments */
   254    Tcl_Obj *CONST objv[]  /* Command arguments */
   255  ){
   256    Tcl_Obj *pRet;
   257  
   258    if( objc!=1 ){
   259      Tcl_WrongNumArgs(interp, 1, objv, "");
   260      return TCL_ERROR;
   261    }
   262  
   263    pRet = Tcl_NewObj();
   264    if( wrapped.mutex_init ){
   265      Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj("mutex", -1));
   266    }
   267    if( wrapped.mem_init ){
   268      Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj("mem", -1));
   269    }
   270    if( wrapped.pcache_init ){
   271      Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj("pcache", -1));
   272    }
   273  
   274    Tcl_SetObjResult(interp, pRet);
   275    return TCL_OK;
   276  }
   277  
   278  int Sqlitetest_init_Init(Tcl_Interp *interp){
   279    static struct {
   280       char *zName;
   281       Tcl_ObjCmdProc *xProc;
   282    } aObjCmd[] = {
   283      {"init_wrapper_install",   init_wrapper_install},
   284      {"init_wrapper_query",     init_wrapper_query  },
   285      {"init_wrapper_uninstall", init_wrapper_uninstall},
   286      {"init_wrapper_clear",     init_wrapper_clear}
   287    };
   288    int i;
   289  
   290    for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){
   291      Tcl_CreateObjCommand(interp, aObjCmd[i].zName, aObjCmd[i].xProc, 0, 0);
   292    }
   293  
   294    return TCL_OK;
   295  }