+ if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){
+ static const struct {
+ const char *zCtrlName; /* Name of a test-control option */
+ int ctrlCode; /* Integer code for that option */
+ } aCtrl[] = {
+ { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE },
+ { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE },
+ { "prng_reset", SQLITE_TESTCTRL_PRNG_RESET },
+ { "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST },
+ { "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL },
+ { "benign_malloc_hooks", SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS },
+ { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE },
+ { "assert", SQLITE_TESTCTRL_ASSERT },
+ { "always", SQLITE_TESTCTRL_ALWAYS },
+ { "reserve", SQLITE_TESTCTRL_RESERVE },
+ { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS },
+ { "iskeyword", SQLITE_TESTCTRL_ISKEYWORD },
+ { "pghdrsz", SQLITE_TESTCTRL_PGHDRSZ },
+ { "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC },
+ };
+ int testctrl = -1;
+ int rc = 0;
+ int i, n;
+ open_db(p);
+
+ /* convert testctrl text option to value. allow any unique prefix
+ ** of the option name, or a numerical value. */
+ n = strlen30(azArg[1]);
+ for(i=0; i<(int)(sizeof(aCtrl)/sizeof(aCtrl[0])); i++){
+ if( strncmp(azArg[1], aCtrl[i].zCtrlName, n)==0 ){
+ if( testctrl<0 ){
+ testctrl = aCtrl[i].ctrlCode;
+ }else{
+ fprintf(stderr, "ambiguous option name: \"%s\"\n", azArg[i]);
+ testctrl = -1;
+ break;
+ }
+ }
+ }
+ if( testctrl<0 ) testctrl = atoi(azArg[1]);
+ if( (testctrl<SQLITE_TESTCTRL_FIRST) || (testctrl>SQLITE_TESTCTRL_LAST) ){
+ fprintf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]);
+ }else{
+ switch(testctrl){
+
+ /* sqlite3_test_control(int, db, int) */
+ case SQLITE_TESTCTRL_OPTIMIZATIONS:
+ case SQLITE_TESTCTRL_RESERVE:
+ if( nArg==3 ){
+ int opt = (int)strtol(azArg[2], 0, 0);
+ rc = sqlite3_test_control(testctrl, p->db, opt);
+ printf("%d (0x%08x)\n", rc, rc);
+ } else {
+ fprintf(stderr,"Error: testctrl %s takes a single int option\n",
+ azArg[1]);
+ }
+ break;
+
+ /* sqlite3_test_control(int) */
+ case SQLITE_TESTCTRL_PRNG_SAVE:
+ case SQLITE_TESTCTRL_PRNG_RESTORE:
+ case SQLITE_TESTCTRL_PRNG_RESET:
+ case SQLITE_TESTCTRL_PGHDRSZ:
+ if( nArg==2 ){
+ rc = sqlite3_test_control(testctrl);
+ printf("%d (0x%08x)\n", rc, rc);
+ } else {
+ fprintf(stderr,"Error: testctrl %s takes no options\n", azArg[1]);
+ }
+ break;
+
+ /* sqlite3_test_control(int, uint) */
+ case SQLITE_TESTCTRL_PENDING_BYTE:
+ if( nArg==3 ){
+ unsigned int opt = (unsigned int)atoi(azArg[2]);
+ rc = sqlite3_test_control(testctrl, opt);
+ printf("%d (0x%08x)\n", rc, rc);
+ } else {
+ fprintf(stderr,"Error: testctrl %s takes a single unsigned"
+ " int option\n", azArg[1]);
+ }
+ break;
+
+ /* sqlite3_test_control(int, int) */
+ case SQLITE_TESTCTRL_ASSERT:
+ case SQLITE_TESTCTRL_ALWAYS:
+ if( nArg==3 ){
+ int opt = atoi(azArg[2]);
+ rc = sqlite3_test_control(testctrl, opt);
+ printf("%d (0x%08x)\n", rc, rc);
+ } else {
+ fprintf(stderr,"Error: testctrl %s takes a single int option\n",
+ azArg[1]);
+ }
+ break;
+
+ /* sqlite3_test_control(int, char *) */
+#ifdef SQLITE_N_KEYWORD
+ case SQLITE_TESTCTRL_ISKEYWORD:
+ if( nArg==3 ){
+ const char *opt = azArg[2];
+ rc = sqlite3_test_control(testctrl, opt);
+ printf("%d (0x%08x)\n", rc, rc);
+ } else {
+ fprintf(stderr,"Error: testctrl %s takes a single char * option\n",
+ azArg[1]);
+ }
+ break;
+#endif
+
+ case SQLITE_TESTCTRL_BITVEC_TEST:
+ case SQLITE_TESTCTRL_FAULT_INSTALL:
+ case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS:
+ case SQLITE_TESTCTRL_SCRATCHMALLOC:
+ default:
+ fprintf(stderr,"Error: CLI support for testctrl %s not implemented\n",
+ azArg[1]);
+ break;
+ }
+ }
+ }else
+