Diff for /elwix/files/sqlite/dist/shell.c between versions 1.2 and 1.3

version 1.2, 2012/10/12 08:22:46 version 1.3, 2013/01/28 01:47:36
Line 36 Line 36
 #include <ctype.h>  #include <ctype.h>
 #include <stdarg.h>  #include <stdarg.h>
   
#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__)#if !defined(_WIN32) && !defined(WIN32)
 # include <signal.h>  # include <signal.h>
 # if !defined(__RTP__) && !defined(_WRS_KERNEL)  # if !defined(__RTP__) && !defined(_WRS_KERNEL)
 #  include <pwd.h>  #  include <pwd.h>
Line 45 Line 45
 # include <sys/types.h>  # include <sys/types.h>
 #endif  #endif
   
 #ifdef __OS2__  
 # include <unistd.h>  
 #endif  
   
 #ifdef HAVE_EDITLINE  #ifdef HAVE_EDITLINE
 # include <editline/editline.h>  # include <editline/editline.h>
 #endif  #endif
Line 57 Line 53
 # include <readline/history.h>  # include <readline/history.h>
 #endif  #endif
 #if !defined(HAVE_EDITLINE) && (!defined(HAVE_READLINE) || HAVE_READLINE!=1)  #if !defined(HAVE_EDITLINE) && (!defined(HAVE_READLINE) || HAVE_READLINE!=1)
# define readline(p) local_getline(p,stdin)# define readline(p) local_getline(p,stdin,0)
 # define add_history(X)  # define add_history(X)
 # define read_history(X)  # define read_history(X)
 # define write_history(X)  # define write_history(X)
Line 68 Line 64
 # include <io.h>  # include <io.h>
 #define isatty(h) _isatty(h)  #define isatty(h) _isatty(h)
 #define access(f,m) _access((f),(m))  #define access(f,m) _access((f),(m))
   #undef popen
   #define popen(a,b) _popen((a),(b))
   #undef pclose
   #define pclose(x) _pclose(x)
 #else  #else
 /* Make sure isatty() has a prototype.  /* Make sure isatty() has a prototype.
 */  */
Line 90  static int enableTimer = 0; Line 90  static int enableTimer = 0;
 #define IsDigit(X)  isdigit((unsigned char)X)  #define IsDigit(X)  isdigit((unsigned char)X)
 #define ToLower(X)  (char)tolower((unsigned char)X)  #define ToLower(X)  (char)tolower((unsigned char)X)
   
#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(__RTP__) && !defined(_WRS_KERNEL)#if !defined(_WIN32) && !defined(WIN32) && !defined(_WRS_KERNEL)
 #include <sys/time.h>  #include <sys/time.h>
 #include <sys/resource.h>  #include <sys/resource.h>
   
