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

     1  /*
     2  ** 2001 September 15
     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  ** Code for testing the utf.c module in SQLite.  This code
    13  ** is not included in the SQLite library.  It is used for automated
    14  ** testing of the SQLite library. Specifically, the code in this file
    15  ** is used for testing the SQLite routines for converting between
    16  ** the various supported unicode encodings.
    17  */
    18  #include "sqliteInt.h"
    19  #include "vdbeInt.h"
    20  #if defined(INCLUDE_SQLITE_TCL_H)
    21  #  include "sqlite_tcl.h"
    22  #else
    23  #  include "tcl.h"
    24  #endif
    25  #include <stdlib.h>
    26  #include <string.h>
    27  
    28  /*
    29  ** The first argument is a TCL UTF-8 string. Return the byte array
    30  ** object with the encoded representation of the string, including
    31  ** the NULL terminator.
    32  */
    33  static int SQLITE_TCLAPI binarize(
    34    void * clientData,
    35    Tcl_Interp *interp,
    36    int objc,
    37    Tcl_Obj *CONST objv[]
    38  ){
    39    int len;
    40    char *bytes;
    41    Tcl_Obj *pRet;
    42    assert(objc==2);
    43  
    44    bytes = Tcl_GetStringFromObj(objv[1], &len);
    45    pRet = Tcl_NewByteArrayObj((u8*)bytes, len+1);
    46    Tcl_SetObjResult(interp, pRet);
    47    return TCL_OK;
    48  }
    49  
    50  /*
    51  ** Usage: test_value_overhead <repeat-count> <do-calls>.
    52  **
    53  ** This routine is used to test the overhead of calls to
    54  ** sqlite3_value_text(), on a value that contains a UTF-8 string. The idea
    55  ** is to figure out whether or not it is a problem to use sqlite3_value
    56  ** structures with collation sequence functions.
    57  **
    58  ** If <do-calls> is 0, then the calls to sqlite3_value_text() are not
    59  ** actually made.
    60  */
    61  static int SQLITE_TCLAPI test_value_overhead(
    62    void * clientData,
    63    Tcl_Interp *interp,
    64    int objc,
    65    Tcl_Obj *CONST objv[]
    66  ){
    67    int do_calls;
    68    int repeat_count;
    69    int i;
    70    Mem val;
    71  
    72    if( objc!=3 ){
    73      Tcl_AppendResult(interp, "wrong # args: should be \"",
    74          Tcl_GetStringFromObj(objv[0], 0), " <repeat-count> <do-calls>", 0);
    75      return TCL_ERROR;
    76    }
    77  
    78    if( Tcl_GetIntFromObj(interp, objv[1], &repeat_count) ) return TCL_ERROR;
    79    if( Tcl_GetIntFromObj(interp, objv[2], &do_calls) ) return TCL_ERROR;
    80  
    81    val.flags = MEM_Str|MEM_Term|MEM_Static;
    82    val.z = "hello world";
    83    val.enc = SQLITE_UTF8;
    84  
    85    for(i=0; i<repeat_count; i++){
    86      if( do_calls ){
    87        sqlite3_value_text(&val);
    88      }
    89    }
    90  
    91    return TCL_OK;
    92  }
    93  
    94  static u8 name_to_enc(Tcl_Interp *interp, Tcl_Obj *pObj){
    95    struct EncName {
    96      char *zName;
    97      u8 enc;
    98    } encnames[] = {
    99      { "UTF8", SQLITE_UTF8 },
   100      { "UTF16LE", SQLITE_UTF16LE },
   101      { "UTF16BE", SQLITE_UTF16BE },
   102      { "UTF16", SQLITE_UTF16 },
   103      { 0, 0 }
   104    };
   105    struct EncName *pEnc;
   106    char *z = Tcl_GetString(pObj);
   107    for(pEnc=&encnames[0]; pEnc->zName; pEnc++){
   108      if( 0==sqlite3StrICmp(z, pEnc->zName) ){
   109        break;
   110      }
   111    }
   112    if( !pEnc->enc ){
   113      Tcl_AppendResult(interp, "No such encoding: ", z, 0);
   114    }
   115    if( pEnc->enc==SQLITE_UTF16 ){
   116      return SQLITE_UTF16NATIVE;
   117    }
   118    return pEnc->enc;
   119  }
   120  
   121  /*
   122  ** Usage:   test_translate <string/blob> <from enc> <to enc> ?<transient>?
   123  **
   124  */
   125  static int SQLITE_TCLAPI test_translate(
   126    void * clientData,
   127    Tcl_Interp *interp,
   128    int objc,
   129    Tcl_Obj *CONST objv[]
   130  ){
   131    u8 enc_from;
   132    u8 enc_to;
   133    sqlite3_value *pVal;
   134  
   135    char *z;
   136    int len;
   137    void (*xDel)(void *p) = SQLITE_STATIC;
   138  
   139    if( objc!=4 && objc!=5 ){
   140      Tcl_AppendResult(interp, "wrong # args: should be \"",
   141          Tcl_GetStringFromObj(objv[0], 0), 
   142          " <string/blob> <from enc> <to enc>", 0
   143      );
   144      return TCL_ERROR;
   145    }
   146    if( objc==5 ){
   147      xDel = sqlite3_free;
   148    }
   149  
   150    enc_from = name_to_enc(interp, objv[2]);
   151    if( !enc_from ) return TCL_ERROR;
   152    enc_to = name_to_enc(interp, objv[3]);
   153    if( !enc_to ) return TCL_ERROR;
   154  
   155    pVal = sqlite3ValueNew(0);
   156  
   157    if( enc_from==SQLITE_UTF8 ){
   158      z = Tcl_GetString(objv[1]);
   159      if( objc==5 ){
   160        z = sqlite3_mprintf("%s", z);
   161      }
   162      sqlite3ValueSetStr(pVal, -1, z, enc_from, xDel);
   163    }else{
   164      z = (char*)Tcl_GetByteArrayFromObj(objv[1], &len);
   165      if( objc==5 ){
   166        char *zTmp = z;
   167        z = sqlite3_malloc(len);
   168        memcpy(z, zTmp, len);
   169      }
   170      sqlite3ValueSetStr(pVal, -1, z, enc_from, xDel);
   171    }
   172  
   173    z = (char *)sqlite3ValueText(pVal, enc_to);
   174    len = sqlite3ValueBytes(pVal, enc_to) + (enc_to==SQLITE_UTF8?1:2);
   175    Tcl_SetObjResult(interp, Tcl_NewByteArrayObj((u8*)z, len));
   176  
   177    sqlite3ValueFree(pVal);
   178  
   179    return TCL_OK;
   180  }
   181  
   182  /*
   183  ** Usage: translate_selftest
   184  **
   185  ** Call sqlite3UtfSelfTest() to run the internal tests for unicode
   186  ** translation. If there is a problem an assert() will fail.
   187  **/
   188  void sqlite3UtfSelfTest(void);
   189  static int SQLITE_TCLAPI test_translate_selftest(
   190    void * clientData,
   191    Tcl_Interp *interp,
   192    int objc,
   193    Tcl_Obj *CONST objv[]
   194  ){
   195  #ifndef SQLITE_OMIT_UTF16
   196    sqlite3UtfSelfTest();
   197  #endif
   198    return SQLITE_OK;
   199  }
   200  
   201  
   202  /*
   203  ** Register commands with the TCL interpreter.
   204  */
   205  int Sqlitetest5_Init(Tcl_Interp *interp){
   206    static struct {
   207      char *zName;
   208      Tcl_ObjCmdProc *xProc;
   209    } aCmd[] = {
   210      { "binarize",                (Tcl_ObjCmdProc*)binarize },
   211      { "test_value_overhead",     (Tcl_ObjCmdProc*)test_value_overhead },
   212      { "test_translate",          (Tcl_ObjCmdProc*)test_translate     },
   213      { "translate_selftest",      (Tcl_ObjCmdProc*)test_translate_selftest},
   214    };
   215    int i;
   216    for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){
   217      Tcl_CreateObjCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0);
   218    }
   219    return SQLITE_OK;
   220  }