Changes On Branch msvc-broken
Not logged in

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

Changes In Branch msvc-broken Excluding Merge-Ins

This is equivalent to a diff from 208d67675c to d787bcd44a

2012-08-29
23:34
The --force flag change should have been on trunk. DRH should follow his own checklists! check-in: 5c420b1690 user: drh tags: trunk
23:33
Allow no-op merges with the --force flag. Closed-Leaf check-in: d787bcd44a user: drh tags: msvc-broken
22:37
found the cause of the crash!!!! check-in: 27905725de user: jan.nijtmans tags: msvc-broken
22:34
working part of [01a2f3a346] check-in: 14733d1519 user: jan.nijtmans tags: trunk
20:48
working part of [ticket-01a2f3a346] (still don't understand, but somehow it doesn't work with msvc) check-in: 517309406a user: jan.nijtmans tags: broken-msvc-2
19:41
Allow UTF-8 characters in sources. translate.exe will translate it to ASCII check-in: 208d67675c user: jan.nijtmans tags: trunk
13:57
Allow UTF-8 characters in sources. translate.exe will translate it to ASCII check-in: 9f6abc5968 user: jan.nijtmans tags: msvc-broken
10:44
Fix a typo on the Ticket Change Details page. check-in: eb82a23827 user: drh tags: trunk

