int main(int argc, char **argv){ char *zErrMsg = 0; struct callback_data data; const char *zInitFile = 0; char *zFirstCmd = 0; int i; extern int sqliteOsFileExists(const char*); #ifdef __MACOS__ argc = ccommand(&argv); #endif Argv0 = argv[0]; main_init(&data); /* Make sure we have a valid signal handler early, before anything ** else is done. */ #ifdef SIGINT signal(SIGINT, interrupt_handler); #endif /* Do an initial pass through the command-line argument to locate ** the name of the database file, the name of the initialization file, ** and the first command to execute. */ for(i=1; i<argc-1; i++){ if( argv[i][0]!='-' ) break; if( strcmp(argv[i],"-separator")==0 || strcmp(argv[i],"-nullvalue")==0 ){ i++; }else if( strcmp(argv[i],"-init")==0 ){ i++; zInitFile = argv[i]; }else if( strcmp(argv[i],"-key")==0 ){ i++; data.zKey = sqlite_mprintf("%s",argv[i]); } } if( i<argc ){ data.zDbFilename = argv[i++]; }else{ data.zDbFilename = ":memory:"; } if( i<argc ){ zFirstCmd = argv[i++]; } data.out = stdout; /* Go ahead and open the database file if it already exists. If the ** file does not exist, delay opening it. This prevents empty database ** files from being created if a user mistypes the database name argument ** to the sqlite command-line tool. */ if( sqliteOsFileExists(data.zDbFilename) ){ open_db(&data); } /* Process the initialization file if there is one. If no -init option ** is given on the command line, look for a file named ~/.sqliterc and ** try to process it. */ process_sqliterc(&data,zInitFile); /* Make a second pass through the command-line argument and set ** options. This second pass is delayed until after the initialization ** file is processed so that the command-line arguments will override ** settings in the initialization file. */ for(i=1; i<argc && argv[i][0]=='-'; i++){ char *z = argv[i]; if( strcmp(z,"-init")==0 || strcmp(z,"-key")==0 ){ i++; }else if( strcmp(z,"-html")==0 ){ data.mode = MODE_Html; }else if( strcmp(z,"-list")==0 ){ data.mode = MODE_List; }else if( strcmp(z,"-line")==0 ){ data.mode = MODE_Line; }else if( strcmp(z,"-column")==0 ){ data.mode = MODE_Column; }else if( strcmp(z,"-separator")==0 ){ i++; sprintf(data.separator,"%.*s",(int)sizeof(data.separator)-1,argv[i]); }else if( strcmp(z,"-nullvalue")==0 ){ i++; sprintf(data.nullvalue,"%.*s",(int)sizeof(data.nullvalue)-1,argv[i]); }else if( strcmp(z,"-header")==0 ){ data.showHeader = 1; }else if( strcmp(z,"-noheader")==0 ){ data.showHeader = 0; }else if( strcmp(z,"-echo")==0 ){ data.echoOn = 1; }else if( strcmp(z,"-version")==0 ){ printf("%s\n", sqlite_version); return 1; }else if( strcmp(z,"-help")==0 ){ usage(1); }else{ fprintf(stderr,"%s: unknown option: %s\n", Argv0, z); fprintf(stderr,"Use -help for a list of options.\n"); return 1; } } if( zFirstCmd ){ /* Run just the command that follows the database name */ if( zFirstCmd[0]=='.' ){ do_meta_command(zFirstCmd, &data); exit(0); }else{ int rc; open_db(&data); rc = sqlite_exec(data.db, zFirstCmd, callback, &data, &zErrMsg); if( rc!=0 && zErrMsg!=0 ){ fprintf(stderr,"SQL error: %s\n", zErrMsg); exit(1); } } }else{ /* Run commands received from standard input */ if( isatty(fileno(stdout)) && isatty(fileno(stdin)) ){ char *zHome; char *zHistory = 0; printf( "SQLite version %s\n" "Enter \".help\" for instructions\n", sqlite_version ); zHome = find_home_dir(); if( zHome && (zHistory = malloc(strlen(zHome)+20))!=0 ){ sprintf(zHistory,"%s/.sqlite_history", zHome); } if( zHistory ) read_history(zHistory); process_input(&data, 0); if( zHistory ){ stifle_history(100); write_history(zHistory); } }else{ process_input(&data, stdin); } } set_table_name(&data, 0); if( db ) sqlite_close(db); return 0; }
/* ** Prepare a virtual machine for execution. This involves things such ** as allocating stack space and initializing the program counter. ** After the VDBE has be prepped, it can be executed by one or more ** calls to sqliteVdbeExec(). */ void sqliteVdbeMakeReady( Vdbe *p, /* The VDBE */ int nVar, /* Number of '?' see in the SQL statement */ int isExplain /* True if the EXPLAIN keywords is present */ ){ int n; assert( p!=0 ); assert( p->magic==VDBE_MAGIC_INIT ); /* Add a HALT instruction to the very end of the program. */ if( p->nOp==0 || (p->aOp && p->aOp[p->nOp-1].opcode!=OP_Halt) ){ sqliteVdbeAddOp(p, OP_Halt, 0, 0); } /* No instruction ever pushes more than a single element onto the ** stack. And the stack never grows on successive executions of the ** same loop. So the total number of instructions is an upper bound ** on the maximum stack depth required. ** ** Allocation all the stack space we will ever need. */ if( p->aStack==0 ){ p->nVar = nVar; assert( nVar>=0 ); n = isExplain ? 10 : p->nOp; p->aStack = sqliteMalloc( n*(sizeof(p->aStack[0]) + 2*sizeof(char*)) /* aStack and zArgv */ + p->nVar*(sizeof(char*)+sizeof(int)+1) /* azVar, anVar, abVar */ ); p->zArgv = (char**)&p->aStack[n]; p->azColName = (char**)&p->zArgv[n]; p->azVar = (char**)&p->azColName[n]; p->anVar = (int*)&p->azVar[p->nVar]; p->abVar = (u8*)&p->anVar[p->nVar]; } sqliteHashInit(&p->agg.hash, SQLITE_HASH_BINARY, 0); p->agg.pSearch = 0; #ifdef MEMORY_DEBUG if( sqliteOsFileExists("vdbe_trace") ){ p->trace = stdout; } #endif p->pTos = &p->aStack[-1]; p->pc = 0; p->rc = SQLITE_OK; p->uniqueCnt = 0; p->returnDepth = 0; p->errorAction = OE_Abort; p->undoTransOnError = 0; p->popStack = 0; p->explain |= isExplain; p->magic = VDBE_MAGIC_RUN; #ifdef VDBE_PROFILE { int i; for(i=0; i<p->nOp; i++){ p->aOp[i].cnt = 0; p->aOp[i].cycles = 0; } } #endif }
int main(int argc, char **argv){ char *zErrMsg = 0; struct callback_data data; int origArgc = argc; char **origArgv = argv; int i; extern int sqliteOsFileExists(const char*); #ifdef __MACOS__ argc = ccommand(&argv); origArgc = argc; origArgv = argv; #endif Argv0 = argv[0]; main_init(&data); /* Make sure we have a valid signal handler early, before anything ** else is done. */ #ifdef SIGINT signal(SIGINT, interrupt_handler); #endif /* Locate the name of the database file */ for(i=1; i<argc; i++){ if( argv[i][0]!='-' ) break; if( strcmp(argv[i],"-separator")==0 || strcmp(argv[i],"-nullvalue")==0 ){ i++; } } data.zDbFilename = i<argc ? argv[i] : ":memory:"; data.out = stdout; /* Go ahead and open the database file if it already exists. If the ** file does not exist, delay opening it. This prevents empty database ** files from being created if a user mistypes the database name argument ** to the sqlite command-line tool. */ if( sqliteOsFileExists(data.zDbFilename) ){ open_db(&data); } /* Process the ~/.sqliterc file, if there is one */ process_sqliterc(&data,NULL); /* Process command-line options */ while( argc>=2 && argv[1][0]=='-' ){ if( argc>=3 && strcmp(argv[1],"-init")==0 ){ /* If we get a -init to do, we have to pretend that ** it replaced the .sqliterc file. Soooo, in order to ** do that we need to start from scratch...*/ main_init(&data); /* treat this file as the sqliterc... */ process_sqliterc(&data,argv[2]); /* fix up the command line so we do not re-read ** the option next time around... */ { int i = 1; for(i=1;i<=argc-2;i++) { argv[i] = argv[i+2]; } } origArgc-=2; /* and reset the command line options to be re-read.*/ argv = origArgv; argc = origArgc; }else if( strcmp(argv[1],"-html")==0 ){ data.mode = MODE_Html; argc--; argv++; }else if( strcmp(argv[1],"-list")==0 ){ data.mode = MODE_List; argc--; argv++; }else if( strcmp(argv[1],"-line")==0 ){ data.mode = MODE_Line; argc--; argv++; }else if( strcmp(argv[1],"-column")==0 ){ data.mode = MODE_Column; argc--; argv++; }else if( argc>=3 && strcmp(argv[1],"-separator")==0 ){ sprintf(data.separator,"%.*s",(int)sizeof(data.separator)-1,argv[2]); argc -= 2; argv += 2; }else if( argc>=3 && strcmp(argv[1],"-nullvalue")==0 ){ sprintf(data.nullvalue,"%.*s",(int)sizeof(data.nullvalue)-1,argv[2]); argc -= 2; argv += 2; }else if( strcmp(argv[1],"-header")==0 ){ data.showHeader = 1; argc--; argv++; }else if( strcmp(argv[1],"-noheader")==0 ){ data.showHeader = 0; argc--; argv++; }else if( strcmp(argv[1],"-echo")==0 ){ data.echoOn = 1; argc--; argv++; }else if( strcmp(argv[1],"-version")==0 ){ printf("%s\n", sqlite_version); return 1; }else if( strcmp(argv[1],"-help")==0 ){ usage(1); }else{ fprintf(stderr,"%s: unknown option: %s\n", Argv0, argv[1]); fprintf(stderr,"Use -help for a list of options.\n"); return 1; } } if( argc<2 ){ usage(0); }else if( argc==3 ){ /* Run just the command that follows the database name */ if( argv[2][0]=='.' ){ do_meta_command(argv[2], &data); exit(0); }else{ int rc; open_db(&data); rc = sqlite_exec(db, argv[2], callback, &data, &zErrMsg); if( rc!=0 && zErrMsg!=0 ){ fprintf(stderr,"SQL error: %s\n", zErrMsg); exit(1); } } }else{ /* Run commands received from standard input */ if( isatty(fileno(stdout)) && isatty(fileno(stdin)) ){ char *zHome; char *zHistory = 0; printf( "SQLite version %s\n" "Enter \".help\" for instructions\n", sqlite_version ); zHome = find_home_dir(); if( zHome && (zHistory = malloc(strlen(zHome)+20))!=0 ){ sprintf(zHistory,"%s/.sqlite_history", zHome); } if( zHistory ) read_history(zHistory); process_input(&data, 0); if( zHistory ){ stifle_history(100); write_history(zHistory); } }else{ process_input(&data, stdin); } } set_table_name(&data, 0); if( db ) sqlite_close(db); return 0; }