| Index: third_party/sqlite/sqlite-src-3100200/tool/showdb.c
|
| diff --git a/third_party/sqlite/sqlite-src-3080704/tool/showdb.c b/third_party/sqlite/sqlite-src-3100200/tool/showdb.c
|
| similarity index 77%
|
| copy from third_party/sqlite/sqlite-src-3080704/tool/showdb.c
|
| copy to third_party/sqlite/sqlite-src-3100200/tool/showdb.c
|
| index 82b8c9f14f98353e6400490126f641c25d99fc77..06cd36cd2c86c552a44ceff802af8265a93dd81d 100644
|
| --- a/third_party/sqlite/sqlite-src-3080704/tool/showdb.c
|
| +++ b/third_party/sqlite/sqlite-src-3100200/tool/showdb.c
|
| @@ -3,6 +3,8 @@
|
| */
|
| #include <stdio.h>
|
| #include <ctype.h>
|
| +#define ISDIGIT(X) isdigit((unsigned char)(X))
|
| +#define ISPRINT(X) isprint((unsigned char)(X))
|
| #include <sys/types.h>
|
| #include <sys/stat.h>
|
| #include <fcntl.h>
|
| @@ -15,13 +17,20 @@
|
|
|
| #include <stdlib.h>
|
| #include <string.h>
|
| +#include <assert.h>
|
| #include "sqlite3.h"
|
|
|
|
|
| -static int pagesize = 1024; /* Size of a database page */
|
| -static int db = -1; /* File descriptor for reading the DB */
|
| -static int mxPage = 0; /* Last page number */
|
| -static int perLine = 16; /* HEX elements to print per line */
|
| +static struct GlobalData {
|
| + int pagesize; /* Size of a database page */
|
| + int dbfd; /* File descriptor for reading the DB */
|
| + int mxPage; /* Last page number */
|
| + int perLine; /* HEX elements to print per line */
|
| + int bRaw; /* True to access db file via OS APIs */
|
| + sqlite3_file *pFd; /* File descriptor for non-raw mode */
|
| + sqlite3 *pDb; /* Database handle that owns pFd */
|
| +} g = {1024, -1, 0, 16, 0, 0, 0};
|
| +
|
|
|
| typedef long long int i64; /* Datatype for 64-bit integers */
|
|
|
| @@ -57,22 +66,122 @@ static void out_of_memory(void){
|
| }
|
|
|
| /*
|
| +** Open a database connection.
|
| +*/
|
| +static sqlite3 *openDatabase(const char *zPrg, const char *zName){
|
| + sqlite3 *db = 0;
|
| + int flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_URI;
|
| + int rc = sqlite3_open_v2(zName, &db, flags, 0);
|
| + if( rc!=SQLITE_OK ){
|
| + const char *zErr = sqlite3_errmsg(db);
|
| + fprintf(stderr, "%s: can't open %s (%s)\n", zPrg, zName, zErr);
|
| + sqlite3_close(db);
|
| + exit(1);
|
| + }
|
| + return db;
|
| +}
|
| +
|
| +/**************************************************************************
|
| +** Beginning of low-level file access functions.
|
| +**
|
| +** All low-level access to the database file read by this program is
|
| +** performed using the following four functions:
|
| +**
|
| +** fileOpen() - open the db file
|
| +** fileClose() - close the db file
|
| +** fileRead() - read raw data from the db file
|
| +** fileGetsize() - return the size of the db file in bytes
|
| +*/
|
| +
|
| +/*
|
| +** Open the database file.
|
| +*/
|
| +static void fileOpen(const char *zPrg, const char *zName){
|
| + assert( g.dbfd<0 );
|
| + if( g.bRaw==0 ){
|
| + int rc;
|
| + void *pArg = (void *)(&g.pFd);
|
| + g.pDb = openDatabase(zPrg, zName);
|
| + rc = sqlite3_file_control(g.pDb, "main", SQLITE_FCNTL_FILE_POINTER, pArg);
|
| + if( rc!=SQLITE_OK ){
|
| + fprintf(stderr,
|
| + "%s: failed to obtain fd for %s (SQLite too old?)\n", zPrg, zName
|
| + );
|
| + exit(1);
|
| + }
|
| + }else{
|
| + g.dbfd = open(zName, O_RDONLY);
|
| + if( g.dbfd<0 ){
|
| + fprintf(stderr,"%s: can't open %s\n", zPrg, zName);
|
| + exit(1);
|
| + }
|
| + }
|
| +}
|
| +
|
| +/*
|
| +** Close the database file opened by fileOpen()
|
| +*/
|
| +static void fileClose(){
|
| + if( g.bRaw==0 ){
|
| + sqlite3_close(g.pDb);
|
| + g.pDb = 0;
|
| + g.pFd = 0;
|
| + }else{
|
| + close(g.dbfd);
|
| + g.dbfd = -1;
|
| + }
|
| +}
|
| +
|
| +/*
|
| ** Read content from the file.
|
| **
|
| -** Space to hold the content is obtained from malloc() and needs to be
|
| -** freed by the caller.
|
| +** Space to hold the content is obtained from sqlite3_malloc() and needs
|
| +** to be freed by the caller.
|
| */
|
| -static unsigned char *getContent(int ofst, int nByte){
|
| +static unsigned char *fileRead(sqlite3_int64 ofst, int nByte){
|
| unsigned char *aData;
|
| - aData = malloc(nByte+32);
|
| + int got;
|
| + aData = sqlite3_malloc(nByte+32);
|
| if( aData==0 ) out_of_memory();
|
| memset(aData, 0, nByte+32);
|
| - lseek(db, ofst, SEEK_SET);
|
| - if( read(db, aData, nByte)<nByte ) memset(aData, 0, nByte);
|
| + if( g.bRaw==0 ){
|
| + int rc = g.pFd->pMethods->xRead(g.pFd, (void*)aData, nByte, ofst);
|
| + if( rc!=SQLITE_OK && rc!=SQLITE_IOERR_SHORT_READ ){
|
| + fprintf(stderr, "error in xRead() - %d\n", rc);
|
| + exit(1);
|
| + }
|
| + }else{
|
| + lseek(g.dbfd, ofst, SEEK_SET);
|
| + got = read(g.dbfd, aData, nByte);
|
| + if( got>0 && got<nByte ) memset(aData+got, 0, nByte-got);
|
| + }
|
| return aData;
|
| }
|
|
|
| /*
|
| +** Return the size of the file in byte.
|
| +*/
|
| +static sqlite3_int64 fileGetsize(void){
|
| + sqlite3_int64 res = 0;
|
| + if( g.bRaw==0 ){
|
| + int rc = g.pFd->pMethods->xFileSize(g.pFd, &res);
|
| + if( rc!=SQLITE_OK ){
|
| + fprintf(stderr, "error in xFileSize() - %d\n", rc);
|
| + exit(1);
|
| + }
|
| + }else{
|
| + struct stat sbuf;
|
| + fstat(g.dbfd, &sbuf);
|
| + res = (sqlite3_int64)(sbuf.st_size);
|
| + }
|
| + return res;
|
| +}
|
| +
|
| +/*
|
| +** End of low-level file access functions.
|
| +**************************************************************************/
|
| +
|
| +/*
|
| ** Print a range of bytes as hex and as ascii.
|
| */
|
| static unsigned char *print_byte_range(
|
| @@ -96,21 +205,21 @@ static unsigned char *print_byte_range(
|
| zOfstFmt = " %08x: ";
|
| }
|
|
|
| - aData = getContent(ofst, nByte);
|
| - for(i=0; i<nByte; i += perLine){
|
| + aData = fileRead(ofst, nByte);
|
| + for(i=0; i<nByte; i += g.perLine){
|
| fprintf(stdout, zOfstFmt, i+printOfst);
|
| - for(j=0; j<perLine; j++){
|
| + for(j=0; j<g.perLine; j++){
|
| if( i+j>nByte ){
|
| fprintf(stdout, " ");
|
| }else{
|
| fprintf(stdout,"%02x ", aData[i+j]);
|
| }
|
| }
|
| - for(j=0; j<perLine; j++){
|
| + for(j=0; j<g.perLine; j++){
|
| if( i+j>nByte ){
|
| fprintf(stdout, " ");
|
| }else{
|
| - fprintf(stdout,"%c", isprint(aData[i+j]) ? aData[i+j] : '.');
|
| + fprintf(stdout,"%c", ISPRINT(aData[i+j]) ? aData[i+j] : '.');
|
| }
|
| }
|
| fprintf(stdout,"\n");
|
| @@ -124,11 +233,11 @@ static unsigned char *print_byte_range(
|
| static void print_page(int iPg){
|
| int iStart;
|
| unsigned char *aData;
|
| - iStart = (iPg-1)*pagesize;
|
| + iStart = (iPg-1)*g.pagesize;
|
| fprintf(stdout, "Page %d: (offsets 0x%x..0x%x)\n",
|
| - iPg, iStart, iStart+pagesize-1);
|
| - aData = print_byte_range(iStart, pagesize, 0);
|
| - free(aData);
|
| + iPg, iStart, iStart+g.pagesize-1);
|
| + aData = print_byte_range(iStart, g.pagesize, 0);
|
| + sqlite3_free(aData);
|
| }
|
|
|
|
|
| @@ -265,14 +374,14 @@ static i64 localPayload(i64 nPayload, char cType){
|
| i64 nLocal;
|
| if( cType==13 ){
|
| /* Table leaf */
|
| - maxLocal = pagesize-35;
|
| - minLocal = (pagesize-12)*32/255-23;
|
| + maxLocal = g.pagesize-35;
|
| + minLocal = (g.pagesize-12)*32/255-23;
|
| }else{
|
| - maxLocal = (pagesize-12)*64/255-23;
|
| - minLocal = (pagesize-12)*32/255-23;
|
| + maxLocal = (g.pagesize-12)*64/255-23;
|
| + minLocal = (g.pagesize-12)*32/255-23;
|
| }
|
| if( nPayload>maxLocal ){
|
| - surplus = minLocal + (nPayload-minLocal)%(pagesize-4);
|
| + surplus = minLocal + (nPayload-minLocal)%(g.pagesize-4);
|
| if( surplus<=maxLocal ){
|
| nLocal = surplus;
|
| }else{
|
| @@ -375,7 +484,7 @@ static void decodeCell(
|
| int szPgHdr, /* Size of the page header. 0 or 100 */
|
| int ofst /* Cell begins at a[ofst] */
|
| ){
|
| - int i, j;
|
| + int i, j = 0;
|
| int leftChild;
|
| i64 k;
|
| i64 nPayload;
|
| @@ -493,7 +602,7 @@ static void decodeCell(
|
| }else{
|
| zConst[0] = '\'';
|
| for(ii=1, jj=0; jj<szCol[i] && ii<24; jj++, ii++){
|
| - zConst[ii] = isprint(pData[jj]) ? pData[jj] : '.';
|
| + zConst[ii] = ISPRINT(pData[jj]) ? pData[jj] : '.';
|
| }
|
| zConst[ii] = 0;
|
| }
|
| @@ -546,11 +655,11 @@ static void decode_btree_page(
|
| case 'c': showCellContent = 1; break;
|
| case 'm': showMap = 1; break;
|
| case 'd': {
|
| - if( !isdigit(zArgs[1]) ){
|
| + if( !ISDIGIT(zArgs[1]) ){
|
| cellToDecode = -1;
|
| }else{
|
| cellToDecode = 0;
|
| - while( isdigit(zArgs[1]) ){
|
| + while( ISDIGIT(zArgs[1]) ){
|
| zArgs++;
|
| cellToDecode = cellToDecode*10 + zArgs[0] - '0';
|
| }
|
| @@ -579,8 +688,8 @@ static void decode_btree_page(
|
| printf(" key: lx=left-child n=payload-size r=rowid\n");
|
| }
|
| if( showMap ){
|
| - zMap = malloc(pagesize);
|
| - memset(zMap, '.', pagesize);
|
| + zMap = sqlite3_malloc(g.pagesize);
|
| + memset(zMap, '.', g.pagesize);
|
| memset(zMap, '1', hdrSize);
|
| memset(&zMap[hdrSize], 'H', iCellPtr);
|
| memset(&zMap[hdrSize+iCellPtr], 'P', 2*nCell);
|
| @@ -609,10 +718,10 @@ static void decode_btree_page(
|
| }
|
| if( showMap ){
|
| printf("Page map: (H=header P=cell-index 1=page-1-header .=free-space)\n");
|
| - for(i=0; i<pagesize; i+=64){
|
| + for(i=0; i<g.pagesize; i+=64){
|
| printf(" %03x: %.64s\n", i, &zMap[i]);
|
| }
|
| - free(zMap);
|
| + sqlite3_free(zMap);
|
| }
|
| }
|
|
|
| @@ -621,14 +730,13 @@ static void decode_btree_page(
|
| */
|
| static void decode_trunk_page(
|
| int pgno, /* The page number */
|
| - int pagesize, /* Size of each page */
|
| int detail, /* Show leaf pages if true */
|
| int recursive /* Follow the trunk change if true */
|
| ){
|
| int n, i;
|
| unsigned char *a;
|
| while( pgno>0 ){
|
| - a = getContent((pgno-1)*pagesize, pagesize);
|
| + a = fileRead((pgno-1)*g.pagesize, g.pagesize);
|
| printf("Decode of freelist trunk page %d:\n", pgno);
|
| print_decode_line(a, 0, 4, "Next freelist trunk page");
|
| print_decode_line(a, 4, 4, "Number of entries on this page");
|
| @@ -648,7 +756,7 @@ static void decode_trunk_page(
|
| }else{
|
| pgno = (int)decodeInt32(&a[0]);
|
| }
|
| - free(a);
|
| + sqlite3_free(a);
|
| }
|
| }
|
|
|
| @@ -667,9 +775,9 @@ static void page_usage_msg(int pgno, const char *zFormat, ...){
|
| va_start(ap, zFormat);
|
| zMsg = sqlite3_vmprintf(zFormat, ap);
|
| va_end(ap);
|
| - if( pgno<=0 || pgno>mxPage ){
|
| + if( pgno<=0 || pgno>g.mxPage ){
|
| printf("ERROR: page %d out of range 1..%d: %s\n",
|
| - pgno, mxPage, zMsg);
|
| + pgno, g.mxPage, zMsg);
|
| sqlite3_free(zMsg);
|
| return;
|
| }
|
| @@ -717,12 +825,12 @@ static void page_usage_cell(
|
| if( nLocal<nPayload ){
|
| int ovfl = decodeInt32(a+nLocal);
|
| int cnt = 0;
|
| - while( ovfl && (cnt++)<mxPage ){
|
| + while( ovfl && (cnt++)<g.mxPage ){
|
| page_usage_msg(ovfl, "overflow %d from cell %d of page %d",
|
| cnt, cellno, pgno);
|
| - a = getContent((ovfl-1)*pagesize, 4);
|
| + a = fileRead((ovfl-1)*g.pagesize, 4);
|
| ovfl = decodeInt32(a);
|
| - free(a);
|
| + sqlite3_free(a);
|
| }
|
| }
|
| }
|
| @@ -743,8 +851,8 @@ static void page_usage_btree(
|
| int i;
|
| int hdr = pgno==1 ? 100 : 0;
|
|
|
| - if( pgno<=0 || pgno>mxPage ) return;
|
| - a = getContent((pgno-1)*pagesize, pagesize);
|
| + if( pgno<=0 || pgno>g.mxPage ) return;
|
| + a = fileRead((pgno-1)*g.pagesize, g.pagesize);
|
| switch( a[hdr] ){
|
| case 2: zType = "interior node of index"; break;
|
| case 5: zType = "interior node of table"; break;
|
| @@ -781,7 +889,7 @@ static void page_usage_btree(
|
| page_usage_cell(a[hdr], a+ofst, pgno, i);
|
| }
|
| }
|
| - free(a);
|
| + sqlite3_free(a);
|
| }
|
|
|
| /*
|
| @@ -795,9 +903,9 @@ static void page_usage_freelist(int pgno){
|
| int iNext;
|
| int parent = 1;
|
|
|
| - while( pgno>0 && pgno<=mxPage && (cnt++)<mxPage ){
|
| + while( pgno>0 && pgno<=g.mxPage && (cnt++)<g.mxPage ){
|
| page_usage_msg(pgno, "freelist trunk #%d child of %d", cnt, parent);
|
| - a = getContent((pgno-1)*pagesize, pagesize);
|
| + a = fileRead((pgno-1)*g.pagesize, g.pagesize);
|
| iNext = decodeInt32(a);
|
| n = decodeInt32(a+4);
|
| for(i=0; i<n; i++){
|
| @@ -805,7 +913,7 @@ static void page_usage_freelist(int pgno){
|
| page_usage_msg(child, "freelist leaf, child %d of trunk page %d",
|
| i, pgno);
|
| }
|
| - free(a);
|
| + sqlite3_free(a);
|
| parent = pgno;
|
| pgno = iNext;
|
| }
|
| @@ -816,10 +924,10 @@ static void page_usage_freelist(int pgno){
|
| */
|
| static void page_usage_ptrmap(unsigned char *a){
|
| if( a[55] ){
|
| - int usable = pagesize - a[20];
|
| + int usable = g.pagesize - a[20];
|
| int pgno = 2;
|
| int perPage = usable/5;
|
| - while( pgno<=mxPage ){
|
| + while( pgno<=g.mxPage ){
|
| page_usage_msg(pgno, "PTRMAP page covering %d..%d",
|
| pgno+1, pgno+perPage);
|
| pgno += perPage + 1;
|
| @@ -830,7 +938,7 @@ static void page_usage_ptrmap(unsigned char *a){
|
| /*
|
| ** Try to figure out how every page in the database file is being used.
|
| */
|
| -static void page_usage_report(const char *zDbName){
|
| +static void page_usage_report(const char *zPrg, const char *zDbName){
|
| int i, j;
|
| int rc;
|
| sqlite3 *db;
|
| @@ -839,30 +947,25 @@ static void page_usage_report(const char *zDbName){
|
| char zQuery[200];
|
|
|
| /* Avoid the pathological case */
|
| - if( mxPage<1 ){
|
| + if( g.mxPage<1 ){
|
| printf("empty database\n");
|
| return;
|
| }
|
|
|
| /* Open the database file */
|
| - rc = sqlite3_open(zDbName, &db);
|
| - if( rc ){
|
| - printf("cannot open database: %s\n", sqlite3_errmsg(db));
|
| - sqlite3_close(db);
|
| - return;
|
| - }
|
| + db = openDatabase(zPrg, zDbName);
|
|
|
| - /* Set up global variables zPageUse[] and mxPage to record page
|
| + /* Set up global variables zPageUse[] and g.mxPage to record page
|
| ** usages */
|
| - zPageUse = sqlite3_malloc( sizeof(zPageUse[0])*(mxPage+1) );
|
| + zPageUse = sqlite3_malloc( sizeof(zPageUse[0])*(g.mxPage+1) );
|
| if( zPageUse==0 ) out_of_memory();
|
| - memset(zPageUse, 0, sizeof(zPageUse[0])*(mxPage+1));
|
| + memset(zPageUse, 0, sizeof(zPageUse[0])*(g.mxPage+1));
|
|
|
| /* Discover the usage of each page */
|
| - a = getContent(0, 100);
|
| + a = fileRead(0, 100);
|
| page_usage_freelist(decodeInt32(a+32));
|
| page_usage_ptrmap(a);
|
| - free(a);
|
| + sqlite3_free(a);
|
| page_usage_btree(1, 0, 0, "sqlite_master");
|
| sqlite3_exec(db, "PRAGMA writable_schema=ON", 0, 0, 0);
|
| for(j=0; j<2; j++){
|
| @@ -884,7 +987,7 @@ static void page_usage_report(const char *zDbName){
|
| sqlite3_close(db);
|
|
|
| /* Print the report and free memory used */
|
| - for(i=1; i<=mxPage; i++){
|
| + for(i=1; i<=g.mxPage; i++){
|
| printf("%5d: %s\n", i, zPageUse[i] ? zPageUse[i] : "???");
|
| sqlite3_free(zPageUse[i]);
|
| }
|
| @@ -904,26 +1007,26 @@ static void ptrmap_coverage_report(const char *zDbName){
|
| int i;
|
|
|
| /* Avoid the pathological case */
|
| - if( mxPage<1 ){
|
| + if( g.mxPage<1 ){
|
| printf("empty database\n");
|
| return;
|
| }
|
|
|
| /* Make sure PTRMAPs are used in this database */
|
| - aHdr = getContent(0, 100);
|
| + aHdr = fileRead(0, 100);
|
| if( aHdr[55]==0 ){
|
| printf("database does not use PTRMAP pages\n");
|
| return;
|
| }
|
| - usable = pagesize - aHdr[20];
|
| + usable = g.pagesize - aHdr[20];
|
| perPage = usable/5;
|
| - free(aHdr);
|
| + sqlite3_free(aHdr);
|
| printf("%5d: root of sqlite_master\n", 1);
|
| - for(pgno=2; pgno<=mxPage; pgno += perPage+1){
|
| + for(pgno=2; pgno<=g.mxPage; pgno += perPage+1){
|
| printf("%5d: PTRMAP page covering %d..%d\n", pgno,
|
| pgno+1, pgno+perPage);
|
| - a = getContent((pgno-1)*pagesize, usable);
|
| - for(i=0; i+5<=usable && pgno+1+i/5<=mxPage; i+=5){
|
| + a = fileRead((pgno-1)*g.pagesize, usable);
|
| + for(i=0; i+5<=usable && pgno+1+i/5<=g.mxPage; i+=5){
|
| const char *zType = "???";
|
| unsigned int iFrom = decodeInt32(&a[i+1]);
|
| switch( a[i] ){
|
| @@ -935,7 +1038,7 @@ static void ptrmap_coverage_report(const char *zDbName){
|
| }
|
| printf("%5d: %s, parent=%u\n", pgno+1+i/5, zType, iFrom);
|
| }
|
| - free(a);
|
| + sqlite3_free(a);
|
| }
|
| }
|
|
|
| @@ -943,8 +1046,10 @@ static void ptrmap_coverage_report(const char *zDbName){
|
| ** Print a usage comment
|
| */
|
| static void usage(const char *argv0){
|
| - fprintf(stderr, "Usage %s FILENAME ?args...?\n\n", argv0);
|
| + fprintf(stderr, "Usage %s ?--uri? FILENAME ?args...?\n\n", argv0);
|
| fprintf(stderr,
|
| + "switches:\n"
|
| + " --raw Read db file directly, bypassing SQLite VFS\n"
|
| "args:\n"
|
| " dbheader Show database header\n"
|
| " pgidx Index of how each page is used\n"
|
| @@ -962,58 +1067,71 @@ static void usage(const char *argv0){
|
| }
|
|
|
| int main(int argc, char **argv){
|
| - struct stat sbuf;
|
| - unsigned char zPgSz[2];
|
| - if( argc<2 ){
|
| - usage(argv[0]);
|
| - exit(1);
|
| + sqlite3_int64 szFile;
|
| + unsigned char *zPgSz;
|
| + const char *zPrg = argv[0]; /* Name of this executable */
|
| + char **azArg = argv;
|
| + int nArg = argc;
|
| +
|
| + /* Check for the "--uri" or "-uri" switch. */
|
| + if( nArg>1 ){
|
| + if( sqlite3_stricmp("-raw", azArg[1])==0
|
| + || sqlite3_stricmp("--raw", azArg[1])==0
|
| + ){
|
| + g.bRaw = 1;
|
| + azArg++;
|
| + nArg--;
|
| + }
|
| }
|
| - db = open(argv[1], O_RDONLY);
|
| - if( db<0 ){
|
| - fprintf(stderr,"%s: can't open %s\n", argv[0], argv[1]);
|
| +
|
| + if( nArg<2 ){
|
| + usage(zPrg);
|
| exit(1);
|
| }
|
| - zPgSz[0] = 0;
|
| - zPgSz[1] = 0;
|
| - lseek(db, 16, SEEK_SET);
|
| - if( read(db, zPgSz, 2)<2 ) memset(zPgSz, 0, 2);
|
| - pagesize = zPgSz[0]*256 + zPgSz[1]*65536;
|
| - if( pagesize==0 ) pagesize = 1024;
|
| - printf("Pagesize: %d\n", pagesize);
|
| - fstat(db, &sbuf);
|
| - mxPage = sbuf.st_size/pagesize;
|
| - printf("Available pages: 1..%d\n", mxPage);
|
| - if( argc==2 ){
|
| +
|
| + fileOpen(zPrg, azArg[1]);
|
| + szFile = fileGetsize();
|
| +
|
| + zPgSz = fileRead(16, 2);
|
| + g.pagesize = zPgSz[0]*256 + zPgSz[1]*65536;
|
| + if( g.pagesize==0 ) g.pagesize = 1024;
|
| + sqlite3_free(zPgSz);
|
| +
|
| + printf("Pagesize: %d\n", g.pagesize);
|
| + g.mxPage = (szFile+g.pagesize-1)/g.pagesize;
|
| +
|
| + printf("Available pages: 1..%d\n", g.mxPage);
|
| + if( nArg==2 ){
|
| int i;
|
| - for(i=1; i<=mxPage; i++) print_page(i);
|
| + for(i=1; i<=g.mxPage; i++) print_page(i);
|
| }else{
|
| int i;
|
| - for(i=2; i<argc; i++){
|
| + for(i=2; i<nArg; i++){
|
| int iStart, iEnd;
|
| char *zLeft;
|
| - if( strcmp(argv[i], "dbheader")==0 ){
|
| + if( strcmp(azArg[i], "dbheader")==0 ){
|
| print_db_header();
|
| continue;
|
| }
|
| - if( strcmp(argv[i], "pgidx")==0 ){
|
| - page_usage_report(argv[1]);
|
| + if( strcmp(azArg[i], "pgidx")==0 ){
|
| + page_usage_report(zPrg, azArg[1]);
|
| continue;
|
| }
|
| - if( strcmp(argv[i], "ptrmap")==0 ){
|
| - ptrmap_coverage_report(argv[1]);
|
| + if( strcmp(azArg[i], "ptrmap")==0 ){
|
| + ptrmap_coverage_report(azArg[1]);
|
| continue;
|
| }
|
| - if( strcmp(argv[i], "help")==0 ){
|
| - usage(argv[0]);
|
| + if( strcmp(azArg[i], "help")==0 ){
|
| + usage(zPrg);
|
| continue;
|
| }
|
| - if( !isdigit(argv[i][0]) ){
|
| - fprintf(stderr, "%s: unknown option: [%s]\n", argv[0], argv[i]);
|
| + if( !ISDIGIT(azArg[i][0]) ){
|
| + fprintf(stderr, "%s: unknown option: [%s]\n", zPrg, azArg[i]);
|
| continue;
|
| }
|
| - iStart = strtol(argv[i], &zLeft, 0);
|
| + iStart = strtol(azArg[i], &zLeft, 0);
|
| if( zLeft && strcmp(zLeft,"..end")==0 ){
|
| - iEnd = mxPage;
|
| + iEnd = g.mxPage;
|
| }else if( zLeft && zLeft[0]=='.' && zLeft[1]=='.' ){
|
| iEnd = strtol(&zLeft[2], 0, 0);
|
| }else if( zLeft && zLeft[0]=='b' ){
|
| @@ -1021,33 +1139,33 @@ int main(int argc, char **argv){
|
| unsigned char *a;
|
| if( iStart==1 ){
|
| ofst = hdrSize = 100;
|
| - nByte = pagesize-100;
|
| + nByte = g.pagesize-100;
|
| }else{
|
| hdrSize = 0;
|
| - ofst = (iStart-1)*pagesize;
|
| - nByte = pagesize;
|
| + ofst = (iStart-1)*g.pagesize;
|
| + nByte = g.pagesize;
|
| }
|
| - a = getContent(ofst, nByte);
|
| + a = fileRead(ofst, nByte);
|
| decode_btree_page(a, iStart, hdrSize, &zLeft[1]);
|
| - free(a);
|
| + sqlite3_free(a);
|
| continue;
|
| }else if( zLeft && zLeft[0]=='t' ){
|
| int detail = 0;
|
| int recursive = 0;
|
| - int i;
|
| - for(i=1; zLeft[i]; i++){
|
| - if( zLeft[i]=='r' ) recursive = 1;
|
| - if( zLeft[i]=='d' ) detail = 1;
|
| + int j;
|
| + for(j=1; zLeft[j]; j++){
|
| + if( zLeft[j]=='r' ) recursive = 1;
|
| + if( zLeft[j]=='d' ) detail = 1;
|
| }
|
| - decode_trunk_page(iStart, pagesize, detail, recursive);
|
| + decode_trunk_page(iStart, detail, recursive);
|
| continue;
|
| }else{
|
| iEnd = iStart;
|
| }
|
| - if( iStart<1 || iEnd<iStart || iEnd>mxPage ){
|
| + if( iStart<1 || iEnd<iStart || iEnd>g.mxPage ){
|
| fprintf(stderr,
|
| "Page argument should be LOWER?..UPPER?. Range 1 to %d\n",
|
| - mxPage);
|
| + g.mxPage);
|
| exit(1);
|
| }
|
| while( iStart<=iEnd ){
|
| @@ -1056,6 +1174,6 @@ int main(int argc, char **argv){
|
| }
|
| }
|
| }
|
| - close(db);
|
| + fileClose();
|
| return 0;
|
| }
|
|
|