]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Factor the code for ".mode" out of do_meta_command() and into its own
authordrh <>
Tue, 11 Nov 2025 00:44:25 +0000 (00:44 +0000)
committerdrh <>
Tue, 11 Nov 2025 00:44:25 +0000 (00:44 +0000)
subroutine, to show how the new infrastructure makes this easy.  We need
to do the same for all the dot-commands.  At the same time, add the
-textjsonb option to .mode.

FossilOrigin-Name: b48aa054df488747a7db56faf1cd0da42e322edff60650b9187448e58eb12def

manifest
manifest.uuid
src/shell.c.in

index 2925737c6ec358580007d8ddd843281300524d79..7382392ac0b41a80d9d83fe154accfecb80f624f 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Bug\sfixes.\s\sAll\stests\sare\snow\spassing.
-D 2025-11-11T00:21:26.959
+C Factor\sthe\scode\sfor\s".mode"\sout\sof\sdo_meta_command()\sand\sinto\sits\sown\nsubroutine,\sto\sshow\show\sthe\snew\sinfrastructure\smakes\sthis\seasy.\s\sWe\sneed\nto\sdo\sthe\ssame\sfor\sall\sthe\sdot-commands.\s\sAt\sthe\ssame\stime,\sadd\sthe\n-textjsonb\soption\sto\s.mode.
+D 2025-11-11T00:44:25.681
 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
@@ -735,7 +735,7 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c
 F src/resolve.c 5616fbcf3b833c7c705b24371828215ad0925d0c0073216c4f153348d5753f0a
 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
 F src/select.c ba9cd07ffa3277883c1986085f6ddc4320f4d35d5f212ab58df79a7ecc1a576a
-F src/shell.c.in 41eafc6ecd66a9cb99b6efb522c3d25eb074078e689fe8ffcd722f38c23dd1d9
+F src/shell.c.in e3f804207b35a78be6a72c794291b771de7fafdc319fce3f9f2979bbf14d7488
 F src/sqlite.h.in 7403a952a8f1239de7525b73c4e3a0f9540ec0607ed24fec887f5832642d44b8
 F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479
 F src/sqlite3ext.h 7f236ca1b175ffe03316d974ef57df79b3938466c28d2f95caef5e08c57f3a52
@@ -2173,8 +2173,8 @@ F tool/version-info.c 33d0390ef484b3b1cb685d59362be891ea162123cea181cb8e6d2cf6dd
 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7
 F tool/warnings.sh d924598cf2f55a4ecbc2aeb055c10bd5f48114793e7ba25f9585435da29e7e98
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P 8cc581e53c2ab15bd311e082048b7c57b03a754d25c0b4beead08a3362ac1c7a
-R 5ec50f9665eadf1d8e44e1c03a2dcff7
+P a0fc99a3bdd12f9ac69511c1aea2bd9a3d5de593d44b4a732cfc8f48e0931c76
+R 89d6866f71ef4d7cd775ab4a25b5defa
 U drh
-Z 2e2be373085f7686f8e083362b123b95
+Z d05d0d77f90346dd26288eb7ce7ea406
 # Remove this line to create a well-formed Fossil manifest.
index 23f7f7ed407942c3f43e08ec3be1b59783b868b3..8b673851dc294f65207fdb97eda6b86eb43fd6c4 100644 (file)
@@ -1 +1 @@
-a0fc99a3bdd12f9ac69511c1aea2bd9a3d5de593d44b4a732cfc8f48e0931c76
+b48aa054df488747a7db56faf1cd0da42e322edff60650b9187448e58eb12def
index 68d6678c1a3dd627139ce28c2df69a316f3066c8..93d2ae414d051a52e865da3b688a55eeae37e89b 100644 (file)
@@ -6981,6 +6981,191 @@ static int faultsim_callback(int iArg){
   return faultsim_state.iErr;
 }
 
