Fossil

Check-in [a8f7a8ac24]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:simplify switching between widechar and unicode variant of dirent
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | restore-win95
Files: files | file ages | folders
SHA1: a8f7a8ac24ea067db5af3cd3a7087ac167bee3a8
User & Date: jan.nijtmans 2012-09-12 22:01:56.392
Context
2012-09-13
07:17
merge trunk check-in: 0930ed2085 user: jan.nijtmans tags: restore-win95
2012-09-12
22:01
simplify switching between widechar and unicode variant of dirent check-in: a8f7a8ac24 user: jan.nijtmans tags: restore-win95
20:55
allow MSVC build without -DUNICODE as well check-in: eede5db7c3 user: jan.nijtmans tags: restore-win95
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/file.c.
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
  }
  rc = blob_compare(&onDisk, pContent);
  blob_reset(&onDisk);
  return rc==0;
}

/*
** Portable unicode implementation of opendir()
*/
#if INTERFACE

#if defined(_WIN32) && defined(UNICODE)
# include <dirent.h>
# define FOSSIL_DIR _WDIR
# define fossil_dirent _wdirent
# define fossil_opendir _wopendir
# define fossil_readdir _wreaddir
# define fossil_closedir _wclosedir
#else
# include <dirent.h>
# define FOSSIL_DIR DIR
# define fossil_dirent dirent
# define fossil_opendir opendir
# define fossil_readdir readdir
# define fossil_closedir closedir
#endif

#endif /* INTERFACE */



/**************************************************************************
** The following routines translate between MBCS and UTF8 on windows.
** Since everything is always UTF8 on unix, these routines are no-ops
** there.
*/








|



<
|
|
|
|
|
|
<
<
|
<
<
<
<



<
<







1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013

1014
1015
1016
1017
1018
1019


1020




1021
1022
1023


1024
1025
1026
1027
1028
1029
1030
  }
  rc = blob_compare(&onDisk, pContent);
  blob_reset(&onDisk);
  return rc==0;
}

/*
** Portable unicode implementation of opendir() for win32
*/
#if INTERFACE


#include <dirent.h>
#if defined(_WIN32) && defined(UNICODE)
#  define dirent _wdirent
#  define opendir _wopendir
#  define readdir _wreaddir
#  define closedir _wclosedir


#  define DIR _WDIR




#endif

#endif /* INTERFACE */



/**************************************************************************
** The following routines translate between MBCS and UTF8 on windows.
** Since everything is always UTF8 on unix, these routines are no-ops
** there.
*/

Changes to src/rebuild.c.
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
}

