]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add experimental support for the 'test_fs' test module on Win32. testFsWin32
authormistachkin <mistachkin@noemail.net>
Mon, 30 Nov 2015 23:29:07 +0000 (23:29 +0000)
committermistachkin <mistachkin@noemail.net>
Mon, 30 Nov 2015 23:29:07 +0000 (23:29 +0000)
FossilOrigin-Name: f3ffb3aeea95712e92919fd5071741327add9643

Makefile.in
Makefile.msc
main.mk
manifest
manifest.uuid
src/test_fs.c
src/test_windirent.c [new file with mode: 0644]
src/test_windirent.h [new file with mode: 0644]
test/vtabH.test

index eaf021b4129954b3eb1d944872a7b69eb165c9a1..f8766ac8f7665c11711149366b2736336f1a95ce 100644 (file)
@@ -402,6 +402,7 @@ TESTSRC = \
   $(TOP)/src/test_tclvar.c \
   $(TOP)/src/test_thread.c \
   $(TOP)/src/test_vfs.c \
+  $(TOP)/src/test_windirent.c \
   $(TOP)/src/test_wsd.c       \
   $(TOP)/ext/fts3/fts3_term.c \
   $(TOP)/ext/fts3/fts3_test.c \
index 57fba11c53e1cb223aeae81a65e8261cb35c1624..5c72001532a2cb9ee0104b7f0f6589046227e9c4 100644 (file)
@@ -1071,6 +1071,7 @@ TESTSRC = \
   $(TOP)\src\test_tclvar.c \
   $(TOP)\src\test_thread.c \
   $(TOP)\src\test_vfs.c \
+  $(TOP)\src\test_windirent.c \
   $(TOP)\src\test_wsd.c \
   $(TOP)\ext\fts3\fts3_term.c \
   $(TOP)\ext\fts3\fts3_test.c \
diff --git a/main.mk b/main.mk
index 838e0753d99f327a47c27897969a9f45be6cfb02..f3a37dc1945e9046bf5d8d1e402459ab7412235d 100644 (file)
--- a/main.mk
+++ b/main.mk
@@ -312,6 +312,7 @@ TESTSRC = \
   $(TOP)/src/test_tclvar.c \
   $(TOP)/src/test_thread.c \
   $(TOP)/src/test_vfs.c \
+  $(TOP)/src/test_windirent.c \
   $(TOP)/src/test_wsd.c
 
 # Extensions to be statically loaded.
index 135ade46f13c287342d1bd669a2e9635470efa87..885c09aea0c10d581daf9cc9a971b8a5b16b8827 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,8 +1,8 @@
-C Add\sthe\sSQLITE_PRINTF_PRECISION_LIMIT\scompile-time\soption.
-D 2015-11-30T22:52:14.011
-F Makefile.in d828db6afa6c1fa060d01e33e4674408df1942a1
+C Add\sexperimental\ssupport\sfor\sthe\s'test_fs'\stest\smodule\son\sWin32.
+D 2015-11-30T23:29:07.971
+F Makefile.in 23d9a63484a383fc64951b25ef44067930f98dc6
 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
-F Makefile.msc e928e68168df69b353300ac87c10105206653a03
+F Makefile.msc e8fdca1cb89a1b58b5f4d3a130ea9a3d28cb314d
 F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7
 F VERSION 8b9d3ac6f1962f94e06ba05462422a544f9c4e36
 F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
@@ -263,7 +263,7 @@ F ext/userauth/userauth.c 5fa3bdb492f481bbc1709fc83c91ebd13460c69e
 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
 F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
 F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60
-F main.mk ae99be5eb22933b1ecf80f94d41d25a3ea80aaf3
+F main.mk 9001039f432baeba1074e2d1885f3dfd572b8636
 F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83
 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271
 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504
@@ -366,7 +366,7 @@ F src/test_btree.c 2e9978eca99a9a4bfa8cae949efb00886860a64f
 F src/test_config.c f2824de39f59d8d621e2d6ec5cc67006d000b2eb
 F src/test_demovfs.c 0de72c2c89551629f58486fde5734b7d90758852
 F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc
-F src/test_fs.c 9a56a587ce1db424af430d5ff650b5736b498238
+F src/test_fs.c aab47ac456316502faa265daadf9ac832fea12b9
 F src/test_func.c 0d9c25956152adefee8881c6fadc8354793764d0
 F src/test_hexio.c abfdecb6fa58c354623978efceb088ca18e379cd
 F src/test_init.c 66b33120ffe9cd853b5a905ec850d51151337b32