+/*
+** COMMAND:  .mode
+*/
+static int dotCmdMode(ShellState *p){
+  int nArg = p->dot.nArg;
+  char **azArg = p->dot.azArg;
+  const char *zMode = 0;
+  const char *zTabname = 0;
+  int i, n2;
+  int chng = 0;       /* 0x01:  change to cmopts.  0x02:  Any other change */
+
+  for(i=1; i<nArg; i++){
+    const char *z = azArg[i];
+    if( optionMatch(z,"wrap") && i+1<nArg ){
+      int w = integerValue(azArg[++i]);
+      if( w<(-QRF_MAX_WIDTH) ) w = -QRF_MAX_WIDTH;
+      if( w>QRF_MAX_WIDTH ) w = QRF_MAX_WIDTH;
+      p->mode.spec.mxColWidth = w;
+      chng |= 1;
+    }else if( optionMatch(z,"ww") ){
+      p->mode.spec.bWordWrap = QRF_Yes;
+      chng |= 1;
+    }else if( optionMatch(z,"wordwrap") ){
+      if( i+1>=nArg ){
+        dotCmdError(p, i, "missing argument", 0);
+        return 1;
+      }
+      p->mode.spec.bWordWrap = (u8)booleanValue(azArg[++i]) ? QRF_Yes : QRF_No;
+      chng |= 1;
+    }else if( optionMatch(z,"quote") ){
+      p->mode.spec.eText = QRF_TEXT_Sql;
+      p->mode.spec.eBlob = QRF_BLOB_Sql;
+      chng |= 1;
+    }else if( optionMatch(z,"textjsonb") ){
+      if( i+1>=nArg ){
+        dotCmdError(p, i, "missing argument", 0);
+        return 1;
+      }
+      p->mode.spec.bTextJsonb = (u8)booleanValue(azArg[++i]) ? QRF_Yes : QRF_No;
+      chng |= 1;
+    }else if( optionMatch(z,"noquote") ){
+      p->mode.spec.eText = QRF_Auto;
+      p->mode.spec.eBlob = QRF_Auto;
+      chng |= 1;
+    }else if( optionMatch(z,"escape") ){
+      /* See similar code at tag-20250224-1 */
+      if( i+1>=nArg ){
+        dotCmdError(p, i, "missing argument", 0);
+        return 1;
+      }
+      const char *zEsc = azArg[++i];
+      int k;
+      for(k=0; k<ArraySize(qrfEscNames); k++){
+        if( sqlite3_stricmp(zEsc,qrfEscNames[k])==0 ){
+          p->mode.spec.eEsc = k;
+          chng |= 2;
+          break;
+        }
+      }
+      if( k>=ArraySize(qrfEscNames) ){
+        sqlite3_fprintf(stderr, "unknown control character escape mode \"%s\""
+                                " - choices:", zEsc);
+        for(k=0; k<ArraySize(qrfEscNames); k++){
+          sqlite3_fprintf(stderr, " %s", qrfEscNames[k]);
+        }
+        sqlite3_fprintf(stderr, "\n");
+        return 1;
+      }
+    }else if( zMode==0 ){
+      zMode = z;
+      /* Apply defaults for qbox pseudo-mode.  If that
+       * overwrites already-set values, user was informed of this.
+       */
+      chng |= 1;
+      if( cli_strcmp(z, "qbox")==0 ){
+        zMode = "box";
+        p->mode.spec.eText = QRF_TEXT_Sql;
+        p->mode.spec.eBlob = QRF_BLOB_Sql;
+      }
+    }else if( zTabname==0 ){
+      zTabname = z;
+    }else if( z[0]=='-' ){
+      sqlite3_fprintf(stderr,"unknown option: %s\n", z);
+      eputz("options:\n"
+            "  --escape MODE\n"
+            "  --noquote\n"
+            "  --quote\n"
+            "  --wordwrap on/off\n"
+            "  --wrap N\n"
+            "  --ww\n");
+      return 1;
+    }else{
+      sqlite3_fprintf(stderr,"extra argument: \"%s\"\n", z);
+      return 1;
+    }
+  }
+  if( !chng ){
+    if( p->mode.eMode==MODE_Column
+     || p->mode.eMode==MODE_Box
+     || p->mode.eMode==MODE_Table
+     || p->mode.eMode==MODE_Markdown
+    ){
+      sqlite3_fprintf(p->out, "current output mode: %s",
+                      modeDescr[p->mode.eMode]);
+      if( p->mode.spec.mxColWidth ){
+        sqlite3_fprintf(p->out, " --wrap %d",
+           p->mode.spec.mxColWidth);
+      }else{
+        sqlite3_fprintf(p->out, " --wrap off");
+      }
+      sqlite3_fprintf(p->out, " --wordwrap %s --%squote --escape %s\n",
+            p->mode.spec.bWordWrap==QRF_Yes ? "on" : "off",
+            p->mode.spec.eText==QRF_TEXT_Sql ? "" : "no",
+            qrfEscNames[p->mode.spec.eEsc==QRF_ESC_Auto?
+                QRF_ESC_Ascii:p->mode.spec.eEsc]
+      );
+    }else{
+      sqlite3_fprintf(p->out,
+            "current output mode: %s --escape %s\n",
+            modeDescr[p->mode.eMode],
+            qrfEscNames[p->mode.spec.eEsc==QRF_ESC_Auto?
+                QRF_ESC_Ascii:p->mode.spec.eEsc]
+      );
+    }
+  }
+  if( zMode==0 ){
+    zMode = modeDescr[p->mode.eMode];
+  }
+  n2 = strlen30(zMode);
+  if( cli_strncmp(zMode,"lines",n2)==0 ){
+    p->mode.eMode = MODE_Line;
+    modeSetStr(&p->mode.spec.zRowSep, SEP_Row);
+  }else if( cli_strncmp(zMode,"columns",n2)==0 ){
+    p->mode.eMode = MODE_Column;
+    modeSetStr(&p->mode.spec.zRowSep, SEP_Row);
+  }else if( cli_strncmp(zMode,"list",n2)==0 ){
+    p->mode.eMode = MODE_List;
+    modeSetStr(&p->mode.spec.zColumnSep, SEP_Column);
+    modeSetStr(&p->mode.spec.zRowSep, SEP_Row);
+  }else if( cli_strncmp(zMode,"html",n2)==0 ){
+    p->mode.eMode = MODE_Html;
+  }else if( cli_strncmp(zMode,"tcl",n2)==0 ){
+    p->mode.eMode = MODE_Tcl;
+    modeSetStr(&p->mode.spec.zColumnSep, SEP_Space);
+    modeSetStr(&p->mode.spec.zRowSep, SEP_Row);
+  }else if( cli_strncmp(zMode,"csv",n2)==0 ){
+    p->mode.eMode = MODE_Csv;
+    modeSetStr(&p->mode.spec.zColumnSep, SEP_Comma);
+    modeSetStr(&p->mode.spec.zRowSep, SEP_CrLf);
+  }else if( cli_strncmp(zMode,"tabs",n2)==0 ){
+    p->mode.eMode = MODE_List;
+    modeSetStr(&p->mode.spec.zColumnSep, SEP_Tab);
+  }else if( cli_strncmp(zMode,"insert",n2)==0 ){
+    p->mode.eMode = MODE_Insert;
+    modeSetStr(&p->mode.spec.zTableName, zTabname);
+  }else if( cli_strncmp(zMode,"quote",n2)==0 ){
+    p->mode.eMode = MODE_Quote;
+    modeSetStr(&p->mode.spec.zColumnSep, SEP_Comma);
+    modeSetStr(&p->mode.spec.zRowSep, SEP_Row);
+  }else if( cli_strncmp(zMode,"ascii",n2)==0 ){
+    p->mode.eMode = MODE_Ascii;
+    modeSetStr(&p->mode.spec.zColumnSep, SEP_Unit);
+    modeSetStr(&p->mode.spec.zRowSep, SEP_Record);
+  }else if( cli_strncmp(zMode,"markdown",n2)==0 ){
+    p->mode.eMode = MODE_Markdown;
+  }else if( cli_strncmp(zMode,"table",n2)==0 ){
+    p->mode.eMode = MODE_Table;
+  }else if( cli_strncmp(zMode,"box",n2)==0 ){
+    p->mode.eMode = MODE_Box;
+  }else if( cli_strncmp(zMode,"count",n2)==0 ){
+    p->mode.eMode = MODE_Count;
+  }else if( cli_strncmp(zMode,"off",n2)==0 ){
+    p->mode.eMode = MODE_Off;
+  }else if( cli_strncmp(zMode,"json",n2)==0 ){
+    p->mode.eMode = MODE_Json;
+  }else{
+    eputz("Error: mode should be one of: "
+          "ascii box column csv html insert json line list markdown "
+          "qbox quote table tabs tcl\n");
+    return 1;
+  }
+  return 0;
+}
+
+
 /*
 ** If an input line begins with "." then invoke this routine to
 ** process that line.
@@ -8394,168 +8579,7 @@ static int do_meta_command(const char *zLine, ShellState *p){
   }else
 
   if( c=='m' && cli_strncmp(azArg[0], "mode", n)==0 ){
-    const char *zMode = 0;
-    const char *zTabname = 0;
-    int i, n2;
-    int chng = 0;       /* 0x01:  change to cmopts.  0x02:  Any other change */
-    for(i=1; i<nArg; i++){
-      const char *z = azArg[i];
-      if( optionMatch(z,"wrap") && i+1<nArg ){
-        int w = integerValue(azArg[++i]);
-        if( w<(-QRF_MAX_WIDTH) ) w = -QRF_MAX_WIDTH;
-        if( w>QRF_MAX_WIDTH ) w = QRF_MAX_WIDTH;
-        p->mode.spec.mxColWidth = w;
-        chng |= 1;
-      }else if( optionMatch(z,"ww") ){
-        p->mode.spec.bWordWrap = QRF_Yes;
-        chng |= 1;
-      }else if( optionMatch(z,"wordwrap") && i+1<nArg ){
-        p->mode.spec.bWordWrap = (u8)booleanValue(azArg[++i]) ? QRF_Yes : QRF_No;
-        chng |= 1;
-      }else if( optionMatch(z,"quote") ){
-        p->mode.spec.eText = QRF_TEXT_Sql;
-        p->mode.spec.eBlob = QRF_BLOB_Sql;
-        chng |= 1;
-      }else if( optionMatch(z,"noquote") ){
-        p->mode.spec.eText = QRF_Auto;
-        p->mode.spec.eBlob = QRF_Auto;
-        chng |= 1;
-      }else if( optionMatch(z,"escape") && i+1<nArg ){
-        /* See similar code at tag-20250224-1 */
-        const char *zEsc = azArg[++i];
-        int k;
-        for(k=0; k<ArraySize(qrfEscNames); k++){
-          if( sqlite3_stricmp(zEsc,qrfEscNames[k])==0 ){
-            p->mode.spec.eEsc = k;
-            chng |= 2;
-            break;
-          }
-        }
-        if( k>=ArraySize(qrfEscNames) ){
-          sqlite3_fprintf(stderr, "unknown control character escape mode \"%s\""
-                                  " - choices:", zEsc);
-          for(k=0; k<ArraySize(qrfEscNames); k++){
-            sqlite3_fprintf(stderr, " %s", qrfEscNames[k]);
-          }
-          sqlite3_fprintf(stderr, "\n");
-          rc = 1;
-          goto meta_command_exit;
-        }
-      }else if( zMode==0 ){
-        zMode = z;
-        /* Apply defaults for qbox pseudo-mode.  If that
-         * overwrites already-set values, user was informed of this.
-         */
-        chng |= 1;
-        if( cli_strcmp(z, "qbox")==0 ){
-          zMode = "box";
-          p->mode.spec.eText = QRF_TEXT_Sql;
-          p->mode.spec.eBlob = QRF_BLOB_Sql;
-        }
-      }else if( zTabname==0 ){
-        zTabname = z;
-      }else if( z[0]=='-' ){
-        sqlite3_fprintf(stderr,"unknown option: %s\n", z);
-        eputz("options:\n"
-              "  --escape MODE\n"
-              "  --noquote\n"
-              "  --quote\n"
-              "  --wordwrap on/off\n"
-              "  --wrap N\n"
-              "  --ww\n");
-        rc = 1;
-        goto meta_command_exit;
-      }else{
-        sqlite3_fprintf(stderr,"extra argument: \"%s\"\n", z);
-        rc = 1;
-        goto meta_command_exit;
-      }
-    }
-    if( !chng ){
-      if( p->mode.eMode==MODE_Column
-       || p->mode.eMode==MODE_Box
-       || p->mode.eMode==MODE_Table
-       || p->mode.eMode==MODE_Markdown
-      ){
-        sqlite3_fprintf(p->out, "current output mode: %s",
-                        modeDescr[p->mode.eMode]);
-        if( p->mode.spec.mxColWidth ){
-          sqlite3_fprintf(p->out, " --wrap %d",
-             p->mode.spec.mxColWidth);
-        }else{
-          sqlite3_fprintf(p->out, " --wrap off");
-        }
-        sqlite3_fprintf(p->out, " --wordwrap %s --%squote --escape %s\n",
-              p->mode.spec.bWordWrap==QRF_Yes ? "on" : "off",
-              p->mode.spec.eText==QRF_TEXT_Sql ? "" : "no",
-              qrfEscNames[p->mode.spec.eEsc==QRF_ESC_Auto?
-                  QRF_ESC_Ascii:p->mode.spec.eEsc]
-        );
-      }else{
-        sqlite3_fprintf(p->out,
-              "current output mode: %s --escape %s\n",
-              modeDescr[p->mode.eMode],
-              qrfEscNames[p->mode.spec.eEsc==QRF_ESC_Auto?
-                  QRF_ESC_Ascii:p->mode.spec.eEsc]
-        );
-      }
-    }
-    if( zMode==0 ){
-      zMode = modeDescr[p->mode.eMode];
-    }
-    n2 = strlen30(zMode);
-    if( cli_strncmp(zMode,"lines",n2)==0 ){
-      p->mode.eMode = MODE_Line;
-      modeSetStr(&p->mode.spec.zRowSep, SEP_Row);
-    }else if( cli_strncmp(zMode,"columns",n2)==0 ){
-      p->mode.eMode = MODE_Column;
-      modeSetStr(&p->mode.spec.zRowSep, SEP_Row);
-    }else if( cli_strncmp(zMode,"list",n2)==0 ){
-      p->mode.eMode = MODE_List;
-      modeSetStr(&p->mode.spec.zColumnSep, SEP_Column);
-      modeSetStr(&p->mode.spec.zRowSep, SEP_Row);
-    }else if( cli_strncmp(zMode,"html",n2)==0 ){
-      p->mode.eMode = MODE_Html;
-    }else if( cli_strncmp(zMode,"tcl",n2)==0 ){
-      p->mode.eMode = MODE_Tcl;
-      modeSetStr(&p->mode.spec.zColumnSep, SEP_Space);
-      modeSetStr(&p->mode.spec.zRowSep, SEP_Row);
-    }else if( cli_strncmp(zMode,"csv",n2)==0 ){
-      p->mode.eMode = MODE_Csv;
-      modeSetStr(&p->mode.spec.zColumnSep, SEP_Comma);
-      modeSetStr(&p->mode.spec.zRowSep, SEP_CrLf);
-    }else if( cli_strncmp(zMode,"tabs",n2)==0 ){
-      p->mode.eMode = MODE_List;
-      modeSetStr(&p->mode.spec.zColumnSep, SEP_Tab);
-    }else if( cli_strncmp(zMode,"insert",n2)==0 ){
-      p->mode.eMode = MODE_Insert;
-      modeSetStr(&p->mode.spec.zTableName, zTabname);
-    }else if( cli_strncmp(zMode,"quote",n2)==0 ){
-      p->mode.eMode = MODE_Quote;
-      modeSetStr(&p->mode.spec.zColumnSep, SEP_Comma);
-      modeSetStr(&p->mode.spec.zRowSep, SEP_Row);
-    }else if( cli_strncmp(zMode,"ascii",n2)==0 ){
-      p->mode.eMode = MODE_Ascii;
-      modeSetStr(&p->mode.spec.zColumnSep, SEP_Unit);
-      modeSetStr(&p->mode.spec.zRowSep, SEP_Record);
-    }else if( cli_strncmp(zMode,"markdown",n2)==0 ){
-      p->mode.eMode = MODE_Markdown;
-    }else if( cli_strncmp(zMode,"table",n2)==0 ){
-      p->mode.eMode = MODE_Table;
-    }else if( cli_strncmp(zMode,"box",n2)==0 ){
-      p->mode.eMode = MODE_Box;
-    }else if( cli_strncmp(zMode,"count",n2)==0 ){
-      p->mode.eMode = MODE_Count;
-    }else if( cli_strncmp(zMode,"off",n2)==0 ){
-      p->mode.eMode = MODE_Off;
-    }else if( cli_strncmp(zMode,"json",n2)==0 ){
-      p->mode.eMode = MODE_Json;
-    }else{
-      eputz("Error: mode should be one of: "
-            "ascii box column csv html insert json line list markdown "
-            "qbox quote table tabs tcl\n");
-      rc = 1;
-    }
+    rc = dotCmdMode(p);
   }else
 
 #ifndef SQLITE_SHELL_FIDDLE