From: dan Date: Sat, 9 Dec 2017 17:58:02 +0000 (+0000) Subject: Improve parsing of ".ar" commands. Add new test file for the same. X-Git-Tag: version-3.22.0~108^2~32 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=88be0209168e1625ef5a5b0ef7f33f14e8895b1b;p=thirdparty%2Fsqlite.git Improve parsing of ".ar" commands. Add new test file for the same. FossilOrigin-Name: 840401cc8ce3a09e0663b46973ecd2856d9607be71d2d1e9b21f7df7a82dcbe5 --- diff --git a/manifest b/manifest index ab01f7195c..98adac2007 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\s".ar\sx"\scommand\sto\sthe\sshell.\sFor\sextracting\sthe\scontents\sof\ssqlar\narchives. -D 2017-12-07T21:03:33.903 +C Improve\sparsing\sof\s".ar"\scommands.\sAdd\snew\stest\sfile\sfor\sthe\ssame. +D 2017-12-09T17:58:02.648 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F Makefile.in 6a879cbf01e37f9eac131414955f71774b566502d9a57ded1b8585b507503cb8 @@ -474,7 +474,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c bbee7e31d369a18a2f4836644769882e9c5d40ef4a3af911db06410b65cb3730 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c 17e220191860a64a18c084141e1a8b7309e166a6f2d42c02021af27ea080d157 -F src/shell.c.in 2f9ae0bee09bdd35922ab7ed264d88e1d7fb34d39d37fc633e6a3a1af60036be +F src/shell.c.in 907661eeab82949420270b24f5989a399242cb8721e6140f73b3a46939fc4820 F src/sqlite.h.in 8fd97993d48b50b9bade38c52f12d175942c9497c960905610c7b03a3e4b5818 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h c02d628cca67f3889c689d82d25c3eb45e2c155db08e4c6089b5840d64687d34 @@ -1214,6 +1214,7 @@ F test/shell4.test 89ad573879a745974ff2df20ff97c5d6ffffbd5d F test/shell5.test 23939a4c51f0421330ea61dbd3c74f9c215f5f8d3d1a94846da6ffc777a35458 F test/shell6.test 1ceb51b2678c472ba6cf1e5da96679ce8347889fe2c3bf93a0e0fa73f00b00d3 F test/shell7.test 115132f66d0463417f408562cc2cf534f6bbc6d83a6d50f0072a9eb171bae97f +F test/shell8.test 98b1d7b218060e557b3a789f3396635a0c03873ea652b3154c7f3f238d4a1a8f F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3 F test/show_speedtest1_rtree.tcl 32e6c5f073d7426148a6936a0408f4b5b169aba5 F test/shrink.test 1b4330b1fd9e818c04726d45cb28db73087535ce @@ -1681,7 +1682,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c9827a01a6e107f38f85c2b2c1c7a599e443067b106217e965b6936441ca619d -R 4b2bb930e9456062f8914cba7a04cf63 +P 0cc699d14adfe8c7b7be50c180186562861806c47425c80c935bce43ee5c5c12 +R 0b3e6167ae82d64c1e021b537a83d40a U dan -Z 4726613d4458219c808274490c55a044 +Z 9b95380c27ad603c463b4469d523a6d2 diff --git a/manifest.uuid b/manifest.uuid index 245ee49a8f..d1e1c772f3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0cc699d14adfe8c7b7be50c180186562861806c47425c80c935bce43ee5c5c12 \ No newline at end of file +840401cc8ce3a09e0663b46973ecd2856d9607be71d2d1e9b21f7df7a82dcbe5 \ No newline at end of file diff --git a/src/shell.c.in b/src/shell.c.in index fe58460fe1..b8471fea9f 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -4116,10 +4116,124 @@ static void shellReset( if( *pRc==SQLITE_OK ) *pRc = rc; } +/* +** Structure representing a single ".ar" command. +*/ +typedef struct ArCommand ArCommand; +struct ArCommand { + int eCmd; /* An AR_CMD_* value */ + const char *zFile; /* --file argument, or NULL */ + const char *zDir; /* --directory argument, or NULL */ + int bVerbose; /* True if --verbose */ + int nArg; /* Number of command arguments */ + char **azArg; /* Array of command arguments */ +}; + +/* +** Print a usage message for the .ar command to stderr and return SQLITE_ERROR. +*/ +static int arUsage(void){ + /* todo */ + raw_printf(stderr, "error in .ar command line\n"); + return SQLITE_ERROR; +} + +/* +** Values for ArCommand.eCmd. +*/ +#define AR_CMD_CREATE 1 +#define AR_CMD_EXTRACT 2 +#define AR_CMD_LIST 3 +#define AR_CMD_UPDATE 4 + +/* +** Parse the command line for an ".ar" command. The results are written into +** structure (*pAr). SQLITE_OK is returned if the command line is parsed +** successfully, otherwise an error message is written to stderr and +** SQLITE_ERROR returned. +*/ +static int arParseCommand( + char **azArg, /* Array of arguments passed to dot command */ + int nArg, /* Number of entries in azArg[] */ + ArCommand *pAr /* Populate this object */ +){ + if( nArg<=1 ){ + return arUsage(); + }else{ + char *z = azArg[1]; + memset(pAr, 0, sizeof(ArCommand)); + + if( z[0]!='-' ){ + /* Traditional style [tar] invocation */ + int i; + int iArg = 2; + for(i=0; z[i]; i++){ + switch( z[i] ){ + case 'c': + if( pAr->eCmd ) return arUsage(); + pAr->eCmd = AR_CMD_CREATE; + break; + case 'x': + if( pAr->eCmd ) return arUsage(); + pAr->eCmd = AR_CMD_EXTRACT; + break; + case 't': + if( pAr->eCmd ) return arUsage(); + pAr->eCmd = AR_CMD_LIST; + break; + case 'u': + if( pAr->eCmd ) return arUsage(); + pAr->eCmd = AR_CMD_UPDATE; + break; + + case 'v': + pAr->bVerbose = 1; + break; + case 'f': + if( iArg>=nArg ) return arUsage(); + pAr->zFile = azArg[iArg++]; + break; + case 'C': + if( iArg>=nArg ) return arUsage(); + pAr->zDir = azArg[iArg++]; + break; + + default: + return arUsage(); + } + } + + pAr->nArg = nArg-iArg; + if( pAr->nArg>0 ){ + pAr->azArg = &azArg[iArg]; + } + } + } + + return SQLITE_OK; +} + +/* +** Implementation of .ar "Update" command. +*/ +static int arUpdateCmd(ShellState *p, ArCommand *pAr){ + raw_printf(stderr, "todo...\n"); + return SQLITE_OK; +} + +/* +** Implementation of .ar "lisT" command. +*/ +static int arListCommand(ShellState *p, ArCommand *pAr){ + raw_printf(stderr, "todo...\n"); + return SQLITE_OK; +} + + /* ** Implementation of .ar "eXtract" command. */ -static int arExtractCommand(ShellState *p, int bVerbose){ +static int arExtractCommand(ShellState *p, ArCommand *pAr){ const char *zSql1 = "SELECT name, writefile(name, " "CASE WHEN (data AND sz>=0 AND sz!=length(data)) THEN uncompress(data) " @@ -4136,7 +4250,7 @@ static int arExtractCommand(ShellState *p, int bVerbose){ shellPrepare(p, &rc, zSql1, &pSql); while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){ - if( bVerbose ){ + if( pAr->bVerbose ){ raw_printf(stdout, "%s\n", sqlite3_column_text(pSql, 0)); } } @@ -4167,9 +4281,7 @@ static int arExtractCommand(ShellState *p, int bVerbose){ */ static int arCreateCommand( ShellState *p, /* Shell state pointer */ - char **azFile, /* Array of files to add to archive */ - int nFile, /* Number of entries in azFile[] */ - int bVerbose /* True to be verbose on stdout */ + ArCommand *pAr /* Command arguments and options */ ){ const char *zSql = "WITH f(n, m, t, d) AS (" @@ -4204,8 +4316,8 @@ static int arCreateCommand( shellPrepare(p, &rc, zInsert, &pInsert); shellPrepare(p, &rc, zSql, &pStmt); - for(i=0; inArg && rc==SQLITE_OK; i++){ + sqlite3_bind_text(pStmt, 1, pAr->azArg[i], -1, SQLITE_STATIC); sqlite3_bind_int(pStmt, 2, S_IFDIR); while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ int sz; @@ -4213,7 +4325,7 @@ static int arCreateCommand( int mode = sqlite3_column_int(pStmt, 1); unsigned int mtime = sqlite3_column_int(pStmt, 2); - if( bVerbose ){ + if( pAr->bVerbose ){ raw_printf(stdout, "%s\n", zName); } @@ -4280,38 +4392,31 @@ static int arDotCommand( char **azArg, /* Array of arguments passed to dot command */ int nArg /* Number of entries in azArg[] */ ){ - int bVerbose = 0; - char cmd = 0; - int i; - int n1; - if( nArg<=1 ) goto usage; + ArCommand cmd; + int rc; + rc = arParseCommand(azArg, nArg, &cmd); + if( rc==SQLITE_OK ){ + switch( cmd.eCmd ){ + case AR_CMD_CREATE: + rc = arCreateCommand(pState, &cmd); + break; - n1 = strlen(azArg[1]); - for(i=0; i