]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
CLI: Add the --ww option as an alias for --wordwrap. Improve the wordwrap
authordrh <>
Tue, 1 Feb 2022 12:28:17 +0000 (12:28 +0000)
committerdrh <>
Tue, 1 Feb 2022 12:28:17 +0000 (12:28 +0000)
algorithm so that it breaks at punctuation if it cannot find space.  Always
wordwrap with --ww even if there is a .width setting for the column.

FossilOrigin-Name: 1b528e31f8c62797e0814568b520c0680ff23a2ee877ca6aa70a167d40ebdf80

manifest
manifest.uuid
src/shell.c.in
test/shell1.test

index 6128f7de2e7d2972f9ac79769961adfd88497aaa..e07a89b93b0aaff1480208381b61268934f3b467 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Add\s"--wordwrap\son/off"\soption\sfor\sCLI\scolumnar\smodes,\sqwbox\sshortcut
-D 2022-02-01T02:50:45.569
+C CLI:\sAdd\sthe\s--ww\soption\sas\san\salias\sfor\s--wordwrap.\s\sImprove\sthe\swordwrap\nalgorithm\sso\sthat\sit\sbreaks\sat\spunctuation\sif\sit\scannot\sfind\sspace.\s\sAlways\nwordwrap\swith\s--ww\seven\sif\sthere\sis\sa\s.width\ssetting\sfor\sthe\scolumn.
+D 2022-02-01T12:28:17.432
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -553,7 +553,7 @@ F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c
 F src/resolve.c 24032ae57aec10df2f3fa2e20be0aae7d256bc704124b76c52d763440c7c0fe9
 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92
 F src/select.c a6d2d4bed279d7fe4fcedaf297eaf6441e8e17c6e3947a32d24d23be52ac02f2
-F src/shell.c.in 4f5e0a9f38aa648ca529efb66f338308262b47a72b6c5c95a1f704619fa1aef0
+F src/shell.c.in b701feb3867d8293aafbb7164d3fd09f76c07a99184bfcac719351976b19e0ef
 F src/sqlite.h.in eaade58049152dac850d57415bcced885ca27ae9582f8aea2cfb7f1db78a521b
 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
 F src/sqlite3ext.h 5d54cf13d3406d8eb65d921a0d3c349de6126b732e695e79ecd4830ce86b4f8a
@@ -1386,7 +1386,7 @@ F test/sharedA.test 49d87ec54ab640fbbc3786ee3c01de94aaa482a3a9f834ad3fe92770eb69
 F test/sharedB.test 16cc7178e20965d75278f410943109b77b2e645e
 F test/shared_err.test 32634e404a3317eeb94abc7a099c556a346fdb8fb3858dbe222a4cbb8926a939
 F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304
-F test/shell1.test 1859ba21623b6a804ab2527b2a7c10b54513e8c4e40cec2b462d0e9f082d4fec
+F test/shell1.test ce2f370886645f38fabdde44976c14a004400f166edea8fdd9741079b645fef6
 F test/shell2.test f00a0501c00583cbc46f7510e1d713366326b2b3e63d06d15937284171a8787c
 F test/shell3.test cb4b835a901742c9719437a89171172ecc4a8823ad97349af8e4e841e6f82566
 F test/shell4.test 8f6c0fce4abed19a8a7f7262517149812a04caa905d01bdc8f5e92573504b759
@@ -1942,9 +1942,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P fd42f4c304079356358e606dd96d4b84cf211c4334c586118b99fe9ad20e20ea
-Q +f51a17b6271a8dd7c48725e4ec2df1fde0460866c81c7225dc27216ab389591e
-R 9664e5ccc659386bbaeacc1cefed4830
-U larrybr
-Z c1cf64e5874e5b6ab186498f765ac9eb
+P 10dbc278708cd2cce7fef90738082dbe31750d93e44b5fa5413a9a32dae7703a
+R 69e29afaa5f754bae2ca14b8682cbcc3
+U drh
+Z 4e6f65c63d4836409df930e76a99a677
 # Remove this line to create a well-formed Fossil manifest.
index 53a5bb21c2ffbe3c861380a675ead96738073925..ea3c3bc91241c3726c2568986d142385a651a98c 100644 (file)
@@ -1 +1 @@
-10dbc278708cd2cce7fef90738082dbe31750d93e44b5fa5413a9a32dae7703a
\ No newline at end of file
+1b528e31f8c62797e0814568b520c0680ff23a2ee877ca6aa70a167d40ebdf80
\ No newline at end of file
index 25afa79910edd07ad5b40ec4961b087ebb2a2a69..bd65c6f2b8768fedf27253d51ea1c849ee836e27 100644 (file)
@@ -1074,7 +1074,6 @@ typedef struct ColModeOpts {
 } ColModeOpts;
 #define ColModeOpts_default { 60, 0, 0 }
 #define ColModeOpts_default_qbox { 60, 1, 0 }
