]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Move non-console FILE* I/O to {Read,Write}File() on Win32. (This is a WIP. It builds...
authorlarrybr <larrybr@noemail.net>
Fri, 20 Sep 2024 02:08:33 +0000 (02:08 +0000)
committerlarrybr <larrybr@noemail.net>
Fri, 20 Sep 2024 02:08:33 +0000 (02:08 +0000)
FossilOrigin-Name: b769ed002794405f1967206b8b8aab4e449d297b0c34fc2d70e1dcc71d4c91b1

ext/consio/console_io.c
ext/consio/console_io.h
manifest
manifest.uuid

index 75324a34fd557ced6a557d83f81bd4229ced427d..39afce0565574bf9ad9241f7585d9ee4ce3491f5 100755 (executable)
@@ -64,6 +64,7 @@ static HANDLE handleOfFile(FILE *pf){
 #endif
 
 #ifndef SQLITE_CIO_NO_TRANSLATE
+
 typedef struct PerStreamTags {
 # if CIO_WIN_WC_XLATE
   HANDLE hx;
@@ -75,8 +76,9 @@ typedef struct PerStreamTags {
   FILE *pf;
 } PerStreamTags;
 
-/* Define NULL-like value for things which can validly be 0. */
+/* Define NULL-like value for FILE* which can validly be 0. */
 # define SHELL_INVALID_FILE_PTR ((FILE *)~0)
+
 # if CIO_WIN_WC_XLATE
 #  define SHELL_INVALID_CONS_MODE 0xFFFF0000
 # endif
@@ -88,7 +90,7 @@ typedef struct PerStreamTags {
 #  define PST_INITIALIZER { 0, SHELL_INVALID_FILE_PTR }
 # endif
 
-/* Quickly say whether a known output is going to the console. */
+/* Quickly say whether a known output is going to the console on Windows. */
 # if CIO_WIN_WC_XLATE
 static short pstReachesConsole(PerStreamTags *ppst){
   return (ppst->hx != INVALID_HANDLE_VALUE);
@@ -154,7 +156,7 @@ static ConsoleInfo consoleInfo = {
   SAC_NoConsole /* sacSetup */
 };
 
-SQLITE_INTERNAL_LINKAGE FILE* invalidFileStream = (FILE *)~0;
+FILE* invalidFileStream = SHELL_INVALID_FILE_PTR;
 
 # if CIO_WIN_WC_XLATE
 static void maybeSetupAsConsole(PerStreamTags *ppst, short odir){
@@ -296,6 +298,77 @@ SQLITE_INTERNAL_LINKAGE void setTextMode(FILE *pf, short bFlush){
 # define setTextMode(f, bFlush) do{ if((bFlush)) fflush(f); }while(0)
 #endif /* defined(SQLITE_CIO_NO_SETMODE) */
 
+
+#if CIO_WIN_WC_XLATE
+static struct FileAltIds {
+  int fd;
+  HANDLE fh;
+} altIdsOfFile(FILE *pf){
+  struct FileAltIds rv = { _fileno(pf) };
+  union { intptr_t osfh; HANDLE fh; } fid = {
+    (rv.fd>=0)? _get_osfhandle(rv.fd) : (intptr_t)INVALID_HANDLE_VALUE
+  };
+  rv.fh = fid.fh;
+  return rv;
+}
+
+SQLITE_INTERNAL_LINKAGE size_t
+cfWrite(const void *buf, size_t osz, size_t ocnt, FILE *pf){
+  size_t rv = 0;
+  struct FileAltIds fai = altIdsOfFile(pf);
+  int fmode = _setmode(fai.fd, _O_BINARY);
+  _setmode(fai.fd, fmode);
+  while( rv < ocnt ){
+    size_t nbo = osz;
+    while( nbo > 0 ){
+      DWORD dwno = (nbo>(1L<<24))? 1L<<24 : (DWORD)nbo;
+      BOOL wrc = TRUE;
+      BOOL genCR = (fmode & _O_TEXT)!=0;
+      if( genCR ){
+        const char *pnl = (const char*)memchr(buf, '\n', nbo);
+        if( pnl ) nbo = pnl - (const char*)buf;
+        else genCR = 0;
+      }
+      if( dwno>0 ) wrc = WriteFile(fai.fh, buf, dwno, 0,0);
+      if( genCR && wrc ){
+        wrc = WriteFile(fai.fh, "\r\n", 2, 0,0);
+        ++dwno; /* Skip over the LF */
+      }
+      if( !wrc ) return rv;
+      buf = (const char*)buf + dwno;
+      nbo -= dwno;
+    }
+    ++rv;
+  }
+  return rv;
+}
+
+/* An fgets() equivalent, using Win32 file API for actual input.
+** Input ends when given buffer is filled or a newline is read.
+** If the FILE object is in text mode, swallows 0x0D. (ASCII CR)
+** This is inefficient, reading single characters at a time.
+** With some buffering and complexity, this could be sped up.
+*/
+SQLITE_INTERNAL_LINKAGE char *
+cfGets(char *cBuf, int n, FILE *pf){
+  int nci = 0;
+  struct FileAltIds fai = altIdsOfFile(pf);
+  int fmode = _setmode(fai.fd, _O_BINARY);
+  BOOL eatCR = (fmode & _O_TEXT)!=0;
+  _setmode(fai.fd, fmode);
+  while( nci < n-1 ){
+    DWORD nr;
+    if( !ReadFile(fai.fh, cBuf+nci, 1, &nr, 0) || nr==0 ) break;
+    if( nr>0 && (!eatCR || cBuf[nci]!='\r') ){
+      nci += nr;
+      if( cBuf[nci-nr]=='\n' ) break;
+    }
+  }
+  if( nci < n ) cBuf[nci] = 0;
+  return (nci>0)? cBuf : 0;
+}
+#endif
+
 #ifndef SQLITE_CIO_NO_TRANSLATE
 # if CIO_WIN_WC_XLATE
 /* Write buffer cBuf as output to stream known to reach console,
@@ -330,6 +403,17 @@ static int conioVmPrintf(PerStreamTags *ppst, const char *zFormat, va_list ap){
     return rv;
   }else return 0;
 }
+
+/* For {f,o,e}PrintfUtf8() when stream is not known to reach console. */
+static int streamVmPrintf(FILE *pso, const char *zFormat, va_list ap){
+  char *z = sqlite3_vmprintf(zFormat, ap);
+  if( z ){
+    int rv = (int)cfWrite(z, (int)strlen(z), 1, pso);
+    sqlite3_free(z);
+    return rv;
+  }else return 0;
+}
+
 # endif /* CIO_WIN_WC_XLATE */
 
 # ifdef CONSIO_GET_EMIT_STREAM
@@ -392,10 +476,10 @@ SQLITE_INTERNAL_LINKAGE int oPrintfUtf8(const char *zFormat, ...){
   if( pstReachesConsole(ppst) ){
     rv = conioVmPrintf(ppst, zFormat, ap);
   }else{
-# endif
-    rv = vfprintf(pfOut, zFormat, ap);
-# if CIO_WIN_WC_XLATE
+    rv = streamVmPrintf(pfOut, zFormat, ap);
   }
+# else
+  rv = vfprintf(pfOut, zFormat, ap);
 # endif
   va_end(ap);
   return rv;
@@ -417,10 +501,10 @@ SQLITE_INTERNAL_LINKAGE int ePrintfUtf8(const char *zFormat, ...){
   if( pstReachesConsole(ppst) ){
     rv = conioVmPrintf(ppst, zFormat, ap);
   }else{
-# endif
-    rv = vfprintf(pfErr, zFormat, ap);
-# if CIO_WIN_WC_XLATE
+    rv = streamVmPrintf(pfErr, zFormat, ap);
   }
+# else
+  rv = vfprintf(pfErr, zFormat, ap);
 # endif
   va_end(ap);
   return rv;
@@ -443,10 +527,10 @@ SQLITE_INTERNAL_LINKAGE int fPrintfUtf8(FILE *pfO, const char *zFormat, ...){
     rv = conioVmPrintf(ppst, zFormat, ap);
     if( 0 == isKnownWritable(ppst->pf) ) restoreConsoleArb(ppst);
   }else{
-# endif
-    rv = vfprintf(pfO, zFormat, ap);
-# if CIO_WIN_WC_XLATE
+    rv = streamVmPrintf(pfO, zFormat, ap);
   }
+# else
+  rv = vfprintf(pfO, zFormat, ap);
 # endif
   va_end(ap);
   return rv;
@@ -468,10 +552,11 @@ SQLITE_INTERNAL_LINKAGE int fPutsUtf8(const char *z, FILE *pfO){
     if( 0 == isKnownWritable(ppst->pf) ) restoreConsoleArb(ppst);
     return rv;
   }else {
-# endif
-    return (fputs(z, pfO)<0)? 0 : (int)strlen(z);
-# if CIO_WIN_WC_XLATE
+    int rv = (int)cfWrite(z, 1, (int)strlen(z), pfO);
+    return (rv<0)? 0 : rv;
   }
+# else
+  return (fputs(z, pfO)<0)? 0 : (int)strlen(z);
 # endif
 }
 
@@ -487,10 +572,11 @@ SQLITE_INTERNAL_LINKAGE int ePutsUtf8(const char *z){
 # if CIO_WIN_WC_XLATE
   if( pstReachesConsole(ppst) ) return conZstrEmit(ppst, z, (int)strlen(z));
   else {
-# endif
-    return (fputs(z, pfErr)<0)? 0 : (int)strlen(z);
-# if CIO_WIN_WC_XLATE
+    int no = (int)cfWrite(z, 1, (int)strlen(z), pfErr);
+    return (no<0)? 0 : no;
   }
+# else
+  return (fputs(z, pfErr)<0)? 0 : (int)strlen(z);
 # endif
 }
 
@@ -506,10 +592,11 @@ SQLITE_INTERNAL_LINKAGE int oPutsUtf8(const char *z){
 # if CIO_WIN_WC_XLATE
   if( pstReachesConsole(ppst) ) return conZstrEmit(ppst, z, (int)strlen(z));
   else {
-# endif
-    return (fputs(z, pfOut)<0)? 0 : (int)strlen(z);
-# if CIO_WIN_WC_XLATE
+    int no = (int)cfWrite(z, 1, (int)strlen(z), pfOut);
+    return (no<0)? 0 : no;
   }
+# else
+  return (fputs(z, pfOut)<0)? 0 : (int)strlen(z);
 # endif
 }
 
@@ -567,10 +654,10 @@ fPutbUtf8(FILE *pfO, const char *cBuf, int nAccept){
     if( 0 == isKnownWritable(ppst->pf) ) restoreConsoleArb(ppst);
     return rv;
   }else {
-#  endif
-    return (int)fwrite(cBuf, 1, nAccept, pfO);
-#  if CIO_WIN_WC_XLATE
+    return (int)cfWrite(cBuf, 1, nAccept, pfO);
   }
+#  else
+  return (int)fwrite(cBuf, 1, nAccept, pfO);
 #  endif
 }
 # endif
@@ -588,101 +675,15 @@ oPutbUtf8(const char *cBuf, int nAccept){
   if( pstReachesConsole(ppst) ){
     return conZstrEmit(ppst, cBuf, nAccept);
   }else {
-# endif
-    return (int)fwrite(cBuf, 1, nAccept, pfOut);
-# if CIO_WIN_WC_XLATE
+    return (int)cfWrite(cBuf, 1, nAccept, pfOut);
   }
-# endif
-}
-
-/*
-** Flush the given output stream. Return non-zero for success, else 0.
-*/
-#if !defined(SQLITE_CIO_NO_FLUSH) && !defined(SQLITE_CIO_NO_SETMODE)
-SQLITE_INTERNAL_LINKAGE int
-fFlushBuffer(FILE *pfOut){
-# if CIO_WIN_WC_XLATE && !defined(SHELL_OMIT_FIO_DUPE)
-  return FlushFileBuffers(handleOfFile(pfOut))? 1 : 0;
 # else
-  return fflush(pfOut);
+  return (int)fwrite(cBuf, 1, nAccept, pfOut);
 # endif
 }
-#endif
-
-#if CIO_WIN_WC_XLATE \
-   && !defined(SHELL_OMIT_FIO_DUPE) \
-   && defined(SQLITE_USE_ONLY_WIN32)
-static struct FileAltIds {
-  int fd;
-  HANDLE fh;
-} altIdsOfFile(FILE *pf){
-  struct FileAltIds rv = { _fileno(pf) };
-  union { intptr_t osfh; HANDLE fh; } fid = {
-    (rv.fd>=0)? _get_osfhandle(rv.fd) : (intptr_t)INVALID_HANDLE_VALUE
-  };
-  rv.fh = fid.fh;
-  return rv;
-}
-
-SQLITE_INTERNAL_LINKAGE size_t
-cfWrite(const void *buf, size_t osz, size_t ocnt, FILE *pf){
-  size_t rv = 0;
-  struct FileAltIds fai = altIdsOfFile(pf);
-  int fmode = _setmode(fai.fd, _O_BINARY);
-  _setmode(fai.fd, fmode);
-  while( rv < ocnt ){
-    size_t nbo = osz;
-    while( nbo > 0 ){
-      DWORD dwno = (nbo>(1L<<24))? 1L<<24 : (DWORD)nbo;
-      BOOL wrc = TRUE;
-      BOOL genCR = (fmode & _O_TEXT)!=0;
-      if( genCR ){
-        const char *pnl = (const char*)memchr(buf, '\n', nbo);
-        if( pnl ) nbo = pnl - (const char*)buf;
-        else genCR = 0;
-      }
-      if( dwno>0 ) wrc = WriteFile(fai.fh, buf, dwno, 0,0);
-      if( genCR && wrc ){
-        wrc = WriteFile(fai.fh, "\r\n", 2, 0,0);
-        ++dwno; /* Skip over the LF */
-      }
-      if( !wrc ) return rv;
-      buf = (const char*)buf + dwno;
-      nbo += dwno;
-    }
-    ++rv;
-  }
-  return rv;
-}
-
-/* An fgets() equivalent, using Win32 file API for actual input.
-** Input ends when given buffer is filled or a newline is read.
-** If the FILE object is in text mode, swallows 0x0D. (ASCII CR)
-*/
-SQLITE_INTERNAL_LINKAGE char *
-cfGets(char *cBuf, int n, FILE *pf){
-  int nci = 0;
-  struct FileAltIds fai = altIdsOfFile(pf);
-  int fmode = _setmode(fai.fd, _O_BINARY);
-  BOOL eatCR = (fmode & _O_TEXT)!=0;
-  _setmode(fai.fd, fmode);
-  while( nci < n-1 ){
-    DWORD nr;
-    if( !ReadFile(fai.fh, cBuf+nci, 1, &nr, 0) || nr==0 ) break;
-    if( nr>0 && (!eatCR || cBuf[nci]!='\r') ){
-      nci += nr;
-      if( cBuf[nci-nr]=='\n' ) break;
-    }
-  }
-  if( nci < n ) cBuf[nci] = 0;
-  return (nci>0)? cBuf : 0;
-}
-# else
-#  define cfWrite(b,os,no,f) fwrite(b,os,no,f)
-#  define cfGets(b,n,f) fgets(b,n,f)
-# endif
 
 # ifdef CONSIO_EPUTB
+/* ePutbUtf8() might be omitted. (Error stream gets formatted output.) */
 SQLITE_INTERNAL_LINKAGE int
 ePutbUtf8(const char *cBuf, int nAccept){
   FILE *pfErr;
@@ -699,7 +700,23 @@ ePutbUtf8(const char *cBuf, int nAccept){
 #  endif
 }
 # endif /* defined(CONSIO_EPUTB) */
+#endif /* !defined(SQLITE_CIO_NO_TRANSLATE) */
+
+/*
+** Flush the given output stream. Return non-zero for success, else 0.
+*/
+#if !defined(SQLITE_CIO_NO_FLUSH) && !defined(SQLITE_CIO_NO_SETMODE)
+SQLITE_INTERNAL_LINKAGE int
+fFlushBuffer(FILE *pfOut){
+# if CIO_WIN_WC_XLATE && !defined(SHELL_OMIT_FIO_DUPE)
+  return FlushFileBuffers(handleOfFile(pfOut))? 1 : 0;
+# else
+  return fflush(pfOut);
+# endif
+}
+#endif
 
+#ifndef SQLITE_CIO_NO_TRANSLATE
 SQLITE_INTERNAL_LINKAGE char* fGetsUtf8(char *cBuf, int ncMax, FILE *pfIn){
   if( pfIn==0 ) pfIn = stdin;
 # if CIO_WIN_WC_XLATE
index 1affa15bad6f94d8ff3a5bc75de066fe9f7ecace..7950be8a5a15103a6acf0206ff89dda3df666e32 100644 (file)
@@ -120,7 +120,7 @@ SQLITE_INTERNAL_LINKAGE void SQLITE_CDECL consoleRestore( void );
 ** It is error to close a stream so designated, then, without
 ** designating another, use the corresponding {o,e}Emit(...).
 */
-SQLITE_INTERNAL_LINKAGE FILE *invalidFileStream;
+extern FILE *invalidFileStream;
 SQLITE_INTERNAL_LINKAGE FILE *setOutputStream(FILE *pf);
 # ifdef CONSIO_SET_ERROR_STREAM
 SQLITE_INTERNAL_LINKAGE FILE *setErrorStream(FILE *pf);
index 55e9207dbb482bf7ebd6ccfa162b1e4d9ae832cd..c21e86ae9e50c793ffa93b511aa224ec84113b89 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Cause\scfGets()\s(under\sSQLITE_USE_ONLY_WIN32)\sto\sbetter\semulate\sfgets().
-D 2024-09-03T02:09:13.849
+C Move\snon-console\sFILE*\sI/O\sto\s{Read,Write}File()\son\sWin32.\s(This\sis\sa\sWIP.\sIt\sbuilds\sbut\sneeds\smore\stesting.)
+D 2024-09-20T02:08:33.299
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -53,8 +53,8 @@ F ext/README.md fd5f78013b0a2bc6f0067afb19e6ad040e89a10179b4f6f03eee58fac5f169bd
 F ext/async/README.txt e12275968f6fde133a80e04387d0e839b0c51f91
 F ext/async/sqlite3async.c 6f247666b495c477628dd19364d279c78ea48cd90c72d9f9b98ad1aff3294f94
 F ext/async/sqlite3async.h 46b47c79357b97ad85d20d2795942c0020dc20c532114a49808287f04aa5309a
-F ext/consio/console_io.c d2b74afae8d301de2e8447b1045fcd33eb59df13bf581d906d99c74fe5d2b13f x
-F ext/consio/console_io.h b5ebe34aa15b357621ebbea3d3f2e2b24750d4280b5802516409e23947fd9ee5
+F ext/consio/console_io.c 64e33ce4e2ae389e0b424b52aa5536542d4ef1bf8fc3096c02fcdb88252d7ac1 x
+F ext/consio/console_io.h 6212909529c4ab3deeeee29db2d0b2b9cd5c881cc9dd51dede079273ce91db3d
 F ext/expert/README.md b321c2762bb93c18ea102d5a5f7753a4b8bac646cb392b3b437f633caf2020c3
 F ext/expert/expert.c d548d603a4cc9e61f446cc179c120c6713511c413f82a4a32b1e1e69d3f086a4
 F ext/expert/expert1.test 661f873fd451127edf822ef0d520088faa319135f6a15bd10be6801ac284ac9b
@@ -2210,8 +2210,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 164b1e1962aa1e16bdf52e9e86d4cf9c9e09220c0821932ac8e390e82074185f
-R 0ea7d1c943863a7b1da4b295016a8f50
+P 2d783524d1671d988ebb1b21c83de99c9f335963b6c20cf4df612f58c13da913
+R 87ebc55b97e725c152c1936c6291b015
 U larrybr
-Z 8cf571eafc534d90679b77113d98b6b5
+Z de6ab6cd993a2843b724bb0751411acd
 # Remove this line to create a well-formed Fossil manifest.
index 47b76c643eba5867877d454cc06e882cf9f3c9e3..7bd1171e43912b1ea23fba1b62ad9951035f8f62 100644 (file)
@@ -1 +1 @@
-2d783524d1671d988ebb1b21c83de99c9f335963b6c20cf4df612f58c13da913
+b769ed002794405f1967206b8b8aab4e449d297b0c34fc2d70e1dcc71d4c91b1