Line 334  static void shellstaticFunc( Line 334  static void shellstaticFunc(
 ** The interface is like "readline" but no command-line editing  ** The interface is like "readline" but no command-line editing
 ** is done.  ** is done.
 */  */
static char *local_getline(char *zPrompt, FILE *in){static char *local_getline(char *zPrompt, FILE *in, int csvFlag){
   char *zLine;    char *zLine;
   int nLine;    int nLine;
   int n;    int n;
     int inQuote = 0;
   
   if( zPrompt && *zPrompt ){    if( zPrompt && *zPrompt ){
     printf("%s",zPrompt);      printf("%s",zPrompt);
Line 361  static char *local_getline(char *zPrompt, FILE *in){ Line 362  static char *local_getline(char *zPrompt, FILE *in){
       zLine[n] = 0;        zLine[n] = 0;
       break;        break;
     }      }
    while( zLine[n] ){ n++; }    while( zLine[n] ){
    if( n>0 && zLine[n-1]=='\n' ){      if( zLine[n]=='"' ) inQuote = !inQuote;
       n++;
     }
     if( n>0 && zLine[n-1]=='\n' && (!inQuote || !csvFlag) ){
       n--;        n--;
       if( n>0 && zLine[n-1]=='\r' ) n--;        if( n>0 && zLine[n-1]=='\r' ) n--;
       zLine[n] = 0;        zLine[n] = 0;
Line 383  static char *one_input_line(const char *zPrior, FILE * Line 387  static char *one_input_line(const char *zPrior, FILE *
   char *zPrompt;    char *zPrompt;
   char *zResult;    char *zResult;
   if( in!=0 ){    if( in!=0 ){
    return local_getline(0, in);    return local_getline(0, in, 0);
   }    }
   if( zPrior && zPrior[0] ){    if( zPrior && zPrior[0] ){
     zPrompt = continuePrompt;      zPrompt = continuePrompt;
Line 415  struct callback_data { Line 419  struct callback_data {
   int statsOn;           /* True to display memory stats before each finalize */    int statsOn;           /* True to display memory stats before each finalize */
   int cnt;               /* Number of records displayed so far */    int cnt;               /* Number of records displayed so far */
   FILE *out;             /* Write results here */    FILE *out;             /* Write results here */
     FILE *traceOut;        /* Output for sqlite3_trace() */
   int nErr;              /* Number of errors seen */    int nErr;              /* Number of errors seen */
   int mode;              /* An output mode setting */    int mode;              /* An output mode setting */
   int writableSchema;    /* True if PRAGMA writable_schema=ON */    int writableSchema;    /* True if PRAGMA writable_schema=ON */
Line 492  static void output_hex_blob(FILE *out, const void *pBl Line 497  static void output_hex_blob(FILE *out, const void *pBl
   int i;    int i;
   char *zBlob = (char *)pBlob;    char *zBlob = (char *)pBlob;
   fprintf(out,"X'");    fprintf(out,"X'");
  for(i=0; i<nBlob; i++){ fprintf(out,"%02x",zBlob[i]); }  for(i=0; i<nBlob; i++){ fprintf(out,"%02x",zBlob[i]&0xff); }
   fprintf(out,"'");    fprintf(out,"'");
 }  }
   
Line 536  static void output_c_string(FILE *out, const char *z){ Line 541  static void output_c_string(FILE *out, const char *z){
     if( c=='\\' ){      if( c=='\\' ){
       fputc(c, out);        fputc(c, out);
       fputc(c, out);        fputc(c, out);
       }else if( c=='"' ){
         fputc('\\', out);
         fputc('"', out);
     }else if( c=='\t' ){      }else if( c=='\t' ){
       fputc('\\', out);        fputc('\\', out);
       fputc('t', out);        fputc('t', out);
Line 614  static const char needCsvQuote[] = { Line 622  static const char needCsvQuote[] = {
 /*  /*
 ** Output a single term of CSV.  Actually, p->separator is used for  ** Output a single term of CSV.  Actually, p->separator is used for
 ** the separator, which may or may not be a comma.  p->nullvalue is  ** the separator, which may or may not be a comma.  p->nullvalue is
** the null value.  Strings are quoted using ANSI-C rules.  Numbers** the null value.  Strings are quoted if necessary.
** appear outside of quotes. 
 */  */
 static void output_csv(struct callback_data *p, const char *z, int bSep){  static void output_csv(struct callback_data *p, const char *z, int bSep){
   FILE *out = p->out;    FILE *out = p->out;
Line 692  static int shell_callback(void *pArg, int nArg, char * Line 699  static int shell_callback(void *pArg, int nArg, char *
           }else{            }else{
             w = 0;              w = 0;
           }            }
          if( w<=0 ){          if( w==0 ){
             w = strlen30(azCol[i] ? azCol[i] : "");              w = strlen30(azCol[i] ? azCol[i] : "");
             if( w<10 ) w = 10;              if( w<10 ) w = 10;
             n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullvalue);              n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullvalue);
Line 702  static int shell_callback(void *pArg, int nArg, char * Line 709  static int shell_callback(void *pArg, int nArg, char *
             p->actualWidth[i] = w;              p->actualWidth[i] = w;
           }            }
           if( p->showHeader ){            if( p->showHeader ){
            fprintf(p->out,"%-*.*s%s",w,w,azCol[i], i==nArg-1 ? "\n": "  ");            if( w<0 ){
               fprintf(p->out,"%*.*s%s",-w,-w,azCol[i], i==nArg-1 ? "\n": "  ");
             }else{
               fprintf(p->out,"%-*.*s%s",w,w,azCol[i], i==nArg-1 ? "\n": "  ");
             }
           }            }
         }          }
         if( p->showHeader ){          if( p->showHeader ){
Line 710  static int shell_callback(void *pArg, int nArg, char * Line 721  static int shell_callback(void *pArg, int nArg, char *
             int w;              int w;
             if( i<ArraySize(p->actualWidth) ){              if( i<ArraySize(p->actualWidth) ){
                w = p->actualWidth[i];                 w = p->actualWidth[i];
                  if( w<0 ) w = -w;
             }else{              }else{
                w = 10;                 w = 10;
             }              }
Line 731  static int shell_callback(void *pArg, int nArg, char * Line 743  static int shell_callback(void *pArg, int nArg, char *
            strlen30(azArg[i])>w ){             strlen30(azArg[i])>w ){
           w = strlen30(azArg[i]);            w = strlen30(azArg[i]);
         }          }
        fprintf(p->out,"%-*.*s%s",w,w,        if( w<0 ){
            azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": "  ");          fprintf(p->out,"%*.*s%s",-w,-w,
               azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": "  ");
         }else{
           fprintf(p->out,"%-*.*s%s",w,w,
               azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": "  ");
         }
       }        }
       break;        break;
     }      }
Line 782  static int shell_callback(void *pArg, int nArg, char * Line 799  static int shell_callback(void *pArg, int nArg, char *
       if( p->cnt++==0 && p->showHeader ){        if( p->cnt++==0 && p->showHeader ){
         for(i=0; i<nArg; i++){          for(i=0; i<nArg; i++){
           output_c_string(p->out,azCol[i] ? azCol[i] : "");            output_c_string(p->out,azCol[i] ? azCol[i] : "");
          fprintf(p->out, "%s", p->separator);          if(i<nArg-1) fprintf(p->out, "%s", p->separator);
         }          }
         fprintf(p->out,"\n");          fprintf(p->out,"\n");
       }        }
       if( azArg==0 ) break;        if( azArg==0 ) break;
       for(i=0; i<nArg; i++){        for(i=0; i<nArg; i++){
         output_c_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);          output_c_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
        fprintf(p->out, "%s", p->separator);        if(i<nArg-1) fprintf(p->out, "%s", p->separator);
       }        }
       fprintf(p->out,"\n");        fprintf(p->out,"\n");
       break;        break;
Line 934  static char *appendText(char *zIn, char const *zAppend Line 951  static char *appendText(char *zIn, char const *zAppend
   
   
 /*  /*
** Execute a query statement that has a single result column.  Print** Execute a query statement that will generate SQL output.  Print
** that result column on a line by itself with a semicolon terminator.** the result columns, comma-separated, on a line and then add a
 ** semicolon terminator to the end of that line.
 **  **
** This is used, for example, to show the schema of the database by** If the number of columns is 1 and that column contains text "--"
** querying the SQLITE_MASTER table.** then write the semicolon on a separate line.  That way, if a 
 ** "--" comment occurs at the end of the statement, the comment
 ** won't consume the semicolon terminator.
 */  */
 static int run_table_dump_query(  static int run_table_dump_query(
   struct callback_data *p, /* Query context */    struct callback_data *p, /* Query context */
Line 947  static int run_table_dump_query( Line 967  static int run_table_dump_query(
 ){  ){
   sqlite3_stmt *pSelect;    sqlite3_stmt *pSelect;
   int rc;    int rc;
     int nResult;
     int i;
     const char *z;
   rc = sqlite3_prepare(p->db, zSelect, -1, &pSelect, 0);    rc = sqlite3_prepare(p->db, zSelect, -1, &pSelect, 0);
   if( rc!=SQLITE_OK || !pSelect ){    if( rc!=SQLITE_OK || !pSelect ){
     fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));      fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
Line 954  static int run_table_dump_query( Line 977  static int run_table_dump_query(
     return rc;      return rc;
   }    }
   rc = sqlite3_step(pSelect);    rc = sqlite3_step(pSelect);
     nResult = sqlite3_column_count(pSelect);
   while( rc==SQLITE_ROW ){    while( rc==SQLITE_ROW ){
     if( zFirstRow ){      if( zFirstRow ){
       fprintf(p->out, "%s", zFirstRow);        fprintf(p->out, "%s", zFirstRow);
       zFirstRow = 0;        zFirstRow = 0;
     }      }
    fprintf(p->out, "%s;\n", sqlite3_column_text(pSelect, 0));    z = (const char*)sqlite3_column_text(pSelect, 0);
     fprintf(p->out, "%s", z);
     for(i=1; i<nResult; i++){ 
       fprintf(p->out, ",%s", sqlite3_column_text(pSelect, i));
     }
     if( z==0 ) z = "";
     while( z[0] && (z[0]!='-' || z[1]!='-') ) z++;
     if( z[0] ){
       fprintf(p->out, "\n;\n");
     }else{
       fprintf(p->out, ";\n");
     }    
     rc = sqlite3_step(pSelect);      rc = sqlite3_step(pSelect);
   }    }
   rc = sqlite3_finalize(pSelect);    rc = sqlite3_finalize(pSelect);
Line 1056  static int display_stats( Line 1091  static int display_stats(
     sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1);      sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1);
     fprintf(pArg->out, "Page cache misses:                   %d\n", iCur);       fprintf(pArg->out, "Page cache misses:                   %d\n", iCur); 
     iHiwtr = iCur = -1;      iHiwtr = iCur = -1;
       sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1);
       fprintf(pArg->out, "Page cache writes:                   %d\n", iCur); 
       iHiwtr = iCur = -1;
     sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);      sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
     fprintf(pArg->out, "Schema Heap Usage:                   %d bytes\n", iCur);       fprintf(pArg->out, "Schema Heap Usage:                   %d bytes\n", iCur); 
     iHiwtr = iCur = -1;      iHiwtr = iCur = -1;
Line 1278  static int dump_callback(void *pArg, int nArg, char ** Line 1316  static int dump_callback(void *pArg, int nArg, char **
     }      }
   
     zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);      zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
       /* Always quote the table name, even if it appears to be pure ascii,
       ** in case it is a keyword. Ex:  INSERT INTO "table" ... */
     zTmp = appendText(zTmp, zTable, '"');      zTmp = appendText(zTmp, zTable, '"');
     if( zTmp ){      if( zTmp ){
       zSelect = appendText(zSelect, zTmp, '\'');        zSelect = appendText(zSelect, zTmp, '\'');
         free(zTmp);
     }      }
     zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);      zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
     rc = sqlite3_step(pTableInfo);      rc = sqlite3_step(pTableInfo);
Line 1290  static int dump_callback(void *pArg, int nArg, char ** Line 1331  static int dump_callback(void *pArg, int nArg, char **
       zSelect = appendText(zSelect, zText, '"');        zSelect = appendText(zSelect, zText, '"');
       rc = sqlite3_step(pTableInfo);        rc = sqlite3_step(pTableInfo);
       if( rc==SQLITE_ROW ){        if( rc==SQLITE_ROW ){
        zSelect = appendText(zSelect, ") || ',' || ", 0);        zSelect = appendText(zSelect, "), ", 0);
       }else{        }else{
         zSelect = appendText(zSelect, ") ", 0);          zSelect = appendText(zSelect, ") ", 0);
       }        }
Line 1309  static int dump_callback(void *pArg, int nArg, char ** Line 1350  static int dump_callback(void *pArg, int nArg, char **
       zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);        zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
       run_table_dump_query(p, zSelect, 0);        run_table_dump_query(p, zSelect, 0);
     }      }
    if( zSelect ) free(zSelect);    free(zSelect);
   }    }
   return 0;    return 0;
 }  }
Line 1339  static int run_schema_dump_query( Line 1380  static int run_schema_dump_query(
     }      }
     zQ2 = malloc( len+100 );      zQ2 = malloc( len+100 );
     if( zQ2==0 ) return rc;      if( zQ2==0 ) return rc;
    sqlite3_snprintf(sizeof(zQ2), zQ2, "%s ORDER BY rowid DESC", zQuery);    sqlite3_snprintf(len+100, zQ2, "%s ORDER BY rowid DESC", zQuery);
     rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr);      rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr);
     if( rc ){      if( rc ){
       fprintf(p->out, "/****** ERROR: %s ******/\n", zErr);        fprintf(p->out, "/****** ERROR: %s ******/\n", zErr);
Line 1388  static char zHelp[] = Line 1429  static char zHelp[] =
   "                         list     Values delimited by .separator string\n"    "                         list     Values delimited by .separator string\n"
   "                         tabs     Tab-separated values\n"    "                         tabs     Tab-separated values\n"
   "                         tcl      TCL list elements\n"    "                         tcl      TCL list elements\n"
  ".nullvalue STRING      Print STRING in place of NULL values\n"  ".nullvalue STRING      Use STRING in place of NULL values\n"
   ".output FILENAME       Send output to FILENAME\n"    ".output FILENAME       Send output to FILENAME\n"
   ".output stdout         Send output to the screen\n"    ".output stdout         Send output to the screen\n"
     ".print STRING...       Print literal STRING\n"
   ".prompt MAIN CONTINUE  Replace the standard prompts\n"    ".prompt MAIN CONTINUE  Replace the standard prompts\n"
   ".quit                  Exit this program\n"    ".quit                  Exit this program\n"
   ".read FILENAME         Execute SQL in FILENAME\n"    ".read FILENAME         Execute SQL in FILENAME\n"
Line 1405  static char zHelp[] = Line 1447  static char zHelp[] =
   "                         If TABLE specified, only list tables matching\n"    "                         If TABLE specified, only list tables matching\n"
   "                         LIKE pattern TABLE.\n"    "                         LIKE pattern TABLE.\n"
   ".timeout MS            Try opening locked tables for MS milliseconds\n"    ".timeout MS            Try opening locked tables for MS milliseconds\n"
     ".trace FILE|off        Output each SQL statement as it is run\n"
   ".vfsname ?AUX?         Print the name of the VFS stack\n"    ".vfsname ?AUX?         Print the name of the VFS stack\n"
   ".width NUM1 NUM2 ...   Set column widths for \"column\" mode\n"    ".width NUM1 NUM2 ...   Set column widths for \"column\" mode\n"
 ;  ;
Line 1422  static int process_input(struct callback_data *p, FILE Line 1465  static int process_input(struct callback_data *p, FILE
 */  */
 static void open_db(struct callback_data *p){  static void open_db(struct callback_data *p){
   if( p->db==0 ){    if( p->db==0 ){
       sqlite3_initialize();
     sqlite3_open(p->zDbFilename, &p->db);      sqlite3_open(p->zDbFilename, &p->db);
     db = p->db;      db = p->db;
     if( db && sqlite3_errcode(db)==SQLITE_OK ){      if( db && sqlite3_errcode(db)==SQLITE_OK ){
Line 1495  static int booleanValue(char *zArg){ Line 1539  static int booleanValue(char *zArg){
 }  }
   
 /*  /*
   ** Close an output file, assuming it is not stderr or stdout
   */
   static void output_file_close(FILE *f){
     if( f && f!=stdout && f!=stderr ) fclose(f);
   }
   
   /*
   ** Try to open an output file.   The names "stdout" and "stderr" are
   ** recognized and do the right thing.  NULL is returned if the output 
   ** filename is "off".
   */
   static FILE *output_file_open(const char *zFile){
     FILE *f;
     if( strcmp(zFile,"stdout")==0 ){
       f = stdout;
     }else if( strcmp(zFile, "stderr")==0 ){
       f = stderr;
     }else if( strcmp(zFile, "off")==0 ){
       f = 0;
     }else{
       f = fopen(zFile, "wb");
       if( f==0 ){
         fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
       }
     }
     return f;
   }
   
   /*
   ** A routine for handling output from sqlite3_trace().
   */
   static void sql_trace_callback(void *pArg, const char *z){
     FILE *f = (FILE*)pArg;
     if( f ) fprintf(f, "%s\n", z);
   }
   
   /*
   ** A no-op routine that runs with the ".breakpoint" doc-command.  This is
   ** a useful spot to set a debugger breakpoint.
   */
   static void test_breakpoint(void){
     static int nCall = 0;
     nCall++;
   }
   
   /*
 ** If an input line begins with "." then invoke this routine to  ** If an input line begins with "." then invoke this routine to
 ** process that line.  ** process that line.
 **  **
Line 1573  static int do_meta_command(char *zLine, struct callbac Line 1663  static int do_meta_command(char *zLine, struct callbac
     bail_on_error = booleanValue(azArg[1]);      bail_on_error = booleanValue(azArg[1]);
   }else    }else
   
     /* The undocumented ".breakpoint" command causes a call to the no-op
     ** routine named test_breakpoint().
     */
     if( c=='b' && n>=3 && strncmp(azArg[0], "breakpoint", n)==0 ){
       test_breakpoint();
     }else
   
   if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 && nArg==1 ){    if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 && nArg==1 ){
     struct callback_data data;      struct callback_data data;
     char *zErrMsg = 0;      char *zErrMsg = 0;
Line 1769  static int do_meta_command(char *zLine, struct callbac Line 1866  static int do_meta_command(char *zLine, struct callbac
     }      }
     sqlite3_exec(p->db, "BEGIN", 0, 0, 0);      sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
     zCommit = "COMMIT";      zCommit = "COMMIT";
    while( (zLine = local_getline(0, in))!=0 ){    while( (zLine = local_getline(0, in, 1))!=0 ){
      char *z;      char *z, c;
       int inQuote = 0;
       lineno++;        lineno++;
       azCol[0] = zLine;        azCol[0] = zLine;
      for(i=0, z=zLine; *z && *z!='\n' && *z!='\r'; z++){      for(i=0, z=zLine; (c = *z)!=0; z++){
        if( *z==p->separator[0] && strncmp(z, p->separator, nSep)==0 ){        if( c=='"' ) inQuote = !inQuote;
         if( c=='\n' ) lineno++;
         if( !inQuote && c==p->separator[0] && strncmp(z,p->separator,nSep)==0 ){
           *z = 0;            *z = 0;
           i++;            i++;
           if( i<nCol ){            if( i<nCol ){
Line 1794  static int do_meta_command(char *zLine, struct callbac Line 1894  static int do_meta_command(char *zLine, struct callbac
         break; /* from while */          break; /* from while */
       }        }
       for(i=0; i<nCol; i++){        for(i=0; i<nCol; i++){
           if( azCol[i][0]=='"' ){
             int k;
             for(z=azCol[i], j=1, k=0; z[j]; j++){
               if( z[j]=='"' ){ j++; if( z[j]==0 ) break; }
               z[k++] = z[j];
             }
             z[k] = 0;
           }
         sqlite3_bind_text(pStmt, i+1, azCol[i], -1, SQLITE_STATIC);          sqlite3_bind_text(pStmt, i+1, azCol[i], -1, SQLITE_STATIC);
       }        }
       sqlite3_step(pStmt);        sqlite3_step(pStmt);
Line 1893  static int do_meta_command(char *zLine, struct callbac Line 2001  static int do_meta_command(char *zLine, struct callbac
   
   if( c=='l' && strncmp(azArg[0], "log", n)==0 && nArg>=2 ){    if( c=='l' && strncmp(azArg[0], "log", n)==0 && nArg>=2 ){
     const char *zFile = azArg[1];      const char *zFile = azArg[1];
    if( p->pLog && p->pLog!=stdout && p->pLog!=stderr ){    output_file_close(p->pLog);
      fclose(p->pLog);    p->pLog = output_file_open(zFile);
      p->pLog = 0; 
    } 
    if( strcmp(zFile,"stdout")==0 ){ 
      p->pLog = stdout; 
    }else if( strcmp(zFile, "stderr")==0 ){ 
      p->pLog = stderr; 
    }else if( strcmp(zFile, "off")==0 ){ 
      p->pLog = 0; 
    }else{ 
      p->pLog = fopen(zFile, "w"); 
      if( p->pLog==0 ){ 
        fprintf(stderr, "Error: cannot open \"%s\"\n", zFile); 
      } 
    } 
   }else    }else
   
   if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg==2 ){    if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg==2 ){
Line 1927  static int do_meta_command(char *zLine, struct callbac Line 2021  static int do_meta_command(char *zLine, struct callbac
       p->mode = MODE_Html;        p->mode = MODE_Html;
     }else if( n2==3 && strncmp(azArg[1],"tcl",n2)==0 ){      }else if( n2==3 && strncmp(azArg[1],"tcl",n2)==0 ){
       p->mode = MODE_Tcl;        p->mode = MODE_Tcl;
         sqlite3_snprintf(sizeof(p->separator), p->separator, " ");
     }else if( n2==3 && strncmp(azArg[1],"csv",n2)==0 ){      }else if( n2==3 && strncmp(azArg[1],"csv",n2)==0 ){
       p->mode = MODE_Csv;        p->mode = MODE_Csv;
       sqlite3_snprintf(sizeof(p->separator), p->separator, ",");        sqlite3_snprintf(sizeof(p->separator), p->separator, ",");
Line 1961  static int do_meta_command(char *zLine, struct callbac Line 2056  static int do_meta_command(char *zLine, struct callbac
   }else    }else
   
   if( c=='o' && strncmp(azArg[0], "output", n)==0 && nArg==2 ){    if( c=='o' && strncmp(azArg[0], "output", n)==0 && nArg==2 ){
    if( p->out!=stdout ){    if( p->outfile[0]=='|' ){
      fclose(p->out);      pclose(p->out);
     }else{
       output_file_close(p->out);
     }      }
    if( strcmp(azArg[1],"stdout")==0 ){    p->outfile[0] = 0;
      p->out = stdout;    if( azArg[1][0]=='|' ){
      sqlite3_snprintf(sizeof(p->outfile), p->outfile, "stdout");      p->out = popen(&azArg[1][1], "w");
       if( p->out==0 ){
         fprintf(stderr,"Error: cannot open pipe \"%s\"\n", &azArg[1][1]);
         p->out = stdout;
         rc = 1;
       }else{
         sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]);
       }
     }else{      }else{
      p->out = fopen(azArg[1], "wb");      p->out = output_file_open(azArg[1]);
       if( p->out==0 ){        if( p->out==0 ){
        fprintf(stderr,"Error: cannot write to \"%s\"\n", azArg[1]);        if( strcmp(azArg[1],"off")!=0 ){
           fprintf(stderr,"Error: cannot write to \"%s\"\n", azArg[1]);
         }
         p->out = stdout;          p->out = stdout;
         rc = 1;          rc = 1;
       } else {        } else {
         sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]);        sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]);
       }        }
     }      }
   }else    }else
   
     if( c=='p' && n>=3 && strncmp(azArg[0], "print", n)==0 ){
       int i;
       for(i=1; i<nArg; i++){
         if( i>1 ) fprintf(p->out, " ");
         fprintf(p->out, "%s", azArg[i]);
       }
       fprintf(p->out, "\n");
     }else
   
   if( c=='p' && strncmp(azArg[0], "prompt", n)==0 && (nArg==2 || nArg==3)){    if( c=='p' && strncmp(azArg[0], "prompt", n)==0 && (nArg==2 || nArg==3)){
     if( nArg >= 2) {      if( nArg >= 2) {
       strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);        strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
Line 2092  static int do_meta_command(char *zLine, struct callbac Line 2207  static int do_meta_command(char *zLine, struct callbac
         zShellStatic = azArg[1];          zShellStatic = azArg[1];
         rc = sqlite3_exec(p->db,          rc = sqlite3_exec(p->db,
           "SELECT sql FROM "            "SELECT sql FROM "
          "  (SELECT sql sql, type type, tbl_name tbl_name, name name"          "  (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
           "     FROM sqlite_master UNION ALL"            "     FROM sqlite_master UNION ALL"
          "   SELECT sql, type, tbl_name, name FROM sqlite_temp_master) "          "   SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
           "WHERE lower(tbl_name) LIKE shellstatic()"            "WHERE lower(tbl_name) LIKE shellstatic()"
           "  AND type!='meta' AND sql NOTNULL "            "  AND type!='meta' AND sql NOTNULL "
          "ORDER BY substr(type,2,1), name",          "ORDER BY substr(type,2,1), "
                   " CASE type WHEN 'view' THEN rowid ELSE name END",
           callback, &data, &zErrMsg);            callback, &data, &zErrMsg);
         zShellStatic = 0;          zShellStatic = 0;
       }        }
     }else{      }else{
       rc = sqlite3_exec(p->db,        rc = sqlite3_exec(p->db,
          "SELECT sql FROM "           "SELECT sql FROM "
         "  (SELECT sql sql, type type, tbl_name tbl_name, name name"         "  (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
          "     FROM sqlite_master UNION ALL"           "     FROM sqlite_master UNION ALL"
         "   SELECT sql, type, tbl_name, name FROM sqlite_temp_master) "         "   SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
          "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%'"           "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%'"
         "ORDER BY substr(type,2,1), name",         "ORDER BY substr(type,2,1),"
                   " CASE type WHEN 'view' THEN rowid ELSE name END",
          callback, &data, &zErrMsg           callback, &data, &zErrMsg
       );        );
     }      }
Line 2156  static int do_meta_command(char *zLine, struct callbac Line 2273  static int do_meta_command(char *zLine, struct callbac
   }else    }else
   
   if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 && nArg<3 ){    if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 && nArg<3 ){
       sqlite3_stmt *pStmt;
     char **azResult;      char **azResult;
    int nRow;    int nRow, nAlloc;
    char *zErrMsg;    char *zSql = 0;
     int ii;
     open_db(p);      open_db(p);
    if( nArg==1 ){    rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0);
      rc = sqlite3_get_table(p->db,    if( rc ) return rc;
        "SELECT name FROM sqlite_master "    zSql = sqlite3_mprintf(
        "WHERE type IN ('table','view') AND name NOT LIKE 'sqlite_%' "        "SELECT name FROM sqlite_master"
        "UNION ALL "        " WHERE type IN ('table','view')"
        "SELECT name FROM sqlite_temp_master "        "   AND name NOT LIKE 'sqlite_%%'"
        "WHERE type IN ('table','view') "        "   AND name LIKE ?1");
        "ORDER BY 1",    while( sqlite3_step(pStmt)==SQLITE_ROW ){
        &azResult, &nRow, 0, &zErrMsg      const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1);
      );      if( zDbName==0 || strcmp(zDbName,"main")==0 ) continue;
    }else{      if( strcmp(zDbName,"temp")==0 ){
      zShellStatic = azArg[1];        zSql = sqlite3_mprintf(
      rc = sqlite3_get_table(p->db,                 "%z UNION ALL "
        "SELECT name FROM sqlite_master "                 "SELECT 'temp.' || name FROM sqlite_temp_master"
        "WHERE type IN ('table','view') AND name LIKE shellstatic() "                 " WHERE type IN ('table','view')"
        "UNION ALL "                 "   AND name NOT LIKE 'sqlite_%%'"
        "SELECT name FROM sqlite_temp_master "                 "   AND name LIKE ?1", zSql);
        "WHERE type IN ('table','view') AND name LIKE shellstatic() "      }else{
        "ORDER BY 1",        zSql = sqlite3_mprintf(
        &azResult, &nRow, 0, &zErrMsg                 "%z UNION ALL "
      );                 "SELECT '%q.' || name FROM \"%w\".sqlite_master"
      zShellStatic = 0;                 " WHERE type IN ('table','view')"
                  "   AND name NOT LIKE 'sqlite_%%'"
                  "   AND name LIKE ?1", zSql, zDbName, zDbName);
       }
     }      }
    if( zErrMsg ){    sqlite3_finalize(pStmt);
      fprintf(stderr,"Error: %s\n", zErrMsg);    zSql = sqlite3_mprintf("%z ORDER BY 1", zSql);
      sqlite3_free(zErrMsg);    rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
      rc = 1;    sqlite3_free(zSql);
    }else if( rc != SQLITE_OK ){    if( rc ) return rc;
      fprintf(stderr,"Error: querying sqlite_master and sqlite_temp_master\n");    nRow = nAlloc = 0;
      rc = 1;    azResult = 0;
     if( nArg>1 ){
       sqlite3_bind_text(pStmt, 1, azArg[1], -1, SQLITE_TRANSIENT);
     }else{      }else{
         sqlite3_bind_text(pStmt, 1, "%", -1, SQLITE_STATIC);
       }
       while( sqlite3_step(pStmt)==SQLITE_ROW ){
         if( nRow>=nAlloc ){
           char **azNew;
           int n = nAlloc*2 + 10;
           azNew = sqlite3_realloc(azResult, sizeof(azResult[0])*n);
           if( azNew==0 ){
             fprintf(stderr, "Error: out of memory\n");
             break;
           }
           nAlloc = n;
           azResult = azNew;
         }
         azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
         if( azResult[nRow] ) nRow++;
       }
       sqlite3_finalize(pStmt);        
       if( nRow>0 ){
       int len, maxlen = 0;        int len, maxlen = 0;
       int i, j;        int i, j;
       int nPrintCol, nPrintRow;        int nPrintCol, nPrintRow;
      for(i=1; i<=nRow; i++){      for(i=0; i<nRow; i++){
        if( azResult[i]==0 ) continue; 
         len = strlen30(azResult[i]);          len = strlen30(azResult[i]);
         if( len>maxlen ) maxlen = len;          if( len>maxlen ) maxlen = len;
       }        }
Line 2203  static int do_meta_command(char *zLine, struct callbac Line 2345  static int do_meta_command(char *zLine, struct callbac
       if( nPrintCol<1 ) nPrintCol = 1;        if( nPrintCol<1 ) nPrintCol = 1;
       nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;        nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
       for(i=0; i<nPrintRow; i++){        for(i=0; i<nPrintRow; i++){
        for(j=i+1; j<=nRow; j+=nPrintRow){        for(j=i; j<nRow; j+=nPrintRow){
          char *zSp = j<=nPrintRow ? "" : "  ";          char *zSp = j<nPrintRow ? "" : "  ";
           printf("%s%-*s", zSp, maxlen, azResult[j] ? azResult[j] : "");            printf("%s%-*s", zSp, maxlen, azResult[j] ? azResult[j] : "");
         }          }
         printf("\n");          printf("\n");
       }        }
     }      }
    sqlite3_free_table(azResult);    for(ii=0; ii<nRow; ii++) sqlite3_free(azResult[ii]);
     sqlite3_free(azResult);
   }else    }else
   
   if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){    if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){
Line 2344  static int do_meta_command(char *zLine, struct callbac Line 2487  static int do_meta_command(char *zLine, struct callbac
     enableTimer = booleanValue(azArg[1]);      enableTimer = booleanValue(azArg[1]);
   }else    }else
       
     if( c=='t' && strncmp(azArg[0], "trace", n)==0 && nArg>1 ){
       open_db(p);
       output_file_close(p->traceOut);
       p->traceOut = output_file_open(azArg[1]);
   #if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
       if( p->traceOut==0 ){
         sqlite3_trace(p->db, 0, 0);
       }else{
         sqlite3_trace(p->db, sql_trace_callback, p->traceOut);
       }
   #endif
     }else
   
   if( c=='v' && strncmp(azArg[0], "version", n)==0 ){    if( c=='v' && strncmp(azArg[0], "version", n)==0 ){
     printf("SQLite %s %s\n" /*extra-version-info*/,      printf("SQLite %s %s\n" /*extra-version-info*/,
         sqlite3_libversion(), sqlite3_sourceid());          sqlite3_libversion(), sqlite3_sourceid());
Line 2361  static int do_meta_command(char *zLine, struct callbac Line 2517  static int do_meta_command(char *zLine, struct callbac
     }      }
   }else    }else
   
   #if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
     if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){
       extern int sqlite3WhereTrace;
       sqlite3WhereTrace = atoi(azArg[1]);
     }else
   #endif
   
   if( c=='w' && strncmp(azArg[0], "width", n)==0 && nArg>1 ){    if( c=='w' && strncmp(azArg[0], "width", n)==0 && nArg>1 ){
     int j;      int j;
     assert( nArg<=ArraySize(azArg) );      assert( nArg<=ArraySize(azArg) );
Line 2468  static int process_input(struct callback_data *p, FILE Line 2631  static int process_input(struct callback_data *p, FILE
     free(zLine);      free(zLine);
     zLine = one_input_line(zSql, in);      zLine = one_input_line(zSql, in);
     if( zLine==0 ){      if( zLine==0 ){
      break;  /* We have reached EOF */      /* End of input */
       if( stdin_is_interactive ) printf("\n");
       break;
     }      }
     if( seenInterrupt ){      if( seenInterrupt ){
       if( in!=0 ) break;        if( in!=0 ) break;
Line 2550  static int process_input(struct callback_data *p, FILE Line 2715  static int process_input(struct callback_data *p, FILE
     free(zSql);      free(zSql);
   }    }
   free(zLine);    free(zLine);
  return errCnt;  return errCnt>0;
 }  }
   
 /*  /*
 ** Return a pathname which is the user's home directory.  A  ** Return a pathname which is the user's home directory.  A
** 0 return indicates an error of some kind.  Space to hold the** 0 return indicates an error of some kind.
** resulting string is obtained from malloc().  The calling 
** function should free the result. 
 */  */
 static char *find_home_dir(void){  static char *find_home_dir(void){
  char *home_dir = NULL;  static char *home_dir = NULL;
   if( home_dir ) return home_dir;
   
#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(_WIN32_WCE) && !defined(__RTP__) && !defined(_WRS_KERNEL)#if !defined(_WIN32) && !defined(WIN32) && !defined(_WIN32_WCE) && !defined(__RTP__) && !defined(_WRS_KERNEL)
  struct passwd *pwent;  {
  uid_t uid = getuid();    struct passwd *pwent;
  if( (pwent=getpwuid(uid)) != NULL) {    uid_t uid = getuid();
    home_dir = pwent->pw_dir;    if( (pwent=getpwuid(uid)) != NULL) {
       home_dir = pwent->pw_dir;
     }
   }    }
 #endif  #endif
   
 #if defined(_WIN32_WCE)  #if defined(_WIN32_WCE)
   /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()    /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
    */     */
  home_dir = strdup("/");  home_dir = "/";
 #else  #else
   
#if defined(_WIN32) || defined(WIN32) || defined(__OS2__)#if defined(_WIN32) || defined(WIN32)
   if (!home_dir) {    if (!home_dir) {
     home_dir = getenv("USERPROFILE");      home_dir = getenv("USERPROFILE");
   }    }
Line 2586  static char *find_home_dir(void){ Line 2752  static char *find_home_dir(void){
     home_dir = getenv("HOME");      home_dir = getenv("HOME");
   }    }
   
#if defined(_WIN32) || defined(WIN32) || defined(__OS2__)#if defined(_WIN32) || defined(WIN32)
   if (!home_dir) {    if (!home_dir) {
     char *zDrive, *zPath;      char *zDrive, *zPath;
     int n;      int n;
Line 2629  static int process_sqliterc( Line 2795  static int process_sqliterc(
   const char *sqliterc = sqliterc_override;    const char *sqliterc = sqliterc_override;
   char *zBuf = 0;    char *zBuf = 0;
   FILE *in = NULL;    FILE *in = NULL;
   int nBuf;  
   int rc = 0;    int rc = 0;
   
   if (sqliterc == NULL) {    if (sqliterc == NULL) {
Line 2640  static int process_sqliterc( Line 2805  static int process_sqliterc(
 #endif  #endif
       return 1;        return 1;
     }      }
    nBuf = strlen30(home_dir) + 16;    sqlite3_initialize();
    zBuf = malloc( nBuf );    zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir);
    if( zBuf==0 ){    sqliterc = zBuf;
      fprintf(stderr,"%s: Error: out of memory\n",Argv0); 
      return 1; 
    } 
    sqlite3_snprintf(nBuf, zBuf,"%s/.sqliterc",home_dir); 
    free(home_dir); 
    sqliterc = (const char*)zBuf; 
   }    }
   in = fopen(sqliterc,"rb");    in = fopen(sqliterc,"rb");
   if( in ){    if( in ){
Line 2658  static int process_sqliterc( Line 2817  static int process_sqliterc(
     rc = process_input(p,in);      rc = process_input(p,in);
     fclose(in);      fclose(in);
   }    }
  free(zBuf);  sqlite3_free(zBuf);
   return rc;    return rc;
 }  }
   
Line 2666  static int process_sqliterc( Line 2825  static int process_sqliterc(
 ** Show available command line options  ** Show available command line options
 */  */
 static const char zOptions[] =   static const char zOptions[] = 
   "   -help                show this message\n"  
   "   -init filename       read/process named file\n"  
   "   -echo                print commands before execution\n"  
   "   -[no]header          turn headers on or off\n"  
   "   -bail                stop after hitting an error\n"    "   -bail                stop after hitting an error\n"
   "   -interactive         force interactive I/O\n"  
   "   -batch               force batch I/O\n"    "   -batch               force batch I/O\n"
   "   -column              set output mode to 'column'\n"    "   -column              set output mode to 'column'\n"
     "   -cmd COMMAND         run \"COMMAND\" before reading stdin\n"
   "   -csv                 set output mode to 'csv'\n"    "   -csv                 set output mode to 'csv'\n"
     "   -echo                print commands before execution\n"
     "   -init FILENAME       read/process named file\n"
     "   -[no]header          turn headers on or off\n"
   #if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
     "   -heap SIZE           Size of heap for memsys3 or memsys5\n"
   #endif
     "   -help                show this message\n"
   "   -html                set output mode to HTML\n"    "   -html                set output mode to HTML\n"
     "   -interactive         force interactive I/O\n"
   "   -line                set output mode to 'line'\n"    "   -line                set output mode to 'line'\n"
   "   -list                set output mode to 'list'\n"    "   -list                set output mode to 'list'\n"
  "   -separator 'x'       set output field separator (|)\n"#ifdef SQLITE_ENABLE_MULTIPLEX
   "   -multiplex           enable the multiplexor VFS\n"
 #endif
   "   -nullvalue TEXT      set text string for NULL values. Default ''\n"
   "   -separator SEP       set output field separator. Default: '|'\n"
   "   -stats               print memory stats before each finalize\n"    "   -stats               print memory stats before each finalize\n"
   "   -nullvalue 'text'    set text string for NULL values\n"  
   "   -version             show SQLite version\n"    "   -version             show SQLite version\n"
   "   -vfs NAME            use NAME as the default VFS\n"    "   -vfs NAME            use NAME as the default VFS\n"
 #ifdef SQLITE_ENABLE_VFSTRACE  #ifdef SQLITE_ENABLE_VFSTRACE
   "   -vfstrace            enable tracing of all VFS calls\n"    "   -vfstrace            enable tracing of all VFS calls\n"
 #endif  #endif
 #ifdef SQLITE_ENABLE_MULTIPLEX  
   "   -multiplex           enable the multiplexor VFS\n"  
 #endif  
 ;  ;
 static void usage(int showDetail){  static void usage(int showDetail){
   fprintf(stderr,    fprintf(stderr,
Line 2718  static void main_init(struct callback_data *data) { Line 2881  static void main_init(struct callback_data *data) {
   sqlite3_config(SQLITE_CONFIG_SINGLETHREAD);    sqlite3_config(SQLITE_CONFIG_SINGLETHREAD);
 }  }
   
   /*
   ** Get the argument to an --option.  Throw an error and die if no argument
   ** is available.
   */
   static char *cmdline_option_value(int argc, char **argv, int i){
     if( i==argc ){
       fprintf(stderr, "%s: Error: missing argument to %s\n",
               argv[0], argv[argc-1]);
       exit(1);
     }
     return argv[i];
   }
   
 int main(int argc, char **argv){  int main(int argc, char **argv){
   char *zErrMsg = 0;    char *zErrMsg = 0;
   struct callback_data data;    struct callback_data data;
Line 2747  int main(int argc, char **argv){ Line 2923  int main(int argc, char **argv){
   ** the size of the alternative malloc heap,    ** the size of the alternative malloc heap,
   ** and the first command to execute.    ** and the first command to execute.
   */    */
  for(i=1; i<argc-1; i++){  for(i=1; i<argc; i++){
     char *z;      char *z;
     if( argv[i][0]!='-' ) break;  
     z = argv[i];      z = argv[i];
    if( z[0]=='-' && z[1]=='-' ) z++;    if( z[0]!='-' ){
    if( strcmp(argv[i],"-separator")==0 || strcmp(argv[i],"-nullvalue")==0 ){      if( data.zDbFilename==0 ){
      i++;        data.zDbFilename = z;
    }else if( strcmp(argv[i],"-init")==0 ){        continue;
      i++;      }
      zInitFile = argv[i];      if( zFirstCmd==0 ){
    /* Need to check for batch mode here to so we can avoid printing        zFirstCmd = z;
    ** informational messages (like from process_sqliterc) before         continue;
    ** we do the actual processing of arguments later in a second pass.      }
    */      fprintf(stderr,"%s: Error: too many options: \"%s\"\n", Argv0, argv[i]);
    }else if( strcmp(argv[i],"-batch")==0 ){      fprintf(stderr,"Use -help for a list of options.\n");
       return 1;
     }
     if( z[1]=='-' ) z++;
     if( strcmp(z,"-separator")==0
      || strcmp(z,"-nullvalue")==0
      || strcmp(z,"-cmd")==0
     ){
       (void)cmdline_option_value(argc, argv, ++i);
     }else if( strcmp(z,"-init")==0 ){
       zInitFile = cmdline_option_value(argc, argv, ++i);
     }else if( strcmp(z,"-batch")==0 ){
       /* Need to check for batch mode here to so we can avoid printing
       ** informational messages (like from process_sqliterc) before 
       ** we do the actual processing of arguments later in a second pass.
       */
       stdin_is_interactive = 0;        stdin_is_interactive = 0;
    }else if( strcmp(argv[i],"-heap")==0 ){    }else if( strcmp(z,"-heap")==0 ){
 #if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)  #if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
       int j, c;        int j, c;
       const char *zSize;        const char *zSize;
       sqlite3_int64 szHeap;        sqlite3_int64 szHeap;
   
      zSize = argv[++i];      zSize = cmdline_option_value(argc, argv, ++i);
       szHeap = atoi(zSize);        szHeap = atoi(zSize);
       for(j=0; (c = zSize[j])!=0; j++){        for(j=0; (c = zSize[j])!=0; j++){
         if( c=='M' ){ szHeap *= 1000000; break; }          if( c=='M' ){ szHeap *= 1000000; break; }
Line 2780  int main(int argc, char **argv){ Line 2970  int main(int argc, char **argv){
       sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);        sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);
 #endif  #endif
 #ifdef SQLITE_ENABLE_VFSTRACE  #ifdef SQLITE_ENABLE_VFSTRACE
    }else if( strcmp(argv[i],"-vfstrace")==0 ){    }else if( strcmp(z,"-vfstrace")==0 ){
       extern int vfstrace_register(        extern int vfstrace_register(
          const char *zTraceName,           const char *zTraceName,
          const char *zOldVfsName,           const char *zOldVfsName,
Line 2791  int main(int argc, char **argv){ Line 2981  int main(int argc, char **argv){
       vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1);        vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1);
 #endif  #endif
 #ifdef SQLITE_ENABLE_MULTIPLEX  #ifdef SQLITE_ENABLE_MULTIPLEX
    }else if( strcmp(argv[i],"-multiplex")==0 ){    }else if( strcmp(z,"-multiplex")==0 ){
       extern int sqlite3_multiple_initialize(const char*,int);        extern int sqlite3_multiple_initialize(const char*,int);
       sqlite3_multiplex_initialize(0, 1);        sqlite3_multiplex_initialize(0, 1);
 #endif  #endif
    }else if( strcmp(argv[i],"-vfs")==0 ){    }else if( strcmp(z,"-vfs")==0 ){
      sqlite3_vfs *pVfs = sqlite3_vfs_find(argv[++i]);      sqlite3_vfs *pVfs = sqlite3_vfs_find(cmdline_option_value(argc,argv,++i));
       if( pVfs ){        if( pVfs ){
         sqlite3_vfs_register(pVfs, 1);          sqlite3_vfs_register(pVfs, 1);
       }else{        }else{
Line 2805  int main(int argc, char **argv){ Line 2995  int main(int argc, char **argv){
       }        }
     }      }
   }    }
  if( i<argc ){  if( data.zDbFilename==0 ){
#if defined(SQLITE_OS_OS2) && SQLITE_OS_OS2 
    data.zDbFilename = (const char *)convertCpPathToUtf8( argv[i++] ); 
#else 
    data.zDbFilename = argv[i++]; 
#endif 
  }else{ 
 #ifndef SQLITE_OMIT_MEMORYDB  #ifndef SQLITE_OMIT_MEMORYDB
     data.zDbFilename = ":memory:";      data.zDbFilename = ":memory:";
 #else  #else
    data.zDbFilename = 0;    fprintf(stderr,"%s: Error: no database filename specified\n", Argv0);
     return 1;
 #endif  #endif
   }    }
   if( i<argc ){  
     zFirstCmd = argv[i++];  
   }  
   if( i<argc ){  
     fprintf(stderr,"%s: Error: too many options: \"%s\"\n", Argv0, argv[i]);  
     fprintf(stderr,"Use -help for a list of options.\n");  
     return 1;  
   }  
   data.out = stdout;    data.out = stdout;
   
 #ifdef SQLITE_OMIT_MEMORYDB  
   if( data.zDbFilename==0 ){  
     fprintf(stderr,"%s: Error: no database filename specified\n", Argv0);  
     return 1;  
   }  
 #endif  
   
   /* Go ahead and open the database file if it already exists.  If the    /* Go ahead and open the database file if it already exists.  If the
   ** file does not exist, delay opening it.  This prevents empty database    ** file does not exist, delay opening it.  This prevents empty database
   ** files from being created if a user mistypes the database name argument    ** files from being created if a user mistypes the database name argument
Line 2858  int main(int argc, char **argv){ Line 3028  int main(int argc, char **argv){
   ** file is processed so that the command-line arguments will override    ** file is processed so that the command-line arguments will override
   ** settings in the initialization file.    ** settings in the initialization file.
   */    */
  for(i=1; i<argc && argv[i][0]=='-'; i++){  for(i=1; i<argc; i++){
     char *z = argv[i];      char *z = argv[i];
       if( z[0]!='-' ) continue;
     if( z[1]=='-' ){ z++; }      if( z[1]=='-' ){ z++; }
     if( strcmp(z,"-init")==0 ){      if( strcmp(z,"-init")==0 ){
       i++;        i++;
Line 2875  int main(int argc, char **argv){ Line 3046  int main(int argc, char **argv){
       data.mode = MODE_Csv;        data.mode = MODE_Csv;
       memcpy(data.separator,",",2);        memcpy(data.separator,",",2);
     }else if( strcmp(z,"-separator")==0 ){      }else if( strcmp(z,"-separator")==0 ){
       i++;  
       if(i>=argc){  
         fprintf(stderr,"%s: Error: missing argument for option: %s\n", Argv0, z);  
         fprintf(stderr,"Use -help for a list of options.\n");  
         return 1;  
       }  
       sqlite3_snprintf(sizeof(data.separator), data.separator,        sqlite3_snprintf(sizeof(data.separator), data.separator,
                       "%.*s",(int)sizeof(data.separator)-1,argv[i]);                       "%s",cmdline_option_value(argc,argv,++i));
     }else if( strcmp(z,"-nullvalue")==0 ){      }else if( strcmp(z,"-nullvalue")==0 ){
       i++;  
       if(i>=argc){  
         fprintf(stderr,"%s: Error: missing argument for option: %s\n", Argv0, z);  
         fprintf(stderr,"Use -help for a list of options.\n");  
         return 1;  
       }  
       sqlite3_snprintf(sizeof(data.nullvalue), data.nullvalue,        sqlite3_snprintf(sizeof(data.nullvalue), data.nullvalue,
                       "%.*s",(int)sizeof(data.nullvalue)-1,argv[i]);                       "%s",cmdline_option_value(argc,argv,++i));
     }else if( strcmp(z,"-header")==0 ){      }else if( strcmp(z,"-header")==0 ){
       data.showHeader = 1;        data.showHeader = 1;
     }else if( strcmp(z,"-noheader")==0 ){      }else if( strcmp(z,"-noheader")==0 ){
Line 2921  int main(int argc, char **argv){ Line 3080  int main(int argc, char **argv){
     }else if( strcmp(z,"-multiplex")==0 ){      }else if( strcmp(z,"-multiplex")==0 ){
       i++;        i++;
 #endif  #endif
    }else if( strcmp(z,"-help")==0 || strcmp(z, "--help")==0 ){    }else if( strcmp(z,"-help")==0 ){
       usage(1);        usage(1);
       }else if( strcmp(z,"-cmd")==0 ){
         if( i==argc-1 ) break;
         z = cmdline_option_value(argc,argv,++i);
         if( z[0]=='.' ){
           rc = do_meta_command(z, &data);
           if( rc && bail_on_error ) return rc;
         }else{
           open_db(&data);
           rc = shell_exec(data.db, z, shell_callback, &data, &zErrMsg);
           if( zErrMsg!=0 ){
             fprintf(stderr,"Error: %s\n", zErrMsg);
             if( bail_on_error ) return rc!=0 ? rc : 1;
           }else if( rc!=0 ){
             fprintf(stderr,"Error: unable to process SQL \"%s\"\n", z);
             if( bail_on_error ) return rc;
           }
         }
     }else{      }else{
       fprintf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);        fprintf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
       fprintf(stderr,"Use -help for a list of options.\n");        fprintf(stderr,"Use -help for a list of options.\n");
Line 2975  int main(int argc, char **argv){ Line 3151  int main(int argc, char **argv){
         write_history(zHistory);          write_history(zHistory);
         free(zHistory);          free(zHistory);
       }        }
       free(zHome);  
     }else{      }else{
       rc = process_input(&data, stdin);        rc = process_input(&data, stdin);
     }      }

Removed from v.1.2  
changed lines
  Added in v.1.3


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>