/*
** Recursively read all files from the directory zPath and install
** every file read as a new artifact in the repository.
*/
void recon_read_dir(char *zPath){
  FOSSIL_DIR *d;
  struct fossil_dirent *pEntry;
  Blob aContent; /* content of the just read artifact */
  static int nFileRead = 0;
  void *zUnicodePath;
  char *zUtf8Name;

  zUnicodePath = fossil_utf8_to_mbcs(zPath);
  d = fossil_opendir(zUnicodePath);
  if( d ){
    while( (pEntry=fossil_readdir(d))!=0 ){
      Blob path;
      char *zSubpath;

      if( pEntry->d_name[0]=='.' ){
        continue;
      }
      zUtf8Name = fossil_mbcs_to_utf8(pEntry->d_name);







|
|


|


|
|

|







815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
}

/*
** Recursively read all files from the directory zPath and install
** every file read as a new artifact in the repository.
*/
void recon_read_dir(char *zPath){
  DIR *d;
  struct dirent *pEntry;
  Blob aContent; /* content of the just read artifact */
  static int nFileRead = 0;
  void *zMbcsPath;
  char *zUtf8Name;

  zMbcsPath = fossil_utf8_to_mbcs(zPath);
  d = opendir(zMbcsPath);
  if( d ){
    while( (pEntry=readdir(d))!=0 ){
      Blob path;
      char *zSubpath;

      if( pEntry->d_name[0]=='.' ){
        continue;
      }
      zUtf8Name = fossil_mbcs_to_utf8(pEntry->d_name);
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
      content_put(&aContent);
      blob_reset(&path);
      blob_reset(&aContent);
      free(zSubpath);
      fossil_print("\r%d", ++nFileRead);
      fflush(stdout);
    }
    fossil_closedir(d);
  }else {
    fossil_panic("encountered error %d while trying to open \"%s\".",
                  errno, g.argv[3]);
  }
  fossil_mbcs_free(zUnicodePath);
}

/*
** COMMAND: reconstruct*
**
** Usage: %fossil reconstruct FILENAME DIRECTORY
**







|




|







851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
      content_put(&aContent);
      blob_reset(&path);
      blob_reset(&aContent);
      free(zSubpath);
      fossil_print("\r%d", ++nFileRead);
      fflush(stdout);
    }
    closedir(d);
  }else {
    fossil_panic("encountered error %d while trying to open \"%s\".",
                  errno, g.argv[3]);
  }
  fossil_mbcs_free(zMbcsPath);
}

/*
** COMMAND: reconstruct*
**
** Usage: %fossil reconstruct FILENAME DIRECTORY
**
Changes to src/vfile.c.
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
** Files whose names begin with "." are omitted unless allFlag is true.
**
** Any files or directories that match the glob pattern pIgnore are 
** excluded from the scan.  Name matching occurs after the first
** nPrefix characters are elided from the filename.
*/
void vfile_scan(Blob *pPath, int nPrefix, int allFlag, Glob *pIgnore){
  FOSSIL_DIR *d;
  int origSize;
  const char *zDir;
  struct fossil_dirent *pEntry;
  int skipAll = 0;
  static Stmt ins;
  static int depth = 0;
  void *zMbcs;

  origSize = blob_size(pPath);
  if( pIgnore ){







|


|







374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
** Files whose names begin with "." are omitted unless allFlag is true.
**
** Any files or directories that match the glob pattern pIgnore are 
** excluded from the scan.  Name matching occurs after the first
** nPrefix characters are elided from the filename.
*/
void vfile_scan(Blob *pPath, int nPrefix, int allFlag, Glob *pIgnore){
  DIR *d;
  int origSize;
  const char *zDir;
  struct dirent *pEntry;
  int skipAll = 0;
  static Stmt ins;
  static int depth = 0;
  void *zMbcs;

  origSize = blob_size(pPath);
  if( pIgnore ){
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
       "  WHERE NOT EXISTS(SELECT 1 FROM vfile WHERE pathname=:file)"
    );
  }
  depth++;

  zDir = blob_str(pPath);
  zMbcs = fossil_utf8_to_mbcs(zDir);
  d = fossil_opendir(zMbcs);
  if( d ){
    while( (pEntry=fossil_readdir(d))!=0 ){
      char *zPath;
      char *zUtf8;
      if( pEntry->d_name[0]=='.' ){
        if( !allFlag ) continue;
        if( pEntry->d_name[1]==0 ) continue;
        if( pEntry->d_name[1]=='.' && pEntry->d_name[2]==0 ) continue;
      }







|

|







401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
       "  WHERE NOT EXISTS(SELECT 1 FROM vfile WHERE pathname=:file)"
    );
  }
  depth++;

  zDir = blob_str(pPath);
  zMbcs = fossil_utf8_to_mbcs(zDir);
  d = opendir(zMbcs);
  if( d ){
    while( (pEntry=readdir(d))!=0 ){
      char *zPath;
      char *zUtf8;
      if( pEntry->d_name[0]=='.' ){
        if( !allFlag ) continue;
        if( pEntry->d_name[1]==0 ) continue;
        if( pEntry->d_name[1]=='.' && pEntry->d_name[2]==0 ) continue;
      }
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
      }else if( file_wd_isfile_or_link(zPath) ){
        db_bind_text(&ins, ":file", &zPath[nPrefix+1]);
        db_step(&ins);
        db_reset(&ins);
      }
      blob_resize(pPath, origSize);
    }
    fossil_closedir(d);
  }
  fossil_mbcs_free(zMbcs);

  depth--;
  if( depth==0 ){
    db_finalize(&ins);
  }







|







428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
      }else if( file_wd_isfile_or_link(zPath) ){
        db_bind_text(&ins, ":file", &zPath[nPrefix+1]);
        db_step(&ins);
        db_reset(&ins);
      }
      blob_resize(pPath, origSize);
    }
    closedir(d);
  }
  fossil_mbcs_free(zMbcs);

  depth--;
  if( depth==0 ){
    db_finalize(&ins);
  }
Changes to win/include/dirent.h.
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL TONI RONKKO BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 *
 * Aug 30, 2012, Jan Nijtmans
 * Remove rewinddir() (not necessary for fossil)
 * Replace everything with its wide-character variant.
 *
 * Mar 15, 2011, Toni Ronkko
 * Defined FILE_ATTRIBUTE_DEVICE for MSVC 6.0.
 *
 * Aug 11, 2010, Toni Ronkko
 * Added d_type and d_namlen fields to dirent structure.  The former is
 * especially useful for determining whether directory entry represents a







|
<
|







18
19
20
21
22
23
24
25

26
27
28
29
30
31
32
33
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL TONI RONKKO BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 *
 * Sept 12, 2012, Jan Nijtmans

 * Switchable wide-character variant.
 *
 * Mar 15, 2011, Toni Ronkko
 * Defined FILE_ATTRIBUTE_DEVICE for MSVC 6.0.
 *
 * Aug 11, 2010, Toni Ronkko
 * Added d_type and d_namlen fields to dirent structure.  The former is
 * especially useful for determining whether directory entry represents a
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162