@@ -393,6 +393,8 @@ F src/test_tclvar.c d86412527da65468ee6fa1b8607c65d0af736bc4
 F src/test_thread.c af391ec03d23486dffbcc250b7e58e073f172af9
 F src/test_vfs.c 3b65d42e18b262805716bd96178c81da8f2d9283
 F src/test_vfstrace.c bab9594adc976cbe696ff3970728830b4c5ed698
+F src/test_windirent.c 8f5fada630348558d5745b334702f301da1ffc61
+F src/test_windirent.h b12055cab6227f7be10f5c19296f67c60cc5e2a5
 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
 F src/threads.c bbfb74450643cb5372a43ad4f6cffd7e9dfcecb0
 F src/tokenize.c 5606871a377f390af7040ec3c12e0d183512d785
@@ -1274,7 +1276,7 @@ F test/vtabC.test 4528f459a13136f982e75614d120aef165f17292
 F test/vtabD.test 05b3f1d77117271671089e48719524b676842e96
 F test/vtabE.test d5024aa42754962f6bb0afd261681686488e7afe
 F test/vtabF.test fd5ad376f5a34fe0891df1f3cddb4fe7c3eb077e
-F test/vtabH.test 186f118d6a4dd25fdb36adfd471993003f83790c
+F test/vtabH.test 2803a8773d1017ac93bbec6900fc7c35bb56c1c3
 F test/vtabI.test 751b07636700dbdea328e4265b6077ccd6811a3f
 F test/vtab_alter.test 9e374885248f69e251bdaacf480b04a197f125e5
 F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8
@@ -1406,7 +1408,10 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f
 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P bb1e2c4df0b81327923f121dd6c002845486a314
-R d3b18adc3009f6c25adcd36c4f052eab
-U drh
-Z 7ba0fba490eff520c14229730eb61dd8
+P ecad75d69e0d5c83dd3584d363e557e84b65f7f2
+R b2c7ca19fb46e255338240c0ac77a2e4
+T *branch * testFsWin32
+T *sym-testFsWin32 *
+T -sym-trunk *
+U mistachkin
+Z b75cf97131a1f035edfb9c37c590fcf6
index 3749928415a343ac239e9079408a70cc9ed51372..2659aede2428422d7baee5dca7e9e4a1571ef4bd 100644 (file)
@@ -1 +1 @@
-ecad75d69e0d5c83dd3584d363e557e84b65f7f2
\ No newline at end of file
+f3ffb3aeea95712e92919fd5071741327add9643
\ No newline at end of file
index 213b65689a3a9030e884c188bf4c26269a2ef31b..de332fa2f5e65ceeeff582ad70d25f4351320620 100644 (file)
 #if SQLITE_OS_UNIX
 # include <unistd.h>
 # include <dirent.h>
+# ifndef DIRENT
+#  define DIRENT dirent
+# endif
 #endif
 #if SQLITE_OS_WIN
 # include <io.h>
+# include "test_windirent.h"
+# ifndef S_ISREG
+#  define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
+# endif
 #endif
 
 #ifndef SQLITE_OMIT_VIRTUALTABLE