-#define ColModeOpts_default_qwbox { 60, 1, 1 }
 
 /*
 ** State information about the database connection is contained in an
@@ -3187,28 +3186,27 @@ static void print_box_row_separator(
 ** the last line, write a NULL into *pzTail. (*pzTail is not allocated.)
 */
 static char *translateForDisplayAndDup(
-  const unsigned char *z,
-  const unsigned char **pzTail,
-  int mxWidth,
-  u8 bWordWrap
+  const unsigned char *z,            /* Input text to be transformed */
+  const unsigned char **pzTail,      /* OUT: Tail of the input for next line */
+  int mxWidth,                       /* Max width.  0 means no limit */
+  u8 bWordWrap                       /* If true, avoid breaking mid-word */
 ){
-  int i, j, n; /* in-index, code-skip, code-count */
-  int iLastWhite = 0, nLastWhite = 0;
-  unsigned char *zOut;
+  int i;                 /* Input bytes consumed */
+  int j;                 /* Output bytes generated */
+  int k;                 /* Input bytes to be displayed */
+  int n;                 /* Output column number */
+  unsigned char *zOut;   /* Output text */
+
   if( z==0 ){
     *pzTail = 0;
     return 0;
   }
   if( mxWidth<0 ) mxWidth = -mxWidth;
   if( mxWidth==0 ) mxWidth = 1000000;
-  i = j= n = 0;
+  i = j = n = 0;
   while( n<mxWidth ){
     if( z[i]>=' ' ){
       n++;
-      if( IsSpace(z[i]) ){
-        iLastWhite = i;
-        nLastWhite = n;
-      }
       do{ i++; j++; }while( (z[i]&0xc0)==0x80 );
       continue;
     }
@@ -3222,10 +3220,24 @@ static char *translateForDisplayAndDup(
     }
     break;
   }
-  if( bWordWrap && iLastWhite>0 && n>=mxWidth ){
-    /* Will word wrap only if it is requested and can do any good. */
-    mxWidth = nLastWhite;
-    i = iLastWhite;
+  if( n>=mxWidth && bWordWrap  ){
+    /* Perhaps try to back up to a better place to break the line */
+    for(k=i; k>i/2; k--){
+      if( isspace(z[k-1]) ) break;
+    }
+    if( k<=i/2 ){
+      for(k=i; k>i/2; k--){
+        if( isalnum(z[k-1])!=isalnum(z[k]) ) break;
+      }
+    }
+    if( k<=i/2 ){
+      k = i;
+    }else{
+      i = k;
+      while( z[i]==' ' ) i++;
+    }
+  }else{
+    k = i;
   }
   if( n>=mxWidth && z[i]>=' ' ){
    *pzTail = &z[i];
@@ -3239,7 +3251,7 @@ static char *translateForDisplayAndDup(
   zOut = malloc( j+1 );
   shell_check_oom(zOut);
   i = j = n = 0;
-  while( n<mxWidth ){
+  while( i<k ){
     if( z[i]>=' ' ){
       n++;
       do{ zOut[j++] = z[i++]; }while( (z[i]&0xc0)==0x80 );
@@ -3321,6 +3333,7 @@ static void exec_prepared_stmt_columnar(
   const unsigned char **azNextLine = 0;
   int bNextLine = 0;
   int bMultiLineRowExists = 0;
+  int bw = p->cmOpts.bWordWrap;
 
   rc = sqlite3_step(pStmt);
   if( rc!=SQLITE_ROW ) return;
@@ -3354,11 +3367,9 @@ static void exec_prepared_stmt_columnar(
   }
   for(i=0; i<nColumn; i++){
     const unsigned char *zNotUsed;
-    u8 bw = 0;
     int wx = p->colWidth[i];
     if( wx==0 ){
       wx = p->cmOpts.iWrap;
-      bw = p->cmOpts.bWordWrap;
     }
     if( wx<0 ) wx = -wx;
     uz = (const unsigned char*)sqlite3_column_name(pStmt,i);
@@ -3377,11 +3388,9 @@ static void exec_prepared_stmt_columnar(
     abRowDiv[nRow] = 1;
     nRow++;
     for(i=0; i<nColumn; i++){
-      u8 bw = 0;
       int wx = p->colWidth[i];
       if( wx==0 ){
         wx = p->cmOpts.iWrap;
-        bw = p->cmOpts.bWordWrap;
       }
       if( wx<0 ) wx = -wx;
       if( useNextLine ){
@@ -4307,14 +4316,14 @@ static const char *(azHelp[]) = {
   "     list        Values delimited by \"|\"",
   "     markdown    Markdown table format",
   "     qbox        Shorthand for \"box --width 60 --quote\"",
-  "     qwbox       Shorthand for \"box --width 60 --wordwrap on --quote\"",
   "     quote       Escape answers as for SQL",
   "     table       ASCII-art table",
   "     tabs        Tab-separated values",
   "     tcl         TCL list elements",
   "   OPTIONS: (for columnar modes or insert mode):",
   "     --wrap N       Wrap output lines to no longer than N characters",
-  "     --wordwrap B   Wrap or not at word boundaries per B (on/off) ",
+  "     --wordwrap B   Wrap or not at word boundaries per B (on/off)",
+  "     --ww           Shorthand for \"--wordwrap 1\"",
   "     --quote        Quote output text as SQL literals",
   "     --noquote      Do not quote output text",
   "     TABLE          The name of SQL table used for \"insert\" mode",
@@ -9106,6 +9115,8 @@ static int do_meta_command(char *zLine, ShellState *p){
       const char *z = azArg[i];
       if( optionMatch(z,"wrap") && i+1<nArg ){
         cmOpts.iWrap = integerValue(azArg[++i]);
+      }else if( optionMatch(z,"ww") ){
+        cmOpts.bWordWrap = 1;
       }else if( optionMatch(z,"wordwrap") && i+1<nArg ){
         cmOpts.bWordWrap = (u8)booleanValue(azArg[++i]);
       }else if( optionMatch(z,"quote") ){
@@ -9114,17 +9125,13 @@ static int do_meta_command(char *zLine, ShellState *p){
         cmOpts.bQuote = 0;
       }else if( zMode==0 ){
         zMode = z;
-        /* Apply defaults for qbox and qwbox pseudo-modes. If that
+        /* Apply defaults for qbox pseudo-mods. If that
          * overwrites already-set values, user was informed of this.
          */
         if( strcmp(z, "qbox")==0 ){
           ColModeOpts cmo = ColModeOpts_default_qbox;
           zMode = "box";
           cmOpts = cmo;
-        }else if( strcmp(z, "qwbox")==0 ){
-          ColModeOpts cmo = ColModeOpts_default_qwbox;
-          zMode = "box";
-          cmOpts = cmo;
         }
       }else if( zTabname==0 ){
         zTabname = z;
@@ -9134,7 +9141,8 @@ static int do_meta_command(char *zLine, ShellState *p){
                             "  --noquote\n"
                             "  --quote\n"
                             "  --wordwrap on/off\n"
-                            "  --wrap N\n");
+                            "  --wrap N\n"
+                            "  --ww\n");
         rc = 1;
         goto meta_command_exit;
       }else{
@@ -9215,7 +9223,7 @@ static int do_meta_command(char *zLine, ShellState *p){
     }else{
       raw_printf(stderr, "Error: mode should be one of: "
          "ascii box column csv html insert json line list markdown "
-         "qbox quote qwbox table tabs tcl\n");
+         "qbox quote table tabs tcl\n");
       rc = 1;
     }
     p->cMode = p->mode;
index 122d38dfa79d7467cd75eb555947005238cce244..745990a7c9227ccc405cd114880a76a5e3d0e427 100644 (file)
@@ -205,10 +205,10 @@ do_test shell1-2.2.4 {
 } {0 {}}
 do_test shell1-2.2.5 {
   catchcmd "test.db" ".mode \"insert FOO"
-} {1 {Error: mode should be one of: ascii box column csv html insert json line list markdown qbox quote qwbox table tabs tcl}}
+} {1 {Error: mode should be one of: ascii box column csv html insert json line list markdown qbox quote table tabs tcl}}
 do_test shell1-2.2.6 {
   catchcmd "test.db" ".mode \'insert FOO"
-} {1 {Error: mode should be one of: ascii box column csv html insert json line list markdown qbox quote qwbox table tabs tcl}}
+} {1 {Error: mode should be one of: ascii box column csv html insert json line list markdown qbox quote table tabs tcl}}
 
 # check multiple tokens, and quoted tokens
 do_test shell1-2.3.1 {
@@ -236,7 +236,7 @@ do_test shell1-2.3.7 {
 # check quoted args are unquoted
 do_test shell1-2.4.1 {
   catchcmd "test.db" ".mode FOO"
-} {1 {Error: mode should be one of: ascii box column csv html insert json line list markdown qbox quote qwbox table tabs tcl}}
+} {1 {Error: mode should be one of: ascii box column csv html insert json line list markdown qbox quote table tabs tcl}}
 do_test shell1-2.4.2 {
   catchcmd "test.db" ".mode csv"
 } {0 {}}
@@ -437,7 +437,7 @@ do_test shell1-3.13.1 {
 } {0 {current output mode: list}}
 do_test shell1-3.13.2 {
   catchcmd "test.db" ".mode FOO"
-} {1 {Error: mode should be one of: ascii box column csv html insert json line list markdown qbox quote qwbox table tabs tcl}}
+} {1 {Error: mode should be one of: ascii box column csv html insert json line list markdown qbox quote table tabs tcl}}
 do_test shell1-3.13.3 {
   catchcmd "test.db" ".mode csv"
 } {0 {}}