163
164
165


166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189

190
191
192
193
194
195
196
#define	S_ISDIR(mode)  (((mode) & S_IFMT) == S_IFDIR)
#define	S_ISREG(mode)  (((mode) & S_IFMT) == S_IFREG)
#define	S_ISLNK(mode)  (((mode) & S_IFMT) == S_IFLNK)
#define	S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK)
#define	S_ISCHR(mode)  (((mode) & S_IFMT) == S_IFCHR)
#define	S_ISBLK(mode)  (((mode) & S_IFMT) == S_IFBLK)

#ifdef __cplusplus
extern "C" {
#endif

#ifdef UNICODE
#  define dirent _wdirent
#  define opendir _wopendir
#  define readdir _wreaddir
#  define closedir _wclosedir

#  define DIR _WDIR
#else
#  define wchar_t char


#endif

typedef struct dirent
{
   wchar_t d_name[MAX_PATH + 1];               /* File name */
   size_t d_namlen;                            /* Length of name without \0 */
   int d_type;                                 /* File type */
} dirent;


typedef struct DIR
{
   dirent           curentry;                  /* Current directory entry */
   WIN32_FIND_DATA  find_data;                 /* Private file data */
   int              cached;                    /* True if data is valid */
   HANDLE           search_handle;             /* Win32 search handle */
   wchar_t          patt[MAX_PATH + 3];        /* Initial directory name */
} DIR;


/* Forward declarations */
static DIR *opendir(const wchar_t *dirname);
static struct dirent *readdir(DIR *dirp);
static int closedir(DIR *dirp);



/* Use the new safe string functions introduced in Visual Studio 2005 */
#if defined(_MSC_VER) && _MSC_VER >= 1400
# define DIRENT_STRNCPY(dest,src,size) _tcsncpy_s((dest),(size),(src),_TRUNCATE)
#else
# define DIRENT_STRNCPY(dest,src,size) _tcsncpy((dest),(src),(size))







<
<
<
<





>

|
|
>
>




|











|




|


>







146
147
148
149
150
151
152




153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
#define	S_ISDIR(mode)  (((mode) & S_IFMT) == S_IFDIR)
#define	S_ISREG(mode)  (((mode) & S_IFMT) == S_IFREG)
#define	S_ISLNK(mode)  (((mode) & S_IFMT) == S_IFLNK)
#define	S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK)
#define	S_ISCHR(mode)  (((mode) & S_IFMT) == S_IFCHR)
#define	S_ISBLK(mode)  (((mode) & S_IFMT) == S_IFBLK)





#ifdef UNICODE
#  define dirent _wdirent
#  define opendir _wopendir
#  define readdir _wreaddir
#  define closedir _wclosedir
#  define rewinddir _wrewinddir
#  define DIR _WDIR
#endif

#ifdef __cplusplus
extern "C" {
#endif

typedef struct dirent
{
   TCHAR d_name[MAX_PATH + 1];                 /* File name */
   size_t d_namlen;                            /* Length of name without \0 */
   int d_type;                                 /* File type */
} dirent;


typedef struct DIR
{
   dirent           curentry;                  /* Current directory entry */
   WIN32_FIND_DATA  find_data;                 /* Private file data */
   int              cached;                    /* True if data is valid */
   HANDLE           search_handle;             /* Win32 search handle */
   TCHAR            patt[MAX_PATH + 3];        /* Initial directory name */
} DIR;


/* Forward declarations */
static DIR *opendir(const TCHAR *dirname);
static struct dirent *readdir(DIR *dirp);
static int closedir(DIR *dirp);
static void rewinddir(DIR* dirp);


/* Use the new safe string functions introduced in Visual Studio 2005 */
#if defined(_MSC_VER) && _MSC_VER >= 1400
# define DIRENT_STRNCPY(dest,src,size) _tcsncpy_s((dest),(size),(src),_TRUNCATE)
#else
# define DIRENT_STRNCPY(dest,src,size) _tcsncpy((dest),(src),(size))
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219


/*****************************************************************************
 * Open directory stream DIRNAME for read and return a pointer to the
 * internal working area that is used to retrieve individual directory
 * entries.
 */
static DIR *opendir(const wchar_t *dirname)
{
   DIR *dirp;

   /* ensure that the resulting search pattern will be a valid file name */
   if (dirname == NULL) {
      DIRENT_SET_ERRNO (ENOENT);
      return NULL;







|







204
205
206
207
208
209
210
211
212
213
214
215
216
217
218


/*****************************************************************************
 * Open directory stream DIRNAME for read and return a pointer to the
 * internal working area that is used to retrieve individual directory
 * entries.
 */
static DIR *opendir(const TCHAR *dirname)
{
   DIR *dirp;

   /* ensure that the resulting search pattern will be a valid file name */
   if (dirname == NULL) {
      DIRENT_SET_ERRNO (ENOENT);
      return NULL;
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244

      /*
       * Convert relative directory name to an absolute one.  This
       * allows rewinddir() to function correctly when the current working
       * directory is changed between opendir() and rewinddir().
       */
      if (GetFullPathName (dirname, MAX_PATH, dirp->patt, NULL)) {
         wchar_t *p;

         /* append the search pattern "\\*\0" to the directory name */
         p = _tcschr (dirp->patt, '\0');
         if (dirp->patt < p  &&  *(p-1) != '\\'  &&  *(p-1) != ':') {
           *p++ = '\\';
         }
         *p++ = '*';







|







229
230
231
232
233
234
235
236
237
238
239
240
241
242
243

      /*
       * Convert relative directory name to an absolute one.  This
       * allows rewinddir() to function correctly when the current working
       * directory is changed between opendir() and rewinddir().
       */
      if (GetFullPathName (dirname, MAX_PATH, dirp->patt, NULL)) {
         TCHAR *p;

         /* append the search pattern "\\*\0" to the directory name */
         p = _tcschr (dirp->patt, '\0');
         if (dirp->patt < p  &&  *(p-1) != '\\'  &&  *(p-1) != ':') {
           *p++ = '\\';
         }
         *p++ = '*';
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
         /* the very last entry has been processed or an error occured */
         FindClose (dirp->search_handle);
         dirp->search_handle = INVALID_HANDLE_VALUE;
         return NULL;
      }
   }

   /* copy as a unicode character string */
   DIRENT_STRNCPY ( dirp->curentry.d_name,
             dirp->find_data.cFileName,
             sizeof(dirp->curentry.d_name)/sizeof(dirp->curentry.d_name[0]) );
   dirp->curentry.d_name[MAX_PATH] = '\0';

   /* compute the length of name */
   dirp->curentry.d_namlen = _tcslen (dirp->curentry.d_name);

   /* determine file type */
   attr = dirp->find_data.dwFileAttributes;







|


|







299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
         /* the very last entry has been processed or an error occured */
         FindClose (dirp->search_handle);
         dirp->search_handle = INVALID_HANDLE_VALUE;
         return NULL;
      }
   }

   /* copy as a multibyte/unicode character string */
   DIRENT_STRNCPY ( dirp->curentry.d_name,
             dirp->find_data.cFileName,
             sizeof(dirp->curentry.d_name)/sizeof(TCHAR) );
   dirp->curentry.d_name[MAX_PATH] = '\0';

   /* compute the length of name */
   dirp->curentry.d_namlen = _tcslen (dirp->curentry.d_name);

   /* determine file type */
   attr = dirp->find_data.dwFileAttributes;
345
346
347
348
349
350
351



























352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
      dirp->search_handle = INVALID_HANDLE_VALUE;
   }

   /* release directory structure */
   free (dirp);
   return 0;
}




























#ifdef UNICODE
#  undef dirent
#  undef opendir
#  undef readdir
#  undef closedir
#  undef DIR
#else
#  undef wchar_t
#endif

#ifdef __cplusplus
}
#endif
#endif /*DIRENT_H*/







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







<
<






344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384


385
386
387
388
389
390
      dirp->search_handle = INVALID_HANDLE_VALUE;
   }

   /* release directory structure */
   free (dirp);
   return 0;
}

/*****************************************************************************
 * Resets the position of the directory stream to which dirp refers to the
 * beginning of the directory.  It also causes the directory stream to refer
 * to the current state of the corresponding directory, as a call to opendir()
 * would have done.  If dirp does not refer to a directory stream, the effect
 * is undefined.
 */
static void rewinddir(DIR* dirp)
{
   if (dirp != NULL) {
      /* release search handle */
      if (dirp->search_handle != INVALID_HANDLE_VALUE) {
         FindClose (dirp->search_handle);
      }

      /* open new search handle and retrieve the first entry */
      dirp->search_handle = FindFirstFile (dirp->patt, &dirp->find_data);
      if (dirp->search_handle != INVALID_HANDLE_VALUE) {
         /* a directory entry is now waiting in memory */
         dirp->cached = 1;
      } else {
         /* failed to re-open directory: no directory entry in memory */
         dirp->cached = 0;
      }
   }
}

#ifdef UNICODE
#  undef dirent
#  undef opendir
#  undef readdir
#  undef closedir
#  undef DIR


#endif

#ifdef __cplusplus
}
#endif
#endif /*DIRENT_H*/