@@ -116,7 +123,7 @@ struct FsdirCsr {
   char *zDir;                     /* Buffer containing directory scanned */
   DIR *pDir;                      /* Open directory */
   sqlite3_int64 iRowid;
-  struct dirent entry;            /* Current entry */
+  struct DIRENT entry;            /* Current entry */
 };
 
 /*
@@ -220,7 +227,7 @@ static int fsdirNext(sqlite3_vtab_cursor *cur){
   FsdirCsr *pCsr = (FsdirCsr*)cur;
 
   if( pCsr->pDir ){
-    struct dirent *pRes = 0;
+    struct DIRENT *pRes = 0;
     readdir_r(pCsr->pDir, &pCsr->entry, &pRes);
     if( pRes==0 ){
       closedir(pCsr->pDir);
@@ -461,15 +468,34 @@ static int fstreeFilter(
   int rc;
   const char *zSql = 
 "WITH r(d) AS ("
-"  SELECT CASE WHEN dir='/' THEN '' ELSE dir END || '/' || name "
-"    FROM fsdir WHERE dir=? AND name NOT LIKE '.%'"
+"  SELECT CASE WHEN dir=?2 THEN ?3 ELSE dir END || '/' || name "
+"    FROM fsdir WHERE dir=?1 AND name NOT LIKE '.%'"
 "  UNION ALL"
 "  SELECT dir || '/' || name FROM r, fsdir WHERE dir=d AND name NOT LIKE '.%'"
 ") SELECT d FROM r;";
 
-  const char *zDir = "/";
-  int nDir = 1;
-  char aWild[2] = {'\0', '\0' };
+  char *zRoot;
+  int nRoot;
+  char *zPrefix;
+  int nPrefix;
+  const char *zDir;
+  int nDir;
+  char aWild[2] = { '\0', '\0' };
+
+#if SQLITE_OS_WIN
+  zRoot = sqlite3_mprintf("%s%c", getenv("SystemDrive"), '/');
+  nRoot = strlen(zRoot);
+  zPrefix = sqlite3_mprintf("%s", getenv("SystemDrive"));
+  nPrefix = strlen(zPrefix);
+#else
+  zRoot = "/";
+  nRoot = 1;
+  zPrefix = "";
+  nPrefix = 0;
+#endif
+
+  zDir = zRoot;
+  nDir = nRoot;
 
   fstreeCloseFd(pCsr);
   sqlite3_finalize(pCsr->pStmt);
@@ -490,9 +516,9 @@ static int fstreeFilter(
         break;
     }
 
-    if( zQuery[0]=='/' ){
+    if( sqlite3_strnicmp(zQuery, zPrefix, nPrefix)==0 ){
       int i;
-      for(i=1; zQuery[i]; i++){
+      for(i=nPrefix; zQuery[i]; i++){
         if( zQuery[i]==aWild[0] || zQuery[i]==aWild[1] ) break;
         if( zQuery[i]=='/' ) nDir = i;
       }
@@ -501,6 +527,13 @@ static int fstreeFilter(
   }
 
   sqlite3_bind_text(pCsr->pStmt, 1, zDir, nDir, SQLITE_TRANSIENT);
+  sqlite3_bind_text(pCsr->pStmt, 2, zRoot, nRoot, SQLITE_TRANSIENT);
+  sqlite3_bind_text(pCsr->pStmt, 3, zPrefix, nPrefix, SQLITE_TRANSIENT);
+
+#if SQLITE_OS_WIN
+  sqlite3_free(zPrefix);
+  sqlite3_free(zRoot);
+#endif
 
   return fstreeNext(pVtabCursor); 
 }
diff --git a/src/test_windirent.c b/src/test_windirent.c
new file mode 100644 (file)
index 0000000..11d7dc0
--- /dev/null
@@ -0,0 +1,157 @@
+/*
+** 2015 November 30
+**
+** The author disclaims copyright to this source code.  In place of
+** a legal notice, here is a blessing:
+**
+**    May you do good and not evil.
+**    May you find forgiveness for yourself and forgive others.
+**    May you share freely, never taking more than you give.
+**
+*************************************************************************
+** This file contains code to implement most of the opendir() family of
+** POSIX functions on Win32 using the MSVCRT.
+*/
+
+#if defined(_WIN32) && defined(_MSC_VER)
+
+#include "test_windirent.h"
+
+/*
+** Implementation of the POSIX opendir() function using the MSVCRT.
+*/
+LPDIR opendir(
+  const char *dirname
+){
+  struct _finddata_t data;
+  LPDIR dirp = (LPDIR)sqlite3_malloc(sizeof(DIR));
+  SIZE_T namesize = sizeof(data.name) / sizeof(data.name[0]);
+
+  if( dirp==NULL ) return NULL;
+  memset(dirp, 0, sizeof(DIR));
+
+  /* TODO: Remove this if Unix-style root paths are not used. */
+  if( sqlite3_stricmp(dirname, "/")==0 ){
+    dirname = getenv("SystemDrive");
+  }
+
+  _snprintf(data.name, namesize, "%s\\*", dirname);
+  dirp->d_handle = _findfirst(data.name, &data);
+
+  if( dirp->d_handle==BAD_INTPTR_T ){
+    closedir(dirp);
+    return NULL;
+  }
+
+  /* TODO: Remove this block to allow hidden and system files. */
+  if( data.attrib&_A_HIDDEN || data.attrib&_A_SYSTEM ){
+    if( _findnext(dirp->d_handle, &data)==-1 ){
+      closedir(dirp);
+      return NULL;
+    }
+  }
+
+  dirp->d_first.d_attributes = data.attrib;
+  strncpy(dirp->d_first.d_name, data.name, NAME_MAX);
+  dirp->d_first.d_name[NAME_MAX] = '\0';
+
+  return dirp;
+}
+
+/*
+** Implementation of the POSIX readdir() function using the MSVCRT.
+*/
+LPDIRENT readdir(
+  LPDIR dirp
+){
+  struct _finddata_t data;
+
+  if( dirp==NULL ) return NULL;
+
+  if( dirp->d_first.d_ino==0 ){
+    dirp->d_first.d_ino++;
+    dirp->d_next.d_ino++;
+
+    return &dirp->d_first;
+  }
+
+next:
+
+  if( _findnext(dirp->d_handle, &data)==-1 ) return NULL;
+
+  /* TODO: Remove this block to allow hidden and system files. */
+  if( data.attrib&_A_HIDDEN ) goto next;
+  if( data.attrib&_A_SYSTEM ) goto next;
+
+  dirp->d_next.d_ino++;
+  dirp->d_next.d_attributes = data.attrib;
+  strncpy(dirp->d_next.d_name, data.name, NAME_MAX);
+  dirp->d_next.d_name[NAME_MAX] = '\0';
+
+  return &dirp->d_next;
+}
+
+/*
+** Implementation of the POSIX readdir_r() function using the MSVCRT.
+*/
+INT readdir_r(
+  LPDIR dirp,
+  LPDIRENT entry,
+  LPDIRENT *result
+){
+  struct _finddata_t data;
+
+  if( dirp==NULL ) return EBADF;
+
+  if( dirp->d_first.d_ino==0 ){
+    dirp->d_first.d_ino++;
+    dirp->d_next.d_ino++;
+
+    entry->d_ino = dirp->d_first.d_ino;
+    entry->d_attributes = dirp->d_first.d_attributes;
+    strncpy(entry->d_name, dirp->d_first.d_name, NAME_MAX);
+    entry->d_name[NAME_MAX] = '\0';
+
+    *result = entry;
+    return 0;
+  }
+
+next:
+
+  if( _findnext(dirp->d_handle, &data)==-1 ){
+    *result = NULL;
+    return ENOENT;
+  }
+
+  /* TODO: Remove this block to allow hidden and system files. */
+  if( data.attrib&_A_HIDDEN ) goto next;
+  if( data.attrib&_A_SYSTEM ) goto next;
+
+  entry->d_ino = (ino_t)-1; /* not available */
+  entry->d_attributes = data.attrib;
+  strncpy(entry->d_name, data.name, NAME_MAX);
+  entry->d_name[NAME_MAX] = '\0';
+
+  *result = entry;
+  return 0;
+}
+
+/*
+** Implementation of the POSIX closedir() function using the MSVCRT.
+*/
+INT closedir(
+  LPDIR dirp
+){
+  INT result = 0;
+
+  if( dirp==NULL ) return EINVAL;
+
+  if( dirp->d_handle!=NULL_INTPTR_T && dirp->d_handle!=BAD_INTPTR_T ){
+    result = _findclose(dirp->d_handle);
+  }
+
+  sqlite3_free(dirp);
+  return result;
+}
+
+#endif /* defined(WIN32) && defined(_MSC_VER) */
diff --git a/src/test_windirent.h b/src/test_windirent.h
new file mode 100644 (file)
index 0000000..0b8d1a7
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+** 2015 November 30
+**
+** The author disclaims copyright to this source code.  In place of
+** a legal notice, here is a blessing:
+**
+**    May you do good and not evil.
+**    May you find forgiveness for yourself and forgive others.
+**    May you share freely, never taking more than you give.
+**
+*************************************************************************
+** This file contains declarations for most of the opendir() family of
+** POSIX functions on Win32 using the MSVCRT.
+*/
+
+#if defined(_WIN32) && defined(_MSC_VER)
+
+/*
+** We need several data types from the Windows SDK header.
+*/
+
+#define WIN32_LEAN_AND_MEAN
+#include "windows.h"
+
+/*
+** We need several support functions from the SQLite core.
+*/
+
+#include "sqlite3.h"
+
+/*
+** We need several things from the ANSI and MSVCRT headers.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <io.h>
+#include <limits.h>
+
+/*
+** We may need to provide the "ino_t" type.
+*/
+
+#ifndef INO_T_DEFINED
+  #define INO_T_DEFINED
+  typedef unsigned short ino_t;
+#endif
+
+/*
+** We need to define "NAME_MAX" if it was not present in "limits.h".
+*/
+
+#ifndef NAME_MAX
+#  ifdef FILENAME_MAX
+#    define NAME_MAX (FILENAME_MAX)
+#  else
+#    define NAME_MAX (260)
+#  endif
+#endif
+
+/*
+** We need to define "NULL_INTPTR_T" and "BAD_INTPTR_T".
+*/
+
+#ifndef NULL_INTPTR_T
+#  define NULL_INTPTR_T ((intptr_t)(0))
+#endif
+
+#ifndef BAD_INTPTR_T
+#  define BAD_INTPTR_T ((intptr_t)(-1))
+#endif
+
+/*
+** We need to provide the necessary structures and related types.
+*/
+
+typedef struct DIRENT DIRENT;
+typedef struct DIR DIR;
+typedef DIRENT *LPDIRENT;
+typedef DIR *LPDIR;
+
+struct DIRENT {
+  ino_t d_ino;               /* Sequence number, do not use. */
+  unsigned d_attributes;     /* Win32 file attributes. */
+  char d_name[NAME_MAX + 1]; /* Name within the directory. */
+};
+
+struct DIR {
+  intptr_t d_handle; /* Value returned by "_findfirst". */
+  DIRENT d_first;    /* DIRENT constructed based on "_findfirst". */
+  DIRENT d_next;     /* DIRENT constructed based on "_findnext". */
+};
+
+/*
+** Finally, we can provide the function prototypes for the opendir(),
+** readdir(), readdir_r(), and closedir() POSIX functions.
+*/
+
+extern LPDIR opendir(const char *dirname);
+extern LPDIRENT readdir(LPDIR dirp);
+extern INT readdir_r(LPDIR dirp, LPDIRENT entry, LPDIRENT *result);
+extern INT closedir(LPDIR dirp);
+
+#endif /* defined(WIN32) && defined(_MSC_VER) */
index 7216677d2abbea6e30510f4ceed7951f3901fc36..6034d95fa15939e050b0240a0c757f7f21404350 100644 (file)
@@ -108,7 +108,7 @@ foreach ::tclvar_set_omit {0 1} {
 
 #-------------------------------------------------------------------------
 #
-if {$::tcl_platform(platform)=="unix"} {
+if {1} {
   reset_db
   register_fs_module db
   do_execsql_test 3.0 {
@@ -116,11 +116,41 @@ if {$::tcl_platform(platform)=="unix"} {
     SELECT name FROM fsdir WHERE dir = '.' AND name = '.'
   } {test.db .}
   
+  proc list_root_files {} {
+    if {$::tcl_platform(platform) eq "windows"} {
+      set res [list]
+      foreach name [glob -directory $::env(SystemDrive)/ -- *] {
+        if {[string index [file tail $name] 0] eq "."} continue
+        lappend res $name
+      }
+      return $res
+    } else {
+      return [exec ls -U /]
+    }
+  }
+
+  proc list_files { pattern } {
+    if {$::tcl_platform(platform) eq "windows"} {
+      set res [list]
+      foreach name [glob -nocomplain $pattern] {
+        if {[string index [file tail $name] 0] eq "."} continue
+        lappend res $name
+      }
+      return $res
+    } else {
+      return [glob -nocomplain $pattern]
+    }
+  }
+
   # Read the first 5 entries from the root directory.
   #
   set res [list]
-  foreach p [lrange [exec ls -U /] 0 4] {
-    lappend res "/$p"
+  foreach p [lrange [list_root_files] 0 4] {
+    if {$::tcl_platform(platform) eq "windows"} {
+      lappend res $p
+    } else {
+      lappend res "/$p"
+    }
   }
   do_execsql_test 3.1 {
     SELECT path FROM fstree LIMIT 5;
@@ -130,7 +160,7 @@ if {$::tcl_platform(platform)=="unix"} {
   #
   proc contents {pattern} {
     set res [list]
-    foreach f [glob -nocomplain $pattern] {
+    foreach f [list_files $pattern] {
       lappend res $f
       if {[file isdir $f]} {
         set res [concat $res [contents "$f/*"]]