Changes to src/export.c.

     1      1   /*
     2         -** Copyright (c) 2010 D. Richard Hipp
            2  +** Copyright © 2010 D. Richard Hipp
     3      3   **
     4      4   ** This program is free software; you can redistribute it and/or
     5      5   ** modify it under the terms of the Simplified BSD License (also
     6      6   ** known as the "2-Clause License" or "FreeBSD License".)
     7      7   
     8      8   ** This program is distributed in the hope that it will be useful,
     9      9   ** but without any warranty; without even the implied warranty of
................................................................................
   134    134     db_multi_exec("CREATE TEMPORARY TABLE oldblob(rid INTEGER PRIMARY KEY)");
   135    135     db_multi_exec("CREATE TEMPORARY TABLE oldcommit(rid INTEGER PRIMARY KEY)");
   136    136     if( markfile_in!=0 ){
   137    137       Stmt qb,qc;
   138    138       char line[100];
   139    139       FILE *f;
   140    140   
   141         -    f = fopen(markfile_in, "r");
          141  +    f = fossil_fopen(markfile_in, "r");
   142    142       if( f==0 ){
   143    143         fossil_panic("cannot open %s for reading", markfile_in);
   144    144       }
   145    145       db_prepare(&qb, "INSERT OR IGNORE INTO oldblob VALUES (:rid)");
   146    146       db_prepare(&qc, "INSERT OR IGNORE INTO oldcommit VALUES (:rid)");
   147    147       while( fgets(line, sizeof(line), f)!=0 ){
   148    148         if( *line == 'b' ){
................................................................................
   323    323       fossil_free(zEncoded);
   324    324     }
   325    325     db_finalize(&q);
   326    326     bag_clear(&vers);
   327    327   
   328    328     if( markfile_out!=0 ){
   329    329       FILE *f;
   330         -    f = fopen(markfile_out, "w");
          330  +    f = fossil_fopen(markfile_out, "w");
   331    331       if( f == 0 ){
   332    332         fossil_panic("cannot open %s for writing", markfile_out);
   333    333       }
   334    334       db_prepare(&q, "SELECT rid FROM oldblob");
   335    335       while( db_step(&q)==SQLITE_ROW ){
   336    336         fprintf(f, "b%d\n", db_column_int(&q, 0));
   337    337       }

Changes to src/file.c.

     1      1   /*
     2         -** Copyright (c) 2006 D. Richard Hipp
            2  +** Copyright © 2006 D. Richard Hipp
     3      3   **
     4      4   ** This program is free software; you can redistribute it and/or
     5      5   ** modify it under the terms of the Simplified BSD License (also
     6      6   ** known as the "2-Clause License" or "FreeBSD License".)
     7      7   
     8      8   ** This program is distributed in the hope that it will be useful,
     9      9   ** but without any warranty; without even the implied warranty of
................................................................................
    30     30   #include <errno.h>
    31     31   #include "file.h"
    32     32   
    33     33   /*
    34     34   ** On Windows, include the Platform SDK header file.
    35     35   */
    36     36   #ifdef _WIN32
           37  +# include <direct.h>
    37     38   # include <windows.h>
    38     39   #endif
    39     40   
    40     41   /*
    41     42   ** The file status information from the most recent stat() call.
    42     43   **
    43     44   ** Use _stati64 rather than stat on windows, in order to handle files
................................................................................
    66     67     if( isWd && g.allowSymlinks ){
    67     68       return lstat(zFilename, buf);
    68     69     }else{
    69     70       return stat(zFilename, buf);
    70     71     }
    71     72   #else
    72     73     int rc = 0;
    73         -  char *zMbcs = fossil_utf8_to_mbcs(zFilename);
    74         -  rc = stat(zMbcs, buf);
           74  +  wchar_t *zMbcs = fossil_utf8_to_unicode(zFilename);
           75  +  rc = _wstati64(zMbcs, buf);
    75     76     fossil_mbcs_free(zMbcs);
    76     77     return rc;
    77     78   #endif
    78     79   }
    79     80   
    80     81   /*
    81     82   ** Fill in the fileStat variable for the file named zFilename.
................................................................................
   296    297   }
   297    298   
   298    299   
   299    300   /*
   300    301   ** Wrapper around the access() system call.
   301    302   */
   302    303   int file_access(const char *zFilename, int flags){
   303         -  char *zMbcs = fossil_utf8_to_mbcs(zFilename);
   304         -  int rc = access(zMbcs, flags);
          304  +#ifdef _WIN32
          305  +  wchar_t *zMbcs = fossil_utf8_to_unicode(zFilename);
          306  +  int rc = _waccess(zMbcs, flags);
   305    307     fossil_mbcs_free(zMbcs);
          308  +#else
          309  +  int rc = access(zFilename, flags);
          310  +#endif
   306    311     return rc;
   307    312   }
   308    313   
   309    314   /*
   310    315   ** Find an unused filename similar to zBase with zSuffix appended.
   311    316   **
   312    317   ** Make the name relative to the working directory if relFlag is true.
................................................................................
   387    392     return rc;
   388    393   }
   389    394   
   390    395   /*
   391    396   ** Delete a file.
   392    397   */
   393    398   void file_delete(const char *zFilename){
   394         -  char *z = fossil_utf8_to_mbcs(zFilename);
   395         -  unlink(z);
          399  +#ifdef _WIN32
          400  +  wchar_t *z = fossil_utf8_to_unicode(zFilename);
          401  +  _wunlink(z);
   396    402     fossil_mbcs_free(z);
          403  +#else
          404  +  unlink(zFilename);
          405  +#endif
   397    406   }
   398    407   
   399    408   /*
   400    409   ** Create the directory named in the argument, if it does not already
   401    410   ** exist.  If forceFlag is 1, delete any prior non-directory object 
   402    411   ** with the same name.
   403    412   **
................................................................................
   408    417     if( rc==2 ){
   409    418       if( !forceFlag ) return 1;
   410    419       file_delete(zName);
   411    420     }
   412    421     if( rc!=1 ){
   413    422   #if defined(_WIN32)
   414    423       int rc;
   415         -    char *zMbcs = fossil_utf8_to_mbcs(zName);
   416         -    rc = mkdir(zMbcs);
          424  +    wchar_t *zMbcs = fossil_utf8_to_unicode(zName);
          425  +    rc = _wmkdir(zMbcs);
   417    426       fossil_mbcs_free(zMbcs);
   418    427       return rc;
   419    428   #else
   420    429       return mkdir(zName, 0755);
   421    430   #endif
   422    431     }
   423    432     return 0;
................................................................................
   559    568       fossil_free(z);
   560    569     }
   561    570   }
   562    571   
   563    572   /*
   564    573   ** Get the current working directory.
   565    574   **
   566         -** On windows, the name is converted from MBCS to UTF8 and all '\\'
          575  +** On windows, the name is converted from unicode to UTF8 and all '\\'
   567    576   ** characters are converted to '/'.  No conversions are needed on
   568    577   ** unix.
   569    578   */
   570    579   void file_getcwd(char *zBuf, int nBuf){
   571    580   #ifdef _WIN32
   572    581     char *zPwdUtf8;
   573    582     int nPwd;
   574    583     int i;
   575         -  char zPwd[2000];
   576         -  if( getcwd(zPwd, sizeof(zPwd)-1)==0 ){
          584  +  wchar_t zPwd[2000];
          585  +  if( _wgetcwd(zPwd, sizeof(zPwd)/sizeof(zPwd[0])-1)==0 ){
   577    586       fossil_fatal("cannot find the current working directory.");
   578    587     }
   579         -  zPwdUtf8 = fossil_mbcs_to_utf8(zPwd);
          588  +  zPwdUtf8 = fossil_unicode_to_utf8(zPwd);
   580    589     nPwd = strlen(zPwdUtf8);
   581    590     if( nPwd > nBuf-1 ){
   582    591       fossil_fatal("pwd too big: max %d\n", nBuf-1);
   583    592     }
   584    593     for(i=0; zPwdUtf8[i]; i++) if( zPwdUtf8[i]=='\\' ) zPwdUtf8[i] = '/';
   585    594     memcpy(zBuf, zPwdUtf8, nPwd+1);
   586    595     fossil_mbcs_free(zPwdUtf8);
................................................................................
   926    935       "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
   927    936       "0123456789";
   928    937     unsigned int i, j;
   929    938     const char *zDir = ".";
   930    939     int cnt = 0;
   931    940   
   932    941   #if defined(_WIN32)
   933         -  char zTmpPath[MAX_PATH];
          942  +  wchar_t zTmpPath[MAX_PATH];
   934    943   
   935         -  if( GetTempPath(sizeof(zTmpPath), zTmpPath) ){
   936         -    azDirs[0] = zTmpPath;
          944  +  if( GetTempPathW(MAX_PATH, zTmpPath) ){
          945  +    azDirs[0] = fossil_unicode_to_utf8(zTmpPath);
   937    946     }
   938    947   
   939    948     azDirs[1] = fossil_getenv("TEMP");
   940    949     azDirs[2] = fossil_getenv("TMP");
   941    950   #endif
   942    951   
   943    952     
................................................................................
   992   1001       blob_read_from_file(&onDisk, zName);
   993   1002     }
   994   1003     rc = blob_compare(&onDisk, pContent);
   995   1004     blob_reset(&onDisk);
   996   1005     return rc==0;
   997   1006   }
   998   1007   
         1008  +/*
         1009  +** Portable unicode implementation of opendir()
         1010  +*/
         1011  +#if INTERFACE
         1012  +
         1013  +#if defined(_WIN32)
         1014  +# include <dirent.h>
         1015  +# define FOSSIL_DIR _WDIR
         1016  +# define fossil_dirent _wdirent
         1017  +# define fossil_opendir _wopendir
         1018  +# define fossil_readdir _wreaddir
         1019  +# define fossil_closedir _wclosedir
         1020  +#else
         1021  +# include <dirent.h>
         1022  +# define FOSSIL_DIR DIR
         1023  +# define fossil_dirent dirent
         1024  +# define fossil_opendir opendir
         1025  +# define fossil_readdir readdir
         1026  +# define fossil_closedir closedir
         1027  +#endif
         1028  +
         1029  +#endif /* INTERFACE */
         1030  +
         1031  +
   999   1032   
  1000   1033   /**************************************************************************
  1001   1034   ** The following routines translate between MBCS and UTF8 on windows.
  1002   1035   ** Since everything is always UTF8 on unix, these routines are no-ops
  1003   1036   ** there.
  1004   1037   */
  1005   1038   
................................................................................
  1012   1045   #ifdef _WIN32
  1013   1046     extern char *sqlite3_win32_mbcs_to_utf8(const char*);
  1014   1047     return sqlite3_win32_mbcs_to_utf8(zMbcs);
  1015   1048   #else
  1016   1049     return (char*)zMbcs;  /* No-op on unix */
  1017   1050   #endif  
  1018   1051   }
         1052  +
         1053  +/*
         1054  +** Translate Unicode to UTF8.  Return a pointer to the translated text.
         1055  +** Call fossil_mbcs_free() to deallocate any memory used to store the
         1056  +** returned pointer when done.
         1057  +*/
         1058  +char *fossil_unicode_to_utf8(const void *zUnicode){
         1059  +#ifdef _WIN32
         1060  +  int nByte = WideCharToMultiByte(CP_UTF8, 0, zUnicode, -1, 0, 0, 0, 0);
         1061  +  char *zUtf = sqlite3_malloc( nByte );
         1062  +  if( zUtf==0 ){
         1063  +    return 0;
         1064  +  }
         1065  +  WideCharToMultiByte(CP_UTF8, 0, zUnicode, -1, zUtf, nByte, 0, 0);
         1066  +  return zUtf;
         1067  +#else
         1068  +  return (char *)zUnicode;  /* No-op on unix */
         1069  +#endif
         1070  +}
  1019   1071   
  1020   1072   /*
  1021   1073   ** Translate UTF8 to MBCS for use in system calls.  Return a pointer to the
  1022   1074   ** translated text..  Call fossil_mbcs_free() to deallocate any memory
  1023   1075   ** used to store the returned pointer when done.
  1024   1076   */
  1025   1077   char *fossil_utf8_to_mbcs(const char *zUtf8){
................................................................................
  1026   1078   #ifdef _WIN32
  1027   1079     extern char *sqlite3_win32_utf8_to_mbcs(const char*);
  1028   1080     return sqlite3_win32_utf8_to_mbcs(zUtf8);
  1029   1081   #else
  1030   1082     return (char*)zUtf8;  /* No-op on unix */
  1031   1083   #endif  
  1032   1084   }
         1085  +
         1086  +/*
         1087  +** Translate UTF8 to unicode for use in system calls.  Return a pointer to the
         1088  +** translated text..  Call fossil_mbcs_free() to deallocate any memory
         1089  +** used to store the returned pointer when done.
         1090  +*/
         1091  +void *fossil_utf8_to_unicode(const char *zUtf8){
         1092  +#ifdef _WIN32
         1093  +  int nByte = MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, 0, 0);
         1094  +  wchar_t *zUnicode = sqlite3_malloc( nByte * 2 );
         1095  +  if( zUnicode==0 ){
         1096  +    return 0;
         1097  +  }
         1098  +  MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, zUnicode, nByte);
         1099  +  return zUnicode;
         1100  +#else
         1101  +  return (void *)zUtf8;  /* No-op on unix */
         1102  +#endif
         1103  +}
  1033   1104   
  1034   1105   /*
  1035   1106   ** Return the value of an environment variable as UTF8.
  1036   1107   */
  1037   1108   char *fossil_getenv(const char *zName){
  1038         -  char *zValue = getenv(zName);
  1039   1109   #ifdef _WIN32
  1040         -  if( zValue ) zValue = fossil_mbcs_to_utf8(zValue);
         1110  +  wchar_t *uName = fossil_utf8_to_unicode(zName);
         1111  +  void *zValue = _wgetenv(uName);
         1112  +  fossil_mbcs_free(uName);
         1113  +  if( zValue ) zValue = fossil_unicode_to_utf8(zValue);
         1114  +#else
         1115  +  char *zValue = getenv(zName);
  1041   1116   #endif
  1042   1117     return zValue;
  1043   1118   }
  1044   1119   
  1045   1120   /*
  1046   1121   ** Translate UTF8 to MBCS for display on the console.  Return a pointer to the
  1047   1122   ** translated text..  Call fossil_mbcs_free() to deallocate any memory
................................................................................
  1083   1158   #endif  
  1084   1159   }
  1085   1160   
  1086   1161   /*
  1087   1162   ** Translate MBCS to UTF8.  Return a pointer.  Call fossil_mbcs_free()
  1088   1163   ** to deallocate any memory used to store the returned pointer when done.
  1089   1164   */
  1090         -void fossil_mbcs_free(char *zOld){
         1165  +void fossil_mbcs_free(void *zOld){
  1091   1166   #ifdef _WIN32
  1092   1167     extern void sqlite3_free(void*);
  1093   1168     sqlite3_free(zOld);
  1094   1169   #else
  1095   1170     /* No-op on unix */
  1096   1171   #endif  
  1097   1172   }
  1098   1173   
  1099   1174   /*
  1100   1175   ** Like fopen() but always takes a UTF8 argument.
  1101   1176   */
  1102   1177   FILE *fossil_fopen(const char *zName, const char *zMode){
  1103         -  char *zMbcs = fossil_utf8_to_mbcs(zName);
  1104         -  FILE *f = fopen(zMbcs, zMode);
  1105         -  fossil_mbcs_free(zMbcs);
         1178  +#ifdef _WIN32
         1179  +  wchar_t *uMode = fossil_utf8_to_unicode(zMode);
         1180  +  wchar_t *uName = fossil_utf8_to_unicode(zName);
         1181  +  FILE *f = _wfopen(uName, uMode);
         1182  +  fossil_mbcs_free(uName);
         1183  +  fossil_mbcs_free(uMode);
         1184  +#else
         1185  +  FILE *f = fopen(zName, zMode);
         1186  +#endif
  1106   1187     return f;
  1107   1188   }

Changes to src/import.c.

     1      1   /*
     2         -** Copyright (c) 2010 D. Richard Hipp
            2  +** Copyright © 2010 D. Richard Hipp
     3      3   **
     4      4   ** This program is free software; you can redistribute it and/or
     5      5   ** modify it under the terms of the Simplified BSD License (also
     6      6   ** known as the "2-Clause License" or "FreeBSD License".)
     7      7   
     8      8   ** This program is distributed in the hope that it will be useful,
     9      9   ** but without any warranty; without even the implied warranty of
................................................................................
   730    730   
   731    731     find_option("git",0,0);  /* Skip the --git option for now */
   732    732     verify_all_options();
   733    733     if( g.argc!=3  && g.argc!=4 ){
   734    734       usage("REPOSITORY-NAME");
   735    735     }
   736    736     if( g.argc==4 ){
   737         -    pIn = fopen(g.argv[3], "rb");
          737  +    pIn = fossil_fopen(g.argv[3], "rb");
   738    738     }else{
   739    739       pIn = stdin;
   740    740       fossil_binary_mode(pIn);
   741    741     }
   742    742     if( !incrFlag ){
   743    743       if( forceFlag ) file_delete(g.argv[2]);
   744    744       db_create_repository(g.argv[2]);

Changes to src/merge.c.

    88     88   **
    89     89   **   --nochange | -n         Dryrun:  do not actually make any changes; just
    90     90   **                           show what would have happened.
    91     91   **
    92     92   **   --case-sensitive BOOL   Overwrite the case-sensitive setting.  If false,
    93     93   **                           files whose names differ only in case are taken
    94     94   **                           to be the same file.
           95  +**
           96  +**   --force | -f            Force the merge even if it would be a no-op.
    95     97   */
    96     98   void merge_cmd(void){
    97     99     int vid;              /* Current version "V" */
    98    100     int mid;              /* Version we are merging from "M" */
    99    101     int pid;              /* The pivot version - most recent common ancestor P */
   100    102     int detailFlag;       /* True if the --detail option is present */
   101    103     int pickFlag;         /* True if the --cherrypick option is present */
   102    104     int backoutFlag;      /* True if the --backout option is present */
   103    105     int nochangeFlag;     /* True if the --nochange or -n option is present */
          106  +  int forceFlag;        /* True if the --force or -f option is present */
   104    107     const char *zBinGlob; /* The value of --binary */
   105    108     const char *zPivot;   /* The value of --baseline */
   106    109     int debugFlag;        /* True if --debug is present */
   107    110     int nChng;            /* Number of file name changes */
   108    111     int *aChng;           /* An array of file name changes */
   109    112     int i;                /* Loop counter */
   110    113     int nConflict = 0;    /* Number of conflicts seen */
................................................................................
   123    126     undo_capture_command_line();
   124    127     detailFlag = find_option("detail",0,0)!=0;
   125    128     pickFlag = find_option("cherrypick",0,0)!=0;
   126    129     backoutFlag = find_option("backout",0,0)!=0;
   127    130     debugFlag = find_option("debug",0,0)!=0;
   128    131     zBinGlob = find_option("binary",0,1);
   129    132     nochangeFlag = find_option("nochange","n",0)!=0;
          133  +  forceFlag = find_option("force","f",0)!=0;
   130    134     zPivot = find_option("baseline",0,1);
   131    135     capture_case_sensitive_option();
   132    136     if( g.argc!=3 ){
   133    137       usage("VERSION");
   134    138     }
   135    139     db_must_be_within_tree();
   136    140     caseSensitive = filenames_are_case_sensitive();
................................................................................
   174    178       int t = pid;
   175    179       pid = mid;
   176    180       mid = t;
   177    181     }
   178    182     if( !is_a_version(pid) ){
   179    183       fossil_fatal("not a version: record #%d", pid);
   180    184     }
   181         -  if( mid==pid ){
   182         -    fossil_print("This merge is a no-op.\n");
          185  +  if( !forceFlag && (mid==pid || vid==pid || mid==vid) ){
          186  +    fossil_print("Merge skipped because it is a no-op. "
          187  +                 " Use --force to override.\n");
   183    188       return;
   184    189     }
   185    190     if( detailFlag ){
   186    191       print_checkin_description(mid, 12, "merge-from:");
   187    192       print_checkin_description(pid, 12, "baseline:");
   188    193     }
   189    194     vfile_check_signature(vid, 1, 0);

Changes to src/rebuild.c.

     1      1   /*
     2         -** Copyright (c) 2007 D. Richard Hipp
            2  +** Copyright © 2007 D. Richard Hipp
     3      3   **
     4      4   ** This program is free software; you can redistribute it and/or
     5      5   ** modify it under the terms of the Simplified BSD License (also
     6      6   ** known as the "2-Clause License" or "FreeBSD License".)
     7      7   
     8      8   ** This program is distributed in the hope that it will be useful,
     9      9   ** but without any warranty; without even the implied warranty of
................................................................................
    16     16   *******************************************************************************
    17     17   **
    18     18   ** This file contains code used to rebuild the database.
    19     19   */
    20     20   #include "config.h"
    21     21   #include "rebuild.h"
    22     22   #include <assert.h>
    23         -#include <dirent.h>
    24     23   #include <errno.h>
    25     24   
    26     25   /*
    27     26   ** Make changes to the stable part of the schema (the part that is not
    28     27   ** simply deleted and reconstructed on a rebuild) to bring the schema
    29     28   ** up to the latest.
    30     29   */
................................................................................
   816    815   }
   817    816   
   818    817   /*
   819    818   ** Recursively read all files from the directory zPath and install
   820    819   ** every file read as a new artifact in the repository.
   821    820   */
   822    821   void recon_read_dir(char *zPath){
   823         -  DIR *d;
   824         -  struct dirent *pEntry;
          822  +  FOSSIL_DIR *d;
          823  +  struct fossil_dirent *pEntry;
   825    824     Blob aContent; /* content of the just read artifact */
   826    825     static int nFileRead = 0;
   827         -  char *zMbcsPath;
          826  +  void *zUnicodePath;
   828    827     char *zUtf8Name;
   829    828   
   830         -  zMbcsPath = fossil_utf8_to_mbcs(zPath);
   831         -  d = opendir(zMbcsPath);
          829  +  zUnicodePath = fossil_utf8_to_unicode(zPath);
          830  +  d = fossil_opendir(zUnicodePath);
   832    831     if( d ){
   833         -    while( (pEntry=readdir(d))!=0 ){
          832  +    while( (pEntry=fossil_readdir(d))!=0 ){
   834    833         Blob path;
   835    834         char *zSubpath;
   836    835   
   837    836         if( pEntry->d_name[0]=='.' ){
   838    837           continue;
   839    838         }
   840         -      zUtf8Name = fossil_mbcs_to_utf8(pEntry->d_name);
          839  +      zUtf8Name = fossil_unicode_to_utf8(pEntry->d_name);
   841    840         zSubpath = mprintf("%s/%s", zPath, zUtf8Name);
   842    841         fossil_mbcs_free(zUtf8Name);
   843    842         if( file_isdir(zSubpath)==1 ){
   844    843           recon_read_dir(zSubpath);
   845    844         }
   846    845         blob_init(&path, 0, 0);
   847    846         blob_appendf(&path, "%s", zSubpath);
................................................................................
   852    851         content_put(&aContent);
   853    852         blob_reset(&path);
   854    853         blob_reset(&aContent);
   855    854         free(zSubpath);
   856    855         fossil_print("\r%d", ++nFileRead);
   857    856         fflush(stdout);
   858    857       }
   859         -    closedir(d);
          858  +    fossil_closedir(d);
   860    859     }else {
   861    860       fossil_panic("encountered error %d while trying to open \"%s\".",
   862    861                     errno, g.argv[3]);
   863    862     }
   864         -  fossil_mbcs_free(zMbcsPath);
          863  +  fossil_mbcs_free(zUnicodePath);
   865    864   }
   866    865   
   867    866   /*
   868    867   ** COMMAND: reconstruct*
   869    868   **
   870    869   ** Usage: %fossil reconstruct FILENAME DIRECTORY
   871    870   **

Changes to src/vfile.c.

     1      1   /*
     2         -** Copyright (c) 2007 D. Richard Hipp
            2  +** Copyright © 2007 D. Richard Hipp
     3      3   **
     4      4   ** This program is free software; you can redistribute it and/or
     5      5   ** modify it under the terms of the Simplified BSD License (also
     6      6   ** known as the "2-Clause License" or "FreeBSD License".)
     7      7   
     8      8   ** This program is distributed in the hope that it will be useful,
     9      9   ** but without any warranty; without even the implied warranty of
................................................................................
    17     17   **
    18     18   ** Procedures for managing the VFILE table.
    19     19   */
    20     20   #include "config.h"
    21     21   #include "vfile.h"
    22     22   #include <assert.h>
    23     23   #include <sys/types.h>
    24         -#if defined(__DMC__)
    25         -#include "dirent.h"
    26         -#else
    27         -#include <dirent.h>
    28         -#endif
    29     24   
    30     25   /*
    31     26   ** The input is guaranteed to be a 40-character well-formed UUID.
    32     27   ** Find its rid.
    33     28   */
    34     29   int fast_uuid_to_rid(const char *zUuid){
    35     30     static Stmt q;
................................................................................
   379    374   ** Files whose names begin with "." are omitted unless allFlag is true.
   380    375   **
   381    376   ** Any files or directories that match the glob pattern pIgnore are 
   382    377   ** excluded from the scan.  Name matching occurs after the first
   383    378   ** nPrefix characters are elided from the filename.
   384    379   */
   385    380   void vfile_scan(Blob *pPath, int nPrefix, int allFlag, Glob *pIgnore){
   386         -  DIR *d;
          381  +  FOSSIL_DIR *d;
   387    382     int origSize;
   388    383     const char *zDir;
   389         -  struct dirent *pEntry;
          384  +  struct fossil_dirent *pEntry;
   390    385     int skipAll = 0;
   391    386     static Stmt ins;
   392    387     static int depth = 0;
   393         -  char *zMbcs;
          388  +  void *zMbcs;
   394    389   
   395    390     origSize = blob_size(pPath);
   396    391     if( pIgnore ){
   397    392       blob_appendf(pPath, "/");
   398    393       if( glob_match(pIgnore, &blob_str(pPath)[nPrefix+1]) ) skipAll = 1;
   399    394       blob_resize(pPath, origSize);
   400    395     }
................................................................................
   405    400          "INSERT OR IGNORE INTO sfile(x) SELECT :file"
   406    401          "  WHERE NOT EXISTS(SELECT 1 FROM vfile WHERE pathname=:file)"
   407    402       );
   408    403     }
   409    404     depth++;
   410    405   
   411    406     zDir = blob_str(pPath);
   412         -  zMbcs = fossil_utf8_to_mbcs(zDir);
   413         -  d = opendir(zMbcs);
          407  +  zMbcs = fossil_utf8_to_unicode(zDir);
          408  +  d = fossil_opendir(zMbcs);
   414    409     if( d ){
   415         -    while( (pEntry=readdir(d))!=0 ){
          410  +    while( (pEntry=fossil_readdir(d))!=0 ){
   416    411         char *zPath;
   417    412         char *zUtf8;
   418    413         if( pEntry->d_name[0]=='.' ){
   419    414           if( !allFlag ) continue;
   420    415           if( pEntry->d_name[1]==0 ) continue;
   421    416           if( pEntry->d_name[1]=='.' && pEntry->d_name[2]==0 ) continue;
   422    417         }
   423         -      zUtf8 = fossil_mbcs_to_utf8(pEntry->d_name);
          418  +      zUtf8 = fossil_unicode_to_utf8(pEntry->d_name);
   424    419         blob_appendf(pPath, "/%s", zUtf8);
   425    420         fossil_mbcs_free(zUtf8);
   426    421         zPath = blob_str(pPath);
   427    422         if( glob_match(pIgnore, &zPath[nPrefix+1]) ){
   428    423           /* do nothing */
   429    424         }else if( file_wd_isdir(zPath)==1 ){
   430    425           if( !vfile_top_of_checkout(zPath) ){
................................................................................
   433    428         }else if( file_wd_isfile_or_link(zPath) ){
   434    429           db_bind_text(&ins, ":file", &zPath[nPrefix+1]);
   435    430           db_step(&ins);
   436    431           db_reset(&ins);
   437    432         }
   438    433         blob_resize(pPath, origSize);
   439    434       }
   440         -    closedir(d);
          435  +    fossil_closedir(d);
   441    436     }
   442    437     fossil_mbcs_free(zMbcs);
   443    438   
   444    439     depth--;
   445    440     if( depth==0 ){
   446    441       db_finalize(&ins);
   447    442     }

Changes to win/include/dirent.h.

    59     59   #define DIRENT_H
    60     60   
    61     61   #include <windows.h>
    62     62   #include <string.h>
    63     63   #include <assert.h>
    64     64   
    65     65   
    66         -typedef struct dirent
           66  +typedef struct _wdirent
    67     67   {
    68         -   char d_name[MAX_PATH + 1]; /* current dir entry (multi-byte char string) */
    69         -   WIN32_FIND_DATAA data;     /* file attributes */
    70         -}  dirent;
           68  +   wchar_t d_name[MAX_PATH + 1]; /* current dir entry (unicode char string) */
           69  +   WIN32_FIND_DATAW data;     /* file attributes */
           70  +}  _wdirent;
    71     71   
    72     72   
    73         -typedef struct DIR
           73  +typedef struct _WDIR
    74     74   {
    75         -   dirent current;            /* Current directory entry */
           75  +   _wdirent current;            /* Current directory entry */
    76     76      int    cached;             /* Indicates un-processed entry in memory */
    77     77      HANDLE search_handle;      /* File search handle */
    78         -   char   patt[MAX_PATH + 3]; /* search pattern (3 = pattern + "\\*\0") */
    79         -} DIR;
           78  +   wchar_t   patt[MAX_PATH + 3]; /* search pattern (3 = pattern + "\\*\0") */
           79  +} _WDIR;
    80     80   
    81     81   
    82     82   /* Forward declarations */
    83         -static DIR *opendir (const char *dirname);
    84         -static struct dirent *readdir (DIR *dirp);
    85         -static int closedir (DIR *dirp);
    86         -static void rewinddir(DIR* dirp);
           83  +static _WDIR *_wopendir (const wchar_t *dirname);
           84  +static struct _wdirent *_wreaddir (_WDIR *dirp);
           85  +static int _wclosedir (_WDIR *dirp);
    87     86   
    88     87   
    89     88   /* Use the new safe string functions introduced in Visual Studio 2005 */
    90     89   #if defined(_MSC_VER) && _MSC_VER >= 1400
    91         -# define STRNCPY(dest,src,size) strncpy_s((dest),(size),(src),_TRUNCATE)
           90  +# define STRNCPY(dest,src,size) wcsncpy_s((dest),(size),(src),_TRUNCATE)
    92     91   #else
    93         -# define STRNCPY(dest,src,size) strncpy((dest),(src),(size))
           92  +# define STRNCPY(dest,src,size) wcsncpy((dest),(src),(size))
    94     93   #endif
    95     94   
    96     95   
    97     96   /*****************************************************************************
    98     97    * Open directory stream DIRNAME for read and return a pointer to the
    99     98    * internal working area that is used to retrieve individual directory
   100     99    * entries.
   101    100    */
   102         -static DIR *opendir(const char *dirname)
          101  +static _WDIR *_wopendir(const wchar_t *dirname)
   103    102   {
   104         -   DIR *dirp;
          103  +   _WDIR *dirp;
   105    104      assert (dirname != NULL);
   106         -   assert (strlen (dirname) < MAX_PATH);
          105  +   assert (wcslen (dirname) < MAX_PATH);
   107    106   
   108         -   /* construct new DIR structure */
   109         -   dirp = (DIR*) malloc (sizeof (struct DIR));
          107  +   /* construct new _WDIR structure */
          108  +   dirp = (_WDIR*) malloc (sizeof (struct _WDIR));
   110    109      if (dirp != NULL) {
   111         -      char *p;
          110  +      wchar_t *p;
   112    111   
   113    112         /* take directory name... */
   114    113         STRNCPY (dirp->patt, dirname, sizeof(dirp->patt));
   115    114         dirp->patt[MAX_PATH] = '\0';
   116    115   
   117    116         /* ... and append search pattern to it */
   118         -      p = strchr (dirp->patt, '\0');
          117  +      p = wcschr (dirp->patt, '\0');
   119    118         if (dirp->patt < p  &&  *(p-1) != '\\'  &&  *(p-1) != ':') {
   120    119            *p++ = '\\';
   121    120         }
   122    121         *p++ = '*';
   123    122         *p = '\0';
   124    123   
   125    124         /* open stream and retrieve first file */
   126         -      dirp->search_handle = FindFirstFileA (dirp->patt, &dirp->current.data);
          125  +      dirp->search_handle = FindFirstFileW (dirp->patt, &dirp->current.data);
   127    126         if (dirp->search_handle == INVALID_HANDLE_VALUE) {
   128    127            /* invalid search pattern? */
   129    128            free (dirp);
   130    129            return NULL;
   131    130         }
   132    131   
   133    132         /* there is an un-processed directory entry in memory now */
................................................................................
   141    140   /*****************************************************************************
   142    141    * Read a directory entry, and return a pointer to a dirent structure
   143    142    * containing the name of the entry in d_name field.  Individual directory
   144    143    * entries returned by this very function include regular files,
   145    144    * sub-directories, pseudo-directories "." and "..", but also volume labels,
   146    145    * hidden files and system files may be returned.
   147    146    */
   148         -static struct dirent *readdir(DIR *dirp)
          147  +static struct _wdirent *_wreaddir(_WDIR *dirp)
   149    148   {
   150    149      assert (dirp != NULL);
   151    150   
   152    151      if (dirp->search_handle == INVALID_HANDLE_VALUE) {
   153    152         /* directory stream was opened/rewound incorrectly or ended normally */
   154    153         return NULL;
   155    154      }
................................................................................
   156    155   
   157    156      /* get next directory entry */
   158    157      if (dirp->cached != 0) {
   159    158         /* a valid directory entry already in memory */
   160    159         dirp->cached = 0;
   161    160      } else {
   162    161         /* read next directory entry from disk */
   163         -      if (FindNextFileA (dirp->search_handle, &dirp->current.data) == FALSE) {
          162  +      if (FindNextFileW (dirp->search_handle, &dirp->current.data) == FALSE) {
   164    163            /* the very last file has been processed or an error occured */
   165    164            FindClose (dirp->search_handle);
   166    165            dirp->search_handle = INVALID_HANDLE_VALUE;
   167    166            return NULL;
   168    167         }
   169    168      }
   170    169   
................................................................................
   179    178   
   180    179   
   181    180   /*****************************************************************************
   182    181    * Close directory stream opened by opendir() function.  Close of the
   183    182    * directory stream invalidates the DIR structure as well as any previously
   184    183    * read directory entry.
   185    184    */
   186         -static int closedir(DIR *dirp)
          185  +static int _wclosedir(_WDIR *dirp)
   187    186   {
   188    187      assert (dirp != NULL);
   189    188   
   190    189      /* release search handle */
   191    190      if (dirp->search_handle != INVALID_HANDLE_VALUE) {
   192    191         FindClose (dirp->search_handle);
   193    192         dirp->search_handle = INVALID_HANDLE_VALUE;
   194    193      }
   195    194   
   196    195      /* release directory handle */
   197    196      free (dirp);
   198    197      return 0;
   199    198   }
   200         -
   201         -
   202         -/*****************************************************************************
   203         - * Resets the position of the directory stream to which dirp refers to the
   204         - * beginning of the directory. It also causes the directory stream to refer
   205         - * to the current state of the corresponding directory, as a call to opendir()
   206         - * would have done. If dirp does not refer to a directory stream, the effect
   207         - * is undefined.
   208         - */
   209         -static void rewinddir(DIR* dirp)
   210         -{
   211         -   /* release search handle */
   212         -   if (dirp->search_handle != INVALID_HANDLE_VALUE) {
   213         -      FindClose (dirp->search_handle);
   214         -      dirp->search_handle = INVALID_HANDLE_VALUE;
   215         -   }
   216         -
   217         -   /* open new search handle and retrieve first file */
   218         -   dirp->search_handle = FindFirstFileA (dirp->patt, &dirp->current.data);
   219         -   if (dirp->search_handle == INVALID_HANDLE_VALUE) {
   220         -      /* invalid search pattern? */
   221         -      free (dirp);
   222         -      return;
   223         -   }
   224         -
   225         -   /* there is an un-processed directory entry in memory now */
   226         -   dirp->cached = 1;
   227         -}
   228         -
   229    199   
   230    200   #endif /*DIRENT_H*/