Fossil SCM

merge trunk

jan.nijtmans 2013-03-04 14:25 ticket-d17d6e5b17 merge
Commit aa6038265a69c03a06ab3971a1e5df8cae7e4d72
+1 -1
--- src/attach.c
+++ src/attach.c
@@ -94,11 +94,11 @@
9494
}
9595
@ <br><a href="/attachview?%s(zUrlTail)">%h(zFilename)</a>
9696
@ [<a href="/attachdownload/%t(zFilename)?%s(zUrlTail)">download</a>]<br />
9797
if( zComment ) while( fossil_isspace(zComment[0]) ) zComment++;
9898
if( zComment && zComment[0] ){
99
- @ %w(zComment)<br />
99
+ @ %!w(zComment)<br />
100100
}
101101
if( zPage==0 && zTkt==0 ){
102102
if( zSrc==0 || zSrc[0]==0 ){
103103
zSrc = "Deleted from";
104104
}else {
105105
--- src/attach.c
+++ src/attach.c
@@ -94,11 +94,11 @@
94 }
95 @ <br><a href="/attachview?%s(zUrlTail)">%h(zFilename)</a>
96 @ [<a href="/attachdownload/%t(zFilename)?%s(zUrlTail)">download</a>]<br />
97 if( zComment ) while( fossil_isspace(zComment[0]) ) zComment++;
98 if( zComment && zComment[0] ){
99 @ %w(zComment)<br />
100 }
101 if( zPage==0 && zTkt==0 ){
102 if( zSrc==0 || zSrc[0]==0 ){
103 zSrc = "Deleted from";
104 }else {
105
--- src/attach.c
+++ src/attach.c
@@ -94,11 +94,11 @@
94 }
95 @ <br><a href="/attachview?%s(zUrlTail)">%h(zFilename)</a>
96 @ [<a href="/attachdownload/%t(zFilename)?%s(zUrlTail)">download</a>]<br />
97 if( zComment ) while( fossil_isspace(zComment[0]) ) zComment++;
98 if( zComment && zComment[0] ){
99 @ %!w(zComment)<br />
100 }
101 if( zPage==0 && zTkt==0 ){
102 if( zSrc==0 || zSrc[0]==0 ){
103 zSrc = "Deleted from";
104 }else {
105
+5 -3
--- src/blob.c
+++ src/blob.c
@@ -792,11 +792,11 @@
792792
}
793793
nName = file_simplify_name(zName, nName, 0);
794794
for(i=1; i<nName; i++){
795795
if( zName[i]=='/' ){
796796
zName[i] = 0;
797
-#if defined(_WIN32)
797
+#if defined(_WIN32) || defined(__CYGWIN__)
798798
/*
799799
** On Windows, local path looks like: C:/develop/project/file.txt
800800
** The if stops us from trying to create a directory of a drive letter
801801
** C: in this example.
802802
*/
@@ -804,11 +804,11 @@
804804
#endif
805805
if( file_mkdir(zName, 1) && file_isdir(zName)!=1 ){
806806
fossil_fatal_recursive("unable to create directory %s", zName);
807807
return 0;
808808
}
809
-#if defined(_WIN32)
809
+#if defined(_WIN32) || defined(__CYGWIN__)
810810
}
811811
#endif
812812
zName[i] = '/';
813813
}
814814
}
@@ -1104,11 +1104,11 @@
11041104
zUtf8 = blob_str(pBlob) + bomSize;
11051105
blob_zero(&temp);
11061106
blob_append(&temp, zUtf8, -1);
11071107
blob_swap(pBlob, &temp);
11081108
blob_reset(&temp);
1109
-#ifdef _WIN32
1109
+#if defined(_WIN32) || defined(__CYGWIN__)
11101110
}else if( starts_with_utf16_bom(pBlob, &bomSize, &bomReverse) ){
11111111
zUtf8 = blob_buffer(pBlob);
11121112
if( bomReverse ){
11131113
/* Found BOM, but with reversed bytes */
11141114
unsigned int i = blob_size(pBlob);
@@ -1124,13 +1124,15 @@
11241124
zUtf8 = blob_str(pBlob) + bomSize;
11251125
zUtf8 = fossil_unicode_to_utf8(zUtf8);
11261126
blob_zero(pBlob);
11271127
blob_append(pBlob, zUtf8, -1);
11281128
fossil_unicode_free(zUtf8);
1129
+#endif /* _WIN32 || __CYGWIN__ */
1130
+#if defined(_WIN32)
11291131
}else if( useMbcs ){
11301132
zUtf8 = fossil_mbcs_to_utf8(blob_str(pBlob));
11311133
blob_reset(pBlob);
11321134
blob_append(pBlob, zUtf8, -1);
11331135
fossil_mbcs_free(zUtf8);
11341136
#endif /* _WIN32 */
11351137
}
11361138
}
11371139
--- src/blob.c
+++ src/blob.c
@@ -792,11 +792,11 @@
792 }
793 nName = file_simplify_name(zName, nName, 0);
794 for(i=1; i<nName; i++){
795 if( zName[i]=='/' ){
796 zName[i] = 0;
797 #if defined(_WIN32)
798 /*
799 ** On Windows, local path looks like: C:/develop/project/file.txt
800 ** The if stops us from trying to create a directory of a drive letter
801 ** C: in this example.
802 */
@@ -804,11 +804,11 @@
804 #endif
805 if( file_mkdir(zName, 1) && file_isdir(zName)!=1 ){
806 fossil_fatal_recursive("unable to create directory %s", zName);
807 return 0;
808 }
809 #if defined(_WIN32)
810 }
811 #endif
812 zName[i] = '/';
813 }
814 }
@@ -1104,11 +1104,11 @@
1104 zUtf8 = blob_str(pBlob) + bomSize;
1105 blob_zero(&temp);
1106 blob_append(&temp, zUtf8, -1);
1107 blob_swap(pBlob, &temp);
1108 blob_reset(&temp);
1109 #ifdef _WIN32
1110 }else if( starts_with_utf16_bom(pBlob, &bomSize, &bomReverse) ){
1111 zUtf8 = blob_buffer(pBlob);
1112 if( bomReverse ){
1113 /* Found BOM, but with reversed bytes */
1114 unsigned int i = blob_size(pBlob);
@@ -1124,13 +1124,15 @@
1124 zUtf8 = blob_str(pBlob) + bomSize;
1125 zUtf8 = fossil_unicode_to_utf8(zUtf8);
1126 blob_zero(pBlob);
1127 blob_append(pBlob, zUtf8, -1);
1128 fossil_unicode_free(zUtf8);
 
 
1129 }else if( useMbcs ){
1130 zUtf8 = fossil_mbcs_to_utf8(blob_str(pBlob));
1131 blob_reset(pBlob);
1132 blob_append(pBlob, zUtf8, -1);
1133 fossil_mbcs_free(zUtf8);
1134 #endif /* _WIN32 */
1135 }
1136 }
1137
--- src/blob.c
+++ src/blob.c
@@ -792,11 +792,11 @@
792 }
793 nName = file_simplify_name(zName, nName, 0);
794 for(i=1; i<nName; i++){
795 if( zName[i]=='/' ){
796 zName[i] = 0;
797 #if defined(_WIN32) || defined(__CYGWIN__)
798 /*
799 ** On Windows, local path looks like: C:/develop/project/file.txt
800 ** The if stops us from trying to create a directory of a drive letter
801 ** C: in this example.
802 */
@@ -804,11 +804,11 @@
804 #endif
805 if( file_mkdir(zName, 1) && file_isdir(zName)!=1 ){
806 fossil_fatal_recursive("unable to create directory %s", zName);
807 return 0;
808 }
809 #if defined(_WIN32) || defined(__CYGWIN__)
810 }
811 #endif
812 zName[i] = '/';
813 }
814 }
@@ -1104,11 +1104,11 @@
1104 zUtf8 = blob_str(pBlob) + bomSize;
1105 blob_zero(&temp);
1106 blob_append(&temp, zUtf8, -1);
1107 blob_swap(pBlob, &temp);
1108 blob_reset(&temp);
1109 #if defined(_WIN32) || defined(__CYGWIN__)
1110 }else if( starts_with_utf16_bom(pBlob, &bomSize, &bomReverse) ){
1111 zUtf8 = blob_buffer(pBlob);
1112 if( bomReverse ){
1113 /* Found BOM, but with reversed bytes */
1114 unsigned int i = blob_size(pBlob);
@@ -1124,13 +1124,15 @@
1124 zUtf8 = blob_str(pBlob) + bomSize;
1125 zUtf8 = fossil_unicode_to_utf8(zUtf8);
1126 blob_zero(pBlob);
1127 blob_append(pBlob, zUtf8, -1);
1128 fossil_unicode_free(zUtf8);
1129 #endif /* _WIN32 || __CYGWIN__ */
1130 #if defined(_WIN32)
1131 }else if( useMbcs ){
1132 zUtf8 = fossil_mbcs_to_utf8(blob_str(pBlob));
1133 blob_reset(pBlob);
1134 blob_append(pBlob, zUtf8, -1);
1135 fossil_mbcs_free(zUtf8);
1136 #endif /* _WIN32 */
1137 }
1138 }
1139
+26 -1
--- src/checkin.c
+++ src/checkin.c
@@ -909,10 +909,35 @@
909909
static int allOk = 0; /* Set to true to disable this routine */
910910
911911
if( allOk ) return 0;
912912
fUnicode = starts_with_utf16_bom(p, 0, 0);
913913
eType = fUnicode ? looks_like_utf16(p) : looks_like_utf8(p);
914
+ if( eType==-4){
915
+ const char *zWarning;
916
+ const char *zDisable;
917
+ Blob ans;
918
+ char cReply;
919
+
920
+ if (!binOk) {
921
+ zWarning = "long lines";
922
+ zDisable = "\"binary-glob\" setting";
923
+ blob_zero(&ans);
924
+ file_relative_name(zFilename, &fname, 0);
925
+ zMsg = mprintf(
926
+ "%s appears to be text, but contains %s. Use --no-warnings or the"
927
+ " %s to disable this warning.\nCommit anyhow (a=all/y/N)? ",
928
+ blob_str(&fname), zWarning, zDisable);
929
+ prompt_user(zMsg, &ans);
930
+ fossil_free(zMsg);
931
+ cReply = blob_str(&ans)[0];
932
+ if( cReply!='y' && cReply!='Y' ){
933
+ fossil_fatal("Abandoning commit due to %s in %s",
934
+ zWarning, blob_str(&fname));
935
+ }
936
+ blob_reset(&ans);
937
+ }
938
+ }
914939
if( eType==0 || eType==-1 || fUnicode ){
915940
const char *zWarning;
916941
const char *zDisable;
917942
const char *zConvert = "c=convert/";
918943
Blob ans;
@@ -941,11 +966,11 @@
941966
if ( encodingOk ){
942967
return 0; /* We don't want encoding warnings for this file. */
943968
}
944969
zWarning = "Unicode";
945970
zDisable = "\"encoding-glob\" setting";
946
-#ifndef _WIN32
971
+#if !defined(_WIN32) && !defined(__CYGWIN__)
947972
zConvert = ""; /* On Unix, we cannot easily convert Unicode files. */
948973
#endif
949974
}
950975
file_relative_name(zFilename, &fname, 0);
951976
blob_zero(&ans);
952977
--- src/checkin.c
+++ src/checkin.c
@@ -909,10 +909,35 @@
909 static int allOk = 0; /* Set to true to disable this routine */
910
911 if( allOk ) return 0;
912 fUnicode = starts_with_utf16_bom(p, 0, 0);
913 eType = fUnicode ? looks_like_utf16(p) : looks_like_utf8(p);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
914 if( eType==0 || eType==-1 || fUnicode ){
915 const char *zWarning;
916 const char *zDisable;
917 const char *zConvert = "c=convert/";
918 Blob ans;
@@ -941,11 +966,11 @@
941 if ( encodingOk ){
942 return 0; /* We don't want encoding warnings for this file. */
943 }
944 zWarning = "Unicode";
945 zDisable = "\"encoding-glob\" setting";
946 #ifndef _WIN32
947 zConvert = ""; /* On Unix, we cannot easily convert Unicode files. */
948 #endif
949 }
950 file_relative_name(zFilename, &fname, 0);
951 blob_zero(&ans);
952
--- src/checkin.c
+++ src/checkin.c
@@ -909,10 +909,35 @@
909 static int allOk = 0; /* Set to true to disable this routine */
910
911 if( allOk ) return 0;
912 fUnicode = starts_with_utf16_bom(p, 0, 0);
913 eType = fUnicode ? looks_like_utf16(p) : looks_like_utf8(p);
914 if( eType==-4){
915 const char *zWarning;
916 const char *zDisable;
917 Blob ans;
918 char cReply;
919
920 if (!binOk) {
921 zWarning = "long lines";
922 zDisable = "\"binary-glob\" setting";
923 blob_zero(&ans);
924 file_relative_name(zFilename, &fname, 0);
925 zMsg = mprintf(
926 "%s appears to be text, but contains %s. Use --no-warnings or the"
927 " %s to disable this warning.\nCommit anyhow (a=all/y/N)? ",
928 blob_str(&fname), zWarning, zDisable);
929 prompt_user(zMsg, &ans);
930 fossil_free(zMsg);
931 cReply = blob_str(&ans)[0];
932 if( cReply!='y' && cReply!='Y' ){
933 fossil_fatal("Abandoning commit due to %s in %s",
934 zWarning, blob_str(&fname));
935 }
936 blob_reset(&ans);
937 }
938 }
939 if( eType==0 || eType==-1 || fUnicode ){
940 const char *zWarning;
941 const char *zDisable;
942 const char *zConvert = "c=convert/";
943 Blob ans;
@@ -941,11 +966,11 @@
966 if ( encodingOk ){
967 return 0; /* We don't want encoding warnings for this file. */
968 }
969 zWarning = "Unicode";
970 zDisable = "\"encoding-glob\" setting";
971 #if !defined(_WIN32) && !defined(__CYGWIN__)
972 zConvert = ""; /* On Unix, we cannot easily convert Unicode files. */
973 #endif
974 }
975 file_relative_name(zFilename, &fname, 0);
976 blob_zero(&ans);
977
+1 -1
--- src/configure.c
+++ src/configure.c
@@ -888,11 +888,11 @@
888888
if( strncmp(zMethod,"pull",n)==0 ){
889889
overwriteFlag = find_option("overwrite",0,0)!=0;
890890
}
891891
url_proxy_options();
892892
if( g.argc!=4 && g.argc!=5 ){
893
- usage("pull AREA ?URL?");
893
+ usage(mprintf("%s AREA ?URL?", zMethod));
894894
}
895895
mask = configure_name_to_mask(g.argv[3], 1);
896896
if( g.argc==5 ){
897897
zServer = g.argv[4];
898898
}
899899
--- src/configure.c
+++ src/configure.c
@@ -888,11 +888,11 @@
888 if( strncmp(zMethod,"pull",n)==0 ){
889 overwriteFlag = find_option("overwrite",0,0)!=0;
890 }
891 url_proxy_options();
892 if( g.argc!=4 && g.argc!=5 ){
893 usage("pull AREA ?URL?");
894 }
895 mask = configure_name_to_mask(g.argv[3], 1);
896 if( g.argc==5 ){
897 zServer = g.argv[4];
898 }
899
--- src/configure.c
+++ src/configure.c
@@ -888,11 +888,11 @@
888 if( strncmp(zMethod,"pull",n)==0 ){
889 overwriteFlag = find_option("overwrite",0,0)!=0;
890 }
891 url_proxy_options();
892 if( g.argc!=4 && g.argc!=5 ){
893 usage(mprintf("%s AREA ?URL?", zMethod));
894 }
895 mask = configure_name_to_mask(g.argv[3], 1);
896 if( g.argc==5 ){
897 zServer = g.argv[4];
898 }
899
+7 -12
--- src/db.c
+++ src/db.c
@@ -29,13 +29,10 @@
2929
**
3030
*/
3131
#include "config.h"
3232
#if ! defined(_WIN32)
3333
# include <pwd.h>
34
-# if defined(__CYGWIN__)
35
-# include <sys/cygwin.h>
36
-# endif
3734
#endif
3835
#include <sqlite3.h>
3936
#include <sys/types.h>
4037
#include <sys/stat.h>
4138
#include <unistd.h>
@@ -794,11 +791,11 @@
794791
** connection so that we can join between the various databases. In that
795792
** case, invoke this routine with useAttach as 1.
796793
*/
797794
void db_open_config(int useAttach){
798795
char *zDbName;
799
- const char *zHome;
796
+ char *zHome;
800797
if( g.configOpen ) return;
801798
#if defined(_WIN32) || defined(__CYGWIN__)
802799
zHome = fossil_getenv("LOCALAPPDATA");
803800
if( zHome==0 ){
804801
zHome = fossil_getenv("APPDATA");
@@ -808,15 +805,14 @@
808805
if( zDrive && zHome ) zHome = mprintf("%s%s", zDrive, zHome);
809806
}
810807
}
811808
#if defined(__CYGWIN__)
812809
if( zHome!=0 ){
813
- /* We now have the win32 path, but we need the Cygwin equivalent */
814
- ssize_t size = cygwin_conv_path(CCP_WIN_A_TO_POSIX, zHome, 0, 0);
815
- char *converted = fossil_malloc(size);
816
- cygwin_conv_path(CCP_WIN_A_TO_POSIX, zHome, converted, size);
817
- zHome = converted;
810
+ /* We now have the win32 path, but we need the Cygwin equivalent. */
811
+ char *zPath = fossil_utf8_to_filename(zHome);
812
+ fossil_filename_free(zHome);
813
+ zHome = zPath;
818814
}
819815
#endif
820816
if( zHome==0 ){
821817
fossil_fatal("cannot locate home directory - "
822818
"please set the LOCALAPPDATA or APPDATA or HOMEPATH "
@@ -830,15 +826,13 @@
830826
}
831827
#endif
832828
if( file_isdir(zHome)!=1 ){
833829
fossil_fatal("invalid home directory: %s", zHome);
834830
}
835
-#ifndef _WIN32
836
- if( access(zHome, W_OK) ){
831
+ if( file_access(zHome, W_OK) ){
837832
fossil_fatal("home directory %s must be writeable", zHome);
838833
}
839
-#endif
840834
g.zHome = mprintf("%/", zHome);
841835
#if defined(_WIN32) || defined(__CYGWIN__)
842836
/* . filenames give some window systems problems and many apps problems */
843837
zDbName = mprintf("%//_fossil", zHome);
844838
#else
@@ -856,10 +850,11 @@
856850
g.dbConfig = db_open(zDbName);
857851
g.zConfigDbType = "configdb";
858852
}
859853
g.configOpen = 1;
860854
free(zDbName);
855
+ fossil_filename_free(zHome);
861856
}
862857
863858
864859
/*
865860
** Returns TRUE if zTable exists in the local database but lacks column
866861
--- src/db.c
+++ src/db.c
@@ -29,13 +29,10 @@
29 **
30 */
31 #include "config.h"
32 #if ! defined(_WIN32)
33 # include <pwd.h>
34 # if defined(__CYGWIN__)
35 # include <sys/cygwin.h>
36 # endif
37 #endif
38 #include <sqlite3.h>
39 #include <sys/types.h>
40 #include <sys/stat.h>
41 #include <unistd.h>
@@ -794,11 +791,11 @@
794 ** connection so that we can join between the various databases. In that
795 ** case, invoke this routine with useAttach as 1.
796 */
797 void db_open_config(int useAttach){
798 char *zDbName;
799 const char *zHome;
800 if( g.configOpen ) return;
801 #if defined(_WIN32) || defined(__CYGWIN__)
802 zHome = fossil_getenv("LOCALAPPDATA");
803 if( zHome==0 ){
804 zHome = fossil_getenv("APPDATA");
@@ -808,15 +805,14 @@
808 if( zDrive && zHome ) zHome = mprintf("%s%s", zDrive, zHome);
809 }
810 }
811 #if defined(__CYGWIN__)
812 if( zHome!=0 ){
813 /* We now have the win32 path, but we need the Cygwin equivalent */
814 ssize_t size = cygwin_conv_path(CCP_WIN_A_TO_POSIX, zHome, 0, 0);
815 char *converted = fossil_malloc(size);
816 cygwin_conv_path(CCP_WIN_A_TO_POSIX, zHome, converted, size);
817 zHome = converted;
818 }
819 #endif
820 if( zHome==0 ){
821 fossil_fatal("cannot locate home directory - "
822 "please set the LOCALAPPDATA or APPDATA or HOMEPATH "
@@ -830,15 +826,13 @@
830 }
831 #endif
832 if( file_isdir(zHome)!=1 ){
833 fossil_fatal("invalid home directory: %s", zHome);
834 }
835 #ifndef _WIN32
836 if( access(zHome, W_OK) ){
837 fossil_fatal("home directory %s must be writeable", zHome);
838 }
839 #endif
840 g.zHome = mprintf("%/", zHome);
841 #if defined(_WIN32) || defined(__CYGWIN__)
842 /* . filenames give some window systems problems and many apps problems */
843 zDbName = mprintf("%//_fossil", zHome);
844 #else
@@ -856,10 +850,11 @@
856 g.dbConfig = db_open(zDbName);
857 g.zConfigDbType = "configdb";
858 }
859 g.configOpen = 1;
860 free(zDbName);
 
861 }
862
863
864 /*
865 ** Returns TRUE if zTable exists in the local database but lacks column
866
--- src/db.c
+++ src/db.c
@@ -29,13 +29,10 @@
29 **
30 */
31 #include "config.h"
32 #if ! defined(_WIN32)
33 # include <pwd.h>
 
 
 
34 #endif
35 #include <sqlite3.h>
36 #include <sys/types.h>
37 #include <sys/stat.h>
38 #include <unistd.h>
@@ -794,11 +791,11 @@
791 ** connection so that we can join between the various databases. In that
792 ** case, invoke this routine with useAttach as 1.
793 */
794 void db_open_config(int useAttach){
795 char *zDbName;
796 char *zHome;
797 if( g.configOpen ) return;
798 #if defined(_WIN32) || defined(__CYGWIN__)
799 zHome = fossil_getenv("LOCALAPPDATA");
800 if( zHome==0 ){
801 zHome = fossil_getenv("APPDATA");
@@ -808,15 +805,14 @@
805 if( zDrive && zHome ) zHome = mprintf("%s%s", zDrive, zHome);
806 }
807 }
808 #if defined(__CYGWIN__)
809 if( zHome!=0 ){
810 /* We now have the win32 path, but we need the Cygwin equivalent. */
811 char *zPath = fossil_utf8_to_filename(zHome);
812 fossil_filename_free(zHome);
813 zHome = zPath;
 
814 }
815 #endif
816 if( zHome==0 ){
817 fossil_fatal("cannot locate home directory - "
818 "please set the LOCALAPPDATA or APPDATA or HOMEPATH "
@@ -830,15 +826,13 @@
826 }
827 #endif
828 if( file_isdir(zHome)!=1 ){
829 fossil_fatal("invalid home directory: %s", zHome);
830 }
831 if( file_access(zHome, W_OK) ){
 
832 fossil_fatal("home directory %s must be writeable", zHome);
833 }
 
834 g.zHome = mprintf("%/", zHome);
835 #if defined(_WIN32) || defined(__CYGWIN__)
836 /* . filenames give some window systems problems and many apps problems */
837 zDbName = mprintf("%//_fossil", zHome);
838 #else
@@ -856,10 +850,11 @@
850 g.dbConfig = db_open(zDbName);
851 g.zConfigDbType = "configdb";
852 }
853 g.configOpen = 1;
854 free(zDbName);
855 fossil_filename_free(zHome);
856 }
857
858
859 /*
860 ** Returns TRUE if zTable exists in the local database but lacks column
861
+54 -28
--- src/diff.c
+++ src/diff.c
@@ -57,11 +57,11 @@
5757
"more than 10,000 changes\n"
5858
5959
#define DIFF_TOO_MANY_CHANGES_HTML \
6060
"<p class='generalError'>More than 10,000 changes</p>\n"
6161
62
-#define looks_like_binary(blob) (looks_like_utf8((blob)) == 0)
62
+#define looks_like_binary(blob) ((looks_like_utf8((blob))&3) == 0)
6363
#endif /* INTERFACE */
6464
6565
/*
6666
** Maximum length of a line in a text file, in bytes. (2**13 = 8192 bytes)
6767
*/
@@ -198,10 +198,14 @@
198198
** to be binary.
199199
**
200200
** (-1) -- The content appears to consist entirely of text, with lines
201201
** delimited by carriage-return, line-feed pairs; however, the
202202
** encoding may not be UTF-8.
203
+**
204
+** (-4) -- The same as 0, but the determination is based on the fact that
205
+** the blob might be text (any encoding) but it has a line length
206
+** bigger than the diff logic in fossil can handle.
203207
**
204208
************************************ WARNING **********************************
205209
**
206210
** This function does not validate that the blob content is properly formed
207211
** UTF-8. It assumes that all code points are the same size. It does not
@@ -215,36 +219,35 @@
215219
*/
216220
int looks_like_utf8(const Blob *pContent){
217221
const char *z = blob_buffer(pContent);
218222
unsigned int n = blob_size(pContent);
219223
int j, c;
220
- int result = 1; /* Assume UTF-8 text with no CR/NL */
224
+ int flags = 0; /* bit 0 = long lines found, 1 = CR/NL found. */
221225
222226
/* Check individual lines.
223227
*/
224
- if( n==0 ) return result; /* Empty file -> text */
228
+ if( n==0 ) return 1; /* Empty file -> text */
225229
c = *z;
226230
if( c==0 ) return 0; /* Zero byte in a file -> binary */
227231
j = (c!='\n');
228232
while( --n>0 ){
229233
c = *++z; ++j;
230234
if( c==0 ) return 0; /* Zero byte in a file -> binary */
231235
if( c=='\n' ){
232
- int c2 = z[-1];
233
- if( c2=='\r' ){
234
- result = -1; /* Contains CR/NL, continue */
236
+ if( z[-1]=='\r' ){
237
+ flags |= 2; /* Contains CR/NL, continue */
235238
}
236239
if( j>LENGTH_MASK ){
237
- return 0; /* Very long line -> binary */
240
+ flags |= 1; /* Very long line, continue */
238241
}
239242
j = 0;
240243
}
241244
}
242
- if( j>LENGTH_MASK ){
243
- return 0; /* Very long line -> binary */
245
+ if( (flags&1) || (j>LENGTH_MASK) ){
246
+ return -4; /* Very long line -> binary */
244247
}
245
- return result; /* No problems seen -> not binary */
248
+ return 1-flags; /* No problems seen -> not binary */
246249
}
247250
248251
/*
249252
** Define the type needed to represent a Unicode (UTF-16) character.
250253
*/
@@ -288,10 +291,14 @@
288291
** to be binary.
289292
**
290293
** (-1) -- The content appears to consist entirely of text, with lines
291294
** delimited by carriage-return, line-feed pairs; however, the
292295
** encoding may not be UTF-16.
296
+**
297
+** (-4) -- The same as 0, but the determination is based on the fact that
298
+** the blob might be text (any encoding) but it has a line length
299
+** bigger than the diff logic in fossil can handle.
293300
**
294301
************************************ WARNING **********************************
295302
**
296303
** This function does not validate that the blob content is properly formed
297304
** UTF-16. It assumes that all code points are the same size. It does not
@@ -305,15 +312,15 @@
305312
*/
306313
int looks_like_utf16(const Blob *pContent){
307314
const WCHAR_T *z = (WCHAR_T *)blob_buffer(pContent);
308315
unsigned int n = blob_size(pContent);
309316
int j, c;
310
- int result = 1; /* Assume UTF-16 text with no CR/NL */
317
+ int flags = 0; /* bit 0 = long lines found, 1 = CR/NL found. */
311318
312319
/* Check individual lines.
313320
*/
314
- if( n==0 ) return result; /* Empty file -> text */
321
+ if( n==0 ) return 1; /* Empty file -> text */
315322
if( n%2 ) return 0; /* Odd number of bytes -> binary (or UTF-8) */
316323
c = *z;
317324
if( c==0 ) return 0; /* NUL character in a file -> binary */
318325
j = ((c!=UTF16BE_LF) && (c!=UTF16LE_LF));
319326
while( (n-=2)>0 ){
@@ -320,22 +327,22 @@
320327
c = *++z; ++j;
321328
if( c==0 ) return 0; /* NUL character in a file -> binary */
322329
if( c==UTF16BE_LF || c==UTF16LE_LF ){
323330
int c2 = z[-1];
324331
if( c2==UTF16BE_CR || c2==UTF16LE_CR ){
325
- result = -1; /* Contains CR/NL, continue */
332
+ flags |= 2; /* Contains CR/NL, continue */
326333
}
327334
if( j>UTF16_LENGTH_MASK ){
328
- return 0; /* Very long line -> binary */
335
+ flags |= 1; /* Very long line, continue */
329336
}
330337
j = 0;
331338
}
332339
}
333
- if( j>UTF16_LENGTH_MASK ){
334
- return 0; /* Very long line -> binary */
340
+ if( (flags&1) || (j>UTF16_LENGTH_MASK) ){
341
+ return -4; /* Very long line -> binary */
335342
}
336
- return result; /* No problems seen -> not binary */
343
+ return 1-flags; /* No problems seen -> not binary */
337344
}
338345
339346
/*
340347
** This function returns an array of bytes representing the byte-order-mark
341348
** for UTF-8.
@@ -855,21 +862,33 @@
855862
/*
856863
** Simplify iStart and iStart2:
857864
**
858865
** * If iStart is a null-change then move iStart2 into iStart
859866
** * Make sure any null-changes are in canonoical form.
867
+** * Make sure all changes are at character boundaries for
868
+** multi-byte characters.
860869
*/
861
-static void sbsSimplifyLine(SbsLine *p){
862
- if( p->iStart2==p->iEnd2 ) p->iStart2 = p->iEnd2 = 0;
870
+static void sbsSimplifyLine(SbsLine *p, const char *z){
871
+ if( p->iStart2==p->iEnd2 ){
872
+ p->iStart2 = p->iEnd2 = 0;
873
+ }else if( p->iStart2 ){
874
+ while( p->iStart2>0 && (z[p->iStart2]&0xc0)==0x80 ) p->iStart2--;
875
+ while( (z[p->iEnd2]&0xc0)==0x80 ) p->iEnd2++;
876
+ }
863877
if( p->iStart==p->iEnd ){
864878
p->iStart = p->iStart2;
865879
p->iEnd = p->iEnd2;
866880
p->zStart = p->zStart2;
867881
p->iStart2 = 0;
868882
p->iEnd2 = 0;
869883
}
870
- if( p->iStart==p->iEnd ) p->iStart = p->iEnd = -1;
884
+ if( p->iStart==p->iEnd ){
885
+ p->iStart = p->iEnd = -1;
886
+ }else if( p->iStart>0 ){
887
+ while( p->iStart>0 && (z[p->iStart]&0xc0)==0x80 ) p->iStart--;
888
+ while( (z[p->iEnd]&0xc0)==0x80 ) p->iEnd++;
889
+ }
871890
}
872891
873892
/*
874893
** Write out lines that have been edited. Adjust the highlight to cover
875894
** only those parts of the line that actually changed.
@@ -881,10 +900,11 @@
881900
DLine *pRight, /* Right line of the change */
882901
int lnRight /* Line number of the right line */
883902
){
884903
int nLeft; /* Length of left line in bytes */
885904
int nRight; /* Length of right line in bytes */
905
+ int nShort; /* Shortest of left and right */
886906
int nPrefix; /* Length of common prefix */
887907
int nSuffix; /* Length of common suffix */
888908
const char *zLeft; /* Text of the left line */
889909
const char *zRight; /* Text of the right line */
890910
int nLeftDiff; /* nLeft - nPrefix - nSuffix */
@@ -896,25 +916,31 @@
896916
897917
nLeft = pLeft->h & LENGTH_MASK;
898918
zLeft = pLeft->z;
899919
nRight = pRight->h & LENGTH_MASK;
900920
zRight = pRight->z;
921
+ nShort = nLeft<nRight ? nLeft : nRight;
901922
902923
nPrefix = 0;
903
- while( nPrefix<nLeft && nPrefix<nRight && zLeft[nPrefix]==zRight[nPrefix] ){
924
+ while( nPrefix<nShort && zLeft[nPrefix]==zRight[nPrefix] ){
904925
nPrefix++;
905926
}
927
+ if( nPrefix<nShort ){
928
+ while( nPrefix>0 && (zLeft[nPrefix]&0xc0)==0x80 ) nPrefix--;
929
+ }
906930
nSuffix = 0;
907
- if( nPrefix<nLeft && nPrefix<nRight ){
908
- while( nSuffix<nLeft && nSuffix<nRight
909
- && zLeft[nLeft-nSuffix-1]==zRight[nRight-nSuffix-1] ){
931
+ if( nPrefix<nShort ){
932
+ while( nSuffix<nShort && zLeft[nLeft-nSuffix-1]==zRight[nRight-nSuffix-1] ){
910933
nSuffix++;
911934
}
935
+ if( nSuffix<nShort ){
936
+ while( nSuffix>0 && (zLeft[nLeft-nSuffix]&0xc0)==0x80 ) nSuffix--;
937
+ }
912938
if( nSuffix==nLeft || nSuffix==nRight ) nPrefix = 0;
913939
}
914
- if( nPrefix+nSuffix > nLeft ) nPrefix = nLeft - nSuffix;
915
- if( nPrefix+nSuffix > nRight ) nPrefix = nRight - nSuffix;
940
+ if( nPrefix+nSuffix > nShort ) nPrefix = nShort - nSuffix;
941
+
916942
917943
/* A single chunk of text inserted on the right */
918944
if( nPrefix+nSuffix==nLeft ){
919945
sbsWriteLineno(p, lnLeft);
920946
p->iStart2 = p->iEnd2 = 0;
@@ -970,11 +996,11 @@
970996
p->zStart = zClassChng;
971997
}
972998
p->iStart2 = nPrefix + aLCS[1];
973999
p->iEnd2 = nLeft - nSuffix;
9741000
p->zStart2 = aLCS[3]==nRightDiff ? zClassRm : zClassChng;
975
- sbsSimplifyLine(p);
1001
+ sbsSimplifyLine(p, zLeft+nPrefix);
9761002
sbsWriteText(p, pLeft, SBS_PAD);
9771003
sbsWrite(p, " | ", 3);
9781004
sbsWriteLineno(p, lnRight);
9791005
p->iStart = nPrefix;
9801006
p->iEnd = nPrefix + aLCS[2];
@@ -985,11 +1011,11 @@
9851011
p->zStart = zClassChng;
9861012
}
9871013
p->iStart2 = nPrefix + aLCS[3];
9881014
p->iEnd2 = nRight - nSuffix;
9891015
p->zStart2 = aLCS[1]==nLeftDiff ? zClassAdd : zClassChng;
990
- sbsSimplifyLine(p);
1016
+ sbsSimplifyLine(p, zRight+nPrefix);
9911017
sbsWriteText(p, pRight, SBS_NEWLINE);
9921018
return;
9931019
}
9941020
9951021
/* If all else fails, show a single big change between left and right */
9961022
--- src/diff.c
+++ src/diff.c
@@ -57,11 +57,11 @@
57 "more than 10,000 changes\n"
58
59 #define DIFF_TOO_MANY_CHANGES_HTML \
60 "<p class='generalError'>More than 10,000 changes</p>\n"
61
62 #define looks_like_binary(blob) (looks_like_utf8((blob)) == 0)
63 #endif /* INTERFACE */
64
65 /*
66 ** Maximum length of a line in a text file, in bytes. (2**13 = 8192 bytes)
67 */
@@ -198,10 +198,14 @@
198 ** to be binary.
199 **
200 ** (-1) -- The content appears to consist entirely of text, with lines
201 ** delimited by carriage-return, line-feed pairs; however, the
202 ** encoding may not be UTF-8.
 
 
 
 
203 **
204 ************************************ WARNING **********************************
205 **
206 ** This function does not validate that the blob content is properly formed
207 ** UTF-8. It assumes that all code points are the same size. It does not
@@ -215,36 +219,35 @@
215 */
216 int looks_like_utf8(const Blob *pContent){
217 const char *z = blob_buffer(pContent);
218 unsigned int n = blob_size(pContent);
219 int j, c;
220 int result = 1; /* Assume UTF-8 text with no CR/NL */
221
222 /* Check individual lines.
223 */
224 if( n==0 ) return result; /* Empty file -> text */
225 c = *z;
226 if( c==0 ) return 0; /* Zero byte in a file -> binary */
227 j = (c!='\n');
228 while( --n>0 ){
229 c = *++z; ++j;
230 if( c==0 ) return 0; /* Zero byte in a file -> binary */
231 if( c=='\n' ){
232 int c2 = z[-1];
233 if( c2=='\r' ){
234 result = -1; /* Contains CR/NL, continue */
235 }
236 if( j>LENGTH_MASK ){
237 return 0; /* Very long line -> binary */
238 }
239 j = 0;
240 }
241 }
242 if( j>LENGTH_MASK ){
243 return 0; /* Very long line -> binary */
244 }
245 return result; /* No problems seen -> not binary */
246 }
247
248 /*
249 ** Define the type needed to represent a Unicode (UTF-16) character.
250 */
@@ -288,10 +291,14 @@
288 ** to be binary.
289 **
290 ** (-1) -- The content appears to consist entirely of text, with lines
291 ** delimited by carriage-return, line-feed pairs; however, the
292 ** encoding may not be UTF-16.
 
 
 
 
293 **
294 ************************************ WARNING **********************************
295 **
296 ** This function does not validate that the blob content is properly formed
297 ** UTF-16. It assumes that all code points are the same size. It does not
@@ -305,15 +312,15 @@
305 */
306 int looks_like_utf16(const Blob *pContent){
307 const WCHAR_T *z = (WCHAR_T *)blob_buffer(pContent);
308 unsigned int n = blob_size(pContent);
309 int j, c;
310 int result = 1; /* Assume UTF-16 text with no CR/NL */
311
312 /* Check individual lines.
313 */
314 if( n==0 ) return result; /* Empty file -> text */
315 if( n%2 ) return 0; /* Odd number of bytes -> binary (or UTF-8) */
316 c = *z;
317 if( c==0 ) return 0; /* NUL character in a file -> binary */
318 j = ((c!=UTF16BE_LF) && (c!=UTF16LE_LF));
319 while( (n-=2)>0 ){
@@ -320,22 +327,22 @@
320 c = *++z; ++j;
321 if( c==0 ) return 0; /* NUL character in a file -> binary */
322 if( c==UTF16BE_LF || c==UTF16LE_LF ){
323 int c2 = z[-1];
324 if( c2==UTF16BE_CR || c2==UTF16LE_CR ){
325 result = -1; /* Contains CR/NL, continue */
326 }
327 if( j>UTF16_LENGTH_MASK ){
328 return 0; /* Very long line -> binary */
329 }
330 j = 0;
331 }
332 }
333 if( j>UTF16_LENGTH_MASK ){
334 return 0; /* Very long line -> binary */
335 }
336 return result; /* No problems seen -> not binary */
337 }
338
339 /*
340 ** This function returns an array of bytes representing the byte-order-mark
341 ** for UTF-8.
@@ -855,21 +862,33 @@
855 /*
856 ** Simplify iStart and iStart2:
857 **
858 ** * If iStart is a null-change then move iStart2 into iStart
859 ** * Make sure any null-changes are in canonoical form.
 
 
860 */
861 static void sbsSimplifyLine(SbsLine *p){
862 if( p->iStart2==p->iEnd2 ) p->iStart2 = p->iEnd2 = 0;
 
 
 
 
 
863 if( p->iStart==p->iEnd ){
864 p->iStart = p->iStart2;
865 p->iEnd = p->iEnd2;
866 p->zStart = p->zStart2;
867 p->iStart2 = 0;
868 p->iEnd2 = 0;
869 }
870 if( p->iStart==p->iEnd ) p->iStart = p->iEnd = -1;
 
 
 
 
 
871 }
872
873 /*
874 ** Write out lines that have been edited. Adjust the highlight to cover
875 ** only those parts of the line that actually changed.
@@ -881,10 +900,11 @@
881 DLine *pRight, /* Right line of the change */
882 int lnRight /* Line number of the right line */
883 ){
884 int nLeft; /* Length of left line in bytes */
885 int nRight; /* Length of right line in bytes */
 
886 int nPrefix; /* Length of common prefix */
887 int nSuffix; /* Length of common suffix */
888 const char *zLeft; /* Text of the left line */
889 const char *zRight; /* Text of the right line */
890 int nLeftDiff; /* nLeft - nPrefix - nSuffix */
@@ -896,25 +916,31 @@
896
897 nLeft = pLeft->h & LENGTH_MASK;
898 zLeft = pLeft->z;
899 nRight = pRight->h & LENGTH_MASK;
900 zRight = pRight->z;
 
901
902 nPrefix = 0;
903 while( nPrefix<nLeft && nPrefix<nRight && zLeft[nPrefix]==zRight[nPrefix] ){
904 nPrefix++;
905 }
 
 
 
906 nSuffix = 0;
907 if( nPrefix<nLeft && nPrefix<nRight ){
908 while( nSuffix<nLeft && nSuffix<nRight
909 && zLeft[nLeft-nSuffix-1]==zRight[nRight-nSuffix-1] ){
910 nSuffix++;
911 }
 
 
 
912 if( nSuffix==nLeft || nSuffix==nRight ) nPrefix = 0;
913 }
914 if( nPrefix+nSuffix > nLeft ) nPrefix = nLeft - nSuffix;
915 if( nPrefix+nSuffix > nRight ) nPrefix = nRight - nSuffix;
916
917 /* A single chunk of text inserted on the right */
918 if( nPrefix+nSuffix==nLeft ){
919 sbsWriteLineno(p, lnLeft);
920 p->iStart2 = p->iEnd2 = 0;
@@ -970,11 +996,11 @@
970 p->zStart = zClassChng;
971 }
972 p->iStart2 = nPrefix + aLCS[1];
973 p->iEnd2 = nLeft - nSuffix;
974 p->zStart2 = aLCS[3]==nRightDiff ? zClassRm : zClassChng;
975 sbsSimplifyLine(p);
976 sbsWriteText(p, pLeft, SBS_PAD);
977 sbsWrite(p, " | ", 3);
978 sbsWriteLineno(p, lnRight);
979 p->iStart = nPrefix;
980 p->iEnd = nPrefix + aLCS[2];
@@ -985,11 +1011,11 @@
985 p->zStart = zClassChng;
986 }
987 p->iStart2 = nPrefix + aLCS[3];
988 p->iEnd2 = nRight - nSuffix;
989 p->zStart2 = aLCS[1]==nLeftDiff ? zClassAdd : zClassChng;
990 sbsSimplifyLine(p);
991 sbsWriteText(p, pRight, SBS_NEWLINE);
992 return;
993 }
994
995 /* If all else fails, show a single big change between left and right */
996
--- src/diff.c
+++ src/diff.c
@@ -57,11 +57,11 @@
57 "more than 10,000 changes\n"
58
59 #define DIFF_TOO_MANY_CHANGES_HTML \
60 "<p class='generalError'>More than 10,000 changes</p>\n"
61
62 #define looks_like_binary(blob) ((looks_like_utf8((blob))&3) == 0)
63 #endif /* INTERFACE */
64
65 /*
66 ** Maximum length of a line in a text file, in bytes. (2**13 = 8192 bytes)
67 */
@@ -198,10 +198,14 @@
198 ** to be binary.
199 **
200 ** (-1) -- The content appears to consist entirely of text, with lines
201 ** delimited by carriage-return, line-feed pairs; however, the
202 ** encoding may not be UTF-8.
203 **
204 ** (-4) -- The same as 0, but the determination is based on the fact that
205 ** the blob might be text (any encoding) but it has a line length
206 ** bigger than the diff logic in fossil can handle.
207 **
208 ************************************ WARNING **********************************
209 **
210 ** This function does not validate that the blob content is properly formed
211 ** UTF-8. It assumes that all code points are the same size. It does not
@@ -215,36 +219,35 @@
219 */
220 int looks_like_utf8(const Blob *pContent){
221 const char *z = blob_buffer(pContent);
222 unsigned int n = blob_size(pContent);
223 int j, c;
224 int flags = 0; /* bit 0 = long lines found, 1 = CR/NL found. */
225
226 /* Check individual lines.
227 */
228 if( n==0 ) return 1; /* Empty file -> text */
229 c = *z;
230 if( c==0 ) return 0; /* Zero byte in a file -> binary */
231 j = (c!='\n');
232 while( --n>0 ){
233 c = *++z; ++j;
234 if( c==0 ) return 0; /* Zero byte in a file -> binary */
235 if( c=='\n' ){
236 if( z[-1]=='\r' ){
237 flags |= 2; /* Contains CR/NL, continue */
 
238 }
239 if( j>LENGTH_MASK ){
240 flags |= 1; /* Very long line, continue */
241 }
242 j = 0;
243 }
244 }
245 if( (flags&1) || (j>LENGTH_MASK) ){
246 return -4; /* Very long line -> binary */
247 }
248 return 1-flags; /* No problems seen -> not binary */
249 }
250
251 /*
252 ** Define the type needed to represent a Unicode (UTF-16) character.
253 */
@@ -288,10 +291,14 @@
291 ** to be binary.
292 **
293 ** (-1) -- The content appears to consist entirely of text, with lines
294 ** delimited by carriage-return, line-feed pairs; however, the
295 ** encoding may not be UTF-16.
296 **
297 ** (-4) -- The same as 0, but the determination is based on the fact that
298 ** the blob might be text (any encoding) but it has a line length
299 ** bigger than the diff logic in fossil can handle.
300 **
301 ************************************ WARNING **********************************
302 **
303 ** This function does not validate that the blob content is properly formed
304 ** UTF-16. It assumes that all code points are the same size. It does not
@@ -305,15 +312,15 @@
312 */
313 int looks_like_utf16(const Blob *pContent){
314 const WCHAR_T *z = (WCHAR_T *)blob_buffer(pContent);
315 unsigned int n = blob_size(pContent);
316 int j, c;
317 int flags = 0; /* bit 0 = long lines found, 1 = CR/NL found. */
318
319 /* Check individual lines.
320 */
321 if( n==0 ) return 1; /* Empty file -> text */
322 if( n%2 ) return 0; /* Odd number of bytes -> binary (or UTF-8) */
323 c = *z;
324 if( c==0 ) return 0; /* NUL character in a file -> binary */
325 j = ((c!=UTF16BE_LF) && (c!=UTF16LE_LF));
326 while( (n-=2)>0 ){
@@ -320,22 +327,22 @@
327 c = *++z; ++j;
328 if( c==0 ) return 0; /* NUL character in a file -> binary */
329 if( c==UTF16BE_LF || c==UTF16LE_LF ){
330 int c2 = z[-1];
331 if( c2==UTF16BE_CR || c2==UTF16LE_CR ){
332 flags |= 2; /* Contains CR/NL, continue */
333 }
334 if( j>UTF16_LENGTH_MASK ){
335 flags |= 1; /* Very long line, continue */
336 }
337 j = 0;
338 }
339 }
340 if( (flags&1) || (j>UTF16_LENGTH_MASK) ){
341 return -4; /* Very long line -> binary */
342 }
343 return 1-flags; /* No problems seen -> not binary */
344 }
345
346 /*
347 ** This function returns an array of bytes representing the byte-order-mark
348 ** for UTF-8.
@@ -855,21 +862,33 @@
862 /*
863 ** Simplify iStart and iStart2:
864 **
865 ** * If iStart is a null-change then move iStart2 into iStart
866 ** * Make sure any null-changes are in canonoical form.
867 ** * Make sure all changes are at character boundaries for
868 ** multi-byte characters.
869 */
870 static void sbsSimplifyLine(SbsLine *p, const char *z){
871 if( p->iStart2==p->iEnd2 ){
872 p->iStart2 = p->iEnd2 = 0;
873 }else if( p->iStart2 ){
874 while( p->iStart2>0 && (z[p->iStart2]&0xc0)==0x80 ) p->iStart2--;
875 while( (z[p->iEnd2]&0xc0)==0x80 ) p->iEnd2++;
876 }
877 if( p->iStart==p->iEnd ){
878 p->iStart = p->iStart2;
879 p->iEnd = p->iEnd2;
880 p->zStart = p->zStart2;
881 p->iStart2 = 0;
882 p->iEnd2 = 0;
883 }
884 if( p->iStart==p->iEnd ){
885 p->iStart = p->iEnd = -1;
886 }else if( p->iStart>0 ){
887 while( p->iStart>0 && (z[p->iStart]&0xc0)==0x80 ) p->iStart--;
888 while( (z[p->iEnd]&0xc0)==0x80 ) p->iEnd++;
889 }
890 }
891
892 /*
893 ** Write out lines that have been edited. Adjust the highlight to cover
894 ** only those parts of the line that actually changed.
@@ -881,10 +900,11 @@
900 DLine *pRight, /* Right line of the change */
901 int lnRight /* Line number of the right line */
902 ){
903 int nLeft; /* Length of left line in bytes */
904 int nRight; /* Length of right line in bytes */
905 int nShort; /* Shortest of left and right */
906 int nPrefix; /* Length of common prefix */
907 int nSuffix; /* Length of common suffix */
908 const char *zLeft; /* Text of the left line */
909 const char *zRight; /* Text of the right line */
910 int nLeftDiff; /* nLeft - nPrefix - nSuffix */
@@ -896,25 +916,31 @@
916
917 nLeft = pLeft->h & LENGTH_MASK;
918 zLeft = pLeft->z;
919 nRight = pRight->h & LENGTH_MASK;
920 zRight = pRight->z;
921 nShort = nLeft<nRight ? nLeft : nRight;
922
923 nPrefix = 0;
924 while( nPrefix<nShort && zLeft[nPrefix]==zRight[nPrefix] ){
925 nPrefix++;
926 }
927 if( nPrefix<nShort ){
928 while( nPrefix>0 && (zLeft[nPrefix]&0xc0)==0x80 ) nPrefix--;
929 }
930 nSuffix = 0;
931 if( nPrefix<nShort ){
932 while( nSuffix<nShort && zLeft[nLeft-nSuffix-1]==zRight[nRight-nSuffix-1] ){
 
933 nSuffix++;
934 }
935 if( nSuffix<nShort ){
936 while( nSuffix>0 && (zLeft[nLeft-nSuffix]&0xc0)==0x80 ) nSuffix--;
937 }
938 if( nSuffix==nLeft || nSuffix==nRight ) nPrefix = 0;
939 }
940 if( nPrefix+nSuffix > nShort ) nPrefix = nShort - nSuffix;
941
942
943 /* A single chunk of text inserted on the right */
944 if( nPrefix+nSuffix==nLeft ){
945 sbsWriteLineno(p, lnLeft);
946 p->iStart2 = p->iEnd2 = 0;
@@ -970,11 +996,11 @@
996 p->zStart = zClassChng;
997 }
998 p->iStart2 = nPrefix + aLCS[1];
999 p->iEnd2 = nLeft - nSuffix;
1000 p->zStart2 = aLCS[3]==nRightDiff ? zClassRm : zClassChng;
1001 sbsSimplifyLine(p, zLeft+nPrefix);
1002 sbsWriteText(p, pLeft, SBS_PAD);
1003 sbsWrite(p, " | ", 3);
1004 sbsWriteLineno(p, lnRight);
1005 p->iStart = nPrefix;
1006 p->iEnd = nPrefix + aLCS[2];
@@ -985,11 +1011,11 @@
1011 p->zStart = zClassChng;
1012 }
1013 p->iStart2 = nPrefix + aLCS[3];
1014 p->iEnd2 = nRight - nSuffix;
1015 p->zStart2 = aLCS[1]==nLeftDiff ? zClassAdd : zClassChng;
1016 sbsSimplifyLine(p, zRight+nPrefix);
1017 sbsWriteText(p, pRight, SBS_NEWLINE);
1018 return;
1019 }
1020
1021 /* If all else fails, show a single big change between left and right */
1022
+17 -15
--- src/file.c
+++ src/file.c
@@ -706,15 +706,13 @@
706706
** Return true if zPath is an absolute pathname. Return false
707707
** if it is relative.
708708
*/
709709
int file_is_absolute_path(const char *zPath){
710710
if( zPath[0]=='/'
711
-#if defined(__CYGWIN__)
711
+#if defined(_WIN32) || defined(__CYGWIN__)
712712
|| zPath[0]=='\\'
713
-#elif defined(_WIN32)
714
- || zPath[0]=='\\'
715
- || (strlen(zPath)>3 && zPath[1]==':'
713
+ || (fossil_isalpha(zPath[0]) && zPath[1]==':'
716714
&& (zPath[2]=='\\' || zPath[2]=='/'))
717715
#endif
718716
){
719717
return 1;
720718
}else{
@@ -731,21 +729,21 @@
731729
** If the slash parameter is non-zero, the trailing slash, if any,
732730
** is retained.
733731
*/
734732
void file_canonical_name(const char *zOrigName, Blob *pOut, int slash){
735733
if( file_is_absolute_path(zOrigName) ){
736
-#if defined(_WIN32)
734
+#if defined(_WIN32) || defined(__CYGWIN__)
737735
char *zOut;
738736
#endif
739737
blob_set(pOut, zOrigName);
740738
blob_materialize(pOut);
741
-#if defined(_WIN32)
739
+#if defined(_WIN32) || defined(__CYGWIN__)
742740
/*
743
- ** On Windows, normalize the drive letter to upper case.
741
+ ** On Windows/cygwin, normalize the drive letter to upper case.
744742
*/
745743
zOut = blob_str(pOut);
746
- if( fossil_isalpha(zOut[0]) && zOut[1]==':' ){
744
+ if( fossil_islower(zOut[0]) && zOut[1]==':' ){
747745
zOut[0] = fossil_toupper(zOut[0]);
748746
}
749747
#endif
750748
}else{
751749
char zPwd[2000];
@@ -752,11 +750,11 @@
752750
file_getcwd(zPwd, sizeof(zPwd)-strlen(zOrigName));
753751
#if defined(_WIN32)
754752
/*
755753
** On Windows, normalize the drive letter to upper case.
756754
*/
757
- if( fossil_isalpha(zPwd[0]) && zPwd[1]==':' ){
755
+ if( fossil_islower(zPwd[0]) && zPwd[1]==':' ){
758756
zPwd[0] = fossil_toupper(zPwd[0]);
759757
}
760758
#endif
761759
blob_zero(pOut);
762760
blob_appendf(pOut, "%//%/", zPwd, zOrigName);
@@ -801,12 +799,12 @@
801799
** contain no "/./" or "/../" terms.
802800
*/
803801
int file_is_canonical(const char *z){
804802
int i;
805803
if( z[0]!='/'
806
-#if defined(_WIN32)
807
- && (z[0]==0 || z[1]!=':' || z[2]!='/')
804
+#if defined(_WIN32) || defined(__CYGWIN__)
805
+ && (!fossil_isupper(z[0]) || z[1]!=':' || z[2]!='/')
808806
#endif
809807
) return 0;
810808
811809
for(i=0; z[i]; i++){
812810
if( z[i]=='\\' ) return 0;
@@ -1014,23 +1012,26 @@
10141012
10151013
/*
10161014
** Construct a random temporary filename into zBuf[].
10171015
*/
10181016
void file_tempname(int nBuf, char *zBuf){
1019
- static const char *azDirs[] = {
10201017
#if defined(_WIN32)
1018
+ const char *azDirs[] = {
10211019
0, /* GetTempPath */
10221020
0, /* TEMP */
10231021
0, /* TMP */
1022
+ ".",
1023
+ };
10241024
#else
1025
+ static const char *const azDirs[] = {
10251026
"/var/tmp",
10261027
"/usr/tmp",
10271028
"/tmp",
10281029
"/temp",
1029
-#endif
10301030
".",
10311031
};
1032
+#endif
10321033
static const unsigned char zChars[] =
10331034
"abcdefghijklmnopqrstuvwxyz"
10341035
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
10351036
"0123456789";
10361037
unsigned int i, j;
@@ -1073,12 +1074,13 @@
10731074
}
10741075
zBuf[j] = 0;
10751076
}while( file_size(zBuf)>=0 );
10761077
10771078
#if defined(_WIN32)
1078
- fossil_unicode_free((char *)azDirs[1]);
1079
- fossil_unicode_free((char *)azDirs[2]);
1079
+ fossil_filename_free((char *)azDirs[0]);
1080
+ fossil_filename_free((char *)azDirs[1]);
1081
+ fossil_filename_free((char *)azDirs[2]);
10801082
#endif
10811083
}
10821084
10831085
10841086
/*
10851087
--- src/file.c
+++ src/file.c
@@ -706,15 +706,13 @@
706 ** Return true if zPath is an absolute pathname. Return false
707 ** if it is relative.
708 */
709 int file_is_absolute_path(const char *zPath){
710 if( zPath[0]=='/'
711 #if defined(__CYGWIN__)
712 || zPath[0]=='\\'
713 #elif defined(_WIN32)
714 || zPath[0]=='\\'
715 || (strlen(zPath)>3 && zPath[1]==':'
716 && (zPath[2]=='\\' || zPath[2]=='/'))
717 #endif
718 ){
719 return 1;
720 }else{
@@ -731,21 +729,21 @@
731 ** If the slash parameter is non-zero, the trailing slash, if any,
732 ** is retained.
733 */
734 void file_canonical_name(const char *zOrigName, Blob *pOut, int slash){
735 if( file_is_absolute_path(zOrigName) ){
736 #if defined(_WIN32)
737 char *zOut;
738 #endif
739 blob_set(pOut, zOrigName);
740 blob_materialize(pOut);
741 #if defined(_WIN32)
742 /*
743 ** On Windows, normalize the drive letter to upper case.
744 */
745 zOut = blob_str(pOut);
746 if( fossil_isalpha(zOut[0]) && zOut[1]==':' ){
747 zOut[0] = fossil_toupper(zOut[0]);
748 }
749 #endif
750 }else{
751 char zPwd[2000];
@@ -752,11 +750,11 @@
752 file_getcwd(zPwd, sizeof(zPwd)-strlen(zOrigName));
753 #if defined(_WIN32)
754 /*
755 ** On Windows, normalize the drive letter to upper case.
756 */
757 if( fossil_isalpha(zPwd[0]) && zPwd[1]==':' ){
758 zPwd[0] = fossil_toupper(zPwd[0]);
759 }
760 #endif
761 blob_zero(pOut);
762 blob_appendf(pOut, "%//%/", zPwd, zOrigName);
@@ -801,12 +799,12 @@
801 ** contain no "/./" or "/../" terms.
802 */
803 int file_is_canonical(const char *z){
804 int i;
805 if( z[0]!='/'
806 #if defined(_WIN32)
807 && (z[0]==0 || z[1]!=':' || z[2]!='/')
808 #endif
809 ) return 0;
810
811 for(i=0; z[i]; i++){
812 if( z[i]=='\\' ) return 0;
@@ -1014,23 +1012,26 @@
1014
1015 /*
1016 ** Construct a random temporary filename into zBuf[].
1017 */
1018 void file_tempname(int nBuf, char *zBuf){
1019 static const char *azDirs[] = {
1020 #if defined(_WIN32)
 
1021 0, /* GetTempPath */
1022 0, /* TEMP */
1023 0, /* TMP */
 
 
1024 #else
 
1025 "/var/tmp",
1026 "/usr/tmp",
1027 "/tmp",
1028 "/temp",
1029 #endif
1030 ".",
1031 };
 
1032 static const unsigned char zChars[] =
1033 "abcdefghijklmnopqrstuvwxyz"
1034 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
1035 "0123456789";
1036 unsigned int i, j;
@@ -1073,12 +1074,13 @@
1073 }
1074 zBuf[j] = 0;
1075 }while( file_size(zBuf)>=0 );
1076
1077 #if defined(_WIN32)
1078 fossil_unicode_free((char *)azDirs[1]);
1079 fossil_unicode_free((char *)azDirs[2]);
 
1080 #endif
1081 }
1082
1083
1084 /*
1085
--- src/file.c
+++ src/file.c
@@ -706,15 +706,13 @@
706 ** Return true if zPath is an absolute pathname. Return false
707 ** if it is relative.
708 */
709 int file_is_absolute_path(const char *zPath){
710 if( zPath[0]=='/'
711 #if defined(_WIN32) || defined(__CYGWIN__)
712 || zPath[0]=='\\'
713 || (fossil_isalpha(zPath[0]) && zPath[1]==':'
 
 
714 && (zPath[2]=='\\' || zPath[2]=='/'))
715 #endif
716 ){
717 return 1;
718 }else{
@@ -731,21 +729,21 @@
729 ** If the slash parameter is non-zero, the trailing slash, if any,
730 ** is retained.
731 */
732 void file_canonical_name(const char *zOrigName, Blob *pOut, int slash){
733 if( file_is_absolute_path(zOrigName) ){
734 #if defined(_WIN32) || defined(__CYGWIN__)
735 char *zOut;
736 #endif
737 blob_set(pOut, zOrigName);
738 blob_materialize(pOut);
739 #if defined(_WIN32) || defined(__CYGWIN__)
740 /*
741 ** On Windows/cygwin, normalize the drive letter to upper case.
742 */
743 zOut = blob_str(pOut);
744 if( fossil_islower(zOut[0]) && zOut[1]==':' ){
745 zOut[0] = fossil_toupper(zOut[0]);
746 }
747 #endif
748 }else{
749 char zPwd[2000];
@@ -752,11 +750,11 @@
750 file_getcwd(zPwd, sizeof(zPwd)-strlen(zOrigName));
751 #if defined(_WIN32)
752 /*
753 ** On Windows, normalize the drive letter to upper case.
754 */
755 if( fossil_islower(zPwd[0]) && zPwd[1]==':' ){
756 zPwd[0] = fossil_toupper(zPwd[0]);
757 }
758 #endif
759 blob_zero(pOut);
760 blob_appendf(pOut, "%//%/", zPwd, zOrigName);
@@ -801,12 +799,12 @@
799 ** contain no "/./" or "/../" terms.
800 */
801 int file_is_canonical(const char *z){
802 int i;
803 if( z[0]!='/'
804 #if defined(_WIN32) || defined(__CYGWIN__)
805 && (!fossil_isupper(z[0]) || z[1]!=':' || z[2]!='/')
806 #endif
807 ) return 0;
808
809 for(i=0; z[i]; i++){
810 if( z[i]=='\\' ) return 0;
@@ -1014,23 +1012,26 @@
1012
1013 /*
1014 ** Construct a random temporary filename into zBuf[].
1015 */
1016 void file_tempname(int nBuf, char *zBuf){
 
1017 #if defined(_WIN32)
1018 const char *azDirs[] = {
1019 0, /* GetTempPath */
1020 0, /* TEMP */
1021 0, /* TMP */
1022 ".",
1023 };
1024 #else
1025 static const char *const azDirs[] = {
1026 "/var/tmp",
1027 "/usr/tmp",
1028 "/tmp",
1029 "/temp",
 
1030 ".",
1031 };
1032 #endif
1033 static const unsigned char zChars[] =
1034 "abcdefghijklmnopqrstuvwxyz"
1035 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
1036 "0123456789";
1037 unsigned int i, j;
@@ -1073,12 +1074,13 @@
1074 }
1075 zBuf[j] = 0;
1076 }while( file_size(zBuf)>=0 );
1077
1078 #if defined(_WIN32)
1079 fossil_filename_free((char *)azDirs[0]);
1080 fossil_filename_free((char *)azDirs[1]);
1081 fossil_filename_free((char *)azDirs[2]);
1082 #endif
1083 }
1084
1085
1086 /*
1087
+17 -15
--- src/file.c
+++ src/file.c
@@ -706,15 +706,13 @@
706706
** Return true if zPath is an absolute pathname. Return false
707707
** if it is relative.
708708
*/
709709
int file_is_absolute_path(const char *zPath){
710710
if( zPath[0]=='/'
711
-#if defined(__CYGWIN__)
711
+#if defined(_WIN32) || defined(__CYGWIN__)
712712
|| zPath[0]=='\\'
713
-#elif defined(_WIN32)
714
- || zPath[0]=='\\'
715
- || (strlen(zPath)>3 && zPath[1]==':'
713
+ || (fossil_isalpha(zPath[0]) && zPath[1]==':'
716714
&& (zPath[2]=='\\' || zPath[2]=='/'))
717715
#endif
718716
){
719717
return 1;
720718
}else{
@@ -731,21 +729,21 @@
731729
** If the slash parameter is non-zero, the trailing slash, if any,
732730
** is retained.
733731
*/
734732
void file_canonical_name(const char *zOrigName, Blob *pOut, int slash){
735733
if( file_is_absolute_path(zOrigName) ){
736
-#if defined(_WIN32)
734
+#if defined(_WIN32) || defined(__CYGWIN__)
737735
char *zOut;
738736
#endif
739737
blob_set(pOut, zOrigName);
740738
blob_materialize(pOut);
741
-#if defined(_WIN32)
739
+#if defined(_WIN32) || defined(__CYGWIN__)
742740
/*
743
- ** On Windows, normalize the drive letter to upper case.
741
+ ** On Windows/cygwin, normalize the drive letter to upper case.
744742
*/
745743
zOut = blob_str(pOut);
746
- if( fossil_isalpha(zOut[0]) && zOut[1]==':' ){
744
+ if( fossil_islower(zOut[0]) && zOut[1]==':' ){
747745
zOut[0] = fossil_toupper(zOut[0]);
748746
}
749747
#endif
750748
}else{
751749
char zPwd[2000];
@@ -752,11 +750,11 @@
752750
file_getcwd(zPwd, sizeof(zPwd)-strlen(zOrigName));
753751
#if defined(_WIN32)
754752
/*
755753
** On Windows, normalize the drive letter to upper case.
756754
*/
757
- if( fossil_isalpha(zPwd[0]) && zPwd[1]==':' ){
755
+ if( fossil_islower(zPwd[0]) && zPwd[1]==':' ){
758756
zPwd[0] = fossil_toupper(zPwd[0]);
759757
}
760758
#endif
761759
blob_zero(pOut);
762760
blob_appendf(pOut, "%//%/", zPwd, zOrigName);
@@ -801,12 +799,12 @@
801799
** contain no "/./" or "/../" terms.
802800
*/
803801
int file_is_canonical(const char *z){
804802
int i;
805803
if( z[0]!='/'
806
-#if defined(_WIN32)
807
- && (z[0]==0 || z[1]!=':' || z[2]!='/')
804
+#if defined(_WIN32) || defined(__CYGWIN__)
805
+ && (!fossil_isupper(z[0]) || z[1]!=':' || z[2]!='/')
808806
#endif
809807
) return 0;
810808
811809
for(i=0; z[i]; i++){
812810
if( z[i]=='\\' ) return 0;
@@ -1014,23 +1012,26 @@
10141012
10151013
/*
10161014
** Construct a random temporary filename into zBuf[].
10171015
*/
10181016
void file_tempname(int nBuf, char *zBuf){
1019
- static const char *azDirs[] = {
10201017
#if defined(_WIN32)
1018
+ const char *azDirs[] = {
10211019
0, /* GetTempPath */
10221020
0, /* TEMP */
10231021
0, /* TMP */
1022
+ ".",
1023
+ };
10241024
#else
1025
+ static const char *const azDirs[] = {
10251026
"/var/tmp",
10261027
"/usr/tmp",
10271028
"/tmp",
10281029
"/temp",
1029
-#endif
10301030
".",
10311031
};
1032
+#endif
10321033
static const unsigned char zChars[] =
10331034
"abcdefghijklmnopqrstuvwxyz"
10341035
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
10351036
"0123456789";
10361037
unsigned int i, j;
@@ -1073,12 +1074,13 @@
10731074
}
10741075
zBuf[j] = 0;
10751076
}while( file_size(zBuf)>=0 );
10761077
10771078
#if defined(_WIN32)
1078
- fossil_unicode_free((char *)azDirs[1]);
1079
- fossil_unicode_free((char *)azDirs[2]);
1079
+ fossil_filename_free((char *)azDirs[0]);
1080
+ fossil_filename_free((char *)azDirs[1]);
1081
+ fossil_filename_free((char *)azDirs[2]);
10801082
#endif
10811083
}
10821084
10831085
10841086
/*
10851087
--- src/file.c
+++ src/file.c
@@ -706,15 +706,13 @@
706 ** Return true if zPath is an absolute pathname. Return false
707 ** if it is relative.
708 */
709 int file_is_absolute_path(const char *zPath){
710 if( zPath[0]=='/'
711 #if defined(__CYGWIN__)
712 || zPath[0]=='\\'
713 #elif defined(_WIN32)
714 || zPath[0]=='\\'
715 || (strlen(zPath)>3 && zPath[1]==':'
716 && (zPath[2]=='\\' || zPath[2]=='/'))
717 #endif
718 ){
719 return 1;
720 }else{
@@ -731,21 +729,21 @@
731 ** If the slash parameter is non-zero, the trailing slash, if any,
732 ** is retained.
733 */
734 void file_canonical_name(const char *zOrigName, Blob *pOut, int slash){
735 if( file_is_absolute_path(zOrigName) ){
736 #if defined(_WIN32)
737 char *zOut;
738 #endif
739 blob_set(pOut, zOrigName);
740 blob_materialize(pOut);
741 #if defined(_WIN32)
742 /*
743 ** On Windows, normalize the drive letter to upper case.
744 */
745 zOut = blob_str(pOut);
746 if( fossil_isalpha(zOut[0]) && zOut[1]==':' ){
747 zOut[0] = fossil_toupper(zOut[0]);
748 }
749 #endif
750 }else{
751 char zPwd[2000];
@@ -752,11 +750,11 @@
752 file_getcwd(zPwd, sizeof(zPwd)-strlen(zOrigName));
753 #if defined(_WIN32)
754 /*
755 ** On Windows, normalize the drive letter to upper case.
756 */
757 if( fossil_isalpha(zPwd[0]) && zPwd[1]==':' ){
758 zPwd[0] = fossil_toupper(zPwd[0]);
759 }
760 #endif
761 blob_zero(pOut);
762 blob_appendf(pOut, "%//%/", zPwd, zOrigName);
@@ -801,12 +799,12 @@
801 ** contain no "/./" or "/../" terms.
802 */
803 int file_is_canonical(const char *z){
804 int i;
805 if( z[0]!='/'
806 #if defined(_WIN32)
807 && (z[0]==0 || z[1]!=':' || z[2]!='/')
808 #endif
809 ) return 0;
810
811 for(i=0; z[i]; i++){
812 if( z[i]=='\\' ) return 0;
@@ -1014,23 +1012,26 @@
1014
1015 /*
1016 ** Construct a random temporary filename into zBuf[].
1017 */
1018 void file_tempname(int nBuf, char *zBuf){
1019 static const char *azDirs[] = {
1020 #if defined(_WIN32)
 
1021 0, /* GetTempPath */
1022 0, /* TEMP */
1023 0, /* TMP */
 
 
1024 #else
 
1025 "/var/tmp",
1026 "/usr/tmp",
1027 "/tmp",
1028 "/temp",
1029 #endif
1030 ".",
1031 };
 
1032 static const unsigned char zChars[] =
1033 "abcdefghijklmnopqrstuvwxyz"
1034 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
1035 "0123456789";
1036 unsigned int i, j;
@@ -1073,12 +1074,13 @@
1073 }
1074 zBuf[j] = 0;
1075 }while( file_size(zBuf)>=0 );
1076
1077 #if defined(_WIN32)
1078 fossil_unicode_free((char *)azDirs[1]);
1079 fossil_unicode_free((char *)azDirs[2]);
 
1080 #endif
1081 }
1082
1083
1084 /*
1085
--- src/file.c
+++ src/file.c
@@ -706,15 +706,13 @@
706 ** Return true if zPath is an absolute pathname. Return false
707 ** if it is relative.
708 */
709 int file_is_absolute_path(const char *zPath){
710 if( zPath[0]=='/'
711 #if defined(_WIN32) || defined(__CYGWIN__)
712 || zPath[0]=='\\'
713 || (fossil_isalpha(zPath[0]) && zPath[1]==':'
 
 
714 && (zPath[2]=='\\' || zPath[2]=='/'))
715 #endif
716 ){
717 return 1;
718 }else{
@@ -731,21 +729,21 @@
729 ** If the slash parameter is non-zero, the trailing slash, if any,
730 ** is retained.
731 */
732 void file_canonical_name(const char *zOrigName, Blob *pOut, int slash){
733 if( file_is_absolute_path(zOrigName) ){
734 #if defined(_WIN32) || defined(__CYGWIN__)
735 char *zOut;
736 #endif
737 blob_set(pOut, zOrigName);
738 blob_materialize(pOut);
739 #if defined(_WIN32) || defined(__CYGWIN__)
740 /*
741 ** On Windows/cygwin, normalize the drive letter to upper case.
742 */
743 zOut = blob_str(pOut);
744 if( fossil_islower(zOut[0]) && zOut[1]==':' ){
745 zOut[0] = fossil_toupper(zOut[0]);
746 }
747 #endif
748 }else{
749 char zPwd[2000];
@@ -752,11 +750,11 @@
750 file_getcwd(zPwd, sizeof(zPwd)-strlen(zOrigName));
751 #if defined(_WIN32)
752 /*
753 ** On Windows, normalize the drive letter to upper case.
754 */
755 if( fossil_islower(zPwd[0]) && zPwd[1]==':' ){
756 zPwd[0] = fossil_toupper(zPwd[0]);
757 }
758 #endif
759 blob_zero(pOut);
760 blob_appendf(pOut, "%//%/", zPwd, zOrigName);
@@ -801,12 +799,12 @@
799 ** contain no "/./" or "/../" terms.
800 */
801 int file_is_canonical(const char *z){
802 int i;
803 if( z[0]!='/'
804 #if defined(_WIN32) || defined(__CYGWIN__)
805 && (!fossil_isupper(z[0]) || z[1]!=':' || z[2]!='/')
806 #endif
807 ) return 0;
808
809 for(i=0; z[i]; i++){
810 if( z[i]=='\\' ) return 0;
@@ -1014,23 +1012,26 @@
1012
1013 /*
1014 ** Construct a random temporary filename into zBuf[].
1015 */
1016 void file_tempname(int nBuf, char *zBuf){
 
1017 #if defined(_WIN32)
1018 const char *azDirs[] = {
1019 0, /* GetTempPath */
1020 0, /* TEMP */
1021 0, /* TMP */
1022 ".",
1023 };
1024 #else
1025 static const char *const azDirs[] = {
1026 "/var/tmp",
1027 "/usr/tmp",
1028 "/tmp",
1029 "/temp",
 
1030 ".",
1031 };
1032 #endif
1033 static const unsigned char zChars[] =
1034 "abcdefghijklmnopqrstuvwxyz"
1035 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
1036 "0123456789";
1037 unsigned int i, j;
@@ -1073,12 +1074,13 @@
1074 }
1075 zBuf[j] = 0;
1076 }while( file_size(zBuf)>=0 );
1077
1078 #if defined(_WIN32)
1079 fossil_filename_free((char *)azDirs[0]);
1080 fossil_filename_free((char *)azDirs[1]);
1081 fossil_filename_free((char *)azDirs[2]);
1082 #endif
1083 }
1084
1085
1086 /*
1087
+1 -1
--- src/finfo.c
+++ src/finfo.c
@@ -418,11 +418,11 @@
418418
}else{
419419
@ <b>Deleted</b> by check-in
420420
}
421421
}
422422
hyperlink_to_uuid(zShortCkin);
423
- @ %h(zCom) (user:
423
+ @ %w(zCom) (user:
424424
hyperlink_to_user(zUser, zDate, "");
425425
@ branch: %h(zBr))
426426
if( g.perm.Hyperlink && zUuid ){
427427
const char *z = zFilename;
428428
if( fpid ){
429429
--- src/finfo.c
+++ src/finfo.c
@@ -418,11 +418,11 @@
418 }else{
419 @ <b>Deleted</b> by check-in
420 }
421 }
422 hyperlink_to_uuid(zShortCkin);
423 @ %h(zCom) (user:
424 hyperlink_to_user(zUser, zDate, "");
425 @ branch: %h(zBr))
426 if( g.perm.Hyperlink && zUuid ){
427 const char *z = zFilename;
428 if( fpid ){
429
--- src/finfo.c
+++ src/finfo.c
@@ -418,11 +418,11 @@
418 }else{
419 @ <b>Deleted</b> by check-in
420 }
421 }
422 hyperlink_to_uuid(zShortCkin);
423 @ %w(zCom) (user:
424 hyperlink_to_user(zUser, zDate, "");
425 @ branch: %h(zBr))
426 if( g.perm.Hyperlink && zUuid ){
427 const char *z = zFilename;
428 if( fpid ){
429
+6 -6
--- src/info.c
+++ src/info.c
@@ -529,14 +529,14 @@
529529
}else{
530530
@ <tr><th>User:</th><td>
531531
hyperlink_to_user(zUser,zDate,"</td></tr>");
532532
}
533533
if( zEComment ){
534
- @ <tr><th>Edited&nbsp;Comment:</th><td>%w(zEComment)</td></tr>
535
- @ <tr><th>Original&nbsp;Comment:</th><td>%w(zComment)</td></tr>
534
+ @ <tr><th>Edited&nbsp;Comment:</th><td>%!w(zEComment)</td></tr>
535
+ @ <tr><th>Original&nbsp;Comment:</th><td>%!w(zComment)</td></tr>
536536
}else{
537
- @ <tr><th>Comment:</th><td>%w(zComment)</td></tr>
537
+ @ <tr><th>Comment:</th><td>%!w(zComment)</td></tr>
538538
}
539539
if( g.perm.Admin ){
540540
db_prepare(&q,
541541
"SELECT rcvfrom.ipaddr, user.login, datetime(rcvfrom.mtime)"
542542
" FROM blob JOIN rcvfrom USING(rcvid) LEFT JOIN user USING(uid)"
@@ -1075,11 +1075,11 @@
10751075
@ - part of checkin
10761076
hyperlink_to_uuid(zVers);
10771077
if( zBr && zBr[0] ){
10781078
@ on branch %z(href("%R/timeline?r=%T",zBr))%h(zBr)</a>
10791079
}
1080
- @ - %w(zCom) (user:
1080
+ @ - %!w(zCom) (user:
10811081
hyperlink_to_user(zUser,zDate,")");
10821082
if( g.perm.Hyperlink ){
10831083
@ %z(href("%R/annotate?checkin=%S&filename=%T",zVers,zName))
10841084
@ [annotate]</a>
10851085
}
@@ -1158,11 +1158,11 @@
11581158
@ Control file referencing
11591159
}
11601160
if( zType[0]!='e' ){
11611161
hyperlink_to_uuid(zUuid);
11621162
}
1163
- @ - %w(zCom) by
1163
+ @ - %!w(zCom) by
11641164
hyperlink_to_user(zUser,zDate," on");
11651165
hyperlink_to_date(zDate, ".");
11661166
if( pDownloadName && blob_size(pDownloadName)==0 ){
11671167
blob_appendf(pDownloadName, "%.10s.txt", zUuid);
11681168
}
@@ -2155,11 +2155,11 @@
21552155
if( zNewColor && zNewColor[0] ){
21562156
@ <tr><td style="background-color: %h(zNewColor);">
21572157
}else{
21582158
@ <tr><td>
21592159
}
2160
- @ %w(blob_str(&comment))
2160
+ @ %!w(blob_str(&comment))
21612161
blob_zero(&suffix);
21622162
blob_appendf(&suffix, "(user: %h", zNewUser);
21632163
db_prepare(&q, "SELECT substr(tagname,5) FROM tagxref, tag"
21642164
" WHERE tagname GLOB 'sym-*' AND tagxref.rid=%d"
21652165
" AND tagtype>1 AND tag.tagid=tagxref.tagid",
21662166
--- src/info.c
+++ src/info.c
@@ -529,14 +529,14 @@
529 }else{
530 @ <tr><th>User:</th><td>
531 hyperlink_to_user(zUser,zDate,"</td></tr>");
532 }
533 if( zEComment ){
534 @ <tr><th>Edited&nbsp;Comment:</th><td>%w(zEComment)</td></tr>
535 @ <tr><th>Original&nbsp;Comment:</th><td>%w(zComment)</td></tr>
536 }else{
537 @ <tr><th>Comment:</th><td>%w(zComment)</td></tr>
538 }
539 if( g.perm.Admin ){
540 db_prepare(&q,
541 "SELECT rcvfrom.ipaddr, user.login, datetime(rcvfrom.mtime)"
542 " FROM blob JOIN rcvfrom USING(rcvid) LEFT JOIN user USING(uid)"
@@ -1075,11 +1075,11 @@
1075 @ - part of checkin
1076 hyperlink_to_uuid(zVers);
1077 if( zBr && zBr[0] ){
1078 @ on branch %z(href("%R/timeline?r=%T",zBr))%h(zBr)</a>
1079 }
1080 @ - %w(zCom) (user:
1081 hyperlink_to_user(zUser,zDate,")");
1082 if( g.perm.Hyperlink ){
1083 @ %z(href("%R/annotate?checkin=%S&filename=%T",zVers,zName))
1084 @ [annotate]</a>
1085 }
@@ -1158,11 +1158,11 @@
1158 @ Control file referencing
1159 }
1160 if( zType[0]!='e' ){
1161 hyperlink_to_uuid(zUuid);
1162 }
1163 @ - %w(zCom) by
1164 hyperlink_to_user(zUser,zDate," on");
1165 hyperlink_to_date(zDate, ".");
1166 if( pDownloadName && blob_size(pDownloadName)==0 ){
1167 blob_appendf(pDownloadName, "%.10s.txt", zUuid);
1168 }
@@ -2155,11 +2155,11 @@
2155 if( zNewColor && zNewColor[0] ){
2156 @ <tr><td style="background-color: %h(zNewColor);">
2157 }else{
2158 @ <tr><td>
2159 }
2160 @ %w(blob_str(&comment))
2161 blob_zero(&suffix);
2162 blob_appendf(&suffix, "(user: %h", zNewUser);
2163 db_prepare(&q, "SELECT substr(tagname,5) FROM tagxref, tag"
2164 " WHERE tagname GLOB 'sym-*' AND tagxref.rid=%d"
2165 " AND tagtype>1 AND tag.tagid=tagxref.tagid",
2166
--- src/info.c
+++ src/info.c
@@ -529,14 +529,14 @@
529 }else{
530 @ <tr><th>User:</th><td>
531 hyperlink_to_user(zUser,zDate,"</td></tr>");
532 }
533 if( zEComment ){
534 @ <tr><th>Edited&nbsp;Comment:</th><td>%!w(zEComment)</td></tr>
535 @ <tr><th>Original&nbsp;Comment:</th><td>%!w(zComment)</td></tr>
536 }else{
537 @ <tr><th>Comment:</th><td>%!w(zComment)</td></tr>
538 }
539 if( g.perm.Admin ){
540 db_prepare(&q,
541 "SELECT rcvfrom.ipaddr, user.login, datetime(rcvfrom.mtime)"
542 " FROM blob JOIN rcvfrom USING(rcvid) LEFT JOIN user USING(uid)"
@@ -1075,11 +1075,11 @@
1075 @ - part of checkin
1076 hyperlink_to_uuid(zVers);
1077 if( zBr && zBr[0] ){
1078 @ on branch %z(href("%R/timeline?r=%T",zBr))%h(zBr)</a>
1079 }
1080 @ - %!w(zCom) (user:
1081 hyperlink_to_user(zUser,zDate,")");
1082 if( g.perm.Hyperlink ){
1083 @ %z(href("%R/annotate?checkin=%S&filename=%T",zVers,zName))
1084 @ [annotate]</a>
1085 }
@@ -1158,11 +1158,11 @@
1158 @ Control file referencing
1159 }
1160 if( zType[0]!='e' ){
1161 hyperlink_to_uuid(zUuid);
1162 }
1163 @ - %!w(zCom) by
1164 hyperlink_to_user(zUser,zDate," on");
1165 hyperlink_to_date(zDate, ".");
1166 if( pDownloadName && blob_size(pDownloadName)==0 ){
1167 blob_appendf(pDownloadName, "%.10s.txt", zUuid);
1168 }
@@ -2155,11 +2155,11 @@
2155 if( zNewColor && zNewColor[0] ){
2156 @ <tr><td style="background-color: %h(zNewColor);">
2157 }else{
2158 @ <tr><td>
2159 }
2160 @ %!w(blob_str(&comment))
2161 blob_zero(&suffix);
2162 blob_appendf(&suffix, "(user: %h", zNewUser);
2163 db_prepare(&q, "SELECT substr(tagname,5) FROM tagxref, tag"
2164 " WHERE tagname GLOB 'sym-*' AND tagxref.rid=%d"
2165 " AND tagtype>1 AND tag.tagid=tagxref.tagid",
2166
+1 -1
--- src/main.c
+++ src/main.c
@@ -605,11 +605,11 @@
605605
606606
/*
607607
** Print a usage comment and quit
608608
*/
609609
void usage(const char *zFormat){
610
- fossil_fatal("Usage: %s %s %s\n", g.argv[0], g.argv[1], zFormat);
610
+ fossil_fatal("Usage: %s %s %s", g.argv[0], g.argv[1], zFormat);
611611
}
612612
613613
/*
614614
** Remove n elements from g.argv beginning with the i-th element.
615615
*/
616616
--- src/main.c
+++ src/main.c
@@ -605,11 +605,11 @@
605
606 /*
607 ** Print a usage comment and quit
608 */
609 void usage(const char *zFormat){
610 fossil_fatal("Usage: %s %s %s\n", g.argv[0], g.argv[1], zFormat);
611 }
612
613 /*
614 ** Remove n elements from g.argv beginning with the i-th element.
615 */
616
--- src/main.c
+++ src/main.c
@@ -605,11 +605,11 @@
605
606 /*
607 ** Print a usage comment and quit
608 */
609 void usage(const char *zFormat){
610 fossil_fatal("Usage: %s %s %s", g.argv[0], g.argv[1], zFormat);
611 }
612
613 /*
614 ** Remove n elements from g.argv beginning with the i-th element.
615 */
616
+8 -3
--- src/printf.c
+++ src/printf.c
@@ -164,15 +164,20 @@
164164
165165
/*
166166
** Return an appropriate set of flags for wiki_convert() for displaying
167167
** comments on a timeline. These flag settings are determined by
168168
** configuration parameters.
169
+**
170
+** The altForm2 argument is true for "%!w" (with the "!" alternate-form-2
171
+** flags) and is false for plain "%w". The ! indicates that the text is
172
+** to be rendered on a form rather than the timeline and that block markup
173
+** is acceptable even if the "timeline-block-markup" setting is false.
169174
*/
170
-static int wiki_convert_flags(void){
175
+static int wiki_convert_flags(int altForm2){
171176
static int wikiFlags = 0;
172177
if( wikiFlags==0 ){
173
- if( db_get_boolean("timeline-block-markup", 0) ){
178
+ if( altForm2 || db_get_boolean("timeline-block-markup", 0) ){
174179
wikiFlags = WIKI_INLINE | WIKI_NOBADLINKS;
175180
}else{
176181
wikiFlags = WIKI_INLINE | WIKI_NOBLOCK | WIKI_NOBADLINKS;
177182
}
178183
if( db_get_boolean("timeline-plaintext", 0) ){
@@ -722,11 +727,11 @@
722727
case etWIKISTR: {
723728
int limit = flag_alternateform ? va_arg(ap,int) : -1;
724729
char *zWiki = va_arg(ap, char*);
725730
Blob wiki;
726731
blob_init(&wiki, zWiki, limit);
727
- wiki_convert(&wiki, pBlob, wiki_convert_flags());
732
+ wiki_convert(&wiki, pBlob, wiki_convert_flags(flag_altform2));
728733
blob_reset(&wiki);
729734
length = width = 0;
730735
break;
731736
}
732737
case etERROR:
733738
--- src/printf.c
+++ src/printf.c
@@ -164,15 +164,20 @@
164
165 /*
166 ** Return an appropriate set of flags for wiki_convert() for displaying
167 ** comments on a timeline. These flag settings are determined by
168 ** configuration parameters.
 
 
 
 
 
169 */
170 static int wiki_convert_flags(void){
171 static int wikiFlags = 0;
172 if( wikiFlags==0 ){
173 if( db_get_boolean("timeline-block-markup", 0) ){
174 wikiFlags = WIKI_INLINE | WIKI_NOBADLINKS;
175 }else{
176 wikiFlags = WIKI_INLINE | WIKI_NOBLOCK | WIKI_NOBADLINKS;
177 }
178 if( db_get_boolean("timeline-plaintext", 0) ){
@@ -722,11 +727,11 @@
722 case etWIKISTR: {
723 int limit = flag_alternateform ? va_arg(ap,int) : -1;
724 char *zWiki = va_arg(ap, char*);
725 Blob wiki;
726 blob_init(&wiki, zWiki, limit);
727 wiki_convert(&wiki, pBlob, wiki_convert_flags());
728 blob_reset(&wiki);
729 length = width = 0;
730 break;
731 }
732 case etERROR:
733
--- src/printf.c
+++ src/printf.c
@@ -164,15 +164,20 @@
164
165 /*
166 ** Return an appropriate set of flags for wiki_convert() for displaying
167 ** comments on a timeline. These flag settings are determined by
168 ** configuration parameters.
169 **
170 ** The altForm2 argument is true for "%!w" (with the "!" alternate-form-2
171 ** flags) and is false for plain "%w". The ! indicates that the text is
172 ** to be rendered on a form rather than the timeline and that block markup
173 ** is acceptable even if the "timeline-block-markup" setting is false.
174 */
175 static int wiki_convert_flags(int altForm2){
176 static int wikiFlags = 0;
177 if( wikiFlags==0 ){
178 if( altForm2 || db_get_boolean("timeline-block-markup", 0) ){
179 wikiFlags = WIKI_INLINE | WIKI_NOBADLINKS;
180 }else{
181 wikiFlags = WIKI_INLINE | WIKI_NOBLOCK | WIKI_NOBADLINKS;
182 }
183 if( db_get_boolean("timeline-plaintext", 0) ){
@@ -722,11 +727,11 @@
727 case etWIKISTR: {
728 int limit = flag_alternateform ? va_arg(ap,int) : -1;
729 char *zWiki = va_arg(ap, char*);
730 Blob wiki;
731 blob_init(&wiki, zWiki, limit);
732 wiki_convert(&wiki, pBlob, wiki_convert_flags(flag_altform2));
733 blob_reset(&wiki);
734 length = width = 0;
735 break;
736 }
737 case etERROR:
738
+3 -2
--- src/regexp.c
+++ src/regexp.c
@@ -111,11 +111,11 @@
111111
ReInput sIn; /* Regular expression text */
112112
const char *zErr; /* Error message to return */
113113
char *aOp; /* Operators for the virtual machine */
114114
int *aArg; /* Arguments to each operator */
115115
unsigned (*xNextChar)(ReInput*); /* Next character function */
116
- char zInit[12]; /* Initial text to match */
116
+ unsigned char zInit[12]; /* Initial text to match */
117117
int nInit; /* Number of characters in zInit */
118118
unsigned nState; /* Number of entries in aOp[] and aArg[] */
119119
unsigned nAlloc; /* Slots allocated for aOp[] and aArg[] */
120120
};
121121
#endif
@@ -197,11 +197,12 @@
197197
198198
/* Look for the initial prefix match, if there is one. */
199199
if( pRe->nInit ){
200200
unsigned char x = pRe->zInit[0];
201201
while( in.i+pRe->nInit<=in.mx
202
- && (zIn[in.i]!=x || memcmp(zIn+in.i, pRe->zInit, pRe->nInit)!=0)
202
+ && (zIn[in.i]!=x ||
203
+ strncmp((const char*)zIn+in.i, (const char*)pRe->zInit, pRe->nInit)!=0)
203204
){
204205
in.i++;
205206
}
206207
if( in.i+pRe->nInit>in.mx ) return 0;
207208
}
208209
--- src/regexp.c
+++ src/regexp.c
@@ -111,11 +111,11 @@
111 ReInput sIn; /* Regular expression text */
112 const char *zErr; /* Error message to return */
113 char *aOp; /* Operators for the virtual machine */
114 int *aArg; /* Arguments to each operator */
115 unsigned (*xNextChar)(ReInput*); /* Next character function */
116 char zInit[12]; /* Initial text to match */
117 int nInit; /* Number of characters in zInit */
118 unsigned nState; /* Number of entries in aOp[] and aArg[] */
119 unsigned nAlloc; /* Slots allocated for aOp[] and aArg[] */
120 };
121 #endif
@@ -197,11 +197,12 @@
197
198 /* Look for the initial prefix match, if there is one. */
199 if( pRe->nInit ){
200 unsigned char x = pRe->zInit[0];
201 while( in.i+pRe->nInit<=in.mx
202 && (zIn[in.i]!=x || memcmp(zIn+in.i, pRe->zInit, pRe->nInit)!=0)
 
203 ){
204 in.i++;
205 }
206 if( in.i+pRe->nInit>in.mx ) return 0;
207 }
208
--- src/regexp.c
+++ src/regexp.c
@@ -111,11 +111,11 @@
111 ReInput sIn; /* Regular expression text */
112 const char *zErr; /* Error message to return */
113 char *aOp; /* Operators for the virtual machine */
114 int *aArg; /* Arguments to each operator */
115 unsigned (*xNextChar)(ReInput*); /* Next character function */
116 unsigned char zInit[12]; /* Initial text to match */
117 int nInit; /* Number of characters in zInit */
118 unsigned nState; /* Number of entries in aOp[] and aArg[] */
119 unsigned nAlloc; /* Slots allocated for aOp[] and aArg[] */
120 };
121 #endif
@@ -197,11 +197,12 @@
197
198 /* Look for the initial prefix match, if there is one. */
199 if( pRe->nInit ){
200 unsigned char x = pRe->zInit[0];
201 while( in.i+pRe->nInit<=in.mx
202 && (zIn[in.i]!=x ||
203 strncmp((const char*)zIn+in.i, (const char*)pRe->zInit, pRe->nInit)!=0)
204 ){
205 in.i++;
206 }
207 if( in.i+pRe->nInit>in.mx ) return 0;
208 }
209
+2 -1
--- src/shell.c
+++ src/shell.c
@@ -88,11 +88,12 @@
8888
/* ctype macros that work with signed characters */
8989
#define IsSpace(X) isspace((unsigned char)X)
9090
#define IsDigit(X) isdigit((unsigned char)X)
9191
#define ToLower(X) (char)tolower((unsigned char)X)
9292
93
-#if !defined(_WIN32) && !defined(WIN32) && !defined(_WRS_KERNEL)
93
+#if !defined(_WIN32) && !defined(WIN32) && !defined(_WRS_KERNEL) \
94
+ && !defined(__minux)
9495
#include <sys/time.h>
9596
#include <sys/resource.h>
9697
9798
/* Saved resource information for the beginning of an operation */
9899
static struct rusage sBegin;
99100
--- src/shell.c
+++ src/shell.c
@@ -88,11 +88,12 @@
88 /* ctype macros that work with signed characters */
89 #define IsSpace(X) isspace((unsigned char)X)
90 #define IsDigit(X) isdigit((unsigned char)X)
91 #define ToLower(X) (char)tolower((unsigned char)X)
92
93 #if !defined(_WIN32) && !defined(WIN32) && !defined(_WRS_KERNEL)
 
94 #include <sys/time.h>
95 #include <sys/resource.h>
96
97 /* Saved resource information for the beginning of an operation */
98 static struct rusage sBegin;
99
--- src/shell.c
+++ src/shell.c
@@ -88,11 +88,12 @@
88 /* ctype macros that work with signed characters */
89 #define IsSpace(X) isspace((unsigned char)X)
90 #define IsDigit(X) isdigit((unsigned char)X)
91 #define ToLower(X) (char)tolower((unsigned char)X)
92
93 #if !defined(_WIN32) && !defined(WIN32) && !defined(_WRS_KERNEL) \
94 && !defined(__minux)
95 #include <sys/time.h>
96 #include <sys/resource.h>
97
98 /* Saved resource information for the beginning of an operation */
99 static struct rusage sBegin;
100
+326 -195
--- src/sqlite3.c
+++ src/sqlite3.c
@@ -438,11 +438,12 @@
438438
** if it is already defined or if it is unneeded because we are
439439
** not doing a threadsafe build. Ticket #2681.
440440
**
441441
** See also ticket #2741.
442442
*/
443
-#if !defined(_XOPEN_SOURCE) && !defined(__DARWIN__) && !defined(__APPLE__) && SQLITE_THREADSAFE
443
+#if !defined(_XOPEN_SOURCE) && !defined(__DARWIN__) \
444
+ && !defined(__APPLE__) && SQLITE_THREADSAFE
444445
# define _XOPEN_SOURCE 500 /* Needed to enable pthread recursive mutexes */
445446
#endif
446447
447448
/*
448449
** The TCL headers are only needed when compiling the TCL bindings.
@@ -673,11 +674,11 @@
673674
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
674675
** [sqlite_version()] and [sqlite_source_id()].
675676
*/
676677
#define SQLITE_VERSION "3.7.16"
677678
#define SQLITE_VERSION_NUMBER 3007016
678
-#define SQLITE_SOURCE_ID "2013-02-13 14:04:28 7e10a62d0eb1cb2bdafb6752b78a9d368e9f21f5"
679
+#define SQLITE_SOURCE_ID "2013-03-01 23:40:26 780d06c5e54590f677f993fa9c313989c2eab8c7"
679680
680681
/*
681682
** CAPI3REF: Run-Time Library Version Numbers
682683
** KEYWORDS: sqlite3_version, sqlite3_sourceid
683684
**
@@ -11915,11 +11916,11 @@
1191511916
SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3*, Select*);
1191611917
SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse*, SrcList*);
1191711918
SQLITE_PRIVATE int sqlite3IsReadOnly(Parse*, Table*, int);
1191811919
SQLITE_PRIVATE void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int);
1191911920
#if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY)
11920
-SQLITE_PRIVATE Expr *sqlite3LimitWhere(Parse *, SrcList *, Expr *, ExprList *, Expr *, Expr *, char *);
11921
+SQLITE_PRIVATE Expr *sqlite3LimitWhere(Parse*,SrcList*,Expr*,ExprList*,Expr*,Expr*,char*);
1192111922
#endif
1192211923
SQLITE_PRIVATE void sqlite3DeleteFrom(Parse*, SrcList*, Expr*);
1192311924
SQLITE_PRIVATE void sqlite3Update(Parse*, SrcList*, ExprList*, Expr*, int);
1192411925
SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(Parse*,SrcList*,Expr*,ExprList*,ExprList*,u16,int);
1192511926
SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo*);
@@ -12096,12 +12097,15 @@
1209612097
**
1209712098
** x = getVarint32( A, B );
1209812099
** x = putVarint32( A, B );
1209912100
**
1210012101
*/
12101
-#define getVarint32(A,B) (u8)((*(A)<(u8)0x80) ? ((B) = (u32)*(A)),1 : sqlite3GetVarint32((A), (u32 *)&(B)))
12102
-#define putVarint32(A,B) (u8)(((u32)(B)<(u32)0x80) ? (*(A) = (unsigned char)(B)),1 : sqlite3PutVarint32((A), (B)))
12102
+#define getVarint32(A,B) \
12103
+ (u8)((*(A)<(u8)0x80)?((B)=(u32)*(A)),1:sqlite3GetVarint32((A),(u32 *)&(B)))
12104
+#define putVarint32(A,B) \
12105
+ (u8)(((u32)(B)<(u32)0x80)?(*(A)=(unsigned char)(B)),1:\
12106
+ sqlite3PutVarint32((A),(B)))
1210312107
#define getVarint sqlite3GetVarint
1210412108
#define putVarint sqlite3PutVarint
1210512109
1210612110
1210712111
SQLITE_PRIVATE const char *sqlite3IndexAffinityStr(Vdbe *, Index *);
@@ -27655,11 +27659,11 @@
2765527659
pNew->ctrlFlags = (u8)ctrlFlags;
2765627660
if( sqlite3_uri_boolean(((ctrlFlags & UNIXFILE_URI) ? zFilename : 0),
2765727661
"psow", SQLITE_POWERSAFE_OVERWRITE) ){
2765827662
pNew->ctrlFlags |= UNIXFILE_PSOW;
2765927663
}
27660
- if( memcmp(pVfs->zName,"unix-excl",10)==0 ){
27664
+ if( strcmp(pVfs->zName,"unix-excl")==0 ){
2766127665
pNew->ctrlFlags |= UNIXFILE_EXCL;
2766227666
}
2766327667
2766427668
#if OS_VXWORKS
2766527669
pNew->pId = vxworksFindFileId(zFilename);
@@ -31959,21 +31963,23 @@
3195931963
bReturn = TRUE;
3196031964
}
3196131965
}
3196231966
3196331967
/* Want a pending lock? */
31964
- else if (dwFileOffsetLow == (DWORD)PENDING_BYTE && nNumberOfBytesToLockLow == 1){
31968
+ else if (dwFileOffsetLow == (DWORD)PENDING_BYTE
31969
+ && nNumberOfBytesToLockLow == 1){
3196531970
/* If no pending lock has been acquired, then acquire it */
3196631971
if (pFile->shared->bPending == 0) {
3196731972
pFile->shared->bPending = TRUE;
3196831973
pFile->local.bPending = TRUE;
3196931974
bReturn = TRUE;
3197031975
}
3197131976
}
3197231977
3197331978
/* Want a reserved lock? */
31974
- else if (dwFileOffsetLow == (DWORD)RESERVED_BYTE && nNumberOfBytesToLockLow == 1){
31979
+ else if (dwFileOffsetLow == (DWORD)RESERVED_BYTE
31980
+ && nNumberOfBytesToLockLow == 1){
3197531981
if (pFile->shared->bReserved == 0) {
3197631982
pFile->shared->bReserved = TRUE;
3197731983
pFile->local.bReserved = TRUE;
3197831984
bReturn = TRUE;
3197931985
}
@@ -32012,11 +32018,12 @@
3201232018
bReturn = TRUE;
3201332019
}
3201432020
3201532021
/* Did we just have a reader lock? */
3201632022
else if (pFile->local.nReaders){
32017
- assert(nNumberOfBytesToUnlockLow == (DWORD)SHARED_SIZE || nNumberOfBytesToUnlockLow == 1);
32023
+ assert(nNumberOfBytesToUnlockLow == (DWORD)SHARED_SIZE
32024
+ || nNumberOfBytesToUnlockLow == 1);
3201832025
pFile->local.nReaders --;
3201932026
if (pFile->local.nReaders == 0)
3202032027
{
3202132028
pFile->shared->nReaders --;
3202232029
}
@@ -32023,19 +32030,21 @@
3202332030
bReturn = TRUE;
3202432031
}
3202532032
}
3202632033
3202732034
/* Releasing a pending lock */
32028
- else if (dwFileOffsetLow == (DWORD)PENDING_BYTE && nNumberOfBytesToUnlockLow == 1){
32035
+ else if (dwFileOffsetLow == (DWORD)PENDING_BYTE
32036
+ && nNumberOfBytesToUnlockLow == 1){
3202932037
if (pFile->local.bPending){
3203032038
pFile->local.bPending = FALSE;
3203132039
pFile->shared->bPending = FALSE;
3203232040
bReturn = TRUE;
3203332041
}
3203432042
}
3203532043
/* Releasing a reserved lock */
32036
- else if (dwFileOffsetLow == (DWORD)RESERVED_BYTE && nNumberOfBytesToUnlockLow == 1){
32044
+ else if (dwFileOffsetLow == (DWORD)RESERVED_BYTE
32045
+ && nNumberOfBytesToUnlockLow == 1){
3203732046
if (pFile->local.bReserved) {
3203832047
pFile->local.bReserved = FALSE;
3203932048
pFile->shared->bReserved = FALSE;
3204032049
bReturn = TRUE;
3204132050
}
@@ -32197,10 +32206,11 @@
3219732206
assert( id!=0 );
3219832207
#ifndef SQLITE_OMIT_WAL
3219932208
assert( pFile->pShm==0 );
3220032209
#endif
3220132210
OSTRACE(("CLOSE %d\n", pFile->h));
32211
+ assert( pFile->h!=NULL && pFile->h!=INVALID_HANDLE_VALUE );
3220232212
do{
3220332213
rc = osCloseHandle(pFile->h);
3220432214
/* SimulateIOError( rc=0; cnt=MX_CLOSE_ATTEMPT; ); */
3220532215
}while( rc==0 && ++cnt < MX_CLOSE_ATTEMPT && (sqlite3_win32_sleep(100), 1) );
3220632216
#if SQLITE_OS_WINCE
@@ -33113,11 +33123,11 @@
3311333123
bRc = osCloseHandle(p->aRegion[i].hMap);
3311433124
OSTRACE(("SHM-PURGE pid-%d close region=%d %s\n",
3311533125
(int)osGetCurrentProcessId(), i,
3311633126
bRc ? "ok" : "failed"));
3311733127
}
33118
- if( p->hFile.h != INVALID_HANDLE_VALUE ){
33128
+ if( p->hFile.h!=NULL && p->hFile.h!=INVALID_HANDLE_VALUE ){
3311933129
SimulateIOErrorBenign(1);
3312033130
winClose((sqlite3_file *)&p->hFile);
3312133131
SimulateIOErrorBenign(0);
3312233132
}
3312333133
if( deleteFlag ){
@@ -33193,11 +33203,11 @@
3319333203
}
3319433204
3319533205
rc = winOpen(pDbFd->pVfs,
3319633206
pShmNode->zFilename, /* Name of the file (UTF-8) */
3319733207
(sqlite3_file*)&pShmNode->hFile, /* File handle here */
33198
- SQLITE_OPEN_WAL | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, /* Mode flags */
33208
+ SQLITE_OPEN_WAL | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
3319933209
0);
3320033210
if( SQLITE_OK!=rc ){
3320133211
goto shm_open_err;
3320233212
}
3320333213
@@ -33808,22 +33818,21 @@
3380833818
|| eType==SQLITE_OPEN_MAIN_JOURNAL || eType==SQLITE_OPEN_TEMP_JOURNAL
3380933819
|| eType==SQLITE_OPEN_SUBJOURNAL || eType==SQLITE_OPEN_MASTER_JOURNAL
3381033820
|| eType==SQLITE_OPEN_TRANSIENT_DB || eType==SQLITE_OPEN_WAL
3381133821
);
3381233822
33813
- assert( id!=0 );
33814
- UNUSED_PARAMETER(pVfs);
33823
+ assert( pFile!=0 );
33824
+ memset(pFile, 0, sizeof(winFile));
33825
+ pFile->h = INVALID_HANDLE_VALUE;
3381533826
3381633827
#if SQLITE_OS_WINRT
3381733828
if( !sqlite3_temp_directory ){
3381833829
sqlite3_log(SQLITE_ERROR,
3381933830
"sqlite3_temp_directory variable should be set for WinRT");
3382033831
}
3382133832
#endif
3382233833
33823
- pFile->h = INVALID_HANDLE_VALUE;
33824
-
3382533834
/* If the second argument to this function is NULL, generate a
3382633835
** temporary file name to use
3382733836
*/
3382833837
if( !zUtf8Name ){
3382933838
assert(isDelete && !isOpenJournal);
@@ -33948,11 +33957,13 @@
3394833957
pFile->lastErrno = lastErrno;
3394933958
winLogError(SQLITE_CANTOPEN, pFile->lastErrno, "winOpen", zUtf8Name);
3395033959
sqlite3_free(zConverted);
3395133960
if( isReadWrite && !isExclusive ){
3395233961
return winOpen(pVfs, zName, id,
33953
- ((flags|SQLITE_OPEN_READONLY)&~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE)), pOutFlags);
33962
+ ((flags|SQLITE_OPEN_READONLY) &
33963
+ ~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE)),
33964
+ pOutFlags);
3395433965
}else{
3395533966
return SQLITE_CANTOPEN_BKPT;
3395633967
}
3395733968
}
3395833969
@@ -33962,23 +33973,10 @@
3396233973
}else{
3396333974
*pOutFlags = SQLITE_OPEN_READONLY;
3396433975
}
3396533976
}
3396633977
33967
- memset(pFile, 0, sizeof(*pFile));
33968
- pFile->pMethod = &winIoMethod;
33969
- pFile->h = h;
33970
- pFile->lastErrno = NO_ERROR;
33971
- pFile->pVfs = pVfs;
33972
-#ifndef SQLITE_OMIT_WAL
33973
- pFile->pShm = 0;
33974
-#endif
33975
- pFile->zPath = zName;
33976
- if( sqlite3_uri_boolean(zName, "psow", SQLITE_POWERSAFE_OVERWRITE) ){
33977
- pFile->ctrlFlags |= WINFILE_PSOW;
33978
- }
33979
-
3398033978
#if SQLITE_OS_WINCE
3398133979
if( isReadWrite && eType==SQLITE_OPEN_MAIN_DB
3398233980
&& (rc = winceCreateLock(zName, pFile))!=SQLITE_OK
3398333981
){
3398433982
osCloseHandle(h);
@@ -33990,10 +33988,19 @@
3399033988
}else
3399133989
#endif
3399233990
{
3399333991
sqlite3_free(zConverted);
3399433992
}
33993
+
33994
+ pFile->pMethod = &winIoMethod;
33995
+ pFile->pVfs = pVfs;
33996
+ pFile->h = h;
33997
+ if( sqlite3_uri_boolean(zName, "psow", SQLITE_POWERSAFE_OVERWRITE) ){
33998
+ pFile->ctrlFlags |= WINFILE_PSOW;
33999
+ }
34000
+ pFile->lastErrno = NO_ERROR;
34001
+ pFile->zPath = zName;
3399534002
3399634003
OpenCounter(+1);
3399734004
return rc;
3399834005
}
3399934006
@@ -34035,11 +34042,12 @@
3403534042
if ( osGetFileAttributesExW(zConverted, GetFileExInfoStandard,
3403634043
&sAttrData) ){
3403734044
attr = sAttrData.dwFileAttributes;
3403834045
}else{
3403934046
lastErrno = osGetLastError();
34040
- if( lastErrno==ERROR_FILE_NOT_FOUND || lastErrno==ERROR_PATH_NOT_FOUND ){
34047
+ if( lastErrno==ERROR_FILE_NOT_FOUND
34048
+ || lastErrno==ERROR_PATH_NOT_FOUND ){
3404134049
rc = SQLITE_IOERR_DELETE_NOENT; /* Already gone? */
3404234050
}else{
3404334051
rc = SQLITE_ERROR;
3404434052
}
3404534053
break;
@@ -34047,11 +34055,12 @@
3404734055
#else
3404834056
attr = osGetFileAttributesW(zConverted);
3404934057
#endif
3405034058
if ( attr==INVALID_FILE_ATTRIBUTES ){
3405134059
lastErrno = osGetLastError();
34052
- if( lastErrno==ERROR_FILE_NOT_FOUND || lastErrno==ERROR_PATH_NOT_FOUND ){
34060
+ if( lastErrno==ERROR_FILE_NOT_FOUND
34061
+ || lastErrno==ERROR_PATH_NOT_FOUND ){
3405334062
rc = SQLITE_IOERR_DELETE_NOENT; /* Already gone? */
3405434063
}else{
3405534064
rc = SQLITE_ERROR;
3405634065
}
3405734066
break;
@@ -34074,11 +34083,12 @@
3407434083
else{
3407534084
do {
3407634085
attr = osGetFileAttributesA(zConverted);
3407734086
if ( attr==INVALID_FILE_ATTRIBUTES ){
3407834087
lastErrno = osGetLastError();
34079
- if( lastErrno==ERROR_FILE_NOT_FOUND || lastErrno==ERROR_PATH_NOT_FOUND ){
34088
+ if( lastErrno==ERROR_FILE_NOT_FOUND
34089
+ || lastErrno==ERROR_PATH_NOT_FOUND ){
3408034090
rc = SQLITE_IOERR_DELETE_NOENT; /* Already gone? */
3408134091
}else{
3408234092
rc = SQLITE_ERROR;
3408334093
}
3408434094
break;
@@ -34242,20 +34252,16 @@
3424234252
** for converting the relative path name to an absolute
3424334253
** one by prepending the data directory and a slash.
3424434254
*/
3424534255
char zOut[MAX_PATH+1];
3424634256
memset(zOut, 0, MAX_PATH+1);
34247
- cygwin_conv_to_win32_path(zRelative, zOut); /* POSIX to Win32 */
34257
+ cygwin_conv_path(CCP_POSIX_TO_WIN_A|CCP_RELATIVE, zRelative, zOut,
34258
+ MAX_PATH+1);
3424834259
sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s\\%s",
3424934260
sqlite3_data_directory, zOut);
3425034261
}else{
34251
- /*
34252
- ** NOTE: The Cygwin docs state that the maximum length needed
34253
- ** for the buffer passed to cygwin_conv_to_full_win32_path
34254
- ** is MAX_PATH.
34255
- */
34256
- cygwin_conv_to_full_win32_path(zRelative, zFull);
34262
+ cygwin_conv_path(CCP_POSIX_TO_WIN_A, zRelative, zFull, nFull);
3425734263
}
3425834264
return SQLITE_OK;
3425934265
#endif
3426034266
3426134267
#if (SQLITE_OS_WINCE || SQLITE_OS_WINRT) && !defined(__CYGWIN__)
@@ -34409,13 +34415,13 @@
3440934415
}
3441034416
static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){
3441134417
UNUSED_PARAMETER(pVfs);
3441234418
getLastErrorMsg(osGetLastError(), nBuf, zBufOut);
3441334419
}
34414
-static void (*winDlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol))(void){
34420
+static void (*winDlSym(sqlite3_vfs *pVfs,void *pH,const char *zSym))(void){
3441534421
UNUSED_PARAMETER(pVfs);
34416
- return (void(*)(void))osGetProcAddressA((HANDLE)pHandle, zSymbol);
34422
+ return (void(*)(void))osGetProcAddressA((HANDLE)pH, zSym);
3441734423
}
3441834424
static void winDlClose(sqlite3_vfs *pVfs, void *pHandle){
3441934425
UNUSED_PARAMETER(pVfs);
3442034426
osFreeLibrary((HANDLE)pHandle);
3442134427
}
@@ -34509,11 +34515,12 @@
3450934515
#ifdef SQLITE_TEST
3451034516
static const sqlite3_int64 unixEpoch = 24405875*(sqlite3_int64)8640000;
3451134517
#endif
3451234518
/* 2^32 - to avoid use of LL and warnings in gcc */
3451334519
static const sqlite3_int64 max32BitValue =
34514
- (sqlite3_int64)2000000000 + (sqlite3_int64)2000000000 + (sqlite3_int64)294967296;
34520
+ (sqlite3_int64)2000000000 + (sqlite3_int64)2000000000 +
34521
+ (sqlite3_int64)294967296;
3451534522
3451634523
#if SQLITE_OS_WINCE
3451734524
SYSTEMTIME time;
3451834525
osGetSystemTime(&time);
3451934526
/* if SystemTimeToFileTime() fails, it returns zero. */
@@ -39187,10 +39194,12 @@
3918739194
pPager->eState = PAGER_ERROR;
3918839195
}
3918939196
return rc;
3919039197
}
3919139198
39199
+static int pager_truncate(Pager *pPager, Pgno nPage);
39200
+
3919239201
/*
3919339202
** This routine ends a transaction. A transaction is usually ended by
3919439203
** either a COMMIT or a ROLLBACK operation. This routine may be called
3919539204
** after rollback of a hot-journal, or if an error occurs while opening
3919639205
** the journal file or writing the very first journal-header of a
@@ -39240,11 +39249,11 @@
3924039249
** tries to unlock the database file if not in exclusive mode. If the
3924139250
** unlock operation fails as well, then the first error code related
3924239251
** to the first error encountered (the journal finalization one) is
3924339252
** returned.
3924439253
*/
39245
-static int pager_end_transaction(Pager *pPager, int hasMaster){
39254
+static int pager_end_transaction(Pager *pPager, int hasMaster, int bCommit){
3924639255
int rc = SQLITE_OK; /* Error code from journal finalization operation */
3924739256
int rc2 = SQLITE_OK; /* Error code from db file unlock operation */
3924839257
3924939258
/* Do nothing if the pager does not have an open write transaction
3925039259
** or at least a RESERVED lock. This function may be called when there
@@ -39326,11 +39335,21 @@
3932639335
** locking_mode=exclusive mode but is no longer, drop the EXCLUSIVE
3932739336
** lock held on the database file.
3932839337
*/
3932939338
rc2 = sqlite3WalEndWriteTransaction(pPager->pWal);
3933039339
assert( rc2==SQLITE_OK );
39340
+ }else if( rc==SQLITE_OK && bCommit && pPager->dbFileSize>pPager->dbSize ){
39341
+ /* This branch is taken when committing a transaction in rollback-journal
39342
+ ** mode if the database file on disk is larger than the database image.
39343
+ ** At this point the journal has been finalized and the transaction
39344
+ ** successfully committed, but the EXCLUSIVE lock is still held on the
39345
+ ** file. So it is safe to truncate the database file to its minimum
39346
+ ** required size. */
39347
+ assert( pPager->eLock==EXCLUSIVE_LOCK );
39348
+ rc = pager_truncate(pPager, pPager->dbSize);
3933139349
}
39350
+
3933239351
if( !pPager->exclusiveMode
3933339352
&& (!pagerUseWal(pPager) || sqlite3WalExclusiveMode(pPager->pWal, 0))
3933439353
){
3933539354
rc2 = pagerUnlockDb(pPager, SHARED_LOCK);
3933639355
pPager->changeCountDone = 0;
@@ -39365,11 +39384,11 @@
3936539384
sqlite3BeginBenignMalloc();
3936639385
sqlite3PagerRollback(pPager);
3936739386
sqlite3EndBenignMalloc();
3936839387
}else if( !pPager->exclusiveMode ){
3936939388
assert( pPager->eState==PAGER_READER );
39370
- pager_end_transaction(pPager, 0);
39389
+ pager_end_transaction(pPager, 0, 0);
3937139390
}
3937239391
}
3937339392
pager_unlock(pPager);
3937439393
}
3937539394
@@ -40140,11 +40159,11 @@
4014040159
&& (pPager->eState>=PAGER_WRITER_DBMOD || pPager->eState==PAGER_OPEN)
4014140160
){
4014240161
rc = sqlite3PagerSync(pPager);
4014340162
}
4014440163
if( rc==SQLITE_OK ){
40145
- rc = pager_end_transaction(pPager, zMaster[0]!='\0');
40164
+ rc = pager_end_transaction(pPager, zMaster[0]!='\0', 0);
4014640165
testcase( rc!=SQLITE_OK );
4014740166
}
4014840167
if( rc==SQLITE_OK && zMaster[0] && res ){
4014940168
/* If there was a master journal and this routine will return success,
4015040169
** see if it is possible to delete the master journal.
@@ -43234,40 +43253,10 @@
4323443253
#else
4323543254
rc = pager_incr_changecounter(pPager, 0);
4323643255
#endif
4323743256
if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
4323843257
43239
- /* If this transaction has made the database smaller, then all pages
43240
- ** being discarded by the truncation must be written to the journal
43241
- ** file.
43242
- **
43243
- ** Before reading the pages with page numbers larger than the
43244
- ** current value of Pager.dbSize, set dbSize back to the value
43245
- ** that it took at the start of the transaction. Otherwise, the
43246
- ** calls to sqlite3PagerGet() return zeroed pages instead of
43247
- ** reading data from the database file.
43248
- */
43249
- if( pPager->dbSize<pPager->dbOrigSize
43250
- && pPager->journalMode!=PAGER_JOURNALMODE_OFF
43251
- ){
43252
- Pgno i; /* Iterator variable */
43253
- const Pgno iSkip = PAGER_MJ_PGNO(pPager); /* Pending lock page */
43254
- const Pgno dbSize = pPager->dbSize; /* Database image size */
43255
- pPager->dbSize = pPager->dbOrigSize;
43256
- for( i=dbSize+1; i<=pPager->dbOrigSize; i++ ){
43257
- if( !sqlite3BitvecTest(pPager->pInJournal, i) && i!=iSkip ){
43258
- PgHdr *pPage; /* Page to journal */
43259
- rc = sqlite3PagerGet(pPager, i, &pPage);
43260
- if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
43261
- rc = sqlite3PagerWrite(pPage);
43262
- sqlite3PagerUnref(pPage);
43263
- if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
43264
- }
43265
- }
43266
- pPager->dbSize = dbSize;
43267
- }
43268
-
4326943258
/* Write the master journal name into the journal file. If a master
4327043259
** journal file name has already been written to the journal file,
4327143260
** or if zMaster is NULL (no master journal), then this call is a no-op.
4327243261
*/
4327343262
rc = writeMasterJournal(pPager, zMaster);
@@ -43291,15 +43280,18 @@
4329143280
if( rc!=SQLITE_OK ){
4329243281
assert( rc!=SQLITE_IOERR_BLOCKED );
4329343282
goto commit_phase_one_exit;
4329443283
}
4329543284
sqlite3PcacheCleanAll(pPager->pPCache);
43296
-
43297
- /* If the file on disk is not the same size as the database image,
43298
- ** then use pager_truncate to grow or shrink the file here.
43299
- */
43300
- if( pPager->dbSize!=pPager->dbFileSize ){
43285
+
43286
+ /* If the file on disk is smaller than the database image, use
43287
+ ** pager_truncate to grow the file here. This can happen if the database
43288
+ ** image was extended as part of the current transaction and then the
43289
+ ** last page in the db image moved to the free-list. In this case the
43290
+ ** last page is never written out to disk, leaving the database file
43291
+ ** undersized. Fix this now if it is the case. */
43292
+ if( pPager->dbSize>pPager->dbFileSize ){
4330143293
Pgno nNew = pPager->dbSize - (pPager->dbSize==PAGER_MJ_PGNO(pPager));
4330243294
assert( pPager->eState==PAGER_WRITER_DBMOD );
4330343295
rc = pager_truncate(pPager, nNew);
4330443296
if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
4330543297
}
@@ -43368,11 +43360,11 @@
4336843360
pPager->eState = PAGER_READER;
4336943361
return SQLITE_OK;
4337043362
}
4337143363
4337243364
PAGERTRACE(("COMMIT %d\n", PAGERID(pPager)));
43373
- rc = pager_end_transaction(pPager, pPager->setMaster);
43365
+ rc = pager_end_transaction(pPager, pPager->setMaster, 1);
4337443366
return pager_error(pPager, rc);
4337543367
}
4337643368
4337743369
/*
4337843370
** If a write transaction is open, then all changes made within the
@@ -43413,15 +43405,15 @@
4341343405
if( pPager->eState<=PAGER_READER ) return SQLITE_OK;
4341443406
4341543407
if( pagerUseWal(pPager) ){
4341643408
int rc2;
4341743409
rc = sqlite3PagerSavepoint(pPager, SAVEPOINT_ROLLBACK, -1);
43418
- rc2 = pager_end_transaction(pPager, pPager->setMaster);
43410
+ rc2 = pager_end_transaction(pPager, pPager->setMaster, 0);
4341943411
if( rc==SQLITE_OK ) rc = rc2;
4342043412
}else if( !isOpen(pPager->jfd) || pPager->eState==PAGER_WRITER_LOCKED ){
4342143413
int eState = pPager->eState;
43422
- rc = pager_end_transaction(pPager, 0);
43414
+ rc = pager_end_transaction(pPager, 0, 0);
4342343415
if( !MEMDB && eState>PAGER_WRITER_LOCKED ){
4342443416
/* This can happen using journal_mode=off. Move the pager to the error
4342543417
** state to indicate that the contents of the cache may not be trusted.
4342643418
** Any active readers will get SQLITE_ABORT.
4342743419
*/
@@ -43815,11 +43807,12 @@
4381543807
** the journal needs to be sync()ed before database page pPg->pgno
4381643808
** can be written to. The caller has already promised not to write to it.
4381743809
*/
4381843810
if( (pPg->flags&PGHDR_NEED_SYNC) && !isCommit ){
4381943811
needSyncPgno = pPg->pgno;
43820
- assert( pageInJournal(pPg) || pPg->pgno>pPager->dbOrigSize );
43812
+ assert( pPager->journalMode==PAGER_JOURNALMODE_OFF ||
43813
+ pageInJournal(pPg) || pPg->pgno>pPager->dbOrigSize );
4382143814
assert( pPg->flags&PGHDR_DIRTY );
4382243815
}
4382343816
4382443817
/* If the cache contains a page with page-number pgno, remove it
4382543818
** from its hash chain. Also, if the PGHDR_NEED_SYNC flag was set for
@@ -47819,10 +47812,11 @@
4781947812
MemPage *pPage1; /* First page of the database */
4782047813
u8 openFlags; /* Flags to sqlite3BtreeOpen() */
4782147814
#ifndef SQLITE_OMIT_AUTOVACUUM
4782247815
u8 autoVacuum; /* True if auto-vacuum is enabled */
4782347816
u8 incrVacuum; /* True if incr-vacuum is enabled */
47817
+ u8 bDoTruncate; /* True to truncate db on commit */
4782447818
#endif
4782547819
u8 inTransaction; /* Transaction state */
4782647820
u8 max1bytePayload; /* Maximum first byte of cell for a 1-byte payload */
4782747821
u16 btsFlags; /* Boolean parameters. See BTS_* macros below */
4782847822
u16 maxLocal; /* Maximum local payload in non-LEAFDATA tables */
@@ -50937,10 +50931,11 @@
5093750931
** is requested, this is a no-op.
5093850932
*/
5093950933
if( p->inTrans==TRANS_WRITE || (p->inTrans==TRANS_READ && !wrflag) ){
5094050934
goto trans_begun;
5094150935
}
50936
+ assert( pBt->bDoTruncate==0 );
5094250937
5094350938
/* Write transactions are not possible on a read-only database */
5094450939
if( (pBt->btsFlags & BTS_READ_ONLY)!=0 && wrflag ){
5094550940
rc = SQLITE_READONLY;
5094650941
goto trans_begun;
@@ -51251,30 +51246,32 @@
5125151246
return rc;
5125251247
}
5125351248
5125451249
/* Forward declaration required by incrVacuumStep(). */
5125551250
static int allocateBtreePage(BtShared *, MemPage **, Pgno *, Pgno, u8);
51251
+#define BTALLOC_ANY 0 /* Allocate any page */
51252
+#define BTALLOC_EXACT 1 /* Allocate exact page if possible */
51253
+#define BTALLOC_LE 2 /* Allocate any page <= the parameter */
5125651254
5125751255
/*
51258
-** Perform a single step of an incremental-vacuum. If successful,
51259
-** return SQLITE_OK. If there is no work to do (and therefore no
51260
-** point in calling this function again), return SQLITE_DONE.
51261
-**
51262
-** More specificly, this function attempts to re-organize the
51263
-** database so that the last page of the file currently in use
51264
-** is no longer in use.
51265
-**
51266
-** If the nFin parameter is non-zero, this function assumes
51267
-** that the caller will keep calling incrVacuumStep() until
51268
-** it returns SQLITE_DONE or an error, and that nFin is the
51269
-** number of pages the database file will contain after this
51270
-** process is complete. If nFin is zero, it is assumed that
51271
-** incrVacuumStep() will be called a finite amount of times
51272
-** which may or may not empty the freelist. A full autovacuum
51273
-** has nFin>0. A "PRAGMA incremental_vacuum" has nFin==0.
51274
-*/
51275
-static int incrVacuumStep(BtShared *pBt, Pgno nFin, Pgno iLastPg){
51256
+** Perform a single step of an incremental-vacuum. If successful, return
51257
+** SQLITE_OK. If there is no work to do (and therefore no point in
51258
+** calling this function again), return SQLITE_DONE. Or, if an error
51259
+** occurs, return some other error code.
51260
+**
51261
+** More specificly, this function attempts to re-organize the database so
51262
+** that the last page of the file currently in use is no longer in use.
51263
+**
51264
+** Parameter nFin is the number of pages that this database would contain
51265
+** were this function called until it returns SQLITE_DONE.
51266
+**
51267
+** If the bCommit parameter is non-zero, this function assumes that the
51268
+** caller will keep calling incrVacuumStep() until it returns SQLITE_DONE
51269
+** or an error. bCommit is passed true for an auto-vacuum-on-commmit
51270
+** operation, or false for an incremental vacuum.
51271
+*/
51272
+static int incrVacuumStep(BtShared *pBt, Pgno nFin, Pgno iLastPg, int bCommit){
5127651273
Pgno nFreeList; /* Number of pages still on the free-list */
5127751274
int rc;
5127851275
5127951276
assert( sqlite3_mutex_held(pBt->mutex) );
5128051277
assert( iLastPg>nFin );
@@ -51295,85 +51292,98 @@
5129551292
if( eType==PTRMAP_ROOTPAGE ){
5129651293
return SQLITE_CORRUPT_BKPT;
5129751294
}
5129851295
5129951296
if( eType==PTRMAP_FREEPAGE ){
51300
- if( nFin==0 ){
51297
+ if( bCommit==0 ){
5130151298
/* Remove the page from the files free-list. This is not required
51302
- ** if nFin is non-zero. In that case, the free-list will be
51299
+ ** if bCommit is non-zero. In that case, the free-list will be
5130351300
** truncated to zero after this function returns, so it doesn't
5130451301
** matter if it still contains some garbage entries.
5130551302
*/
5130651303
Pgno iFreePg;
5130751304
MemPage *pFreePg;
51308
- rc = allocateBtreePage(pBt, &pFreePg, &iFreePg, iLastPg, 1);
51305
+ rc = allocateBtreePage(pBt, &pFreePg, &iFreePg, iLastPg, BTALLOC_EXACT);
5130951306
if( rc!=SQLITE_OK ){
5131051307
return rc;
5131151308
}
5131251309
assert( iFreePg==iLastPg );
5131351310
releasePage(pFreePg);
5131451311
}
5131551312
} else {
5131651313
Pgno iFreePg; /* Index of free page to move pLastPg to */
5131751314
MemPage *pLastPg;
51315
+ u8 eMode = BTALLOC_ANY; /* Mode parameter for allocateBtreePage() */
51316
+ Pgno iNear = 0; /* nearby parameter for allocateBtreePage() */
5131851317
5131951318
rc = btreeGetPage(pBt, iLastPg, &pLastPg, 0);
5132051319
if( rc!=SQLITE_OK ){
5132151320
return rc;
5132251321
}
5132351322
51324
- /* If nFin is zero, this loop runs exactly once and page pLastPg
51323
+ /* If bCommit is zero, this loop runs exactly once and page pLastPg
5132551324
** is swapped with the first free page pulled off the free list.
5132651325
**
51327
- ** On the other hand, if nFin is greater than zero, then keep
51326
+ ** On the other hand, if bCommit is greater than zero, then keep
5132851327
** looping until a free-page located within the first nFin pages
5132951328
** of the file is found.
5133051329
*/
51330
+ if( bCommit==0 ){
51331
+ eMode = BTALLOC_LE;
51332
+ iNear = nFin;
51333
+ }
5133151334
do {
5133251335
MemPage *pFreePg;
51333
- rc = allocateBtreePage(pBt, &pFreePg, &iFreePg, 0, 0);
51336
+ rc = allocateBtreePage(pBt, &pFreePg, &iFreePg, iNear, eMode);
5133451337
if( rc!=SQLITE_OK ){
5133551338
releasePage(pLastPg);
5133651339
return rc;
5133751340
}
5133851341
releasePage(pFreePg);
51339
- }while( nFin!=0 && iFreePg>nFin );
51342
+ }while( bCommit && iFreePg>nFin );
5134051343
assert( iFreePg<iLastPg );
5134151344
51342
- rc = sqlite3PagerWrite(pLastPg->pDbPage);
51343
- if( rc==SQLITE_OK ){
51344
- rc = relocatePage(pBt, pLastPg, eType, iPtrPage, iFreePg, nFin!=0);
51345
- }
51345
+ rc = relocatePage(pBt, pLastPg, eType, iPtrPage, iFreePg, nFin!=0);
5134651346
releasePage(pLastPg);
5134751347
if( rc!=SQLITE_OK ){
5134851348
return rc;
5134951349
}
5135051350
}
5135151351
}
5135251352
51353
- if( nFin==0 ){
51354
- iLastPg--;
51355
- while( iLastPg==PENDING_BYTE_PAGE(pBt)||PTRMAP_ISPAGE(pBt, iLastPg) ){
51356
- if( PTRMAP_ISPAGE(pBt, iLastPg) ){
51357
- MemPage *pPg;
51358
- rc = btreeGetPage(pBt, iLastPg, &pPg, 0);
51359
- if( rc!=SQLITE_OK ){
51360
- return rc;
51361
- }
51362
- rc = sqlite3PagerWrite(pPg->pDbPage);
51363
- releasePage(pPg);
51364
- if( rc!=SQLITE_OK ){
51365
- return rc;
51366
- }
51367
- }
51368
- iLastPg--;
51369
- }
51370
- sqlite3PagerTruncateImage(pBt->pPager, iLastPg);
51353
+ if( bCommit==0 ){
51354
+ do {
51355
+ iLastPg--;
51356
+ }while( iLastPg==PENDING_BYTE_PAGE(pBt) || PTRMAP_ISPAGE(pBt, iLastPg) );
51357
+ pBt->bDoTruncate = 1;
5137151358
pBt->nPage = iLastPg;
5137251359
}
5137351360
return SQLITE_OK;
5137451361
}
51362
+
51363
+/*
51364
+** The database opened by the first argument is an auto-vacuum database
51365
+** nOrig pages in size containing nFree free pages. Return the expected
51366
+** size of the database in pages following an auto-vacuum operation.
51367
+*/
51368
+static Pgno finalDbSize(BtShared *pBt, Pgno nOrig, Pgno nFree){
51369
+ int nEntry; /* Number of entries on one ptrmap page */
51370
+ Pgno nPtrmap; /* Number of PtrMap pages to be freed */
51371
+ Pgno nFin; /* Return value */
51372
+
51373
+ nEntry = pBt->usableSize/5;
51374
+ nPtrmap = (nFree-nOrig+PTRMAP_PAGENO(pBt, nOrig)+nEntry)/nEntry;
51375
+ nFin = nOrig - nFree - nPtrmap;
51376
+ if( nOrig>PENDING_BYTE_PAGE(pBt) && nFin<PENDING_BYTE_PAGE(pBt) ){
51377
+ nFin--;
51378
+ }
51379
+ while( PTRMAP_ISPAGE(pBt, nFin) || nFin==PENDING_BYTE_PAGE(pBt) ){
51380
+ nFin--;
51381
+ }
51382
+
51383
+ return nFin;
51384
+}
5137551385
5137651386
/*
5137751387
** A write-transaction must be opened before calling this function.
5137851388
** It performs a single unit of work towards an incremental vacuum.
5137951389
**
@@ -51388,15 +51398,25 @@
5138851398
sqlite3BtreeEnter(p);
5138951399
assert( pBt->inTransaction==TRANS_WRITE && p->inTrans==TRANS_WRITE );
5139051400
if( !pBt->autoVacuum ){
5139151401
rc = SQLITE_DONE;
5139251402
}else{
51393
- invalidateAllOverflowCache(pBt);
51394
- rc = incrVacuumStep(pBt, 0, btreePagecount(pBt));
51395
- if( rc==SQLITE_OK ){
51396
- rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
51397
- put4byte(&pBt->pPage1->aData[28], pBt->nPage);
51403
+ Pgno nOrig = btreePagecount(pBt);
51404
+ Pgno nFree = get4byte(&pBt->pPage1->aData[36]);
51405
+ Pgno nFin = finalDbSize(pBt, nOrig, nFree);
51406
+
51407
+ if( nOrig<nFin ){
51408
+ rc = SQLITE_CORRUPT_BKPT;
51409
+ }else if( nFree>0 ){
51410
+ invalidateAllOverflowCache(pBt);
51411
+ rc = incrVacuumStep(pBt, nFin, nOrig, 0);
51412
+ if( rc==SQLITE_OK ){
51413
+ rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
51414
+ put4byte(&pBt->pPage1->aData[28], pBt->nPage);
51415
+ }
51416
+ }else{
51417
+ rc = SQLITE_DONE;
5139851418
}
5139951419
}
5140051420
sqlite3BtreeLeave(p);
5140151421
return rc;
5140251422
}
@@ -51419,13 +51439,11 @@
5141951439
invalidateAllOverflowCache(pBt);
5142051440
assert(pBt->autoVacuum);
5142151441
if( !pBt->incrVacuum ){
5142251442
Pgno nFin; /* Number of pages in database after autovacuuming */
5142351443
Pgno nFree; /* Number of pages on the freelist initially */
51424
- Pgno nPtrmap; /* Number of PtrMap pages to be freed */
5142551444
Pgno iFree; /* The next page to be freed */
51426
- int nEntry; /* Number of entries on one ptrmap page */
5142751445
Pgno nOrig; /* Database size before freeing */
5142851446
5142951447
nOrig = btreePagecount(pBt);
5143051448
if( PTRMAP_ISPAGE(pBt, nOrig) || nOrig==PENDING_BYTE_PAGE(pBt) ){
5143151449
/* It is not possible to create a database for which the final page
@@ -51434,30 +51452,22 @@
5143451452
*/
5143551453
return SQLITE_CORRUPT_BKPT;
5143651454
}
5143751455
5143851456
nFree = get4byte(&pBt->pPage1->aData[36]);
51439
- nEntry = pBt->usableSize/5;
51440
- nPtrmap = (nFree-nOrig+PTRMAP_PAGENO(pBt, nOrig)+nEntry)/nEntry;
51441
- nFin = nOrig - nFree - nPtrmap;
51442
- if( nOrig>PENDING_BYTE_PAGE(pBt) && nFin<PENDING_BYTE_PAGE(pBt) ){
51443
- nFin--;
51444
- }
51445
- while( PTRMAP_ISPAGE(pBt, nFin) || nFin==PENDING_BYTE_PAGE(pBt) ){
51446
- nFin--;
51447
- }
51457
+ nFin = finalDbSize(pBt, nOrig, nFree);
5144851458
if( nFin>nOrig ) return SQLITE_CORRUPT_BKPT;
5144951459
5145051460
for(iFree=nOrig; iFree>nFin && rc==SQLITE_OK; iFree--){
51451
- rc = incrVacuumStep(pBt, nFin, iFree);
51461
+ rc = incrVacuumStep(pBt, nFin, iFree, 1);
5145251462
}
5145351463
if( (rc==SQLITE_DONE || rc==SQLITE_OK) && nFree>0 ){
5145451464
rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
5145551465
put4byte(&pBt->pPage1->aData[32], 0);
5145651466
put4byte(&pBt->pPage1->aData[36], 0);
5145751467
put4byte(&pBt->pPage1->aData[28], nFin);
51458
- sqlite3PagerTruncateImage(pBt->pPager, nFin);
51468
+ pBt->bDoTruncate = 1;
5145951469
pBt->nPage = nFin;
5146051470
}
5146151471
if( rc!=SQLITE_OK ){
5146251472
sqlite3PagerRollback(pPager);
5146351473
}
@@ -51508,10 +51518,13 @@
5150851518
if( rc!=SQLITE_OK ){
5150951519
sqlite3BtreeLeave(p);
5151051520
return rc;
5151151521
}
5151251522
}
51523
+ if( pBt->bDoTruncate ){
51524
+ sqlite3PagerTruncateImage(pBt->pPager, pBt->nPage);
51525
+ }
5151351526
#endif
5151451527
rc = sqlite3PagerCommitPhaseOne(pBt->pPager, zMaster, 0);
5151551528
sqlite3BtreeLeave(p);
5151651529
}
5151751530
return rc;
@@ -51523,10 +51536,13 @@
5152351536
*/
5152451537
static void btreeEndTransaction(Btree *p){
5152551538
BtShared *pBt = p->pBt;
5152651539
assert( sqlite3BtreeHoldsMutex(p) );
5152751540
51541
+#ifndef SQLITE_OMIT_AUTOVACUUM
51542
+ pBt->bDoTruncate = 0;
51543
+#endif
5152851544
btreeClearHasContent(pBt);
5152951545
if( p->inTrans>TRANS_NONE && p->db->activeVdbeCnt>1 ){
5153051546
/* If there are other active statements that belong to this database
5153151547
** handle, downgrade to a read-only transaction. The other statements
5153251548
** may still be reading from the database. */
@@ -53209,11 +53225,11 @@
5320953225
static int allocateBtreePage(
5321053226
BtShared *pBt,
5321153227
MemPage **ppPage,
5321253228
Pgno *pPgno,
5321353229
Pgno nearby,
53214
- u8 exact
53230
+ u8 eMode
5321553231
){
5321653232
MemPage *pPage1;
5321753233
int rc;
5321853234
u32 n; /* Number of pages on the freelist */
5321953235
u32 k; /* Number of leaves on the trunk of the freelist */
@@ -53237,20 +53253,23 @@
5323753253
/* If the 'exact' parameter was true and a query of the pointer-map
5323853254
** shows that the page 'nearby' is somewhere on the free-list, then
5323953255
** the entire-list will be searched for that page.
5324053256
*/
5324153257
#ifndef SQLITE_OMIT_AUTOVACUUM
53242
- if( exact && nearby<=mxPage ){
53243
- u8 eType;
53244
- assert( nearby>0 );
53245
- assert( pBt->autoVacuum );
53246
- rc = ptrmapGet(pBt, nearby, &eType, 0);
53247
- if( rc ) return rc;
53248
- if( eType==PTRMAP_FREEPAGE ){
53249
- searchList = 1;
53250
- }
53251
- *pPgno = nearby;
53258
+ if( eMode==BTALLOC_EXACT ){
53259
+ if( nearby<=mxPage ){
53260
+ u8 eType;
53261
+ assert( nearby>0 );
53262
+ assert( pBt->autoVacuum );
53263
+ rc = ptrmapGet(pBt, nearby, &eType, 0);
53264
+ if( rc ) return rc;
53265
+ if( eType==PTRMAP_FREEPAGE ){
53266
+ searchList = 1;
53267
+ }
53268
+ }
53269
+ }else if( eMode==BTALLOC_LE ){
53270
+ searchList = 1;
5325253271
}
5325353272
#endif
5325453273
5325553274
/* Decrement the free-list count by 1. Set iTrunk to the index of the
5325653275
** first free-list trunk page. iPrevTrunk is initially 1.
@@ -53301,15 +53320,17 @@
5330153320
}else if( k>(u32)(pBt->usableSize/4 - 2) ){
5330253321
/* Value of k is out of range. Database corruption */
5330353322
rc = SQLITE_CORRUPT_BKPT;
5330453323
goto end_allocate_page;
5330553324
#ifndef SQLITE_OMIT_AUTOVACUUM
53306
- }else if( searchList && nearby==iTrunk ){
53325
+ }else if( searchList
53326
+ && (nearby==iTrunk || (iTrunk<nearby && eMode==BTALLOC_LE))
53327
+ ){
5330753328
/* The list is being searched and this trunk page is the page
5330853329
** to allocate, regardless of whether it has leaves.
5330953330
*/
53310
- assert( *pPgno==iTrunk );
53331
+ *pPgno = iTrunk;
5331153332
*ppPage = pTrunk;
5331253333
searchList = 0;
5331353334
rc = sqlite3PagerWrite(pTrunk->pDbPage);
5331453335
if( rc ){
5331553336
goto end_allocate_page;
@@ -53368,18 +53389,28 @@
5336853389
u32 closest;
5336953390
Pgno iPage;
5337053391
unsigned char *aData = pTrunk->aData;
5337153392
if( nearby>0 ){
5337253393
u32 i;
53373
- int dist;
5337453394
closest = 0;
53375
- dist = sqlite3AbsInt32(get4byte(&aData[8]) - nearby);
53376
- for(i=1; i<k; i++){
53377
- int d2 = sqlite3AbsInt32(get4byte(&aData[8+i*4]) - nearby);
53378
- if( d2<dist ){
53379
- closest = i;
53380
- dist = d2;
53395
+ if( eMode==BTALLOC_LE ){
53396
+ for(i=0; i<k; i++){
53397
+ iPage = get4byte(&aData[8+i*4]);
53398
+ if( iPage<=nearby ){
53399
+ closest = i;
53400
+ break;
53401
+ }
53402
+ }
53403
+ }else{
53404
+ int dist;
53405
+ dist = sqlite3AbsInt32(get4byte(&aData[8]) - nearby);
53406
+ for(i=1; i<k; i++){
53407
+ int d2 = sqlite3AbsInt32(get4byte(&aData[8+i*4]) - nearby);
53408
+ if( d2<dist ){
53409
+ closest = i;
53410
+ dist = d2;
53411
+ }
5338153412
}
5338253413
}
5338353414
}else{
5338453415
closest = 0;
5338553416
}
@@ -53389,11 +53420,13 @@
5338953420
if( iPage>mxPage ){
5339053421
rc = SQLITE_CORRUPT_BKPT;
5339153422
goto end_allocate_page;
5339253423
}
5339353424
testcase( iPage==mxPage );
53394
- if( !searchList || iPage==nearby ){
53425
+ if( !searchList
53426
+ || (iPage==nearby || (iPage<nearby && eMode==BTALLOC_LE))
53427
+ ){
5339553428
int noContent;
5339653429
*pPgno = iPage;
5339753430
TRACE(("ALLOCATE: %d was leaf %d of %d on trunk %d"
5339853431
": %d more free pages\n",
5339953432
*pPgno, closest+1, k, pTrunk->pgno, n-1));
@@ -53416,12 +53449,30 @@
5341653449
}
5341753450
releasePage(pPrevTrunk);
5341853451
pPrevTrunk = 0;
5341953452
}while( searchList );
5342053453
}else{
53421
- /* There are no pages on the freelist, so create a new page at the
53422
- ** end of the file */
53454
+ /* There are no pages on the freelist, so append a new page to the
53455
+ ** database image.
53456
+ **
53457
+ ** Normally, new pages allocated by this block can be requested from the
53458
+ ** pager layer with the 'no-content' flag set. This prevents the pager
53459
+ ** from trying to read the pages content from disk. However, if the
53460
+ ** current transaction has already run one or more incremental-vacuum
53461
+ ** steps, then the page we are about to allocate may contain content
53462
+ ** that is required in the event of a rollback. In this case, do
53463
+ ** not set the no-content flag. This causes the pager to load and journal
53464
+ ** the current page content before overwriting it.
53465
+ **
53466
+ ** Note that the pager will not actually attempt to load or journal
53467
+ ** content for any page that really does lie past the end of the database
53468
+ ** file on disk. So the effects of disabling the no-content optimization
53469
+ ** here are confined to those pages that lie between the end of the
53470
+ ** database image and the end of the database file.
53471
+ */
53472
+ int bNoContent = (0==pBt->bDoTruncate);
53473
+
5342353474
rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
5342453475
if( rc ) return rc;
5342553476
pBt->nPage++;
5342653477
if( pBt->nPage==PENDING_BYTE_PAGE(pBt) ) pBt->nPage++;
5342753478
@@ -53432,11 +53483,11 @@
5343253483
** becomes a new pointer-map page, the second is used by the caller.
5343353484
*/
5343453485
MemPage *pPg = 0;
5343553486
TRACE(("ALLOCATE: %d from end of file (pointer-map page)\n", pBt->nPage));
5343653487
assert( pBt->nPage!=PENDING_BYTE_PAGE(pBt) );
53437
- rc = btreeGetPage(pBt, pBt->nPage, &pPg, 1);
53488
+ rc = btreeGetPage(pBt, pBt->nPage, &pPg, bNoContent);
5343853489
if( rc==SQLITE_OK ){
5343953490
rc = sqlite3PagerWrite(pPg->pDbPage);
5344053491
releasePage(pPg);
5344153492
}
5344253493
if( rc ) return rc;
@@ -53446,11 +53497,11 @@
5344653497
#endif
5344753498
put4byte(28 + (u8*)pBt->pPage1->aData, pBt->nPage);
5344853499
*pPgno = pBt->nPage;
5344953500
5345053501
assert( *pPgno!=PENDING_BYTE_PAGE(pBt) );
53451
- rc = btreeGetPage(pBt, *pPgno, ppPage, 1);
53502
+ rc = btreeGetPage(pBt, *pPgno, ppPage, bNoContent);
5345253503
if( rc ) return rc;
5345353504
rc = sqlite3PagerWrite((*ppPage)->pDbPage);
5345453505
if( rc!=SQLITE_OK ){
5345553506
releasePage(*ppPage);
5345653507
}
@@ -55461,11 +55512,11 @@
5546155512
5546255513
/* Allocate a page. The page that currently resides at pgnoRoot will
5546355514
** be moved to the allocated page (unless the allocated page happens
5546455515
** to reside at pgnoRoot).
5546555516
*/
55466
- rc = allocateBtreePage(pBt, &pPageMove, &pgnoMove, pgnoRoot, 1);
55517
+ rc = allocateBtreePage(pBt, &pPageMove, &pgnoMove, pgnoRoot, BTALLOC_EXACT);
5546755518
if( rc!=SQLITE_OK ){
5546855519
return rc;
5546955520
}
5547055521
5547155522
if( pgnoMove!=pgnoRoot ){
@@ -57153,11 +57204,10 @@
5715357204
}
5715457205
}else{
5715557206
nDestTruncate = nSrcPage * (pgszSrc/pgszDest);
5715657207
}
5715757208
assert( nDestTruncate>0 );
57158
- sqlite3PagerTruncateImage(pDestPager, nDestTruncate);
5715957209
5716057210
if( pgszSrc<pgszDest ){
5716157211
/* If the source page-size is smaller than the destination page-size,
5716257212
** two extra things may need to happen:
5716357213
**
@@ -57167,10 +57217,12 @@
5716757217
** pending-byte page in the source database may need to be
5716857218
** copied into the destination database.
5716957219
*/
5717057220
const i64 iSize = (i64)pgszSrc * (i64)nSrcPage;
5717157221
sqlite3_file * const pFile = sqlite3PagerFile(pDestPager);
57222
+ Pgno iPg;
57223
+ int nDstPage;
5717257224
i64 iOff;
5717357225
i64 iEnd;
5717457226
5717557227
assert( pFile );
5717657228
assert( nDestTruncate==0
@@ -57177,17 +57229,30 @@
5717757229
|| (i64)nDestTruncate*(i64)pgszDest >= iSize || (
5717857230
nDestTruncate==(int)(PENDING_BYTE_PAGE(p->pDest->pBt)-1)
5717957231
&& iSize>=PENDING_BYTE && iSize<=PENDING_BYTE+pgszDest
5718057232
));
5718157233
57182
- /* This call ensures that all data required to recreate the original
57234
+ /* This block ensures that all data required to recreate the original
5718357235
** database has been stored in the journal for pDestPager and the
5718457236
** journal synced to disk. So at this point we may safely modify
5718557237
** the database file in any way, knowing that if a power failure
5718657238
** occurs, the original database will be reconstructed from the
5718757239
** journal file. */
57188
- rc = sqlite3PagerCommitPhaseOne(pDestPager, 0, 1);
57240
+ sqlite3PagerPagecount(pDestPager, &nDstPage);
57241
+ for(iPg=nDestTruncate; rc==SQLITE_OK && iPg<=(Pgno)nDstPage; iPg++){
57242
+ if( iPg!=PENDING_BYTE_PAGE(p->pDest->pBt) ){
57243
+ DbPage *pPg;
57244
+ rc = sqlite3PagerGet(pDestPager, iPg, &pPg);
57245
+ if( rc==SQLITE_OK ){
57246
+ rc = sqlite3PagerWrite(pPg);
57247
+ sqlite3PagerUnref(pPg);
57248
+ }
57249
+ }
57250
+ }
57251
+ if( rc==SQLITE_OK ){
57252
+ rc = sqlite3PagerCommitPhaseOne(pDestPager, 0, 1);
57253
+ }
5718957254
5719057255
/* Write the extra pages and truncate the database file as required */
5719157256
iEnd = MIN(PENDING_BYTE + pgszDest, iSize);
5719257257
for(
5719357258
iOff=PENDING_BYTE+pgszSrc;
@@ -57210,10 +57275,11 @@
5721057275
/* Sync the database file to disk. */
5721157276
if( rc==SQLITE_OK ){
5721257277
rc = sqlite3PagerSync(pDestPager);
5721357278
}
5721457279
}else{
57280
+ sqlite3PagerTruncateImage(pDestPager, nDestTruncate);
5721557281
rc = sqlite3PagerCommitPhaseOne(pDestPager, 0, 0);
5721657282
}
5721757283
5721857284
/* Finish committing the transaction to the destination database. */
5721957285
if( SQLITE_OK==rc
@@ -63039,11 +63105,11 @@
6303963105
return 0;
6304063106
}
6304163107
if( zName ){
6304263108
for(i=0; i<p->nzVar; i++){
6304363109
const char *z = p->azVar[i];
63044
- if( z && memcmp(z,zName,nName)==0 && z[nName]==0 ){
63110
+ if( z && strncmp(z,zName,nName)==0 && z[nName]==0 ){
6304563111
return i+1;
6304663112
}
6304763113
}
6304863114
}
6304963115
return 0;
@@ -72691,16 +72757,16 @@
7269172757
const char *zTab,
7269272758
const char *zDb
7269372759
){
7269472760
int n;
7269572761
for(n=0; ALWAYS(zSpan[n]) && zSpan[n]!='.'; n++){}
72696
- if( zDb && sqlite3StrNICmp(zSpan, zDb, n)!=0 ){
72762
+ if( zDb && (sqlite3StrNICmp(zSpan, zDb, n)!=0 || zDb[n]!=0) ){
7269772763
return 0;
7269872764
}
7269972765
zSpan += n+1;
7270072766
for(n=0; ALWAYS(zSpan[n]) && zSpan[n]!='.'; n++){}
72701
- if( zTab && sqlite3StrNICmp(zSpan, zTab, n)!=0 ){
72767
+ if( zTab && (sqlite3StrNICmp(zSpan, zTab, n)!=0 || zTab[n]!=0) ){
7270272768
return 0;
7270372769
}
7270472770
zSpan += n+1;
7270572771
if( zCol && sqlite3StrICmp(zSpan, zCol)!=0 ){
7270672772
return 0;
@@ -74493,11 +74559,11 @@
7449374559
** number as the prior appearance of the same name, or if the name
7449474560
** has never appeared before, reuse the same variable number
7449574561
*/
7449674562
ynVar i;
7449774563
for(i=0; i<pParse->nzVar; i++){
74498
- if( pParse->azVar[i] && memcmp(pParse->azVar[i],z,n+1)==0 ){
74564
+ if( pParse->azVar[i] && strcmp(pParse->azVar[i],z)==0 ){
7449974565
pExpr->iColumn = x = (ynVar)i+1;
7450074566
break;
7450174567
}
7450274568
}
7450374569
if( x==0 ) x = pExpr->iColumn = (ynVar)(++pParse->nVar);
@@ -79350,11 +79416,11 @@
7935079416
}
7935179417
if( pTab->tnum==0 ){
7935279418
/* Do not gather statistics on views or virtual tables */
7935379419
return;
7935479420
}
79355
- if( memcmp(pTab->zName, "sqlite_", 7)==0 ){
79421
+ if( sqlite3_strnicmp(pTab->zName, "sqlite_", 7)==0 ){
7935679422
/* Do not gather statistics on system tables */
7935779423
return;
7935879424
}
7935979425
assert( sqlite3BtreeHoldsAllMutexes(db) );
7936079426
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
@@ -79760,11 +79826,11 @@
7976079826
}
7976179827
if( i==0 ) pTable->nRowEst = v;
7976279828
if( pIndex==0 ) break;
7976379829
pIndex->aiRowEst[i] = v;
7976479830
if( *z==' ' ) z++;
79765
- if( memcmp(z, "unordered", 10)==0 ){
79831
+ if( strcmp(z, "unordered")==0 ){
7976679832
pIndex->bUnordered = 1;
7976779833
break;
7976879834
}
7976979835
}
7977079836
return 0;
@@ -83409,11 +83475,11 @@
8340983475
pDb = &db->aDb[iDb];
8341083476
8341183477
assert( pTab!=0 );
8341283478
assert( pParse->nErr==0 );
8341383479
if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0
83414
- && memcmp(&pTab->zName[7],"altertab_",9)!=0 ){
83480
+ && sqlite3StrNICmp(&pTab->zName[7],"altertab_",9)!=0 ){
8341583481
sqlite3ErrorMsg(pParse, "table %s may not be indexed", pTab->zName);
8341683482
goto exit_create_index;
8341783483
}
8341883484
#ifndef SQLITE_OMIT_VIEW
8341983485
if( pTab->pSelect ){
@@ -86787,10 +86853,61 @@
8678786853
sqlite3_result_text(context, "NULL", 4, SQLITE_STATIC);
8678886854
break;
8678986855
}
8679086856
}
8679186857
}
86858
+
86859
+/*
86860
+** The unicode() function. Return the integer unicode code-point value
86861
+** for the first character of the input string.
86862
+*/
86863
+static void unicodeFunc(
86864
+ sqlite3_context *context,
86865
+ int argc,
86866
+ sqlite3_value **argv
86867
+){
86868
+ const unsigned char *z = sqlite3_value_text(argv[0]);
86869
+ (void)argc;
86870
+ if( z && z[0] ) sqlite3_result_int(context, sqlite3Utf8Read(&z));
86871
+}
86872
+
86873
+/*
86874
+** The char() function takes zero or more arguments, each of which is
86875
+** an integer. It constructs a string where each character of the string
86876
+** is the unicode character for the corresponding integer argument.
86877
+*/
86878
+static void charFunc(
86879
+ sqlite3_context *context,
86880
+ int argc,
86881
+ sqlite3_value **argv
86882
+){
86883
+ unsigned char *z, *zOut;
86884
+ int i;
86885
+ zOut = z = sqlite3_malloc( argc*4 );
86886
+ if( z==0 ){
86887
+ sqlite3_result_error_nomem(context);
86888
+ return;
86889
+ }
86890
+ for(i=0; i<argc; i++){
86891
+ sqlite3_int64 x;
86892
+ unsigned c;
86893
+ x = sqlite3_value_int64(argv[i]);
86894
+ if( x<0 || x>0x10ffff ) x = 0xfffd;
86895
+ c = (unsigned)(x & 0x1fffff);
86896
+ if( c<=0xFFFF ){
86897
+ if( c>=0xd800 && c<=0xdfff ) c = 0xfffd;
86898
+ *zOut++ = (u8)(c&0x00FF);
86899
+ *zOut++ = (u8)((c>>8)&0x00FF);
86900
+ }else{
86901
+ *zOut++ = (u8)(((c>>10)&0x003F) + (((c-0x10000)>>10)&0x00C0));
86902
+ *zOut++ = (u8)(0x00D8 + (((c-0x10000)>>18)&0x03));
86903
+ *zOut++ = (u8)(c&0x00FF);
86904
+ *zOut++ = (u8)(0x00DC + ((c>>8)&0x03));
86905
+ }
86906
+ }
86907
+ sqlite3_result_text16le(context, (char*)z, (int)(zOut-z), sqlite3_free);
86908
+}
8679286909
8679386910
/*
8679486911
** The hex() function. Interpret the argument as a blob. Return
8679586912
** a hexadecimal rendering as text.
8679686913
*/
@@ -87415,10 +87532,12 @@
8741587532
FUNCTION2(typeof, 1, 0, 0, typeofFunc, SQLITE_FUNC_TYPEOF),
8741687533
FUNCTION2(length, 1, 0, 0, lengthFunc, SQLITE_FUNC_LENGTH),
8741787534
FUNCTION(instr, 2, 0, 0, instrFunc ),
8741887535
FUNCTION(substr, 2, 0, 0, substrFunc ),
8741987536
FUNCTION(substr, 3, 0, 0, substrFunc ),
87537
+ FUNCTION(unicode, 1, 0, 0, unicodeFunc ),
87538
+ FUNCTION(char, -1, 0, 0, charFunc ),
8742087539
FUNCTION(abs, 1, 0, 0, absFunc ),
8742187540
#ifndef SQLITE_OMIT_FLOATING_POINT
8742287541
FUNCTION(round, 1, 0, 0, roundFunc ),
8742387542
FUNCTION(round, 2, 0, 0, roundFunc ),
8742487543
#endif
@@ -91626,10 +91745,23 @@
9162691745
0,
9162791746
#endif
9162891747
sqlite3_blob_reopen,
9162991748
sqlite3_vtab_config,
9163091749
sqlite3_vtab_on_conflict,
91750
+ sqlite3_close_v2,
91751
+ sqlite3_db_filename,
91752
+ sqlite3_db_readonly,
91753
+ sqlite3_db_release_memory,
91754
+ sqlite3_errstr,
91755
+ sqlite3_stmt_busy,
91756
+ sqlite3_stmt_readonly,
91757
+ sqlite3_stricmp,
91758
+ sqlite3_uri_boolean,
91759
+ sqlite3_uri_int64,
91760
+ sqlite3_uri_parameter,
91761
+ sqlite3_vsnprintf,
91762
+ sqlite3_wal_checkpoint_v2
9163191763
};
9163291764
9163391765
/*
9163491766
** Attempt to load an SQLite extension library contained in the file
9163591767
** zFile. The entry point is zProc. zProc may be 0 in which case a
@@ -92866,10 +92998,11 @@
9286692998
Column *pCol;
9286792999
Index *pPk;
9286893000
for(pPk=pTab->pIndex; pPk && pPk->autoIndex!=2; pPk=pPk->pNext){}
9286993001
sqlite3VdbeSetNumCols(v, 6);
9287093002
pParse->nMem = 6;
93003
+ sqlite3CodeVerifySchema(pParse, iDb);
9287193004
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "cid", SQLITE_STATIC);
9287293005
sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE_STATIC);
9287393006
sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "type", SQLITE_STATIC);
9287493007
sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "notnull", SQLITE_STATIC);
9287593008
sqlite3VdbeSetColName(v, 4, COLNAME_NAME, "dflt_value", SQLITE_STATIC);
@@ -92911,10 +93044,11 @@
9291193044
if( pIdx ){
9291293045
int i;
9291393046
pTab = pIdx->pTable;
9291493047
sqlite3VdbeSetNumCols(v, 3);
9291593048
pParse->nMem = 3;
93049
+ sqlite3CodeVerifySchema(pParse, iDb);
9291693050
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seqno", SQLITE_STATIC);
9291793051
sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "cid", SQLITE_STATIC);
9291893052
sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "name", SQLITE_STATIC);
9291993053
for(i=0; i<pIdx->nColumn; i++){
9292093054
int cnum = pIdx->aiColumn[i];
@@ -92937,10 +93071,11 @@
9293793071
pIdx = pTab->pIndex;
9293893072
if( pIdx ){
9293993073
int i = 0;
9294093074
sqlite3VdbeSetNumCols(v, 3);
9294193075
pParse->nMem = 3;
93076
+ sqlite3CodeVerifySchema(pParse, iDb);
9294293077
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", SQLITE_STATIC);
9294393078
sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE_STATIC);
9294493079
sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "unique", SQLITE_STATIC);
9294593080
while(pIdx){
9294693081
sqlite3VdbeAddOp2(v, OP_Integer, i, 1);
@@ -93000,10 +93135,11 @@
9300093135
pFK = pTab->pFKey;
9300193136
if( pFK ){
9300293137
int i = 0;
9300393138
sqlite3VdbeSetNumCols(v, 8);
9300493139
pParse->nMem = 8;
93140
+ sqlite3CodeVerifySchema(pParse, iDb);
9300593141
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "id", SQLITE_STATIC);
9300693142
sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "seq", SQLITE_STATIC);
9300793143
sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "table", SQLITE_STATIC);
9300893144
sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "from", SQLITE_STATIC);
9300993145
sqlite3VdbeSetColName(v, 4, COLNAME_NAME, "to", SQLITE_STATIC);
@@ -96914,11 +97050,12 @@
9691497050
if( op==TK_ALL ){
9691597051
regPrev = 0;
9691697052
}else{
9691797053
int nExpr = p->pEList->nExpr;
9691897054
assert( nOrderBy>=nExpr || db->mallocFailed );
96919
- regPrev = sqlite3GetTempRange(pParse, nExpr+1);
97055
+ regPrev = pParse->nMem+1;
97056
+ pParse->nMem += nExpr+1;
9692097057
sqlite3VdbeAddOp2(v, OP_Integer, 0, regPrev);
9692197058
pKeyDup = sqlite3DbMallocZero(db,
9692297059
sizeof(*pKeyDup) + nExpr*(sizeof(CollSeq*)+1) );
9692397060
if( pKeyDup ){
9692497061
pKeyDup->aSortOrder = (u8*)&pKeyDup->aColl[nExpr];
@@ -97096,16 +97233,10 @@
9709697233
sqlite3VdbeAddOp4(v, OP_Compare, destA.iSdst, destB.iSdst, nOrderBy,
9709797234
(char*)pKeyMerge, P4_KEYINFO_HANDOFF);
9709897235
sqlite3VdbeChangeP5(v, OPFLAG_PERMUTE);
9709997236
sqlite3VdbeAddOp3(v, OP_Jump, addrAltB, addrAeqB, addrAgtB);
9710097237
97101
- /* Release temporary registers
97102
- */
97103
- if( regPrev ){
97104
- sqlite3ReleaseTempRange(pParse, regPrev, nOrderBy+1);
97105
- }
97106
-
9710797238
/* Jump to the this point in order to terminate the query.
9710897239
*/
9710997240
sqlite3VdbeResolveLabel(v, labelEnd);
9711097241
9711197242
/* Set the number of output columns
@@ -114105,11 +114236,11 @@
114105114236
}
114106114237
}
114107114238
sqlite3VtabRollback(db);
114108114239
sqlite3EndBenignMalloc();
114109114240
114110
- if( db->flags&SQLITE_InternChanges ){
114241
+ if( (db->flags&SQLITE_InternChanges)!=0 && db->init.busy==0 ){
114111114242
sqlite3ExpirePreparedStatements(db);
114112114243
sqlite3ResetAllSchemasOfConnection(db);
114113114244
}
114114114245
114115114246
/* Any deferred constraint violations have now been resolved. */
114116114247
--- src/sqlite3.c
+++ src/sqlite3.c
@@ -438,11 +438,12 @@
438 ** if it is already defined or if it is unneeded because we are
439 ** not doing a threadsafe build. Ticket #2681.
440 **
441 ** See also ticket #2741.
442 */
443 #if !defined(_XOPEN_SOURCE) && !defined(__DARWIN__) && !defined(__APPLE__) && SQLITE_THREADSAFE
 
444 # define _XOPEN_SOURCE 500 /* Needed to enable pthread recursive mutexes */
445 #endif
446
447 /*
448 ** The TCL headers are only needed when compiling the TCL bindings.
@@ -673,11 +674,11 @@
673 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
674 ** [sqlite_version()] and [sqlite_source_id()].
675 */
676 #define SQLITE_VERSION "3.7.16"
677 #define SQLITE_VERSION_NUMBER 3007016
678 #define SQLITE_SOURCE_ID "2013-02-13 14:04:28 7e10a62d0eb1cb2bdafb6752b78a9d368e9f21f5"
679
680 /*
681 ** CAPI3REF: Run-Time Library Version Numbers
682 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
683 **
@@ -11915,11 +11916,11 @@
11915 SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3*, Select*);
11916 SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse*, SrcList*);
11917 SQLITE_PRIVATE int sqlite3IsReadOnly(Parse*, Table*, int);
11918 SQLITE_PRIVATE void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int);
11919 #if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY)
11920 SQLITE_PRIVATE Expr *sqlite3LimitWhere(Parse *, SrcList *, Expr *, ExprList *, Expr *, Expr *, char *);
11921 #endif
11922 SQLITE_PRIVATE void sqlite3DeleteFrom(Parse*, SrcList*, Expr*);
11923 SQLITE_PRIVATE void sqlite3Update(Parse*, SrcList*, ExprList*, Expr*, int);
11924 SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(Parse*,SrcList*,Expr*,ExprList*,ExprList*,u16,int);
11925 SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo*);
@@ -12096,12 +12097,15 @@
12096 **
12097 ** x = getVarint32( A, B );
12098 ** x = putVarint32( A, B );
12099 **
12100 */
12101 #define getVarint32(A,B) (u8)((*(A)<(u8)0x80) ? ((B) = (u32)*(A)),1 : sqlite3GetVarint32((A), (u32 *)&(B)))
12102 #define putVarint32(A,B) (u8)(((u32)(B)<(u32)0x80) ? (*(A) = (unsigned char)(B)),1 : sqlite3PutVarint32((A), (B)))
 
 
 
12103 #define getVarint sqlite3GetVarint
12104 #define putVarint sqlite3PutVarint
12105
12106
12107 SQLITE_PRIVATE const char *sqlite3IndexAffinityStr(Vdbe *, Index *);
@@ -27655,11 +27659,11 @@
27655 pNew->ctrlFlags = (u8)ctrlFlags;
27656 if( sqlite3_uri_boolean(((ctrlFlags & UNIXFILE_URI) ? zFilename : 0),
27657 "psow", SQLITE_POWERSAFE_OVERWRITE) ){
27658 pNew->ctrlFlags |= UNIXFILE_PSOW;
27659 }
27660 if( memcmp(pVfs->zName,"unix-excl",10)==0 ){
27661 pNew->ctrlFlags |= UNIXFILE_EXCL;
27662 }
27663
27664 #if OS_VXWORKS
27665 pNew->pId = vxworksFindFileId(zFilename);
@@ -31959,21 +31963,23 @@
31959 bReturn = TRUE;
31960 }
31961 }
31962
31963 /* Want a pending lock? */
31964 else if (dwFileOffsetLow == (DWORD)PENDING_BYTE && nNumberOfBytesToLockLow == 1){
 
31965 /* If no pending lock has been acquired, then acquire it */
31966 if (pFile->shared->bPending == 0) {
31967 pFile->shared->bPending = TRUE;
31968 pFile->local.bPending = TRUE;
31969 bReturn = TRUE;
31970 }
31971 }
31972
31973 /* Want a reserved lock? */
31974 else if (dwFileOffsetLow == (DWORD)RESERVED_BYTE && nNumberOfBytesToLockLow == 1){
 
31975 if (pFile->shared->bReserved == 0) {
31976 pFile->shared->bReserved = TRUE;
31977 pFile->local.bReserved = TRUE;
31978 bReturn = TRUE;
31979 }
@@ -32012,11 +32018,12 @@
32012 bReturn = TRUE;
32013 }
32014
32015 /* Did we just have a reader lock? */
32016 else if (pFile->local.nReaders){
32017 assert(nNumberOfBytesToUnlockLow == (DWORD)SHARED_SIZE || nNumberOfBytesToUnlockLow == 1);
 
32018 pFile->local.nReaders --;
32019 if (pFile->local.nReaders == 0)
32020 {
32021 pFile->shared->nReaders --;
32022 }
@@ -32023,19 +32030,21 @@
32023 bReturn = TRUE;
32024 }
32025 }
32026
32027 /* Releasing a pending lock */
32028 else if (dwFileOffsetLow == (DWORD)PENDING_BYTE && nNumberOfBytesToUnlockLow == 1){
 
32029 if (pFile->local.bPending){
32030 pFile->local.bPending = FALSE;
32031 pFile->shared->bPending = FALSE;
32032 bReturn = TRUE;
32033 }
32034 }
32035 /* Releasing a reserved lock */
32036 else if (dwFileOffsetLow == (DWORD)RESERVED_BYTE && nNumberOfBytesToUnlockLow == 1){
 
32037 if (pFile->local.bReserved) {
32038 pFile->local.bReserved = FALSE;
32039 pFile->shared->bReserved = FALSE;
32040 bReturn = TRUE;
32041 }
@@ -32197,10 +32206,11 @@
32197 assert( id!=0 );
32198 #ifndef SQLITE_OMIT_WAL
32199 assert( pFile->pShm==0 );
32200 #endif
32201 OSTRACE(("CLOSE %d\n", pFile->h));
 
32202 do{
32203 rc = osCloseHandle(pFile->h);
32204 /* SimulateIOError( rc=0; cnt=MX_CLOSE_ATTEMPT; ); */
32205 }while( rc==0 && ++cnt < MX_CLOSE_ATTEMPT && (sqlite3_win32_sleep(100), 1) );
32206 #if SQLITE_OS_WINCE
@@ -33113,11 +33123,11 @@
33113 bRc = osCloseHandle(p->aRegion[i].hMap);
33114 OSTRACE(("SHM-PURGE pid-%d close region=%d %s\n",
33115 (int)osGetCurrentProcessId(), i,
33116 bRc ? "ok" : "failed"));
33117 }
33118 if( p->hFile.h != INVALID_HANDLE_VALUE ){
33119 SimulateIOErrorBenign(1);
33120 winClose((sqlite3_file *)&p->hFile);
33121 SimulateIOErrorBenign(0);
33122 }
33123 if( deleteFlag ){
@@ -33193,11 +33203,11 @@
33193 }
33194
33195 rc = winOpen(pDbFd->pVfs,
33196 pShmNode->zFilename, /* Name of the file (UTF-8) */
33197 (sqlite3_file*)&pShmNode->hFile, /* File handle here */
33198 SQLITE_OPEN_WAL | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, /* Mode flags */
33199 0);
33200 if( SQLITE_OK!=rc ){
33201 goto shm_open_err;
33202 }
33203
@@ -33808,22 +33818,21 @@
33808 || eType==SQLITE_OPEN_MAIN_JOURNAL || eType==SQLITE_OPEN_TEMP_JOURNAL
33809 || eType==SQLITE_OPEN_SUBJOURNAL || eType==SQLITE_OPEN_MASTER_JOURNAL
33810 || eType==SQLITE_OPEN_TRANSIENT_DB || eType==SQLITE_OPEN_WAL
33811 );
33812
33813 assert( id!=0 );
33814 UNUSED_PARAMETER(pVfs);
 
33815
33816 #if SQLITE_OS_WINRT
33817 if( !sqlite3_temp_directory ){
33818 sqlite3_log(SQLITE_ERROR,
33819 "sqlite3_temp_directory variable should be set for WinRT");
33820 }
33821 #endif
33822
33823 pFile->h = INVALID_HANDLE_VALUE;
33824
33825 /* If the second argument to this function is NULL, generate a
33826 ** temporary file name to use
33827 */
33828 if( !zUtf8Name ){
33829 assert(isDelete && !isOpenJournal);
@@ -33948,11 +33957,13 @@
33948 pFile->lastErrno = lastErrno;
33949 winLogError(SQLITE_CANTOPEN, pFile->lastErrno, "winOpen", zUtf8Name);
33950 sqlite3_free(zConverted);
33951 if( isReadWrite && !isExclusive ){
33952 return winOpen(pVfs, zName, id,
33953 ((flags|SQLITE_OPEN_READONLY)&~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE)), pOutFlags);
 
 
33954 }else{
33955 return SQLITE_CANTOPEN_BKPT;
33956 }
33957 }
33958
@@ -33962,23 +33973,10 @@
33962 }else{
33963 *pOutFlags = SQLITE_OPEN_READONLY;
33964 }
33965 }
33966
33967 memset(pFile, 0, sizeof(*pFile));
33968 pFile->pMethod = &winIoMethod;
33969 pFile->h = h;
33970 pFile->lastErrno = NO_ERROR;
33971 pFile->pVfs = pVfs;
33972 #ifndef SQLITE_OMIT_WAL
33973 pFile->pShm = 0;
33974 #endif
33975 pFile->zPath = zName;
33976 if( sqlite3_uri_boolean(zName, "psow", SQLITE_POWERSAFE_OVERWRITE) ){
33977 pFile->ctrlFlags |= WINFILE_PSOW;
33978 }
33979
33980 #if SQLITE_OS_WINCE
33981 if( isReadWrite && eType==SQLITE_OPEN_MAIN_DB
33982 && (rc = winceCreateLock(zName, pFile))!=SQLITE_OK
33983 ){
33984 osCloseHandle(h);
@@ -33990,10 +33988,19 @@
33990 }else
33991 #endif
33992 {
33993 sqlite3_free(zConverted);
33994 }
 
 
 
 
 
 
 
 
 
33995
33996 OpenCounter(+1);
33997 return rc;
33998 }
33999
@@ -34035,11 +34042,12 @@
34035 if ( osGetFileAttributesExW(zConverted, GetFileExInfoStandard,
34036 &sAttrData) ){
34037 attr = sAttrData.dwFileAttributes;
34038 }else{
34039 lastErrno = osGetLastError();
34040 if( lastErrno==ERROR_FILE_NOT_FOUND || lastErrno==ERROR_PATH_NOT_FOUND ){
 
34041 rc = SQLITE_IOERR_DELETE_NOENT; /* Already gone? */
34042 }else{
34043 rc = SQLITE_ERROR;
34044 }
34045 break;
@@ -34047,11 +34055,12 @@
34047 #else
34048 attr = osGetFileAttributesW(zConverted);
34049 #endif
34050 if ( attr==INVALID_FILE_ATTRIBUTES ){
34051 lastErrno = osGetLastError();
34052 if( lastErrno==ERROR_FILE_NOT_FOUND || lastErrno==ERROR_PATH_NOT_FOUND ){
 
34053 rc = SQLITE_IOERR_DELETE_NOENT; /* Already gone? */
34054 }else{
34055 rc = SQLITE_ERROR;
34056 }
34057 break;
@@ -34074,11 +34083,12 @@
34074 else{
34075 do {
34076 attr = osGetFileAttributesA(zConverted);
34077 if ( attr==INVALID_FILE_ATTRIBUTES ){
34078 lastErrno = osGetLastError();
34079 if( lastErrno==ERROR_FILE_NOT_FOUND || lastErrno==ERROR_PATH_NOT_FOUND ){
 
34080 rc = SQLITE_IOERR_DELETE_NOENT; /* Already gone? */
34081 }else{
34082 rc = SQLITE_ERROR;
34083 }
34084 break;
@@ -34242,20 +34252,16 @@
34242 ** for converting the relative path name to an absolute
34243 ** one by prepending the data directory and a slash.
34244 */
34245 char zOut[MAX_PATH+1];
34246 memset(zOut, 0, MAX_PATH+1);
34247 cygwin_conv_to_win32_path(zRelative, zOut); /* POSIX to Win32 */
 
34248 sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s\\%s",
34249 sqlite3_data_directory, zOut);
34250 }else{
34251 /*
34252 ** NOTE: The Cygwin docs state that the maximum length needed
34253 ** for the buffer passed to cygwin_conv_to_full_win32_path
34254 ** is MAX_PATH.
34255 */
34256 cygwin_conv_to_full_win32_path(zRelative, zFull);
34257 }
34258 return SQLITE_OK;
34259 #endif
34260
34261 #if (SQLITE_OS_WINCE || SQLITE_OS_WINRT) && !defined(__CYGWIN__)
@@ -34409,13 +34415,13 @@
34409 }
34410 static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){
34411 UNUSED_PARAMETER(pVfs);
34412 getLastErrorMsg(osGetLastError(), nBuf, zBufOut);
34413 }
34414 static void (*winDlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol))(void){
34415 UNUSED_PARAMETER(pVfs);
34416 return (void(*)(void))osGetProcAddressA((HANDLE)pHandle, zSymbol);
34417 }
34418 static void winDlClose(sqlite3_vfs *pVfs, void *pHandle){
34419 UNUSED_PARAMETER(pVfs);
34420 osFreeLibrary((HANDLE)pHandle);
34421 }
@@ -34509,11 +34515,12 @@
34509 #ifdef SQLITE_TEST
34510 static const sqlite3_int64 unixEpoch = 24405875*(sqlite3_int64)8640000;
34511 #endif
34512 /* 2^32 - to avoid use of LL and warnings in gcc */
34513 static const sqlite3_int64 max32BitValue =
34514 (sqlite3_int64)2000000000 + (sqlite3_int64)2000000000 + (sqlite3_int64)294967296;
 
34515
34516 #if SQLITE_OS_WINCE
34517 SYSTEMTIME time;
34518 osGetSystemTime(&time);
34519 /* if SystemTimeToFileTime() fails, it returns zero. */
@@ -39187,10 +39194,12 @@
39187 pPager->eState = PAGER_ERROR;
39188 }
39189 return rc;
39190 }
39191
 
 
39192 /*
39193 ** This routine ends a transaction. A transaction is usually ended by
39194 ** either a COMMIT or a ROLLBACK operation. This routine may be called
39195 ** after rollback of a hot-journal, or if an error occurs while opening
39196 ** the journal file or writing the very first journal-header of a
@@ -39240,11 +39249,11 @@
39240 ** tries to unlock the database file if not in exclusive mode. If the
39241 ** unlock operation fails as well, then the first error code related
39242 ** to the first error encountered (the journal finalization one) is
39243 ** returned.
39244 */
39245 static int pager_end_transaction(Pager *pPager, int hasMaster){
39246 int rc = SQLITE_OK; /* Error code from journal finalization operation */
39247 int rc2 = SQLITE_OK; /* Error code from db file unlock operation */
39248
39249 /* Do nothing if the pager does not have an open write transaction
39250 ** or at least a RESERVED lock. This function may be called when there
@@ -39326,11 +39335,21 @@
39326 ** locking_mode=exclusive mode but is no longer, drop the EXCLUSIVE
39327 ** lock held on the database file.
39328 */
39329 rc2 = sqlite3WalEndWriteTransaction(pPager->pWal);
39330 assert( rc2==SQLITE_OK );
 
 
 
 
 
 
 
 
 
39331 }
 
39332 if( !pPager->exclusiveMode
39333 && (!pagerUseWal(pPager) || sqlite3WalExclusiveMode(pPager->pWal, 0))
39334 ){
39335 rc2 = pagerUnlockDb(pPager, SHARED_LOCK);
39336 pPager->changeCountDone = 0;
@@ -39365,11 +39384,11 @@
39365 sqlite3BeginBenignMalloc();
39366 sqlite3PagerRollback(pPager);
39367 sqlite3EndBenignMalloc();
39368 }else if( !pPager->exclusiveMode ){
39369 assert( pPager->eState==PAGER_READER );
39370 pager_end_transaction(pPager, 0);
39371 }
39372 }
39373 pager_unlock(pPager);
39374 }
39375
@@ -40140,11 +40159,11 @@
40140 && (pPager->eState>=PAGER_WRITER_DBMOD || pPager->eState==PAGER_OPEN)
40141 ){
40142 rc = sqlite3PagerSync(pPager);
40143 }
40144 if( rc==SQLITE_OK ){
40145 rc = pager_end_transaction(pPager, zMaster[0]!='\0');
40146 testcase( rc!=SQLITE_OK );
40147 }
40148 if( rc==SQLITE_OK && zMaster[0] && res ){
40149 /* If there was a master journal and this routine will return success,
40150 ** see if it is possible to delete the master journal.
@@ -43234,40 +43253,10 @@
43234 #else
43235 rc = pager_incr_changecounter(pPager, 0);
43236 #endif
43237 if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
43238
43239 /* If this transaction has made the database smaller, then all pages
43240 ** being discarded by the truncation must be written to the journal
43241 ** file.
43242 **
43243 ** Before reading the pages with page numbers larger than the
43244 ** current value of Pager.dbSize, set dbSize back to the value
43245 ** that it took at the start of the transaction. Otherwise, the
43246 ** calls to sqlite3PagerGet() return zeroed pages instead of
43247 ** reading data from the database file.
43248 */
43249 if( pPager->dbSize<pPager->dbOrigSize
43250 && pPager->journalMode!=PAGER_JOURNALMODE_OFF
43251 ){
43252 Pgno i; /* Iterator variable */
43253 const Pgno iSkip = PAGER_MJ_PGNO(pPager); /* Pending lock page */
43254 const Pgno dbSize = pPager->dbSize; /* Database image size */
43255 pPager->dbSize = pPager->dbOrigSize;
43256 for( i=dbSize+1; i<=pPager->dbOrigSize; i++ ){
43257 if( !sqlite3BitvecTest(pPager->pInJournal, i) && i!=iSkip ){
43258 PgHdr *pPage; /* Page to journal */
43259 rc = sqlite3PagerGet(pPager, i, &pPage);
43260 if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
43261 rc = sqlite3PagerWrite(pPage);
43262 sqlite3PagerUnref(pPage);
43263 if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
43264 }
43265 }
43266 pPager->dbSize = dbSize;
43267 }
43268
43269 /* Write the master journal name into the journal file. If a master
43270 ** journal file name has already been written to the journal file,
43271 ** or if zMaster is NULL (no master journal), then this call is a no-op.
43272 */
43273 rc = writeMasterJournal(pPager, zMaster);
@@ -43291,15 +43280,18 @@
43291 if( rc!=SQLITE_OK ){
43292 assert( rc!=SQLITE_IOERR_BLOCKED );
43293 goto commit_phase_one_exit;
43294 }
43295 sqlite3PcacheCleanAll(pPager->pPCache);
43296
43297 /* If the file on disk is not the same size as the database image,
43298 ** then use pager_truncate to grow or shrink the file here.
43299 */
43300 if( pPager->dbSize!=pPager->dbFileSize ){
 
 
 
43301 Pgno nNew = pPager->dbSize - (pPager->dbSize==PAGER_MJ_PGNO(pPager));
43302 assert( pPager->eState==PAGER_WRITER_DBMOD );
43303 rc = pager_truncate(pPager, nNew);
43304 if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
43305 }
@@ -43368,11 +43360,11 @@
43368 pPager->eState = PAGER_READER;
43369 return SQLITE_OK;
43370 }
43371
43372 PAGERTRACE(("COMMIT %d\n", PAGERID(pPager)));
43373 rc = pager_end_transaction(pPager, pPager->setMaster);
43374 return pager_error(pPager, rc);
43375 }
43376
43377 /*
43378 ** If a write transaction is open, then all changes made within the
@@ -43413,15 +43405,15 @@
43413 if( pPager->eState<=PAGER_READER ) return SQLITE_OK;
43414
43415 if( pagerUseWal(pPager) ){
43416 int rc2;
43417 rc = sqlite3PagerSavepoint(pPager, SAVEPOINT_ROLLBACK, -1);
43418 rc2 = pager_end_transaction(pPager, pPager->setMaster);
43419 if( rc==SQLITE_OK ) rc = rc2;
43420 }else if( !isOpen(pPager->jfd) || pPager->eState==PAGER_WRITER_LOCKED ){
43421 int eState = pPager->eState;
43422 rc = pager_end_transaction(pPager, 0);
43423 if( !MEMDB && eState>PAGER_WRITER_LOCKED ){
43424 /* This can happen using journal_mode=off. Move the pager to the error
43425 ** state to indicate that the contents of the cache may not be trusted.
43426 ** Any active readers will get SQLITE_ABORT.
43427 */
@@ -43815,11 +43807,12 @@
43815 ** the journal needs to be sync()ed before database page pPg->pgno
43816 ** can be written to. The caller has already promised not to write to it.
43817 */
43818 if( (pPg->flags&PGHDR_NEED_SYNC) && !isCommit ){
43819 needSyncPgno = pPg->pgno;
43820 assert( pageInJournal(pPg) || pPg->pgno>pPager->dbOrigSize );
 
43821 assert( pPg->flags&PGHDR_DIRTY );
43822 }
43823
43824 /* If the cache contains a page with page-number pgno, remove it
43825 ** from its hash chain. Also, if the PGHDR_NEED_SYNC flag was set for
@@ -47819,10 +47812,11 @@
47819 MemPage *pPage1; /* First page of the database */
47820 u8 openFlags; /* Flags to sqlite3BtreeOpen() */
47821 #ifndef SQLITE_OMIT_AUTOVACUUM
47822 u8 autoVacuum; /* True if auto-vacuum is enabled */
47823 u8 incrVacuum; /* True if incr-vacuum is enabled */
 
47824 #endif
47825 u8 inTransaction; /* Transaction state */
47826 u8 max1bytePayload; /* Maximum first byte of cell for a 1-byte payload */
47827 u16 btsFlags; /* Boolean parameters. See BTS_* macros below */
47828 u16 maxLocal; /* Maximum local payload in non-LEAFDATA tables */
@@ -50937,10 +50931,11 @@
50937 ** is requested, this is a no-op.
50938 */
50939 if( p->inTrans==TRANS_WRITE || (p->inTrans==TRANS_READ && !wrflag) ){
50940 goto trans_begun;
50941 }
 
50942
50943 /* Write transactions are not possible on a read-only database */
50944 if( (pBt->btsFlags & BTS_READ_ONLY)!=0 && wrflag ){
50945 rc = SQLITE_READONLY;
50946 goto trans_begun;
@@ -51251,30 +51246,32 @@
51251 return rc;
51252 }
51253
51254 /* Forward declaration required by incrVacuumStep(). */
51255 static int allocateBtreePage(BtShared *, MemPage **, Pgno *, Pgno, u8);
 
 
 
51256
51257 /*
51258 ** Perform a single step of an incremental-vacuum. If successful,
51259 ** return SQLITE_OK. If there is no work to do (and therefore no
51260 ** point in calling this function again), return SQLITE_DONE.
51261 **
51262 ** More specificly, this function attempts to re-organize the
51263 ** database so that the last page of the file currently in use
51264 ** is no longer in use.
51265 **
51266 ** If the nFin parameter is non-zero, this function assumes
51267 ** that the caller will keep calling incrVacuumStep() until
51268 ** it returns SQLITE_DONE or an error, and that nFin is the
51269 ** number of pages the database file will contain after this
51270 ** process is complete. If nFin is zero, it is assumed that
51271 ** incrVacuumStep() will be called a finite amount of times
51272 ** which may or may not empty the freelist. A full autovacuum
51273 ** has nFin>0. A "PRAGMA incremental_vacuum" has nFin==0.
51274 */
51275 static int incrVacuumStep(BtShared *pBt, Pgno nFin, Pgno iLastPg){
51276 Pgno nFreeList; /* Number of pages still on the free-list */
51277 int rc;
51278
51279 assert( sqlite3_mutex_held(pBt->mutex) );
51280 assert( iLastPg>nFin );
@@ -51295,85 +51292,98 @@
51295 if( eType==PTRMAP_ROOTPAGE ){
51296 return SQLITE_CORRUPT_BKPT;
51297 }
51298
51299 if( eType==PTRMAP_FREEPAGE ){
51300 if( nFin==0 ){
51301 /* Remove the page from the files free-list. This is not required
51302 ** if nFin is non-zero. In that case, the free-list will be
51303 ** truncated to zero after this function returns, so it doesn't
51304 ** matter if it still contains some garbage entries.
51305 */
51306 Pgno iFreePg;
51307 MemPage *pFreePg;
51308 rc = allocateBtreePage(pBt, &pFreePg, &iFreePg, iLastPg, 1);
51309 if( rc!=SQLITE_OK ){
51310 return rc;
51311 }
51312 assert( iFreePg==iLastPg );
51313 releasePage(pFreePg);
51314 }
51315 } else {
51316 Pgno iFreePg; /* Index of free page to move pLastPg to */
51317 MemPage *pLastPg;
 
 
51318
51319 rc = btreeGetPage(pBt, iLastPg, &pLastPg, 0);
51320 if( rc!=SQLITE_OK ){
51321 return rc;
51322 }
51323
51324 /* If nFin is zero, this loop runs exactly once and page pLastPg
51325 ** is swapped with the first free page pulled off the free list.
51326 **
51327 ** On the other hand, if nFin is greater than zero, then keep
51328 ** looping until a free-page located within the first nFin pages
51329 ** of the file is found.
51330 */
 
 
 
 
51331 do {
51332 MemPage *pFreePg;
51333 rc = allocateBtreePage(pBt, &pFreePg, &iFreePg, 0, 0);
51334 if( rc!=SQLITE_OK ){
51335 releasePage(pLastPg);
51336 return rc;
51337 }
51338 releasePage(pFreePg);
51339 }while( nFin!=0 && iFreePg>nFin );
51340 assert( iFreePg<iLastPg );
51341
51342 rc = sqlite3PagerWrite(pLastPg->pDbPage);
51343 if( rc==SQLITE_OK ){
51344 rc = relocatePage(pBt, pLastPg, eType, iPtrPage, iFreePg, nFin!=0);
51345 }
51346 releasePage(pLastPg);
51347 if( rc!=SQLITE_OK ){
51348 return rc;
51349 }
51350 }
51351 }
51352
51353 if( nFin==0 ){
51354 iLastPg--;
51355 while( iLastPg==PENDING_BYTE_PAGE(pBt)||PTRMAP_ISPAGE(pBt, iLastPg) ){
51356 if( PTRMAP_ISPAGE(pBt, iLastPg) ){
51357 MemPage *pPg;
51358 rc = btreeGetPage(pBt, iLastPg, &pPg, 0);
51359 if( rc!=SQLITE_OK ){
51360 return rc;
51361 }
51362 rc = sqlite3PagerWrite(pPg->pDbPage);
51363 releasePage(pPg);
51364 if( rc!=SQLITE_OK ){
51365 return rc;
51366 }
51367 }
51368 iLastPg--;
51369 }
51370 sqlite3PagerTruncateImage(pBt->pPager, iLastPg);
51371 pBt->nPage = iLastPg;
51372 }
51373 return SQLITE_OK;
51374 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51375
51376 /*
51377 ** A write-transaction must be opened before calling this function.
51378 ** It performs a single unit of work towards an incremental vacuum.
51379 **
@@ -51388,15 +51398,25 @@
51388 sqlite3BtreeEnter(p);
51389 assert( pBt->inTransaction==TRANS_WRITE && p->inTrans==TRANS_WRITE );
51390 if( !pBt->autoVacuum ){
51391 rc = SQLITE_DONE;
51392 }else{
51393 invalidateAllOverflowCache(pBt);
51394 rc = incrVacuumStep(pBt, 0, btreePagecount(pBt));
51395 if( rc==SQLITE_OK ){
51396 rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
51397 put4byte(&pBt->pPage1->aData[28], pBt->nPage);
 
 
 
 
 
 
 
 
 
 
51398 }
51399 }
51400 sqlite3BtreeLeave(p);
51401 return rc;
51402 }
@@ -51419,13 +51439,11 @@
51419 invalidateAllOverflowCache(pBt);
51420 assert(pBt->autoVacuum);
51421 if( !pBt->incrVacuum ){
51422 Pgno nFin; /* Number of pages in database after autovacuuming */
51423 Pgno nFree; /* Number of pages on the freelist initially */
51424 Pgno nPtrmap; /* Number of PtrMap pages to be freed */
51425 Pgno iFree; /* The next page to be freed */
51426 int nEntry; /* Number of entries on one ptrmap page */
51427 Pgno nOrig; /* Database size before freeing */
51428
51429 nOrig = btreePagecount(pBt);
51430 if( PTRMAP_ISPAGE(pBt, nOrig) || nOrig==PENDING_BYTE_PAGE(pBt) ){
51431 /* It is not possible to create a database for which the final page
@@ -51434,30 +51452,22 @@
51434 */
51435 return SQLITE_CORRUPT_BKPT;
51436 }
51437
51438 nFree = get4byte(&pBt->pPage1->aData[36]);
51439 nEntry = pBt->usableSize/5;
51440 nPtrmap = (nFree-nOrig+PTRMAP_PAGENO(pBt, nOrig)+nEntry)/nEntry;
51441 nFin = nOrig - nFree - nPtrmap;
51442 if( nOrig>PENDING_BYTE_PAGE(pBt) && nFin<PENDING_BYTE_PAGE(pBt) ){
51443 nFin--;
51444 }
51445 while( PTRMAP_ISPAGE(pBt, nFin) || nFin==PENDING_BYTE_PAGE(pBt) ){
51446 nFin--;
51447 }
51448 if( nFin>nOrig ) return SQLITE_CORRUPT_BKPT;
51449
51450 for(iFree=nOrig; iFree>nFin && rc==SQLITE_OK; iFree--){
51451 rc = incrVacuumStep(pBt, nFin, iFree);
51452 }
51453 if( (rc==SQLITE_DONE || rc==SQLITE_OK) && nFree>0 ){
51454 rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
51455 put4byte(&pBt->pPage1->aData[32], 0);
51456 put4byte(&pBt->pPage1->aData[36], 0);
51457 put4byte(&pBt->pPage1->aData[28], nFin);
51458 sqlite3PagerTruncateImage(pBt->pPager, nFin);
51459 pBt->nPage = nFin;
51460 }
51461 if( rc!=SQLITE_OK ){
51462 sqlite3PagerRollback(pPager);
51463 }
@@ -51508,10 +51518,13 @@
51508 if( rc!=SQLITE_OK ){
51509 sqlite3BtreeLeave(p);
51510 return rc;
51511 }
51512 }
 
 
 
51513 #endif
51514 rc = sqlite3PagerCommitPhaseOne(pBt->pPager, zMaster, 0);
51515 sqlite3BtreeLeave(p);
51516 }
51517 return rc;
@@ -51523,10 +51536,13 @@
51523 */
51524 static void btreeEndTransaction(Btree *p){
51525 BtShared *pBt = p->pBt;
51526 assert( sqlite3BtreeHoldsMutex(p) );
51527
 
 
 
51528 btreeClearHasContent(pBt);
51529 if( p->inTrans>TRANS_NONE && p->db->activeVdbeCnt>1 ){
51530 /* If there are other active statements that belong to this database
51531 ** handle, downgrade to a read-only transaction. The other statements
51532 ** may still be reading from the database. */
@@ -53209,11 +53225,11 @@
53209 static int allocateBtreePage(
53210 BtShared *pBt,
53211 MemPage **ppPage,
53212 Pgno *pPgno,
53213 Pgno nearby,
53214 u8 exact
53215 ){
53216 MemPage *pPage1;
53217 int rc;
53218 u32 n; /* Number of pages on the freelist */
53219 u32 k; /* Number of leaves on the trunk of the freelist */
@@ -53237,20 +53253,23 @@
53237 /* If the 'exact' parameter was true and a query of the pointer-map
53238 ** shows that the page 'nearby' is somewhere on the free-list, then
53239 ** the entire-list will be searched for that page.
53240 */
53241 #ifndef SQLITE_OMIT_AUTOVACUUM
53242 if( exact && nearby<=mxPage ){
53243 u8 eType;
53244 assert( nearby>0 );
53245 assert( pBt->autoVacuum );
53246 rc = ptrmapGet(pBt, nearby, &eType, 0);
53247 if( rc ) return rc;
53248 if( eType==PTRMAP_FREEPAGE ){
53249 searchList = 1;
53250 }
53251 *pPgno = nearby;
 
 
 
53252 }
53253 #endif
53254
53255 /* Decrement the free-list count by 1. Set iTrunk to the index of the
53256 ** first free-list trunk page. iPrevTrunk is initially 1.
@@ -53301,15 +53320,17 @@
53301 }else if( k>(u32)(pBt->usableSize/4 - 2) ){
53302 /* Value of k is out of range. Database corruption */
53303 rc = SQLITE_CORRUPT_BKPT;
53304 goto end_allocate_page;
53305 #ifndef SQLITE_OMIT_AUTOVACUUM
53306 }else if( searchList && nearby==iTrunk ){
 
 
53307 /* The list is being searched and this trunk page is the page
53308 ** to allocate, regardless of whether it has leaves.
53309 */
53310 assert( *pPgno==iTrunk );
53311 *ppPage = pTrunk;
53312 searchList = 0;
53313 rc = sqlite3PagerWrite(pTrunk->pDbPage);
53314 if( rc ){
53315 goto end_allocate_page;
@@ -53368,18 +53389,28 @@
53368 u32 closest;
53369 Pgno iPage;
53370 unsigned char *aData = pTrunk->aData;
53371 if( nearby>0 ){
53372 u32 i;
53373 int dist;
53374 closest = 0;
53375 dist = sqlite3AbsInt32(get4byte(&aData[8]) - nearby);
53376 for(i=1; i<k; i++){
53377 int d2 = sqlite3AbsInt32(get4byte(&aData[8+i*4]) - nearby);
53378 if( d2<dist ){
53379 closest = i;
53380 dist = d2;
 
 
 
 
 
 
 
 
 
 
 
53381 }
53382 }
53383 }else{
53384 closest = 0;
53385 }
@@ -53389,11 +53420,13 @@
53389 if( iPage>mxPage ){
53390 rc = SQLITE_CORRUPT_BKPT;
53391 goto end_allocate_page;
53392 }
53393 testcase( iPage==mxPage );
53394 if( !searchList || iPage==nearby ){
 
 
53395 int noContent;
53396 *pPgno = iPage;
53397 TRACE(("ALLOCATE: %d was leaf %d of %d on trunk %d"
53398 ": %d more free pages\n",
53399 *pPgno, closest+1, k, pTrunk->pgno, n-1));
@@ -53416,12 +53449,30 @@
53416 }
53417 releasePage(pPrevTrunk);
53418 pPrevTrunk = 0;
53419 }while( searchList );
53420 }else{
53421 /* There are no pages on the freelist, so create a new page at the
53422 ** end of the file */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53423 rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
53424 if( rc ) return rc;
53425 pBt->nPage++;
53426 if( pBt->nPage==PENDING_BYTE_PAGE(pBt) ) pBt->nPage++;
53427
@@ -53432,11 +53483,11 @@
53432 ** becomes a new pointer-map page, the second is used by the caller.
53433 */
53434 MemPage *pPg = 0;
53435 TRACE(("ALLOCATE: %d from end of file (pointer-map page)\n", pBt->nPage));
53436 assert( pBt->nPage!=PENDING_BYTE_PAGE(pBt) );
53437 rc = btreeGetPage(pBt, pBt->nPage, &pPg, 1);
53438 if( rc==SQLITE_OK ){
53439 rc = sqlite3PagerWrite(pPg->pDbPage);
53440 releasePage(pPg);
53441 }
53442 if( rc ) return rc;
@@ -53446,11 +53497,11 @@
53446 #endif
53447 put4byte(28 + (u8*)pBt->pPage1->aData, pBt->nPage);
53448 *pPgno = pBt->nPage;
53449
53450 assert( *pPgno!=PENDING_BYTE_PAGE(pBt) );
53451 rc = btreeGetPage(pBt, *pPgno, ppPage, 1);
53452 if( rc ) return rc;
53453 rc = sqlite3PagerWrite((*ppPage)->pDbPage);
53454 if( rc!=SQLITE_OK ){
53455 releasePage(*ppPage);
53456 }
@@ -55461,11 +55512,11 @@
55461
55462 /* Allocate a page. The page that currently resides at pgnoRoot will
55463 ** be moved to the allocated page (unless the allocated page happens
55464 ** to reside at pgnoRoot).
55465 */
55466 rc = allocateBtreePage(pBt, &pPageMove, &pgnoMove, pgnoRoot, 1);
55467 if( rc!=SQLITE_OK ){
55468 return rc;
55469 }
55470
55471 if( pgnoMove!=pgnoRoot ){
@@ -57153,11 +57204,10 @@
57153 }
57154 }else{
57155 nDestTruncate = nSrcPage * (pgszSrc/pgszDest);
57156 }
57157 assert( nDestTruncate>0 );
57158 sqlite3PagerTruncateImage(pDestPager, nDestTruncate);
57159
57160 if( pgszSrc<pgszDest ){
57161 /* If the source page-size is smaller than the destination page-size,
57162 ** two extra things may need to happen:
57163 **
@@ -57167,10 +57217,12 @@
57167 ** pending-byte page in the source database may need to be
57168 ** copied into the destination database.
57169 */
57170 const i64 iSize = (i64)pgszSrc * (i64)nSrcPage;
57171 sqlite3_file * const pFile = sqlite3PagerFile(pDestPager);
 
 
57172 i64 iOff;
57173 i64 iEnd;
57174
57175 assert( pFile );
57176 assert( nDestTruncate==0
@@ -57177,17 +57229,30 @@
57177 || (i64)nDestTruncate*(i64)pgszDest >= iSize || (
57178 nDestTruncate==(int)(PENDING_BYTE_PAGE(p->pDest->pBt)-1)
57179 && iSize>=PENDING_BYTE && iSize<=PENDING_BYTE+pgszDest
57180 ));
57181
57182 /* This call ensures that all data required to recreate the original
57183 ** database has been stored in the journal for pDestPager and the
57184 ** journal synced to disk. So at this point we may safely modify
57185 ** the database file in any way, knowing that if a power failure
57186 ** occurs, the original database will be reconstructed from the
57187 ** journal file. */
57188 rc = sqlite3PagerCommitPhaseOne(pDestPager, 0, 1);
 
 
 
 
 
 
 
 
 
 
 
 
 
57189
57190 /* Write the extra pages and truncate the database file as required */
57191 iEnd = MIN(PENDING_BYTE + pgszDest, iSize);
57192 for(
57193 iOff=PENDING_BYTE+pgszSrc;
@@ -57210,10 +57275,11 @@
57210 /* Sync the database file to disk. */
57211 if( rc==SQLITE_OK ){
57212 rc = sqlite3PagerSync(pDestPager);
57213 }
57214 }else{
 
57215 rc = sqlite3PagerCommitPhaseOne(pDestPager, 0, 0);
57216 }
57217
57218 /* Finish committing the transaction to the destination database. */
57219 if( SQLITE_OK==rc
@@ -63039,11 +63105,11 @@
63039 return 0;
63040 }
63041 if( zName ){
63042 for(i=0; i<p->nzVar; i++){
63043 const char *z = p->azVar[i];
63044 if( z && memcmp(z,zName,nName)==0 && z[nName]==0 ){
63045 return i+1;
63046 }
63047 }
63048 }
63049 return 0;
@@ -72691,16 +72757,16 @@
72691 const char *zTab,
72692 const char *zDb
72693 ){
72694 int n;
72695 for(n=0; ALWAYS(zSpan[n]) && zSpan[n]!='.'; n++){}
72696 if( zDb && sqlite3StrNICmp(zSpan, zDb, n)!=0 ){
72697 return 0;
72698 }
72699 zSpan += n+1;
72700 for(n=0; ALWAYS(zSpan[n]) && zSpan[n]!='.'; n++){}
72701 if( zTab && sqlite3StrNICmp(zSpan, zTab, n)!=0 ){
72702 return 0;
72703 }
72704 zSpan += n+1;
72705 if( zCol && sqlite3StrICmp(zSpan, zCol)!=0 ){
72706 return 0;
@@ -74493,11 +74559,11 @@
74493 ** number as the prior appearance of the same name, or if the name
74494 ** has never appeared before, reuse the same variable number
74495 */
74496 ynVar i;
74497 for(i=0; i<pParse->nzVar; i++){
74498 if( pParse->azVar[i] && memcmp(pParse->azVar[i],z,n+1)==0 ){
74499 pExpr->iColumn = x = (ynVar)i+1;
74500 break;
74501 }
74502 }
74503 if( x==0 ) x = pExpr->iColumn = (ynVar)(++pParse->nVar);
@@ -79350,11 +79416,11 @@
79350 }
79351 if( pTab->tnum==0 ){
79352 /* Do not gather statistics on views or virtual tables */
79353 return;
79354 }
79355 if( memcmp(pTab->zName, "sqlite_", 7)==0 ){
79356 /* Do not gather statistics on system tables */
79357 return;
79358 }
79359 assert( sqlite3BtreeHoldsAllMutexes(db) );
79360 iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
@@ -79760,11 +79826,11 @@
79760 }
79761 if( i==0 ) pTable->nRowEst = v;
79762 if( pIndex==0 ) break;
79763 pIndex->aiRowEst[i] = v;
79764 if( *z==' ' ) z++;
79765 if( memcmp(z, "unordered", 10)==0 ){
79766 pIndex->bUnordered = 1;
79767 break;
79768 }
79769 }
79770 return 0;
@@ -83409,11 +83475,11 @@
83409 pDb = &db->aDb[iDb];
83410
83411 assert( pTab!=0 );
83412 assert( pParse->nErr==0 );
83413 if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0
83414 && memcmp(&pTab->zName[7],"altertab_",9)!=0 ){
83415 sqlite3ErrorMsg(pParse, "table %s may not be indexed", pTab->zName);
83416 goto exit_create_index;
83417 }
83418 #ifndef SQLITE_OMIT_VIEW
83419 if( pTab->pSelect ){
@@ -86787,10 +86853,61 @@
86787 sqlite3_result_text(context, "NULL", 4, SQLITE_STATIC);
86788 break;
86789 }
86790 }
86791 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
86792
86793 /*
86794 ** The hex() function. Interpret the argument as a blob. Return
86795 ** a hexadecimal rendering as text.
86796 */
@@ -87415,10 +87532,12 @@
87415 FUNCTION2(typeof, 1, 0, 0, typeofFunc, SQLITE_FUNC_TYPEOF),
87416 FUNCTION2(length, 1, 0, 0, lengthFunc, SQLITE_FUNC_LENGTH),
87417 FUNCTION(instr, 2, 0, 0, instrFunc ),
87418 FUNCTION(substr, 2, 0, 0, substrFunc ),
87419 FUNCTION(substr, 3, 0, 0, substrFunc ),
 
 
87420 FUNCTION(abs, 1, 0, 0, absFunc ),
87421 #ifndef SQLITE_OMIT_FLOATING_POINT
87422 FUNCTION(round, 1, 0, 0, roundFunc ),
87423 FUNCTION(round, 2, 0, 0, roundFunc ),
87424 #endif
@@ -91626,10 +91745,23 @@
91626 0,
91627 #endif
91628 sqlite3_blob_reopen,
91629 sqlite3_vtab_config,
91630 sqlite3_vtab_on_conflict,
 
 
 
 
 
 
 
 
 
 
 
 
 
91631 };
91632
91633 /*
91634 ** Attempt to load an SQLite extension library contained in the file
91635 ** zFile. The entry point is zProc. zProc may be 0 in which case a
@@ -92866,10 +92998,11 @@
92866 Column *pCol;
92867 Index *pPk;
92868 for(pPk=pTab->pIndex; pPk && pPk->autoIndex!=2; pPk=pPk->pNext){}
92869 sqlite3VdbeSetNumCols(v, 6);
92870 pParse->nMem = 6;
 
92871 sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "cid", SQLITE_STATIC);
92872 sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE_STATIC);
92873 sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "type", SQLITE_STATIC);
92874 sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "notnull", SQLITE_STATIC);
92875 sqlite3VdbeSetColName(v, 4, COLNAME_NAME, "dflt_value", SQLITE_STATIC);
@@ -92911,10 +93044,11 @@
92911 if( pIdx ){
92912 int i;
92913 pTab = pIdx->pTable;
92914 sqlite3VdbeSetNumCols(v, 3);
92915 pParse->nMem = 3;
 
92916 sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seqno", SQLITE_STATIC);
92917 sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "cid", SQLITE_STATIC);
92918 sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "name", SQLITE_STATIC);
92919 for(i=0; i<pIdx->nColumn; i++){
92920 int cnum = pIdx->aiColumn[i];
@@ -92937,10 +93071,11 @@
92937 pIdx = pTab->pIndex;
92938 if( pIdx ){
92939 int i = 0;
92940 sqlite3VdbeSetNumCols(v, 3);
92941 pParse->nMem = 3;
 
92942 sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", SQLITE_STATIC);
92943 sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE_STATIC);
92944 sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "unique", SQLITE_STATIC);
92945 while(pIdx){
92946 sqlite3VdbeAddOp2(v, OP_Integer, i, 1);
@@ -93000,10 +93135,11 @@
93000 pFK = pTab->pFKey;
93001 if( pFK ){
93002 int i = 0;
93003 sqlite3VdbeSetNumCols(v, 8);
93004 pParse->nMem = 8;
 
93005 sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "id", SQLITE_STATIC);
93006 sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "seq", SQLITE_STATIC);
93007 sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "table", SQLITE_STATIC);
93008 sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "from", SQLITE_STATIC);
93009 sqlite3VdbeSetColName(v, 4, COLNAME_NAME, "to", SQLITE_STATIC);
@@ -96914,11 +97050,12 @@
96914 if( op==TK_ALL ){
96915 regPrev = 0;
96916 }else{
96917 int nExpr = p->pEList->nExpr;
96918 assert( nOrderBy>=nExpr || db->mallocFailed );
96919 regPrev = sqlite3GetTempRange(pParse, nExpr+1);
 
96920 sqlite3VdbeAddOp2(v, OP_Integer, 0, regPrev);
96921 pKeyDup = sqlite3DbMallocZero(db,
96922 sizeof(*pKeyDup) + nExpr*(sizeof(CollSeq*)+1) );
96923 if( pKeyDup ){
96924 pKeyDup->aSortOrder = (u8*)&pKeyDup->aColl[nExpr];
@@ -97096,16 +97233,10 @@
97096 sqlite3VdbeAddOp4(v, OP_Compare, destA.iSdst, destB.iSdst, nOrderBy,
97097 (char*)pKeyMerge, P4_KEYINFO_HANDOFF);
97098 sqlite3VdbeChangeP5(v, OPFLAG_PERMUTE);
97099 sqlite3VdbeAddOp3(v, OP_Jump, addrAltB, addrAeqB, addrAgtB);
97100
97101 /* Release temporary registers
97102 */
97103 if( regPrev ){
97104 sqlite3ReleaseTempRange(pParse, regPrev, nOrderBy+1);
97105 }
97106
97107 /* Jump to the this point in order to terminate the query.
97108 */
97109 sqlite3VdbeResolveLabel(v, labelEnd);
97110
97111 /* Set the number of output columns
@@ -114105,11 +114236,11 @@
114105 }
114106 }
114107 sqlite3VtabRollback(db);
114108 sqlite3EndBenignMalloc();
114109
114110 if( db->flags&SQLITE_InternChanges ){
114111 sqlite3ExpirePreparedStatements(db);
114112 sqlite3ResetAllSchemasOfConnection(db);
114113 }
114114
114115 /* Any deferred constraint violations have now been resolved. */
114116
--- src/sqlite3.c
+++ src/sqlite3.c
@@ -438,11 +438,12 @@
438 ** if it is already defined or if it is unneeded because we are
439 ** not doing a threadsafe build. Ticket #2681.
440 **
441 ** See also ticket #2741.
442 */
443 #if !defined(_XOPEN_SOURCE) && !defined(__DARWIN__) \
444 && !defined(__APPLE__) && SQLITE_THREADSAFE
445 # define _XOPEN_SOURCE 500 /* Needed to enable pthread recursive mutexes */
446 #endif
447
448 /*
449 ** The TCL headers are only needed when compiling the TCL bindings.
@@ -673,11 +674,11 @@
674 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
675 ** [sqlite_version()] and [sqlite_source_id()].
676 */
677 #define SQLITE_VERSION "3.7.16"
678 #define SQLITE_VERSION_NUMBER 3007016
679 #define SQLITE_SOURCE_ID "2013-03-01 23:40:26 780d06c5e54590f677f993fa9c313989c2eab8c7"
680
681 /*
682 ** CAPI3REF: Run-Time Library Version Numbers
683 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
684 **
@@ -11915,11 +11916,11 @@
11916 SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3*, Select*);
11917 SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse*, SrcList*);
11918 SQLITE_PRIVATE int sqlite3IsReadOnly(Parse*, Table*, int);
11919 SQLITE_PRIVATE void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int);
11920 #if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY)
11921 SQLITE_PRIVATE Expr *sqlite3LimitWhere(Parse*,SrcList*,Expr*,ExprList*,Expr*,Expr*,char*);
11922 #endif
11923 SQLITE_PRIVATE void sqlite3DeleteFrom(Parse*, SrcList*, Expr*);
11924 SQLITE_PRIVATE void sqlite3Update(Parse*, SrcList*, ExprList*, Expr*, int);
11925 SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(Parse*,SrcList*,Expr*,ExprList*,ExprList*,u16,int);
11926 SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo*);
@@ -12096,12 +12097,15 @@
12097 **
12098 ** x = getVarint32( A, B );
12099 ** x = putVarint32( A, B );
12100 **
12101 */
12102 #define getVarint32(A,B) \
12103 (u8)((*(A)<(u8)0x80)?((B)=(u32)*(A)),1:sqlite3GetVarint32((A),(u32 *)&(B)))
12104 #define putVarint32(A,B) \
12105 (u8)(((u32)(B)<(u32)0x80)?(*(A)=(unsigned char)(B)),1:\
12106 sqlite3PutVarint32((A),(B)))
12107 #define getVarint sqlite3GetVarint
12108 #define putVarint sqlite3PutVarint
12109
12110
12111 SQLITE_PRIVATE const char *sqlite3IndexAffinityStr(Vdbe *, Index *);
@@ -27655,11 +27659,11 @@
27659 pNew->ctrlFlags = (u8)ctrlFlags;
27660 if( sqlite3_uri_boolean(((ctrlFlags & UNIXFILE_URI) ? zFilename : 0),
27661 "psow", SQLITE_POWERSAFE_OVERWRITE) ){
27662 pNew->ctrlFlags |= UNIXFILE_PSOW;
27663 }
27664 if( strcmp(pVfs->zName,"unix-excl")==0 ){
27665 pNew->ctrlFlags |= UNIXFILE_EXCL;
27666 }
27667
27668 #if OS_VXWORKS
27669 pNew->pId = vxworksFindFileId(zFilename);
@@ -31959,21 +31963,23 @@
31963 bReturn = TRUE;
31964 }
31965 }
31966
31967 /* Want a pending lock? */
31968 else if (dwFileOffsetLow == (DWORD)PENDING_BYTE
31969 && nNumberOfBytesToLockLow == 1){
31970 /* If no pending lock has been acquired, then acquire it */
31971 if (pFile->shared->bPending == 0) {
31972 pFile->shared->bPending = TRUE;
31973 pFile->local.bPending = TRUE;
31974 bReturn = TRUE;
31975 }
31976 }
31977
31978 /* Want a reserved lock? */
31979 else if (dwFileOffsetLow == (DWORD)RESERVED_BYTE
31980 && nNumberOfBytesToLockLow == 1){
31981 if (pFile->shared->bReserved == 0) {
31982 pFile->shared->bReserved = TRUE;
31983 pFile->local.bReserved = TRUE;
31984 bReturn = TRUE;
31985 }
@@ -32012,11 +32018,12 @@
32018 bReturn = TRUE;
32019 }
32020
32021 /* Did we just have a reader lock? */
32022 else if (pFile->local.nReaders){
32023 assert(nNumberOfBytesToUnlockLow == (DWORD)SHARED_SIZE
32024 || nNumberOfBytesToUnlockLow == 1);
32025 pFile->local.nReaders --;
32026 if (pFile->local.nReaders == 0)
32027 {
32028 pFile->shared->nReaders --;
32029 }
@@ -32023,19 +32030,21 @@
32030 bReturn = TRUE;
32031 }
32032 }
32033
32034 /* Releasing a pending lock */
32035 else if (dwFileOffsetLow == (DWORD)PENDING_BYTE
32036 && nNumberOfBytesToUnlockLow == 1){
32037 if (pFile->local.bPending){
32038 pFile->local.bPending = FALSE;
32039 pFile->shared->bPending = FALSE;
32040 bReturn = TRUE;
32041 }
32042 }
32043 /* Releasing a reserved lock */
32044 else if (dwFileOffsetLow == (DWORD)RESERVED_BYTE
32045 && nNumberOfBytesToUnlockLow == 1){
32046 if (pFile->local.bReserved) {
32047 pFile->local.bReserved = FALSE;
32048 pFile->shared->bReserved = FALSE;
32049 bReturn = TRUE;
32050 }
@@ -32197,10 +32206,11 @@
32206 assert( id!=0 );
32207 #ifndef SQLITE_OMIT_WAL
32208 assert( pFile->pShm==0 );
32209 #endif
32210 OSTRACE(("CLOSE %d\n", pFile->h));
32211 assert( pFile->h!=NULL && pFile->h!=INVALID_HANDLE_VALUE );
32212 do{
32213 rc = osCloseHandle(pFile->h);
32214 /* SimulateIOError( rc=0; cnt=MX_CLOSE_ATTEMPT; ); */
32215 }while( rc==0 && ++cnt < MX_CLOSE_ATTEMPT && (sqlite3_win32_sleep(100), 1) );
32216 #if SQLITE_OS_WINCE
@@ -33113,11 +33123,11 @@
33123 bRc = osCloseHandle(p->aRegion[i].hMap);
33124 OSTRACE(("SHM-PURGE pid-%d close region=%d %s\n",
33125 (int)osGetCurrentProcessId(), i,
33126 bRc ? "ok" : "failed"));
33127 }
33128 if( p->hFile.h!=NULL && p->hFile.h!=INVALID_HANDLE_VALUE ){
33129 SimulateIOErrorBenign(1);
33130 winClose((sqlite3_file *)&p->hFile);
33131 SimulateIOErrorBenign(0);
33132 }
33133 if( deleteFlag ){
@@ -33193,11 +33203,11 @@
33203 }
33204
33205 rc = winOpen(pDbFd->pVfs,
33206 pShmNode->zFilename, /* Name of the file (UTF-8) */
33207 (sqlite3_file*)&pShmNode->hFile, /* File handle here */
33208 SQLITE_OPEN_WAL | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
33209 0);
33210 if( SQLITE_OK!=rc ){
33211 goto shm_open_err;
33212 }
33213
@@ -33808,22 +33818,21 @@
33818 || eType==SQLITE_OPEN_MAIN_JOURNAL || eType==SQLITE_OPEN_TEMP_JOURNAL
33819 || eType==SQLITE_OPEN_SUBJOURNAL || eType==SQLITE_OPEN_MASTER_JOURNAL
33820 || eType==SQLITE_OPEN_TRANSIENT_DB || eType==SQLITE_OPEN_WAL
33821 );
33822
33823 assert( pFile!=0 );
33824 memset(pFile, 0, sizeof(winFile));
33825 pFile->h = INVALID_HANDLE_VALUE;
33826
33827 #if SQLITE_OS_WINRT
33828 if( !sqlite3_temp_directory ){
33829 sqlite3_log(SQLITE_ERROR,
33830 "sqlite3_temp_directory variable should be set for WinRT");
33831 }
33832 #endif
33833
 
 
33834 /* If the second argument to this function is NULL, generate a
33835 ** temporary file name to use
33836 */
33837 if( !zUtf8Name ){
33838 assert(isDelete && !isOpenJournal);
@@ -33948,11 +33957,13 @@
33957 pFile->lastErrno = lastErrno;
33958 winLogError(SQLITE_CANTOPEN, pFile->lastErrno, "winOpen", zUtf8Name);
33959 sqlite3_free(zConverted);
33960 if( isReadWrite && !isExclusive ){
33961 return winOpen(pVfs, zName, id,
33962 ((flags|SQLITE_OPEN_READONLY) &
33963 ~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE)),
33964 pOutFlags);
33965 }else{
33966 return SQLITE_CANTOPEN_BKPT;
33967 }
33968 }
33969
@@ -33962,23 +33973,10 @@
33973 }else{
33974 *pOutFlags = SQLITE_OPEN_READONLY;
33975 }
33976 }
33977
 
 
 
 
 
 
 
 
 
 
 
 
 
33978 #if SQLITE_OS_WINCE
33979 if( isReadWrite && eType==SQLITE_OPEN_MAIN_DB
33980 && (rc = winceCreateLock(zName, pFile))!=SQLITE_OK
33981 ){
33982 osCloseHandle(h);
@@ -33990,10 +33988,19 @@
33988 }else
33989 #endif
33990 {
33991 sqlite3_free(zConverted);
33992 }
33993
33994 pFile->pMethod = &winIoMethod;
33995 pFile->pVfs = pVfs;
33996 pFile->h = h;
33997 if( sqlite3_uri_boolean(zName, "psow", SQLITE_POWERSAFE_OVERWRITE) ){
33998 pFile->ctrlFlags |= WINFILE_PSOW;
33999 }
34000 pFile->lastErrno = NO_ERROR;
34001 pFile->zPath = zName;
34002
34003 OpenCounter(+1);
34004 return rc;
34005 }
34006
@@ -34035,11 +34042,12 @@
34042 if ( osGetFileAttributesExW(zConverted, GetFileExInfoStandard,
34043 &sAttrData) ){
34044 attr = sAttrData.dwFileAttributes;
34045 }else{
34046 lastErrno = osGetLastError();
34047 if( lastErrno==ERROR_FILE_NOT_FOUND
34048 || lastErrno==ERROR_PATH_NOT_FOUND ){
34049 rc = SQLITE_IOERR_DELETE_NOENT; /* Already gone? */
34050 }else{
34051 rc = SQLITE_ERROR;
34052 }
34053 break;
@@ -34047,11 +34055,12 @@
34055 #else
34056 attr = osGetFileAttributesW(zConverted);
34057 #endif
34058 if ( attr==INVALID_FILE_ATTRIBUTES ){
34059 lastErrno = osGetLastError();
34060 if( lastErrno==ERROR_FILE_NOT_FOUND
34061 || lastErrno==ERROR_PATH_NOT_FOUND ){
34062 rc = SQLITE_IOERR_DELETE_NOENT; /* Already gone? */
34063 }else{
34064 rc = SQLITE_ERROR;
34065 }
34066 break;
@@ -34074,11 +34083,12 @@
34083 else{
34084 do {
34085 attr = osGetFileAttributesA(zConverted);
34086 if ( attr==INVALID_FILE_ATTRIBUTES ){
34087 lastErrno = osGetLastError();
34088 if( lastErrno==ERROR_FILE_NOT_FOUND
34089 || lastErrno==ERROR_PATH_NOT_FOUND ){
34090 rc = SQLITE_IOERR_DELETE_NOENT; /* Already gone? */
34091 }else{
34092 rc = SQLITE_ERROR;
34093 }
34094 break;
@@ -34242,20 +34252,16 @@
34252 ** for converting the relative path name to an absolute
34253 ** one by prepending the data directory and a slash.
34254 */
34255 char zOut[MAX_PATH+1];
34256 memset(zOut, 0, MAX_PATH+1);
34257 cygwin_conv_path(CCP_POSIX_TO_WIN_A|CCP_RELATIVE, zRelative, zOut,
34258 MAX_PATH+1);
34259 sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s\\%s",
34260 sqlite3_data_directory, zOut);
34261 }else{
34262 cygwin_conv_path(CCP_POSIX_TO_WIN_A, zRelative, zFull, nFull);
 
 
 
 
 
34263 }
34264 return SQLITE_OK;
34265 #endif
34266
34267 #if (SQLITE_OS_WINCE || SQLITE_OS_WINRT) && !defined(__CYGWIN__)
@@ -34409,13 +34415,13 @@
34415 }
34416 static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){
34417 UNUSED_PARAMETER(pVfs);
34418 getLastErrorMsg(osGetLastError(), nBuf, zBufOut);
34419 }
34420 static void (*winDlSym(sqlite3_vfs *pVfs,void *pH,const char *zSym))(void){
34421 UNUSED_PARAMETER(pVfs);
34422 return (void(*)(void))osGetProcAddressA((HANDLE)pH, zSym);
34423 }
34424 static void winDlClose(sqlite3_vfs *pVfs, void *pHandle){
34425 UNUSED_PARAMETER(pVfs);
34426 osFreeLibrary((HANDLE)pHandle);
34427 }
@@ -34509,11 +34515,12 @@
34515 #ifdef SQLITE_TEST
34516 static const sqlite3_int64 unixEpoch = 24405875*(sqlite3_int64)8640000;
34517 #endif
34518 /* 2^32 - to avoid use of LL and warnings in gcc */
34519 static const sqlite3_int64 max32BitValue =
34520 (sqlite3_int64)2000000000 + (sqlite3_int64)2000000000 +
34521 (sqlite3_int64)294967296;
34522
34523 #if SQLITE_OS_WINCE
34524 SYSTEMTIME time;
34525 osGetSystemTime(&time);
34526 /* if SystemTimeToFileTime() fails, it returns zero. */
@@ -39187,10 +39194,12 @@
39194 pPager->eState = PAGER_ERROR;
39195 }
39196 return rc;
39197 }
39198
39199 static int pager_truncate(Pager *pPager, Pgno nPage);
39200
39201 /*
39202 ** This routine ends a transaction. A transaction is usually ended by
39203 ** either a COMMIT or a ROLLBACK operation. This routine may be called
39204 ** after rollback of a hot-journal, or if an error occurs while opening
39205 ** the journal file or writing the very first journal-header of a
@@ -39240,11 +39249,11 @@
39249 ** tries to unlock the database file if not in exclusive mode. If the
39250 ** unlock operation fails as well, then the first error code related
39251 ** to the first error encountered (the journal finalization one) is
39252 ** returned.
39253 */
39254 static int pager_end_transaction(Pager *pPager, int hasMaster, int bCommit){
39255 int rc = SQLITE_OK; /* Error code from journal finalization operation */
39256 int rc2 = SQLITE_OK; /* Error code from db file unlock operation */
39257
39258 /* Do nothing if the pager does not have an open write transaction
39259 ** or at least a RESERVED lock. This function may be called when there
@@ -39326,11 +39335,21 @@
39335 ** locking_mode=exclusive mode but is no longer, drop the EXCLUSIVE
39336 ** lock held on the database file.
39337 */
39338 rc2 = sqlite3WalEndWriteTransaction(pPager->pWal);
39339 assert( rc2==SQLITE_OK );
39340 }else if( rc==SQLITE_OK && bCommit && pPager->dbFileSize>pPager->dbSize ){
39341 /* This branch is taken when committing a transaction in rollback-journal
39342 ** mode if the database file on disk is larger than the database image.
39343 ** At this point the journal has been finalized and the transaction
39344 ** successfully committed, but the EXCLUSIVE lock is still held on the
39345 ** file. So it is safe to truncate the database file to its minimum
39346 ** required size. */
39347 assert( pPager->eLock==EXCLUSIVE_LOCK );
39348 rc = pager_truncate(pPager, pPager->dbSize);
39349 }
39350
39351 if( !pPager->exclusiveMode
39352 && (!pagerUseWal(pPager) || sqlite3WalExclusiveMode(pPager->pWal, 0))
39353 ){
39354 rc2 = pagerUnlockDb(pPager, SHARED_LOCK);
39355 pPager->changeCountDone = 0;
@@ -39365,11 +39384,11 @@
39384 sqlite3BeginBenignMalloc();
39385 sqlite3PagerRollback(pPager);
39386 sqlite3EndBenignMalloc();
39387 }else if( !pPager->exclusiveMode ){
39388 assert( pPager->eState==PAGER_READER );
39389 pager_end_transaction(pPager, 0, 0);
39390 }
39391 }
39392 pager_unlock(pPager);
39393 }
39394
@@ -40140,11 +40159,11 @@
40159 && (pPager->eState>=PAGER_WRITER_DBMOD || pPager->eState==PAGER_OPEN)
40160 ){
40161 rc = sqlite3PagerSync(pPager);
40162 }
40163 if( rc==SQLITE_OK ){
40164 rc = pager_end_transaction(pPager, zMaster[0]!='\0', 0);
40165 testcase( rc!=SQLITE_OK );
40166 }
40167 if( rc==SQLITE_OK && zMaster[0] && res ){
40168 /* If there was a master journal and this routine will return success,
40169 ** see if it is possible to delete the master journal.
@@ -43234,40 +43253,10 @@
43253 #else
43254 rc = pager_incr_changecounter(pPager, 0);
43255 #endif
43256 if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
43257
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43258 /* Write the master journal name into the journal file. If a master
43259 ** journal file name has already been written to the journal file,
43260 ** or if zMaster is NULL (no master journal), then this call is a no-op.
43261 */
43262 rc = writeMasterJournal(pPager, zMaster);
@@ -43291,15 +43280,18 @@
43280 if( rc!=SQLITE_OK ){
43281 assert( rc!=SQLITE_IOERR_BLOCKED );
43282 goto commit_phase_one_exit;
43283 }
43284 sqlite3PcacheCleanAll(pPager->pPCache);
43285
43286 /* If the file on disk is smaller than the database image, use
43287 ** pager_truncate to grow the file here. This can happen if the database
43288 ** image was extended as part of the current transaction and then the
43289 ** last page in the db image moved to the free-list. In this case the
43290 ** last page is never written out to disk, leaving the database file
43291 ** undersized. Fix this now if it is the case. */
43292 if( pPager->dbSize>pPager->dbFileSize ){
43293 Pgno nNew = pPager->dbSize - (pPager->dbSize==PAGER_MJ_PGNO(pPager));
43294 assert( pPager->eState==PAGER_WRITER_DBMOD );
43295 rc = pager_truncate(pPager, nNew);
43296 if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
43297 }
@@ -43368,11 +43360,11 @@
43360 pPager->eState = PAGER_READER;
43361 return SQLITE_OK;
43362 }
43363
43364 PAGERTRACE(("COMMIT %d\n", PAGERID(pPager)));
43365 rc = pager_end_transaction(pPager, pPager->setMaster, 1);
43366 return pager_error(pPager, rc);
43367 }
43368
43369 /*
43370 ** If a write transaction is open, then all changes made within the
@@ -43413,15 +43405,15 @@
43405 if( pPager->eState<=PAGER_READER ) return SQLITE_OK;
43406
43407 if( pagerUseWal(pPager) ){
43408 int rc2;
43409 rc = sqlite3PagerSavepoint(pPager, SAVEPOINT_ROLLBACK, -1);
43410 rc2 = pager_end_transaction(pPager, pPager->setMaster, 0);
43411 if( rc==SQLITE_OK ) rc = rc2;
43412 }else if( !isOpen(pPager->jfd) || pPager->eState==PAGER_WRITER_LOCKED ){
43413 int eState = pPager->eState;
43414 rc = pager_end_transaction(pPager, 0, 0);
43415 if( !MEMDB && eState>PAGER_WRITER_LOCKED ){
43416 /* This can happen using journal_mode=off. Move the pager to the error
43417 ** state to indicate that the contents of the cache may not be trusted.
43418 ** Any active readers will get SQLITE_ABORT.
43419 */
@@ -43815,11 +43807,12 @@
43807 ** the journal needs to be sync()ed before database page pPg->pgno
43808 ** can be written to. The caller has already promised not to write to it.
43809 */
43810 if( (pPg->flags&PGHDR_NEED_SYNC) && !isCommit ){
43811 needSyncPgno = pPg->pgno;
43812 assert( pPager->journalMode==PAGER_JOURNALMODE_OFF ||
43813 pageInJournal(pPg) || pPg->pgno>pPager->dbOrigSize );
43814 assert( pPg->flags&PGHDR_DIRTY );
43815 }
43816
43817 /* If the cache contains a page with page-number pgno, remove it
43818 ** from its hash chain. Also, if the PGHDR_NEED_SYNC flag was set for
@@ -47819,10 +47812,11 @@
47812 MemPage *pPage1; /* First page of the database */
47813 u8 openFlags; /* Flags to sqlite3BtreeOpen() */
47814 #ifndef SQLITE_OMIT_AUTOVACUUM
47815 u8 autoVacuum; /* True if auto-vacuum is enabled */
47816 u8 incrVacuum; /* True if incr-vacuum is enabled */
47817 u8 bDoTruncate; /* True to truncate db on commit */
47818 #endif
47819 u8 inTransaction; /* Transaction state */
47820 u8 max1bytePayload; /* Maximum first byte of cell for a 1-byte payload */
47821 u16 btsFlags; /* Boolean parameters. See BTS_* macros below */
47822 u16 maxLocal; /* Maximum local payload in non-LEAFDATA tables */
@@ -50937,10 +50931,11 @@
50931 ** is requested, this is a no-op.
50932 */
50933 if( p->inTrans==TRANS_WRITE || (p->inTrans==TRANS_READ && !wrflag) ){
50934 goto trans_begun;
50935 }
50936 assert( pBt->bDoTruncate==0 );
50937
50938 /* Write transactions are not possible on a read-only database */
50939 if( (pBt->btsFlags & BTS_READ_ONLY)!=0 && wrflag ){
50940 rc = SQLITE_READONLY;
50941 goto trans_begun;
@@ -51251,30 +51246,32 @@
51246 return rc;
51247 }
51248
51249 /* Forward declaration required by incrVacuumStep(). */
51250 static int allocateBtreePage(BtShared *, MemPage **, Pgno *, Pgno, u8);
51251 #define BTALLOC_ANY 0 /* Allocate any page */
51252 #define BTALLOC_EXACT 1 /* Allocate exact page if possible */
51253 #define BTALLOC_LE 2 /* Allocate any page <= the parameter */
51254
51255 /*
51256 ** Perform a single step of an incremental-vacuum. If successful, return
51257 ** SQLITE_OK. If there is no work to do (and therefore no point in
51258 ** calling this function again), return SQLITE_DONE. Or, if an error
51259 ** occurs, return some other error code.
51260 **
51261 ** More specificly, this function attempts to re-organize the database so
51262 ** that the last page of the file currently in use is no longer in use.
51263 **
51264 ** Parameter nFin is the number of pages that this database would contain
51265 ** were this function called until it returns SQLITE_DONE.
51266 **
51267 ** If the bCommit parameter is non-zero, this function assumes that the
51268 ** caller will keep calling incrVacuumStep() until it returns SQLITE_DONE
51269 ** or an error. bCommit is passed true for an auto-vacuum-on-commmit
51270 ** operation, or false for an incremental vacuum.
51271 */
51272 static int incrVacuumStep(BtShared *pBt, Pgno nFin, Pgno iLastPg, int bCommit){
 
51273 Pgno nFreeList; /* Number of pages still on the free-list */
51274 int rc;
51275
51276 assert( sqlite3_mutex_held(pBt->mutex) );
51277 assert( iLastPg>nFin );
@@ -51295,85 +51292,98 @@
51292 if( eType==PTRMAP_ROOTPAGE ){
51293 return SQLITE_CORRUPT_BKPT;
51294 }
51295
51296 if( eType==PTRMAP_FREEPAGE ){
51297 if( bCommit==0 ){
51298 /* Remove the page from the files free-list. This is not required
51299 ** if bCommit is non-zero. In that case, the free-list will be
51300 ** truncated to zero after this function returns, so it doesn't
51301 ** matter if it still contains some garbage entries.
51302 */
51303 Pgno iFreePg;
51304 MemPage *pFreePg;
51305 rc = allocateBtreePage(pBt, &pFreePg, &iFreePg, iLastPg, BTALLOC_EXACT);
51306 if( rc!=SQLITE_OK ){
51307 return rc;
51308 }
51309 assert( iFreePg==iLastPg );
51310 releasePage(pFreePg);
51311 }
51312 } else {
51313 Pgno iFreePg; /* Index of free page to move pLastPg to */
51314 MemPage *pLastPg;
51315 u8 eMode = BTALLOC_ANY; /* Mode parameter for allocateBtreePage() */
51316 Pgno iNear = 0; /* nearby parameter for allocateBtreePage() */
51317
51318 rc = btreeGetPage(pBt, iLastPg, &pLastPg, 0);
51319 if( rc!=SQLITE_OK ){
51320 return rc;
51321 }
51322
51323 /* If bCommit is zero, this loop runs exactly once and page pLastPg
51324 ** is swapped with the first free page pulled off the free list.
51325 **
51326 ** On the other hand, if bCommit is greater than zero, then keep
51327 ** looping until a free-page located within the first nFin pages
51328 ** of the file is found.
51329 */
51330 if( bCommit==0 ){
51331 eMode = BTALLOC_LE;
51332 iNear = nFin;
51333 }
51334 do {
51335 MemPage *pFreePg;
51336 rc = allocateBtreePage(pBt, &pFreePg, &iFreePg, iNear, eMode);
51337 if( rc!=SQLITE_OK ){
51338 releasePage(pLastPg);
51339 return rc;
51340 }
51341 releasePage(pFreePg);
51342 }while( bCommit && iFreePg>nFin );
51343 assert( iFreePg<iLastPg );
51344
51345 rc = relocatePage(pBt, pLastPg, eType, iPtrPage, iFreePg, nFin!=0);
 
 
 
51346 releasePage(pLastPg);
51347 if( rc!=SQLITE_OK ){
51348 return rc;
51349 }
51350 }
51351 }
51352
51353 if( bCommit==0 ){
51354 do {
51355 iLastPg--;
51356 }while( iLastPg==PENDING_BYTE_PAGE(pBt) || PTRMAP_ISPAGE(pBt, iLastPg) );
51357 pBt->bDoTruncate = 1;
 
 
 
 
 
 
 
 
 
 
 
 
 
51358 pBt->nPage = iLastPg;
51359 }
51360 return SQLITE_OK;
51361 }
51362
51363 /*
51364 ** The database opened by the first argument is an auto-vacuum database
51365 ** nOrig pages in size containing nFree free pages. Return the expected
51366 ** size of the database in pages following an auto-vacuum operation.
51367 */
51368 static Pgno finalDbSize(BtShared *pBt, Pgno nOrig, Pgno nFree){
51369 int nEntry; /* Number of entries on one ptrmap page */
51370 Pgno nPtrmap; /* Number of PtrMap pages to be freed */
51371 Pgno nFin; /* Return value */
51372
51373 nEntry = pBt->usableSize/5;
51374 nPtrmap = (nFree-nOrig+PTRMAP_PAGENO(pBt, nOrig)+nEntry)/nEntry;
51375 nFin = nOrig - nFree - nPtrmap;
51376 if( nOrig>PENDING_BYTE_PAGE(pBt) && nFin<PENDING_BYTE_PAGE(pBt) ){
51377 nFin--;
51378 }
51379 while( PTRMAP_ISPAGE(pBt, nFin) || nFin==PENDING_BYTE_PAGE(pBt) ){
51380 nFin--;
51381 }
51382
51383 return nFin;
51384 }
51385
51386 /*
51387 ** A write-transaction must be opened before calling this function.
51388 ** It performs a single unit of work towards an incremental vacuum.
51389 **
@@ -51388,15 +51398,25 @@
51398 sqlite3BtreeEnter(p);
51399 assert( pBt->inTransaction==TRANS_WRITE && p->inTrans==TRANS_WRITE );
51400 if( !pBt->autoVacuum ){
51401 rc = SQLITE_DONE;
51402 }else{
51403 Pgno nOrig = btreePagecount(pBt);
51404 Pgno nFree = get4byte(&pBt->pPage1->aData[36]);
51405 Pgno nFin = finalDbSize(pBt, nOrig, nFree);
51406
51407 if( nOrig<nFin ){
51408 rc = SQLITE_CORRUPT_BKPT;
51409 }else if( nFree>0 ){
51410 invalidateAllOverflowCache(pBt);
51411 rc = incrVacuumStep(pBt, nFin, nOrig, 0);
51412 if( rc==SQLITE_OK ){
51413 rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
51414 put4byte(&pBt->pPage1->aData[28], pBt->nPage);
51415 }
51416 }else{
51417 rc = SQLITE_DONE;
51418 }
51419 }
51420 sqlite3BtreeLeave(p);
51421 return rc;
51422 }
@@ -51419,13 +51439,11 @@
51439 invalidateAllOverflowCache(pBt);
51440 assert(pBt->autoVacuum);
51441 if( !pBt->incrVacuum ){
51442 Pgno nFin; /* Number of pages in database after autovacuuming */
51443 Pgno nFree; /* Number of pages on the freelist initially */
 
51444 Pgno iFree; /* The next page to be freed */
 
51445 Pgno nOrig; /* Database size before freeing */
51446
51447 nOrig = btreePagecount(pBt);
51448 if( PTRMAP_ISPAGE(pBt, nOrig) || nOrig==PENDING_BYTE_PAGE(pBt) ){
51449 /* It is not possible to create a database for which the final page
@@ -51434,30 +51452,22 @@
51452 */
51453 return SQLITE_CORRUPT_BKPT;
51454 }
51455
51456 nFree = get4byte(&pBt->pPage1->aData[36]);
51457 nFin = finalDbSize(pBt, nOrig, nFree);
 
 
 
 
 
 
 
 
51458 if( nFin>nOrig ) return SQLITE_CORRUPT_BKPT;
51459
51460 for(iFree=nOrig; iFree>nFin && rc==SQLITE_OK; iFree--){
51461 rc = incrVacuumStep(pBt, nFin, iFree, 1);
51462 }
51463 if( (rc==SQLITE_DONE || rc==SQLITE_OK) && nFree>0 ){
51464 rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
51465 put4byte(&pBt->pPage1->aData[32], 0);
51466 put4byte(&pBt->pPage1->aData[36], 0);
51467 put4byte(&pBt->pPage1->aData[28], nFin);
51468 pBt->bDoTruncate = 1;
51469 pBt->nPage = nFin;
51470 }
51471 if( rc!=SQLITE_OK ){
51472 sqlite3PagerRollback(pPager);
51473 }
@@ -51508,10 +51518,13 @@
51518 if( rc!=SQLITE_OK ){
51519 sqlite3BtreeLeave(p);
51520 return rc;
51521 }
51522 }
51523 if( pBt->bDoTruncate ){
51524 sqlite3PagerTruncateImage(pBt->pPager, pBt->nPage);
51525 }
51526 #endif
51527 rc = sqlite3PagerCommitPhaseOne(pBt->pPager, zMaster, 0);
51528 sqlite3BtreeLeave(p);
51529 }
51530 return rc;
@@ -51523,10 +51536,13 @@
51536 */
51537 static void btreeEndTransaction(Btree *p){
51538 BtShared *pBt = p->pBt;
51539 assert( sqlite3BtreeHoldsMutex(p) );
51540
51541 #ifndef SQLITE_OMIT_AUTOVACUUM
51542 pBt->bDoTruncate = 0;
51543 #endif
51544 btreeClearHasContent(pBt);
51545 if( p->inTrans>TRANS_NONE && p->db->activeVdbeCnt>1 ){
51546 /* If there are other active statements that belong to this database
51547 ** handle, downgrade to a read-only transaction. The other statements
51548 ** may still be reading from the database. */
@@ -53209,11 +53225,11 @@
53225 static int allocateBtreePage(
53226 BtShared *pBt,
53227 MemPage **ppPage,
53228 Pgno *pPgno,
53229 Pgno nearby,
53230 u8 eMode
53231 ){
53232 MemPage *pPage1;
53233 int rc;
53234 u32 n; /* Number of pages on the freelist */
53235 u32 k; /* Number of leaves on the trunk of the freelist */
@@ -53237,20 +53253,23 @@
53253 /* If the 'exact' parameter was true and a query of the pointer-map
53254 ** shows that the page 'nearby' is somewhere on the free-list, then
53255 ** the entire-list will be searched for that page.
53256 */
53257 #ifndef SQLITE_OMIT_AUTOVACUUM
53258 if( eMode==BTALLOC_EXACT ){
53259 if( nearby<=mxPage ){
53260 u8 eType;
53261 assert( nearby>0 );
53262 assert( pBt->autoVacuum );
53263 rc = ptrmapGet(pBt, nearby, &eType, 0);
53264 if( rc ) return rc;
53265 if( eType==PTRMAP_FREEPAGE ){
53266 searchList = 1;
53267 }
53268 }
53269 }else if( eMode==BTALLOC_LE ){
53270 searchList = 1;
53271 }
53272 #endif
53273
53274 /* Decrement the free-list count by 1. Set iTrunk to the index of the
53275 ** first free-list trunk page. iPrevTrunk is initially 1.
@@ -53301,15 +53320,17 @@
53320 }else if( k>(u32)(pBt->usableSize/4 - 2) ){
53321 /* Value of k is out of range. Database corruption */
53322 rc = SQLITE_CORRUPT_BKPT;
53323 goto end_allocate_page;
53324 #ifndef SQLITE_OMIT_AUTOVACUUM
53325 }else if( searchList
53326 && (nearby==iTrunk || (iTrunk<nearby && eMode==BTALLOC_LE))
53327 ){
53328 /* The list is being searched and this trunk page is the page
53329 ** to allocate, regardless of whether it has leaves.
53330 */
53331 *pPgno = iTrunk;
53332 *ppPage = pTrunk;
53333 searchList = 0;
53334 rc = sqlite3PagerWrite(pTrunk->pDbPage);
53335 if( rc ){
53336 goto end_allocate_page;
@@ -53368,18 +53389,28 @@
53389 u32 closest;
53390 Pgno iPage;
53391 unsigned char *aData = pTrunk->aData;
53392 if( nearby>0 ){
53393 u32 i;
 
53394 closest = 0;
53395 if( eMode==BTALLOC_LE ){
53396 for(i=0; i<k; i++){
53397 iPage = get4byte(&aData[8+i*4]);
53398 if( iPage<=nearby ){
53399 closest = i;
53400 break;
53401 }
53402 }
53403 }else{
53404 int dist;
53405 dist = sqlite3AbsInt32(get4byte(&aData[8]) - nearby);
53406 for(i=1; i<k; i++){
53407 int d2 = sqlite3AbsInt32(get4byte(&aData[8+i*4]) - nearby);
53408 if( d2<dist ){
53409 closest = i;
53410 dist = d2;
53411 }
53412 }
53413 }
53414 }else{
53415 closest = 0;
53416 }
@@ -53389,11 +53420,13 @@
53420 if( iPage>mxPage ){
53421 rc = SQLITE_CORRUPT_BKPT;
53422 goto end_allocate_page;
53423 }
53424 testcase( iPage==mxPage );
53425 if( !searchList
53426 || (iPage==nearby || (iPage<nearby && eMode==BTALLOC_LE))
53427 ){
53428 int noContent;
53429 *pPgno = iPage;
53430 TRACE(("ALLOCATE: %d was leaf %d of %d on trunk %d"
53431 ": %d more free pages\n",
53432 *pPgno, closest+1, k, pTrunk->pgno, n-1));
@@ -53416,12 +53449,30 @@
53449 }
53450 releasePage(pPrevTrunk);
53451 pPrevTrunk = 0;
53452 }while( searchList );
53453 }else{
53454 /* There are no pages on the freelist, so append a new page to the
53455 ** database image.
53456 **
53457 ** Normally, new pages allocated by this block can be requested from the
53458 ** pager layer with the 'no-content' flag set. This prevents the pager
53459 ** from trying to read the pages content from disk. However, if the
53460 ** current transaction has already run one or more incremental-vacuum
53461 ** steps, then the page we are about to allocate may contain content
53462 ** that is required in the event of a rollback. In this case, do
53463 ** not set the no-content flag. This causes the pager to load and journal
53464 ** the current page content before overwriting it.
53465 **
53466 ** Note that the pager will not actually attempt to load or journal
53467 ** content for any page that really does lie past the end of the database
53468 ** file on disk. So the effects of disabling the no-content optimization
53469 ** here are confined to those pages that lie between the end of the
53470 ** database image and the end of the database file.
53471 */
53472 int bNoContent = (0==pBt->bDoTruncate);
53473
53474 rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
53475 if( rc ) return rc;
53476 pBt->nPage++;
53477 if( pBt->nPage==PENDING_BYTE_PAGE(pBt) ) pBt->nPage++;
53478
@@ -53432,11 +53483,11 @@
53483 ** becomes a new pointer-map page, the second is used by the caller.
53484 */
53485 MemPage *pPg = 0;
53486 TRACE(("ALLOCATE: %d from end of file (pointer-map page)\n", pBt->nPage));
53487 assert( pBt->nPage!=PENDING_BYTE_PAGE(pBt) );
53488 rc = btreeGetPage(pBt, pBt->nPage, &pPg, bNoContent);
53489 if( rc==SQLITE_OK ){
53490 rc = sqlite3PagerWrite(pPg->pDbPage);
53491 releasePage(pPg);
53492 }
53493 if( rc ) return rc;
@@ -53446,11 +53497,11 @@
53497 #endif
53498 put4byte(28 + (u8*)pBt->pPage1->aData, pBt->nPage);
53499 *pPgno = pBt->nPage;
53500
53501 assert( *pPgno!=PENDING_BYTE_PAGE(pBt) );
53502 rc = btreeGetPage(pBt, *pPgno, ppPage, bNoContent);
53503 if( rc ) return rc;
53504 rc = sqlite3PagerWrite((*ppPage)->pDbPage);
53505 if( rc!=SQLITE_OK ){
53506 releasePage(*ppPage);
53507 }
@@ -55461,11 +55512,11 @@
55512
55513 /* Allocate a page. The page that currently resides at pgnoRoot will
55514 ** be moved to the allocated page (unless the allocated page happens
55515 ** to reside at pgnoRoot).
55516 */
55517 rc = allocateBtreePage(pBt, &pPageMove, &pgnoMove, pgnoRoot, BTALLOC_EXACT);
55518 if( rc!=SQLITE_OK ){
55519 return rc;
55520 }
55521
55522 if( pgnoMove!=pgnoRoot ){
@@ -57153,11 +57204,10 @@
57204 }
57205 }else{
57206 nDestTruncate = nSrcPage * (pgszSrc/pgszDest);
57207 }
57208 assert( nDestTruncate>0 );
 
57209
57210 if( pgszSrc<pgszDest ){
57211 /* If the source page-size is smaller than the destination page-size,
57212 ** two extra things may need to happen:
57213 **
@@ -57167,10 +57217,12 @@
57217 ** pending-byte page in the source database may need to be
57218 ** copied into the destination database.
57219 */
57220 const i64 iSize = (i64)pgszSrc * (i64)nSrcPage;
57221 sqlite3_file * const pFile = sqlite3PagerFile(pDestPager);
57222 Pgno iPg;
57223 int nDstPage;
57224 i64 iOff;
57225 i64 iEnd;
57226
57227 assert( pFile );
57228 assert( nDestTruncate==0
@@ -57177,17 +57229,30 @@
57229 || (i64)nDestTruncate*(i64)pgszDest >= iSize || (
57230 nDestTruncate==(int)(PENDING_BYTE_PAGE(p->pDest->pBt)-1)
57231 && iSize>=PENDING_BYTE && iSize<=PENDING_BYTE+pgszDest
57232 ));
57233
57234 /* This block ensures that all data required to recreate the original
57235 ** database has been stored in the journal for pDestPager and the
57236 ** journal synced to disk. So at this point we may safely modify
57237 ** the database file in any way, knowing that if a power failure
57238 ** occurs, the original database will be reconstructed from the
57239 ** journal file. */
57240 sqlite3PagerPagecount(pDestPager, &nDstPage);
57241 for(iPg=nDestTruncate; rc==SQLITE_OK && iPg<=(Pgno)nDstPage; iPg++){
57242 if( iPg!=PENDING_BYTE_PAGE(p->pDest->pBt) ){
57243 DbPage *pPg;
57244 rc = sqlite3PagerGet(pDestPager, iPg, &pPg);
57245 if( rc==SQLITE_OK ){
57246 rc = sqlite3PagerWrite(pPg);
57247 sqlite3PagerUnref(pPg);
57248 }
57249 }
57250 }
57251 if( rc==SQLITE_OK ){
57252 rc = sqlite3PagerCommitPhaseOne(pDestPager, 0, 1);
57253 }
57254
57255 /* Write the extra pages and truncate the database file as required */
57256 iEnd = MIN(PENDING_BYTE + pgszDest, iSize);
57257 for(
57258 iOff=PENDING_BYTE+pgszSrc;
@@ -57210,10 +57275,11 @@
57275 /* Sync the database file to disk. */
57276 if( rc==SQLITE_OK ){
57277 rc = sqlite3PagerSync(pDestPager);
57278 }
57279 }else{
57280 sqlite3PagerTruncateImage(pDestPager, nDestTruncate);
57281 rc = sqlite3PagerCommitPhaseOne(pDestPager, 0, 0);
57282 }
57283
57284 /* Finish committing the transaction to the destination database. */
57285 if( SQLITE_OK==rc
@@ -63039,11 +63105,11 @@
63105 return 0;
63106 }
63107 if( zName ){
63108 for(i=0; i<p->nzVar; i++){
63109 const char *z = p->azVar[i];
63110 if( z && strncmp(z,zName,nName)==0 && z[nName]==0 ){
63111 return i+1;
63112 }
63113 }
63114 }
63115 return 0;
@@ -72691,16 +72757,16 @@
72757 const char *zTab,
72758 const char *zDb
72759 ){
72760 int n;
72761 for(n=0; ALWAYS(zSpan[n]) && zSpan[n]!='.'; n++){}
72762 if( zDb && (sqlite3StrNICmp(zSpan, zDb, n)!=0 || zDb[n]!=0) ){
72763 return 0;
72764 }
72765 zSpan += n+1;
72766 for(n=0; ALWAYS(zSpan[n]) && zSpan[n]!='.'; n++){}
72767 if( zTab && (sqlite3StrNICmp(zSpan, zTab, n)!=0 || zTab[n]!=0) ){
72768 return 0;
72769 }
72770 zSpan += n+1;
72771 if( zCol && sqlite3StrICmp(zSpan, zCol)!=0 ){
72772 return 0;
@@ -74493,11 +74559,11 @@
74559 ** number as the prior appearance of the same name, or if the name
74560 ** has never appeared before, reuse the same variable number
74561 */
74562 ynVar i;
74563 for(i=0; i<pParse->nzVar; i++){
74564 if( pParse->azVar[i] && strcmp(pParse->azVar[i],z)==0 ){
74565 pExpr->iColumn = x = (ynVar)i+1;
74566 break;
74567 }
74568 }
74569 if( x==0 ) x = pExpr->iColumn = (ynVar)(++pParse->nVar);
@@ -79350,11 +79416,11 @@
79416 }
79417 if( pTab->tnum==0 ){
79418 /* Do not gather statistics on views or virtual tables */
79419 return;
79420 }
79421 if( sqlite3_strnicmp(pTab->zName, "sqlite_", 7)==0 ){
79422 /* Do not gather statistics on system tables */
79423 return;
79424 }
79425 assert( sqlite3BtreeHoldsAllMutexes(db) );
79426 iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
@@ -79760,11 +79826,11 @@
79826 }
79827 if( i==0 ) pTable->nRowEst = v;
79828 if( pIndex==0 ) break;
79829 pIndex->aiRowEst[i] = v;
79830 if( *z==' ' ) z++;
79831 if( strcmp(z, "unordered")==0 ){
79832 pIndex->bUnordered = 1;
79833 break;
79834 }
79835 }
79836 return 0;
@@ -83409,11 +83475,11 @@
83475 pDb = &db->aDb[iDb];
83476
83477 assert( pTab!=0 );
83478 assert( pParse->nErr==0 );
83479 if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0
83480 && sqlite3StrNICmp(&pTab->zName[7],"altertab_",9)!=0 ){
83481 sqlite3ErrorMsg(pParse, "table %s may not be indexed", pTab->zName);
83482 goto exit_create_index;
83483 }
83484 #ifndef SQLITE_OMIT_VIEW
83485 if( pTab->pSelect ){
@@ -86787,10 +86853,61 @@
86853 sqlite3_result_text(context, "NULL", 4, SQLITE_STATIC);
86854 break;
86855 }
86856 }
86857 }
86858
86859 /*
86860 ** The unicode() function. Return the integer unicode code-point value
86861 ** for the first character of the input string.
86862 */
86863 static void unicodeFunc(
86864 sqlite3_context *context,
86865 int argc,
86866 sqlite3_value **argv
86867 ){
86868 const unsigned char *z = sqlite3_value_text(argv[0]);
86869 (void)argc;
86870 if( z && z[0] ) sqlite3_result_int(context, sqlite3Utf8Read(&z));
86871 }
86872
86873 /*
86874 ** The char() function takes zero or more arguments, each of which is
86875 ** an integer. It constructs a string where each character of the string
86876 ** is the unicode character for the corresponding integer argument.
86877 */
86878 static void charFunc(
86879 sqlite3_context *context,
86880 int argc,
86881 sqlite3_value **argv
86882 ){
86883 unsigned char *z, *zOut;
86884 int i;
86885 zOut = z = sqlite3_malloc( argc*4 );
86886 if( z==0 ){
86887 sqlite3_result_error_nomem(context);
86888 return;
86889 }
86890 for(i=0; i<argc; i++){
86891 sqlite3_int64 x;
86892 unsigned c;
86893 x = sqlite3_value_int64(argv[i]);
86894 if( x<0 || x>0x10ffff ) x = 0xfffd;
86895 c = (unsigned)(x & 0x1fffff);
86896 if( c<=0xFFFF ){
86897 if( c>=0xd800 && c<=0xdfff ) c = 0xfffd;
86898 *zOut++ = (u8)(c&0x00FF);
86899 *zOut++ = (u8)((c>>8)&0x00FF);
86900 }else{
86901 *zOut++ = (u8)(((c>>10)&0x003F) + (((c-0x10000)>>10)&0x00C0));
86902 *zOut++ = (u8)(0x00D8 + (((c-0x10000)>>18)&0x03));
86903 *zOut++ = (u8)(c&0x00FF);
86904 *zOut++ = (u8)(0x00DC + ((c>>8)&0x03));
86905 }
86906 }
86907 sqlite3_result_text16le(context, (char*)z, (int)(zOut-z), sqlite3_free);
86908 }
86909
86910 /*
86911 ** The hex() function. Interpret the argument as a blob. Return
86912 ** a hexadecimal rendering as text.
86913 */
@@ -87415,10 +87532,12 @@
87532 FUNCTION2(typeof, 1, 0, 0, typeofFunc, SQLITE_FUNC_TYPEOF),
87533 FUNCTION2(length, 1, 0, 0, lengthFunc, SQLITE_FUNC_LENGTH),
87534 FUNCTION(instr, 2, 0, 0, instrFunc ),
87535 FUNCTION(substr, 2, 0, 0, substrFunc ),
87536 FUNCTION(substr, 3, 0, 0, substrFunc ),
87537 FUNCTION(unicode, 1, 0, 0, unicodeFunc ),
87538 FUNCTION(char, -1, 0, 0, charFunc ),
87539 FUNCTION(abs, 1, 0, 0, absFunc ),
87540 #ifndef SQLITE_OMIT_FLOATING_POINT
87541 FUNCTION(round, 1, 0, 0, roundFunc ),
87542 FUNCTION(round, 2, 0, 0, roundFunc ),
87543 #endif
@@ -91626,10 +91745,23 @@
91745 0,
91746 #endif
91747 sqlite3_blob_reopen,
91748 sqlite3_vtab_config,
91749 sqlite3_vtab_on_conflict,
91750 sqlite3_close_v2,
91751 sqlite3_db_filename,
91752 sqlite3_db_readonly,
91753 sqlite3_db_release_memory,
91754 sqlite3_errstr,
91755 sqlite3_stmt_busy,
91756 sqlite3_stmt_readonly,
91757 sqlite3_stricmp,
91758 sqlite3_uri_boolean,
91759 sqlite3_uri_int64,
91760 sqlite3_uri_parameter,
91761 sqlite3_vsnprintf,
91762 sqlite3_wal_checkpoint_v2
91763 };
91764
91765 /*
91766 ** Attempt to load an SQLite extension library contained in the file
91767 ** zFile. The entry point is zProc. zProc may be 0 in which case a
@@ -92866,10 +92998,11 @@
92998 Column *pCol;
92999 Index *pPk;
93000 for(pPk=pTab->pIndex; pPk && pPk->autoIndex!=2; pPk=pPk->pNext){}
93001 sqlite3VdbeSetNumCols(v, 6);
93002 pParse->nMem = 6;
93003 sqlite3CodeVerifySchema(pParse, iDb);
93004 sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "cid", SQLITE_STATIC);
93005 sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE_STATIC);
93006 sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "type", SQLITE_STATIC);
93007 sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "notnull", SQLITE_STATIC);
93008 sqlite3VdbeSetColName(v, 4, COLNAME_NAME, "dflt_value", SQLITE_STATIC);
@@ -92911,10 +93044,11 @@
93044 if( pIdx ){
93045 int i;
93046 pTab = pIdx->pTable;
93047 sqlite3VdbeSetNumCols(v, 3);
93048 pParse->nMem = 3;
93049 sqlite3CodeVerifySchema(pParse, iDb);
93050 sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seqno", SQLITE_STATIC);
93051 sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "cid", SQLITE_STATIC);
93052 sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "name", SQLITE_STATIC);
93053 for(i=0; i<pIdx->nColumn; i++){
93054 int cnum = pIdx->aiColumn[i];
@@ -92937,10 +93071,11 @@
93071 pIdx = pTab->pIndex;
93072 if( pIdx ){
93073 int i = 0;
93074 sqlite3VdbeSetNumCols(v, 3);
93075 pParse->nMem = 3;
93076 sqlite3CodeVerifySchema(pParse, iDb);
93077 sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", SQLITE_STATIC);
93078 sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE_STATIC);
93079 sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "unique", SQLITE_STATIC);
93080 while(pIdx){
93081 sqlite3VdbeAddOp2(v, OP_Integer, i, 1);
@@ -93000,10 +93135,11 @@
93135 pFK = pTab->pFKey;
93136 if( pFK ){
93137 int i = 0;
93138 sqlite3VdbeSetNumCols(v, 8);
93139 pParse->nMem = 8;
93140 sqlite3CodeVerifySchema(pParse, iDb);
93141 sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "id", SQLITE_STATIC);
93142 sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "seq", SQLITE_STATIC);
93143 sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "table", SQLITE_STATIC);
93144 sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "from", SQLITE_STATIC);
93145 sqlite3VdbeSetColName(v, 4, COLNAME_NAME, "to", SQLITE_STATIC);
@@ -96914,11 +97050,12 @@
97050 if( op==TK_ALL ){
97051 regPrev = 0;
97052 }else{
97053 int nExpr = p->pEList->nExpr;
97054 assert( nOrderBy>=nExpr || db->mallocFailed );
97055 regPrev = pParse->nMem+1;
97056 pParse->nMem += nExpr+1;
97057 sqlite3VdbeAddOp2(v, OP_Integer, 0, regPrev);
97058 pKeyDup = sqlite3DbMallocZero(db,
97059 sizeof(*pKeyDup) + nExpr*(sizeof(CollSeq*)+1) );
97060 if( pKeyDup ){
97061 pKeyDup->aSortOrder = (u8*)&pKeyDup->aColl[nExpr];
@@ -97096,16 +97233,10 @@
97233 sqlite3VdbeAddOp4(v, OP_Compare, destA.iSdst, destB.iSdst, nOrderBy,
97234 (char*)pKeyMerge, P4_KEYINFO_HANDOFF);
97235 sqlite3VdbeChangeP5(v, OPFLAG_PERMUTE);
97236 sqlite3VdbeAddOp3(v, OP_Jump, addrAltB, addrAeqB, addrAgtB);
97237
 
 
 
 
 
 
97238 /* Jump to the this point in order to terminate the query.
97239 */
97240 sqlite3VdbeResolveLabel(v, labelEnd);
97241
97242 /* Set the number of output columns
@@ -114105,11 +114236,11 @@
114236 }
114237 }
114238 sqlite3VtabRollback(db);
114239 sqlite3EndBenignMalloc();
114240
114241 if( (db->flags&SQLITE_InternChanges)!=0 && db->init.busy==0 ){
114242 sqlite3ExpirePreparedStatements(db);
114243 sqlite3ResetAllSchemasOfConnection(db);
114244 }
114245
114246 /* Any deferred constraint violations have now been resolved. */
114247
+1 -1
--- src/sqlite3.h
+++ src/sqlite3.h
@@ -107,11 +107,11 @@
107107
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
108108
** [sqlite_version()] and [sqlite_source_id()].
109109
*/
110110
#define SQLITE_VERSION "3.7.16"
111111
#define SQLITE_VERSION_NUMBER 3007016
112
-#define SQLITE_SOURCE_ID "2013-02-13 14:04:28 7e10a62d0eb1cb2bdafb6752b78a9d368e9f21f5"
112
+#define SQLITE_SOURCE_ID "2013-03-01 23:40:26 780d06c5e54590f677f993fa9c313989c2eab8c7"
113113
114114
/*
115115
** CAPI3REF: Run-Time Library Version Numbers
116116
** KEYWORDS: sqlite3_version, sqlite3_sourceid
117117
**
118118
--- src/sqlite3.h
+++ src/sqlite3.h
@@ -107,11 +107,11 @@
107 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
108 ** [sqlite_version()] and [sqlite_source_id()].
109 */
110 #define SQLITE_VERSION "3.7.16"
111 #define SQLITE_VERSION_NUMBER 3007016
112 #define SQLITE_SOURCE_ID "2013-02-13 14:04:28 7e10a62d0eb1cb2bdafb6752b78a9d368e9f21f5"
113
114 /*
115 ** CAPI3REF: Run-Time Library Version Numbers
116 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
117 **
118
--- src/sqlite3.h
+++ src/sqlite3.h
@@ -107,11 +107,11 @@
107 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
108 ** [sqlite_version()] and [sqlite_source_id()].
109 */
110 #define SQLITE_VERSION "3.7.16"
111 #define SQLITE_VERSION_NUMBER 3007016
112 #define SQLITE_SOURCE_ID "2013-03-01 23:40:26 780d06c5e54590f677f993fa9c313989c2eab8c7"
113
114 /*
115 ** CAPI3REF: Run-Time Library Version Numbers
116 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
117 **
118
+1
--- src/sync.c
+++ src/sync.c
@@ -245,10 +245,11 @@
245245
usage("remote-url ?URL|off?");
246246
}
247247
if( g.argc==3 ){
248248
db_unset("last-sync-url", 0);
249249
db_unset("last-sync-pw", 0);
250
+ if( is_false(g.argv[2]) ) return;
250251
url_parse(g.argv[2], URL_REMEMBER|URL_PROMPT_PW);
251252
}
252253
zUrl = db_get("last-sync-url", 0);
253254
if( zUrl==0 ){
254255
fossil_print("off\n");
255256
--- src/sync.c
+++ src/sync.c
@@ -245,10 +245,11 @@
245 usage("remote-url ?URL|off?");
246 }
247 if( g.argc==3 ){
248 db_unset("last-sync-url", 0);
249 db_unset("last-sync-pw", 0);
 
250 url_parse(g.argv[2], URL_REMEMBER|URL_PROMPT_PW);
251 }
252 zUrl = db_get("last-sync-url", 0);
253 if( zUrl==0 ){
254 fossil_print("off\n");
255
--- src/sync.c
+++ src/sync.c
@@ -245,10 +245,11 @@
245 usage("remote-url ?URL|off?");
246 }
247 if( g.argc==3 ){
248 db_unset("last-sync-url", 0);
249 db_unset("last-sync-pw", 0);
250 if( is_false(g.argv[2]) ) return;
251 url_parse(g.argv[2], URL_REMEMBER|URL_PROMPT_PW);
252 }
253 zUrl = db_get("last-sync-url", 0);
254 if( zUrl==0 ){
255 fossil_print("off\n");
256
+1
--- src/url.c
+++ src/url.c
@@ -429,10 +429,11 @@
429429
/*
430430
** Prompt the user for the password for g.urlUser. Store the result
431431
** in g.urlPasswd.
432432
*/
433433
void url_prompt_for_password(void){
434
+ if( g.urlIsSsh || g.urlIsFile ) return;
434435
if( isatty(fileno(stdin))
435436
&& (g.urlFlags & URL_PROMPT_PW)!=0
436437
&& (g.urlFlags & URL_PROMPTED)==0
437438
){
438439
char *zPrompt = mprintf("\rpassword for %s: ", g.urlUser);
439440
--- src/url.c
+++ src/url.c
@@ -429,10 +429,11 @@
429 /*
430 ** Prompt the user for the password for g.urlUser. Store the result
431 ** in g.urlPasswd.
432 */
433 void url_prompt_for_password(void){
 
434 if( isatty(fileno(stdin))
435 && (g.urlFlags & URL_PROMPT_PW)!=0
436 && (g.urlFlags & URL_PROMPTED)==0
437 ){
438 char *zPrompt = mprintf("\rpassword for %s: ", g.urlUser);
439
--- src/url.c
+++ src/url.c
@@ -429,10 +429,11 @@
429 /*
430 ** Prompt the user for the password for g.urlUser. Store the result
431 ** in g.urlPasswd.
432 */
433 void url_prompt_for_password(void){
434 if( g.urlIsSsh || g.urlIsFile ) return;
435 if( isatty(fileno(stdin))
436 && (g.urlFlags & URL_PROMPT_PW)!=0
437 && (g.urlFlags & URL_PROMPTED)==0
438 ){
439 char *zPrompt = mprintf("\rpassword for %s: ", g.urlUser);
440
+45 -14
--- src/utf8.c
+++ src/utf8.c
@@ -23,10 +23,18 @@
2323
#include "utf8.h"
2424
#include <sqlite3.h>
2525
#ifdef _WIN32
2626
# include <windows.h>
2727
#endif
28
+#ifdef __CYGWIN__
29
+# include <sys/cygwin.h>
30
+# define CP_UTF8 65001
31
+ __declspec(dllimport) extern __stdcall int WideCharToMultiByte(int, int,
32
+ const char *, int, const char *, int, const char *, const char *);
33
+ __declspec(dllimport) extern __stdcall int MultiByteToWideChar(int, int,
34
+ const char *, int, wchar_t*, int);
35
+#endif
2836
2937
#ifdef _WIN32
3038
/*
3139
** Translate MBCS to UTF-8. Return a pointer to the translated text.
3240
** Call fossil_mbcs_free() to deallocate any memory used to store the
@@ -42,19 +50,20 @@
4250
** any memory used to hold the translation
4351
*/
4452
void fossil_mbcs_free(char *zOld){
4553
sqlite3_free(zOld);
4654
}
55
+#endif /* _WIN32 */
4756
4857
/*
4958
** Translate Unicode text into UTF-8.
5059
** Return a pointer to the translated text.
5160
** Call fossil_unicode_free() to deallocate any memory used to store the
5261
** returned pointer when done.
5362
*/
5463
char *fossil_unicode_to_utf8(const void *zUnicode){
55
-#ifdef _WIN32
64
+#if defined(_WIN32) || defined(__CYGWIN__)
5665
int nByte = WideCharToMultiByte(CP_UTF8, 0, zUnicode, -1, 0, 0, 0, 0);
5766
char *zUtf = sqlite3_malloc( nByte );
5867
if( zUtf==0 ){
5968
return 0;
6069
}
@@ -69,11 +78,11 @@
6978
** Translate UTF-8 to unicode for use in system calls. Return a pointer to the
7079
** translated text.. Call fossil_unicode_free() to deallocate any memory
7180
** used to store the returned pointer when done.
7281
*/
7382
void *fossil_utf8_to_unicode(const char *zUtf8){
74
-#ifdef _WIN32
83
+#if defined(_WIN32) || defined(__CYGWIN__)
7584
int nByte = MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, 0, 0);
7685
wchar_t *zUnicode = sqlite3_malloc( nByte * 2 );
7786
if( zUnicode==0 ){
7887
return 0;
7988
}
@@ -87,17 +96,16 @@
8796
/*
8897
** Deallocate any memory that was previously allocated by
8998
** fossil_unicode_to_utf8().
9099
*/
91100
void fossil_unicode_free(void *pOld){
92
-#ifdef _WIN32
101
+#if defined(_WIN32) || defined(__CYGWIN__)
93102
sqlite3_free(pOld);
94103
#else
95104
fossil_free(pOld);
96105
#endif
97106
}
98
-#endif /* _WIN32 */
99107
100108
#if defined(__APPLE__) && !defined(WITHOUT_ICONV)
101109
# include <iconv.h>
102110
#endif
103111
@@ -104,10 +112,14 @@
104112
/*
105113
** Translate text from the filename character set into UTF-8.
106114
** Return a pointer to the translated text.
107115
** Call fossil_filename_free() to deallocate any memory used to store the
108116
** returned pointer when done.
117
+**
118
+** This function must not convert '\' to '/' on windows/cygwin, as it is
119
+** used in places where we are not sure it's really filenames we are handling,
120
+** e.g. fossil_getenv() or handling the argv arguments from main().
109121
**
110122
** On Windows, translate some characters in the in the range
111123
** U+F001 - U+F07F (private use area) to ASCII. Cygwin sometimes
112124
** generates such filenames. See:
113125
** <http://cygwin.com/cygwin-ug-net/using-specialnames.html>
@@ -124,11 +136,11 @@
124136
pUtf = qUtf = zUtf;
125137
while( *pUtf ) {
126138
if( *pUtf == (char)0xef ){
127139
wchar_t c = ((pUtf[1]&0x3f)<<6)|(pUtf[2]&0x3f);
128140
/* Only really convert it when the resulting char is in range. */
129
- if ( c && ((c <= ' ') || wcschr(L"\"*.:<>?|", c)) ){
141
+ if ( c && ((c < ' ') || wcschr(L"\"*:<>?|", c)) ){
130142
*qUtf++ = c; pUtf+=3; continue;
131143
}
132144
}
133145
*qUtf++ = *pUtf++;
134146
}
@@ -184,38 +196,57 @@
184196
** See: <http://cygwin.com/cygwin-ug-net/using-specialnames.html>
185197
**
186198
*/
187199
void *fossil_utf8_to_filename(const char *zUtf8){
188200
#ifdef _WIN32
189
- int nByte = MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, 0, 0);
190
- wchar_t *zUnicode = sqlite3_malloc( nByte * 2 );
201
+ int nChar = MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, 0, 0);
202
+ wchar_t *zUnicode = sqlite3_malloc( nChar * 2 );
191203
wchar_t *wUnicode = zUnicode;
192204
if( zUnicode==0 ){
193205
return 0;
194206
}
195
- MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, zUnicode, nByte);
207
+ MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, zUnicode, nChar);
196208
/* If path starts with "<drive>:/" or "<drive>:\", don't translate the ':' */
197209
if( fossil_isalpha(zUtf8[0]) && zUtf8[1]==':'
198210
&& (zUtf8[2]=='\\' || zUtf8[2]=='/')) {
199211
zUnicode[2] = '\\';
200212
wUnicode += 3;
201213
}
202214
while( *wUnicode != '\0' ){
203
- if ( (*wUnicode < 32) || wcschr(L"\"*:<>?|", *wUnicode) ){
215
+ if ( (*wUnicode < ' ') || wcschr(L"\"*:<>?|", *wUnicode) ){
204216
*wUnicode |= 0xF000;
205217
}else if( *wUnicode == '/' ){
206218
*wUnicode = '\\';
207219
}
208220
++wUnicode;
209221
}
210222
return zUnicode;
211223
#elif defined(__CYGWIN__)
212
- char *zPath = fossil_strdup(zUtf8);
213
- char *p = zPath;
214
- while( (*p = *zUtf8++) != 0){
215
- if (*p++ == '\\' ) {
216
- p[-1] = '/';
224
+ char *zPath, *p;
225
+ if( fossil_isalpha(zUtf8[0]) && (zUtf8[1]==':')
226
+ && (zUtf8[2]=='\\' || zUtf8[2]=='/')) {
227
+ /* win32 absolute path starting with drive specifier. */
228
+ int nByte;
229
+ wchar_t zUnicode[2000];
230
+ wchar_t *wUnicode = zUnicode;
231
+ MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, zUnicode, count(zUnicode));
232
+ while( *wUnicode != '\0' ){
233
+ if( *wUnicode == '/' ){
234
+ *wUnicode = '\\';
235
+ }
236
+ ++wUnicode;
237
+ }
238
+ nByte = cygwin_conv_path(CCP_WIN_W_TO_POSIX, zUnicode, NULL, 0);
239
+ zPath = fossil_malloc(nByte);
240
+ cygwin_conv_path(CCP_WIN_W_TO_POSIX, zUnicode, zPath, nByte);
241
+ } else {
242
+ zPath = fossil_strdup(zUtf8);
243
+ zUtf8 = p = zPath;
244
+ while( (*p = *zUtf8++) != 0){
245
+ if (*p++ == '\\' ) {
246
+ p[-1] = '/';
247
+ }
217248
}
218249
}
219250
return zPath;
220251
#elif defined(__APPLE__) && !defined(WITHOUT_ICONV)
221252
return fossil_strdup(zUtf8);
222253
223254
ADDED test/Greek-Lipsum-1.txt
224255
ADDED test/Greek-Lipsum-2.txt
--- src/utf8.c
+++ src/utf8.c
@@ -23,10 +23,18 @@
23 #include "utf8.h"
24 #include <sqlite3.h>
25 #ifdef _WIN32
26 # include <windows.h>
27 #endif
 
 
 
 
 
 
 
 
28
29 #ifdef _WIN32
30 /*
31 ** Translate MBCS to UTF-8. Return a pointer to the translated text.
32 ** Call fossil_mbcs_free() to deallocate any memory used to store the
@@ -42,19 +50,20 @@
42 ** any memory used to hold the translation
43 */
44 void fossil_mbcs_free(char *zOld){
45 sqlite3_free(zOld);
46 }
 
47
48 /*
49 ** Translate Unicode text into UTF-8.
50 ** Return a pointer to the translated text.
51 ** Call fossil_unicode_free() to deallocate any memory used to store the
52 ** returned pointer when done.
53 */
54 char *fossil_unicode_to_utf8(const void *zUnicode){
55 #ifdef _WIN32
56 int nByte = WideCharToMultiByte(CP_UTF8, 0, zUnicode, -1, 0, 0, 0, 0);
57 char *zUtf = sqlite3_malloc( nByte );
58 if( zUtf==0 ){
59 return 0;
60 }
@@ -69,11 +78,11 @@
69 ** Translate UTF-8 to unicode for use in system calls. Return a pointer to the
70 ** translated text.. Call fossil_unicode_free() to deallocate any memory
71 ** used to store the returned pointer when done.
72 */
73 void *fossil_utf8_to_unicode(const char *zUtf8){
74 #ifdef _WIN32
75 int nByte = MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, 0, 0);
76 wchar_t *zUnicode = sqlite3_malloc( nByte * 2 );
77 if( zUnicode==0 ){
78 return 0;
79 }
@@ -87,17 +96,16 @@
87 /*
88 ** Deallocate any memory that was previously allocated by
89 ** fossil_unicode_to_utf8().
90 */
91 void fossil_unicode_free(void *pOld){
92 #ifdef _WIN32
93 sqlite3_free(pOld);
94 #else
95 fossil_free(pOld);
96 #endif
97 }
98 #endif /* _WIN32 */
99
100 #if defined(__APPLE__) && !defined(WITHOUT_ICONV)
101 # include <iconv.h>
102 #endif
103
@@ -104,10 +112,14 @@
104 /*
105 ** Translate text from the filename character set into UTF-8.
106 ** Return a pointer to the translated text.
107 ** Call fossil_filename_free() to deallocate any memory used to store the
108 ** returned pointer when done.
 
 
 
 
109 **
110 ** On Windows, translate some characters in the in the range
111 ** U+F001 - U+F07F (private use area) to ASCII. Cygwin sometimes
112 ** generates such filenames. See:
113 ** <http://cygwin.com/cygwin-ug-net/using-specialnames.html>
@@ -124,11 +136,11 @@
124 pUtf = qUtf = zUtf;
125 while( *pUtf ) {
126 if( *pUtf == (char)0xef ){
127 wchar_t c = ((pUtf[1]&0x3f)<<6)|(pUtf[2]&0x3f);
128 /* Only really convert it when the resulting char is in range. */
129 if ( c && ((c <= ' ') || wcschr(L"\"*.:<>?|", c)) ){
130 *qUtf++ = c; pUtf+=3; continue;
131 }
132 }
133 *qUtf++ = *pUtf++;
134 }
@@ -184,38 +196,57 @@
184 ** See: <http://cygwin.com/cygwin-ug-net/using-specialnames.html>
185 **
186 */
187 void *fossil_utf8_to_filename(const char *zUtf8){
188 #ifdef _WIN32
189 int nByte = MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, 0, 0);
190 wchar_t *zUnicode = sqlite3_malloc( nByte * 2 );
191 wchar_t *wUnicode = zUnicode;
192 if( zUnicode==0 ){
193 return 0;
194 }
195 MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, zUnicode, nByte);
196 /* If path starts with "<drive>:/" or "<drive>:\", don't translate the ':' */
197 if( fossil_isalpha(zUtf8[0]) && zUtf8[1]==':'
198 && (zUtf8[2]=='\\' || zUtf8[2]=='/')) {
199 zUnicode[2] = '\\';
200 wUnicode += 3;
201 }
202 while( *wUnicode != '\0' ){
203 if ( (*wUnicode < 32) || wcschr(L"\"*:<>?|", *wUnicode) ){
204 *wUnicode |= 0xF000;
205 }else if( *wUnicode == '/' ){
206 *wUnicode = '\\';
207 }
208 ++wUnicode;
209 }
210 return zUnicode;
211 #elif defined(__CYGWIN__)
212 char *zPath = fossil_strdup(zUtf8);
213 char *p = zPath;
214 while( (*p = *zUtf8++) != 0){
215 if (*p++ == '\\' ) {
216 p[-1] = '/';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
217 }
218 }
219 return zPath;
220 #elif defined(__APPLE__) && !defined(WITHOUT_ICONV)
221 return fossil_strdup(zUtf8);
222
223 DDED test/Greek-Lipsum-1.txt
224 DDED test/Greek-Lipsum-2.txt
--- src/utf8.c
+++ src/utf8.c
@@ -23,10 +23,18 @@
23 #include "utf8.h"
24 #include <sqlite3.h>
25 #ifdef _WIN32
26 # include <windows.h>
27 #endif
28 #ifdef __CYGWIN__
29 # include <sys/cygwin.h>
30 # define CP_UTF8 65001
31 __declspec(dllimport) extern __stdcall int WideCharToMultiByte(int, int,
32 const char *, int, const char *, int, const char *, const char *);
33 __declspec(dllimport) extern __stdcall int MultiByteToWideChar(int, int,
34 const char *, int, wchar_t*, int);
35 #endif
36
37 #ifdef _WIN32
38 /*
39 ** Translate MBCS to UTF-8. Return a pointer to the translated text.
40 ** Call fossil_mbcs_free() to deallocate any memory used to store the
@@ -42,19 +50,20 @@
50 ** any memory used to hold the translation
51 */
52 void fossil_mbcs_free(char *zOld){
53 sqlite3_free(zOld);
54 }
55 #endif /* _WIN32 */
56
57 /*
58 ** Translate Unicode text into UTF-8.
59 ** Return a pointer to the translated text.
60 ** Call fossil_unicode_free() to deallocate any memory used to store the
61 ** returned pointer when done.
62 */
63 char *fossil_unicode_to_utf8(const void *zUnicode){
64 #if defined(_WIN32) || defined(__CYGWIN__)
65 int nByte = WideCharToMultiByte(CP_UTF8, 0, zUnicode, -1, 0, 0, 0, 0);
66 char *zUtf = sqlite3_malloc( nByte );
67 if( zUtf==0 ){
68 return 0;
69 }
@@ -69,11 +78,11 @@
78 ** Translate UTF-8 to unicode for use in system calls. Return a pointer to the
79 ** translated text.. Call fossil_unicode_free() to deallocate any memory
80 ** used to store the returned pointer when done.
81 */
82 void *fossil_utf8_to_unicode(const char *zUtf8){
83 #if defined(_WIN32) || defined(__CYGWIN__)
84 int nByte = MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, 0, 0);
85 wchar_t *zUnicode = sqlite3_malloc( nByte * 2 );
86 if( zUnicode==0 ){
87 return 0;
88 }
@@ -87,17 +96,16 @@
96 /*
97 ** Deallocate any memory that was previously allocated by
98 ** fossil_unicode_to_utf8().
99 */
100 void fossil_unicode_free(void *pOld){
101 #if defined(_WIN32) || defined(__CYGWIN__)
102 sqlite3_free(pOld);
103 #else
104 fossil_free(pOld);
105 #endif
106 }
 
107
108 #if defined(__APPLE__) && !defined(WITHOUT_ICONV)
109 # include <iconv.h>
110 #endif
111
@@ -104,10 +112,14 @@
112 /*
113 ** Translate text from the filename character set into UTF-8.
114 ** Return a pointer to the translated text.
115 ** Call fossil_filename_free() to deallocate any memory used to store the
116 ** returned pointer when done.
117 **
118 ** This function must not convert '\' to '/' on windows/cygwin, as it is
119 ** used in places where we are not sure it's really filenames we are handling,
120 ** e.g. fossil_getenv() or handling the argv arguments from main().
121 **
122 ** On Windows, translate some characters in the in the range
123 ** U+F001 - U+F07F (private use area) to ASCII. Cygwin sometimes
124 ** generates such filenames. See:
125 ** <http://cygwin.com/cygwin-ug-net/using-specialnames.html>
@@ -124,11 +136,11 @@
136 pUtf = qUtf = zUtf;
137 while( *pUtf ) {
138 if( *pUtf == (char)0xef ){
139 wchar_t c = ((pUtf[1]&0x3f)<<6)|(pUtf[2]&0x3f);
140 /* Only really convert it when the resulting char is in range. */
141 if ( c && ((c < ' ') || wcschr(L"\"*:<>?|", c)) ){
142 *qUtf++ = c; pUtf+=3; continue;
143 }
144 }
145 *qUtf++ = *pUtf++;
146 }
@@ -184,38 +196,57 @@
196 ** See: <http://cygwin.com/cygwin-ug-net/using-specialnames.html>
197 **
198 */
199 void *fossil_utf8_to_filename(const char *zUtf8){
200 #ifdef _WIN32
201 int nChar = MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, 0, 0);
202 wchar_t *zUnicode = sqlite3_malloc( nChar * 2 );
203 wchar_t *wUnicode = zUnicode;
204 if( zUnicode==0 ){
205 return 0;
206 }
207 MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, zUnicode, nChar);
208 /* If path starts with "<drive>:/" or "<drive>:\", don't translate the ':' */
209 if( fossil_isalpha(zUtf8[0]) && zUtf8[1]==':'
210 && (zUtf8[2]=='\\' || zUtf8[2]=='/')) {
211 zUnicode[2] = '\\';
212 wUnicode += 3;
213 }
214 while( *wUnicode != '\0' ){
215 if ( (*wUnicode < ' ') || wcschr(L"\"*:<>?|", *wUnicode) ){
216 *wUnicode |= 0xF000;
217 }else if( *wUnicode == '/' ){
218 *wUnicode = '\\';
219 }
220 ++wUnicode;
221 }
222 return zUnicode;
223 #elif defined(__CYGWIN__)
224 char *zPath, *p;
225 if( fossil_isalpha(zUtf8[0]) && (zUtf8[1]==':')
226 && (zUtf8[2]=='\\' || zUtf8[2]=='/')) {
227 /* win32 absolute path starting with drive specifier. */
228 int nByte;
229 wchar_t zUnicode[2000];
230 wchar_t *wUnicode = zUnicode;
231 MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, zUnicode, count(zUnicode));
232 while( *wUnicode != '\0' ){
233 if( *wUnicode == '/' ){
234 *wUnicode = '\\';
235 }
236 ++wUnicode;
237 }
238 nByte = cygwin_conv_path(CCP_WIN_W_TO_POSIX, zUnicode, NULL, 0);
239 zPath = fossil_malloc(nByte);
240 cygwin_conv_path(CCP_WIN_W_TO_POSIX, zUnicode, zPath, nByte);
241 } else {
242 zPath = fossil_strdup(zUtf8);
243 zUtf8 = p = zPath;
244 while( (*p = *zUtf8++) != 0){
245 if (*p++ == '\\' ) {
246 p[-1] = '/';
247 }
248 }
249 }
250 return zPath;
251 #elif defined(__APPLE__) && !defined(WITHOUT_ICONV)
252 return fossil_strdup(zUtf8);
253
254 DDED test/Greek-Lipsum-1.txt
255 DDED test/Greek-Lipsum-2.txt
+45 -14
--- src/utf8.c
+++ src/utf8.c
@@ -23,10 +23,18 @@
2323
#include "utf8.h"
2424
#include <sqlite3.h>
2525
#ifdef _WIN32
2626
# include <windows.h>
2727
#endif
28
+#ifdef __CYGWIN__
29
+# include <sys/cygwin.h>
30
+# define CP_UTF8 65001
31
+ __declspec(dllimport) extern __stdcall int WideCharToMultiByte(int, int,
32
+ const char *, int, const char *, int, const char *, const char *);
33
+ __declspec(dllimport) extern __stdcall int MultiByteToWideChar(int, int,
34
+ const char *, int, wchar_t*, int);
35
+#endif
2836
2937
#ifdef _WIN32
3038
/*
3139
** Translate MBCS to UTF-8. Return a pointer to the translated text.
3240
** Call fossil_mbcs_free() to deallocate any memory used to store the
@@ -42,19 +50,20 @@
4250
** any memory used to hold the translation
4351
*/
4452
void fossil_mbcs_free(char *zOld){
4553
sqlite3_free(zOld);
4654
}
55
+#endif /* _WIN32 */
4756
4857
/*
4958
** Translate Unicode text into UTF-8.
5059
** Return a pointer to the translated text.
5160
** Call fossil_unicode_free() to deallocate any memory used to store the
5261
** returned pointer when done.
5362
*/
5463
char *fossil_unicode_to_utf8(const void *zUnicode){
55
-#ifdef _WIN32
64
+#if defined(_WIN32) || defined(__CYGWIN__)
5665
int nByte = WideCharToMultiByte(CP_UTF8, 0, zUnicode, -1, 0, 0, 0, 0);
5766
char *zUtf = sqlite3_malloc( nByte );
5867
if( zUtf==0 ){
5968
return 0;
6069
}
@@ -69,11 +78,11 @@
6978
** Translate UTF-8 to unicode for use in system calls. Return a pointer to the
7079
** translated text.. Call fossil_unicode_free() to deallocate any memory
7180
** used to store the returned pointer when done.
7281
*/
7382
void *fossil_utf8_to_unicode(const char *zUtf8){
74
-#ifdef _WIN32
83
+#if defined(_WIN32) || defined(__CYGWIN__)
7584
int nByte = MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, 0, 0);
7685
wchar_t *zUnicode = sqlite3_malloc( nByte * 2 );
7786
if( zUnicode==0 ){
7887
return 0;
7988
}
@@ -87,17 +96,16 @@
8796
/*
8897
** Deallocate any memory that was previously allocated by
8998
** fossil_unicode_to_utf8().
9099
*/
91100
void fossil_unicode_free(void *pOld){
92
-#ifdef _WIN32
101
+#if defined(_WIN32) || defined(__CYGWIN__)
93102
sqlite3_free(pOld);
94103
#else
95104
fossil_free(pOld);
96105
#endif
97106
}
98
-#endif /* _WIN32 */
99107
100108
#if defined(__APPLE__) && !defined(WITHOUT_ICONV)
101109
# include <iconv.h>
102110
#endif
103111
@@ -104,10 +112,14 @@
104112
/*
105113
** Translate text from the filename character set into UTF-8.
106114
** Return a pointer to the translated text.
107115
** Call fossil_filename_free() to deallocate any memory used to store the
108116
** returned pointer when done.
117
+**
118
+** This function must not convert '\' to '/' on windows/cygwin, as it is
119
+** used in places where we are not sure it's really filenames we are handling,
120
+** e.g. fossil_getenv() or handling the argv arguments from main().
109121
**
110122
** On Windows, translate some characters in the in the range
111123
** U+F001 - U+F07F (private use area) to ASCII. Cygwin sometimes
112124
** generates such filenames. See:
113125
** <http://cygwin.com/cygwin-ug-net/using-specialnames.html>
@@ -124,11 +136,11 @@
124136
pUtf = qUtf = zUtf;
125137
while( *pUtf ) {
126138
if( *pUtf == (char)0xef ){
127139
wchar_t c = ((pUtf[1]&0x3f)<<6)|(pUtf[2]&0x3f);
128140
/* Only really convert it when the resulting char is in range. */
129
- if ( c && ((c <= ' ') || wcschr(L"\"*.:<>?|", c)) ){
141
+ if ( c && ((c < ' ') || wcschr(L"\"*:<>?|", c)) ){
130142
*qUtf++ = c; pUtf+=3; continue;
131143
}
132144
}
133145
*qUtf++ = *pUtf++;
134146
}
@@ -184,38 +196,57 @@
184196
** See: <http://cygwin.com/cygwin-ug-net/using-specialnames.html>
185197
**
186198
*/
187199
void *fossil_utf8_to_filename(const char *zUtf8){
188200
#ifdef _WIN32
189
- int nByte = MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, 0, 0);
190
- wchar_t *zUnicode = sqlite3_malloc( nByte * 2 );
201
+ int nChar = MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, 0, 0);
202
+ wchar_t *zUnicode = sqlite3_malloc( nChar * 2 );
191203
wchar_t *wUnicode = zUnicode;
192204
if( zUnicode==0 ){
193205
return 0;
194206
}
195
- MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, zUnicode, nByte);
207
+ MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, zUnicode, nChar);
196208
/* If path starts with "<drive>:/" or "<drive>:\", don't translate the ':' */
197209
if( fossil_isalpha(zUtf8[0]) && zUtf8[1]==':'
198210
&& (zUtf8[2]=='\\' || zUtf8[2]=='/')) {
199211
zUnicode[2] = '\\';
200212
wUnicode += 3;
201213
}
202214
while( *wUnicode != '\0' ){
203
- if ( (*wUnicode < 32) || wcschr(L"\"*:<>?|", *wUnicode) ){
215
+ if ( (*wUnicode < ' ') || wcschr(L"\"*:<>?|", *wUnicode) ){
204216
*wUnicode |= 0xF000;
205217
}else if( *wUnicode == '/' ){
206218
*wUnicode = '\\';
207219
}
208220
++wUnicode;
209221
}
210222
return zUnicode;
211223
#elif defined(__CYGWIN__)
212
- char *zPath = fossil_strdup(zUtf8);
213
- char *p = zPath;
214
- while( (*p = *zUtf8++) != 0){
215
- if (*p++ == '\\' ) {
216
- p[-1] = '/';
224
+ char *zPath, *p;
225
+ if( fossil_isalpha(zUtf8[0]) && (zUtf8[1]==':')
226
+ && (zUtf8[2]=='\\' || zUtf8[2]=='/')) {
227
+ /* win32 absolute path starting with drive specifier. */
228
+ int nByte;
229
+ wchar_t zUnicode[2000];
230
+ wchar_t *wUnicode = zUnicode;
231
+ MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, zUnicode, count(zUnicode));
232
+ while( *wUnicode != '\0' ){
233
+ if( *wUnicode == '/' ){
234
+ *wUnicode = '\\';
235
+ }
236
+ ++wUnicode;
237
+ }
238
+ nByte = cygwin_conv_path(CCP_WIN_W_TO_POSIX, zUnicode, NULL, 0);
239
+ zPath = fossil_malloc(nByte);
240
+ cygwin_conv_path(CCP_WIN_W_TO_POSIX, zUnicode, zPath, nByte);
241
+ } else {
242
+ zPath = fossil_strdup(zUtf8);
243
+ zUtf8 = p = zPath;
244
+ while( (*p = *zUtf8++) != 0){
245
+ if (*p++ == '\\' ) {
246
+ p[-1] = '/';
247
+ }
217248
}
218249
}
219250
return zPath;
220251
#elif defined(__APPLE__) && !defined(WITHOUT_ICONV)
221252
return fossil_strdup(zUtf8);
222253
223254
ADDED test/Greek-Lipsum-1.txt
224255
ADDED test/Greek-Lipsum-2.txt
--- src/utf8.c
+++ src/utf8.c
@@ -23,10 +23,18 @@
23 #include "utf8.h"
24 #include <sqlite3.h>
25 #ifdef _WIN32
26 # include <windows.h>
27 #endif
 
 
 
 
 
 
 
 
28
29 #ifdef _WIN32
30 /*
31 ** Translate MBCS to UTF-8. Return a pointer to the translated text.
32 ** Call fossil_mbcs_free() to deallocate any memory used to store the
@@ -42,19 +50,20 @@
42 ** any memory used to hold the translation
43 */
44 void fossil_mbcs_free(char *zOld){
45 sqlite3_free(zOld);
46 }
 
47
48 /*
49 ** Translate Unicode text into UTF-8.
50 ** Return a pointer to the translated text.
51 ** Call fossil_unicode_free() to deallocate any memory used to store the
52 ** returned pointer when done.
53 */
54 char *fossil_unicode_to_utf8(const void *zUnicode){
55 #ifdef _WIN32
56 int nByte = WideCharToMultiByte(CP_UTF8, 0, zUnicode, -1, 0, 0, 0, 0);
57 char *zUtf = sqlite3_malloc( nByte );
58 if( zUtf==0 ){
59 return 0;
60 }
@@ -69,11 +78,11 @@
69 ** Translate UTF-8 to unicode for use in system calls. Return a pointer to the
70 ** translated text.. Call fossil_unicode_free() to deallocate any memory
71 ** used to store the returned pointer when done.
72 */
73 void *fossil_utf8_to_unicode(const char *zUtf8){
74 #ifdef _WIN32
75 int nByte = MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, 0, 0);
76 wchar_t *zUnicode = sqlite3_malloc( nByte * 2 );
77 if( zUnicode==0 ){
78 return 0;
79 }
@@ -87,17 +96,16 @@
87 /*
88 ** Deallocate any memory that was previously allocated by
89 ** fossil_unicode_to_utf8().
90 */
91 void fossil_unicode_free(void *pOld){
92 #ifdef _WIN32
93 sqlite3_free(pOld);
94 #else
95 fossil_free(pOld);
96 #endif
97 }
98 #endif /* _WIN32 */
99
100 #if defined(__APPLE__) && !defined(WITHOUT_ICONV)
101 # include <iconv.h>
102 #endif
103
@@ -104,10 +112,14 @@
104 /*
105 ** Translate text from the filename character set into UTF-8.
106 ** Return a pointer to the translated text.
107 ** Call fossil_filename_free() to deallocate any memory used to store the
108 ** returned pointer when done.
 
 
 
 
109 **
110 ** On Windows, translate some characters in the in the range
111 ** U+F001 - U+F07F (private use area) to ASCII. Cygwin sometimes
112 ** generates such filenames. See:
113 ** <http://cygwin.com/cygwin-ug-net/using-specialnames.html>
@@ -124,11 +136,11 @@
124 pUtf = qUtf = zUtf;
125 while( *pUtf ) {
126 if( *pUtf == (char)0xef ){
127 wchar_t c = ((pUtf[1]&0x3f)<<6)|(pUtf[2]&0x3f);
128 /* Only really convert it when the resulting char is in range. */
129 if ( c && ((c <= ' ') || wcschr(L"\"*.:<>?|", c)) ){
130 *qUtf++ = c; pUtf+=3; continue;
131 }
132 }
133 *qUtf++ = *pUtf++;
134 }
@@ -184,38 +196,57 @@
184 ** See: <http://cygwin.com/cygwin-ug-net/using-specialnames.html>
185 **
186 */
187 void *fossil_utf8_to_filename(const char *zUtf8){
188 #ifdef _WIN32
189 int nByte = MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, 0, 0);
190 wchar_t *zUnicode = sqlite3_malloc( nByte * 2 );
191 wchar_t *wUnicode = zUnicode;
192 if( zUnicode==0 ){
193 return 0;
194 }
195 MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, zUnicode, nByte);
196 /* If path starts with "<drive>:/" or "<drive>:\", don't translate the ':' */
197 if( fossil_isalpha(zUtf8[0]) && zUtf8[1]==':'
198 && (zUtf8[2]=='\\' || zUtf8[2]=='/')) {
199 zUnicode[2] = '\\';
200 wUnicode += 3;
201 }
202 while( *wUnicode != '\0' ){
203 if ( (*wUnicode < 32) || wcschr(L"\"*:<>?|", *wUnicode) ){
204 *wUnicode |= 0xF000;
205 }else if( *wUnicode == '/' ){
206 *wUnicode = '\\';
207 }
208 ++wUnicode;
209 }
210 return zUnicode;
211 #elif defined(__CYGWIN__)
212 char *zPath = fossil_strdup(zUtf8);
213 char *p = zPath;
214 while( (*p = *zUtf8++) != 0){
215 if (*p++ == '\\' ) {
216 p[-1] = '/';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
217 }
218 }
219 return zPath;
220 #elif defined(__APPLE__) && !defined(WITHOUT_ICONV)
221 return fossil_strdup(zUtf8);
222
223 DDED test/Greek-Lipsum-1.txt
224 DDED test/Greek-Lipsum-2.txt
--- src/utf8.c
+++ src/utf8.c
@@ -23,10 +23,18 @@
23 #include "utf8.h"
24 #include <sqlite3.h>
25 #ifdef _WIN32
26 # include <windows.h>
27 #endif
28 #ifdef __CYGWIN__
29 # include <sys/cygwin.h>
30 # define CP_UTF8 65001
31 __declspec(dllimport) extern __stdcall int WideCharToMultiByte(int, int,
32 const char *, int, const char *, int, const char *, const char *);
33 __declspec(dllimport) extern __stdcall int MultiByteToWideChar(int, int,
34 const char *, int, wchar_t*, int);
35 #endif
36
37 #ifdef _WIN32
38 /*
39 ** Translate MBCS to UTF-8. Return a pointer to the translated text.
40 ** Call fossil_mbcs_free() to deallocate any memory used to store the
@@ -42,19 +50,20 @@
50 ** any memory used to hold the translation
51 */
52 void fossil_mbcs_free(char *zOld){
53 sqlite3_free(zOld);
54 }
55 #endif /* _WIN32 */
56
57 /*
58 ** Translate Unicode text into UTF-8.
59 ** Return a pointer to the translated text.
60 ** Call fossil_unicode_free() to deallocate any memory used to store the
61 ** returned pointer when done.
62 */
63 char *fossil_unicode_to_utf8(const void *zUnicode){
64 #if defined(_WIN32) || defined(__CYGWIN__)
65 int nByte = WideCharToMultiByte(CP_UTF8, 0, zUnicode, -1, 0, 0, 0, 0);
66 char *zUtf = sqlite3_malloc( nByte );
67 if( zUtf==0 ){
68 return 0;
69 }
@@ -69,11 +78,11 @@
78 ** Translate UTF-8 to unicode for use in system calls. Return a pointer to the
79 ** translated text.. Call fossil_unicode_free() to deallocate any memory
80 ** used to store the returned pointer when done.
81 */
82 void *fossil_utf8_to_unicode(const char *zUtf8){
83 #if defined(_WIN32) || defined(__CYGWIN__)
84 int nByte = MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, 0, 0);
85 wchar_t *zUnicode = sqlite3_malloc( nByte * 2 );
86 if( zUnicode==0 ){
87 return 0;
88 }
@@ -87,17 +96,16 @@
96 /*
97 ** Deallocate any memory that was previously allocated by
98 ** fossil_unicode_to_utf8().
99 */
100 void fossil_unicode_free(void *pOld){
101 #if defined(_WIN32) || defined(__CYGWIN__)
102 sqlite3_free(pOld);
103 #else
104 fossil_free(pOld);
105 #endif
106 }
 
107
108 #if defined(__APPLE__) && !defined(WITHOUT_ICONV)
109 # include <iconv.h>
110 #endif
111
@@ -104,10 +112,14 @@
112 /*
113 ** Translate text from the filename character set into UTF-8.
114 ** Return a pointer to the translated text.
115 ** Call fossil_filename_free() to deallocate any memory used to store the
116 ** returned pointer when done.
117 **
118 ** This function must not convert '\' to '/' on windows/cygwin, as it is
119 ** used in places where we are not sure it's really filenames we are handling,
120 ** e.g. fossil_getenv() or handling the argv arguments from main().
121 **
122 ** On Windows, translate some characters in the in the range
123 ** U+F001 - U+F07F (private use area) to ASCII. Cygwin sometimes
124 ** generates such filenames. See:
125 ** <http://cygwin.com/cygwin-ug-net/using-specialnames.html>
@@ -124,11 +136,11 @@
136 pUtf = qUtf = zUtf;
137 while( *pUtf ) {
138 if( *pUtf == (char)0xef ){
139 wchar_t c = ((pUtf[1]&0x3f)<<6)|(pUtf[2]&0x3f);
140 /* Only really convert it when the resulting char is in range. */
141 if ( c && ((c < ' ') || wcschr(L"\"*:<>?|", c)) ){
142 *qUtf++ = c; pUtf+=3; continue;
143 }
144 }
145 *qUtf++ = *pUtf++;
146 }
@@ -184,38 +196,57 @@
196 ** See: <http://cygwin.com/cygwin-ug-net/using-specialnames.html>
197 **
198 */
199 void *fossil_utf8_to_filename(const char *zUtf8){
200 #ifdef _WIN32
201 int nChar = MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, 0, 0);
202 wchar_t *zUnicode = sqlite3_malloc( nChar * 2 );
203 wchar_t *wUnicode = zUnicode;
204 if( zUnicode==0 ){
205 return 0;
206 }
207 MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, zUnicode, nChar);
208 /* If path starts with "<drive>:/" or "<drive>:\", don't translate the ':' */
209 if( fossil_isalpha(zUtf8[0]) && zUtf8[1]==':'
210 && (zUtf8[2]=='\\' || zUtf8[2]=='/')) {
211 zUnicode[2] = '\\';
212 wUnicode += 3;
213 }
214 while( *wUnicode != '\0' ){
215 if ( (*wUnicode < ' ') || wcschr(L"\"*:<>?|", *wUnicode) ){
216 *wUnicode |= 0xF000;
217 }else if( *wUnicode == '/' ){
218 *wUnicode = '\\';
219 }
220 ++wUnicode;
221 }
222 return zUnicode;
223 #elif defined(__CYGWIN__)
224 char *zPath, *p;
225 if( fossil_isalpha(zUtf8[0]) && (zUtf8[1]==':')
226 && (zUtf8[2]=='\\' || zUtf8[2]=='/')) {
227 /* win32 absolute path starting with drive specifier. */
228 int nByte;
229 wchar_t zUnicode[2000];
230 wchar_t *wUnicode = zUnicode;
231 MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, zUnicode, count(zUnicode));
232 while( *wUnicode != '\0' ){
233 if( *wUnicode == '/' ){
234 *wUnicode = '\\';
235 }
236 ++wUnicode;
237 }
238 nByte = cygwin_conv_path(CCP_WIN_W_TO_POSIX, zUnicode, NULL, 0);
239 zPath = fossil_malloc(nByte);
240 cygwin_conv_path(CCP_WIN_W_TO_POSIX, zUnicode, zPath, nByte);
241 } else {
242 zPath = fossil_strdup(zUtf8);
243 zUtf8 = p = zPath;
244 while( (*p = *zUtf8++) != 0){
245 if (*p++ == '\\' ) {
246 p[-1] = '/';
247 }
248 }
249 }
250 return zPath;
251 #elif defined(__APPLE__) && !defined(WITHOUT_ICONV)
252 return fossil_strdup(zUtf8);
253
254 DDED test/Greek-Lipsum-1.txt
255 DDED test/Greek-Lipsum-2.txt
--- a/test/Greek-Lipsum-1.txt
+++ b/test/Greek-Lipsum-1.txt
@@ -0,0 +1,77 @@
1
+Κυο εξ υνυμ δισπυθανδο, ερος αλιενυμ κυι θε. Νες εξ ελωκυενθιαμ
2
+ινστρυσθιορ. Θεμπορ νοσθερ συ εως. Πυρθο μωφεθ μωδερατιυς ατ μελ. Συ δυο
3
+αμετ ειυς. Πρι δεσωρε ινθεγρε ασυμσαν αδ, πρω αν ρεβυμ εφφισιανθυρ
4
+νεσεσιταθιβυς.
5
+
6
+Νοσθρυμ συσιπιαντυρ ηας ει, ορναθυς ρεσυσαβο πρι ιδ, περ νολυισε οπωρθερε
7
+ιδ. Θε παρτιενδω περτινασια ινσωρρυπτε φις. Δισθας φαβυλας γυβεργρεν εως
8
+ιν, αλιι σολυμ ηις θε, ποσθυλανθ ασυσαμυς ετ ηας. Νο ινανι φαβυλας
9
+θχεωπηραστυς ναμ, ευμ διστα ηομερω εα. Μαγνα φυγιθ υθ περ, εσθ ατ νοσθρυμ
10
+δεσερυισε.
11
+
12
+Φις αυδιαμ λαβορες παθριοκυε εξ, ετ φευγιαθ δεφινιεβας σιθ. Αμετ εριπυιτ
13
+δελισατα υσυ ετ, σενσιβυς φολυπθατιβυς περ εξ. Κυωδ ιγνωθα τιβικυε ατ εαμ,
14
+νυλλα ηωνεσθαθις υθ νες. Φιξ αν μυτατ εξερσι λαβωρε. Σεδ νονυμυ κυοδσι
15
+δελενιτ νε, συμο φιδε εα κυι. Ποπυλω μαιορυμ περσεκυερις αν πρω.
16
+
17
+Σολυμ σωνφενιρε αδ ηας, αν ευμ σολυτα ρεγιονε προδεσεθ. Φερο λαβορες
18
+σαλυταθυς θε δυο, ηις νε φερο βλανδιτ πραεσενθ, ιδ φις σολεατ φιφενδυμ. Συ
19
+συμ μωδω συμμο δολορες. Θε ναμ πωσιθ φευγιαθ τινσιδυνθ.
20
+
21
+Υθ ιψυμ νεμωρε σαπιενθεμ μεα, ει εφερτι εφφισιενδι ηας. Ευμ αλβυσιυς
22
+πραεσενθ συ, δεσωρε σεθερο ινδοστυμ μει ει. Ηις υθ συμμο μαλορυμ μανδαμυς,
23
+κυι ιν συαφιθαθε περισυλις, ιισκυε οφφισιις κυο νο. Νε νονυμυ ηαβεμυς
24
+πχιλωσοπηια φις. Ετ ηας υταμυρ ρεφορμιδανς. Ινερμις δεθραξιθ νεγλεγενθυρ
25
+δυο υθ, τωρκυαθος δισεντιυνθ φιθυπερατοριβυς φιξ νε. Εα σεδ συας μελιυς,
26
+φιμ προβο ινδοστυμ ρεπριμικυε ευ.
27
+
28
+Πρι ιν λυδυς αυδιρε, συμμο περτινασια σωνσεθεθυρ φις ιν, σιθ εξ επισυρι
29
+μαλυισετ σωνσεπθαμ. Αν δετρασθο ελειφενδ εξπλισαρι πρω. Ιυδισο σομμοδο συμ
30
+αδ. Δισαμ δισυντ φυλπυτατε ιν πρω, εξ ηις δελενιτ μαιεσθατις. Ρεβυμ νονυμυ
31
+αππαρεατ σιθ εα, σιθ ιδ νυλλα σολεατ πεθενθιυμ, ει οπθιων περσεκυερις ευμ.
32
+Υθ νισλ ινσωλενς φιξ, εσθ φερι ιισκυε αργυμενθυμ συ, σεθερο μολεστιε
33
+αδιπισινγ ευ μεα.
34
+
35
+Ετ μεα μυσιυς λατινε, μει σεμπερ δεσερυντ περτινασια αν. Συ φενιαμ ποπυλω
36
+αθωμωρυμ κυο. Νο ιυς ρεβυμ φιθυπεραθα δισπυτατιονι, ατ αλθερυμ χενδρεριτ
37
+φιθυπεραθα συμ. Ευμ αυτεμ αππετερε αδιπισινγ ετ, νο κυο συας ελειφενδ. Εαμ
38
+θαλε δισαμ εξ.
39
+
40
+Ετ σομμοδο λεγενδως φελ, διαμ φωλυπθαρια νο μελ, δυο φελιτ νεμωρε αδ. Αν
41
+εξπετενδα συαφιθαθε φελ, ενιμ ασυμσαν περ αδ, εα φιμ μωδω υνυμ. Εα κυωδ
42
+προβο περσεσυτι φελ, ευ φερι πρωπριαε ινσιδεριντ νες. Εξ νες οδιο δελενιτ,
43
+ελιτ ιυδισο ινθεγρε δυο ιδ. Μελ αλικυιπ περισυλις ετ, ατ ηας αυγυε λαβορες
44
+ασεντιορ.
45
+
46
+Συ νυλλα δωσενδι δεφινιτιωνες φελ. Δωλορε δισερετ ρεφορμιδανς αδ πρω.
47
+Εφερτι πρωβατυς υρβανιθας νο μελ. Ιν φιξ φασεθε δεθραξιθ ομιθταντυρ, ζριλ
48
+υτιναμ παθριοκυε συ νες. Κυο ει δισενθιετ ασομμοδαρε.
49
+
50
+Ηας θε ομνεσκυε δελισαθισιμι. Εξερσι δελισατα ινιμισυς ευμ ευ, ιδ ελιτρ
51
+μελιορε αβχορρεανθ εσθ, εως οπθιων προδεσεθ σονσεσθεθυερ ιν. Ναμ διαμ ασυμ
52
+τεμποριβυς αν. Σομμυνε δεφινιθιονεμ κυο ιν, ηας νωμιναφι φιφενδυμ ατ.
53
+Ομνεσκυε δεφινιεβας μεα θε.
54
+
55
+Εαμ σανστυς αλβυσιυς ευ, φελ στετ επισυρι ιν, κυο αδ περτιναξ σενσεριτ
56
+τωρκυαθος. Λαβωρε νυσκυαμ ιν κυι, ερος σαεπε τιβικυε εσθ ατ. Φερο υτιναμ
57
+φελ νε, αδ απεριρι ομιθταντυρ δεφινιτιωνες δυο. Ινφενιρε ελειφενδ παθριοκυε
58
+εξ ναμ. Ιδ ναμ μινιμ υθροκυε. Αδ ναθυμ αππετερε σεα.
59
+
60
+Μολλις φολυμυς κυι νο, θε φιμ υβικυε αδιπισι διγνισιμ. Νοβις νοσθρω
61
+μενανδρι υσυ νο, πριμα ελιτρ κυαεκυε ιδ ηας. Πρω εα παρτεμ δομινγ. Θε
62
+φασεθε αυδιρε φολυπθατιβυς ιυς. Φις δεθραξιθ ινφενιρε ετ, αν ιυς πωσθεα
63
+μεδιοσριθαθεμ.
64
+
65
+Εα αδχυς υταμυρ φις. Σιβω λαυδεμ υσυ αδ, φις λεγιμυς πλασεραθ φερθερεμ συ.
66
+Φιμ ατ ειυς αλθερυμ φιθυπερατοριβυς, ατ λατινε ηαβεμυς φολυτπατ μεα. Γραεσω
67
+λυσιλιυς εα φελ.
68
+
69
+Θε φιξ βρυτε συμμο, φελ ωμιτθαμ ιμπερδιετ εξ. Μεα ιν μωδω νυμκυαμ, σεα
70
+τρασθατος εξπετενδα αδ. Γραεσε πλαθονεμ ρεπυδιανδαε φιξ εα, εα ετιαμ
71
+σωνσθιτυθο ασυεφεριθ σιθ. Ατ πυρθο ναθυμ σονγυε φιξ, κυι ετ δισαμ ινερμις
72
+ινιμισυς.
73
+
74
+Περ υθ διστα ινθεγρε, περ ρεκυε φιερενθ αδ. Νε δεσερυντ ινφενιρε σωνσεθεθυρ
75
+μει, αν ηομερω αργυμενθυμ ρεπυδιανδαε περ, ηις σωνσυλ μελιορε ινθελλεγαμ
76
+υθ. Νες εα λαβιθυρ δολορεμ υλλαμσορπερ. Μει εσεντ νεσεσιταθιβυς ιν, αφφερθ
77
+σαυσαε ινθερεσετ ηας αν.
--- a/test/Greek-Lipsum-1.txt
+++ b/test/Greek-Lipsum-1.txt
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
--- a/test/Greek-Lipsum-1.txt
+++ b/test/Greek-Lipsum-1.txt
@@ -0,0 +1,77 @@
1 Κυο εξ υνυμ δισπυθανδο, ερος αλιενυμ κυι θε. Νες εξ ελωκυενθιαμ
2 ινστρυσθιορ. Θεμπορ νοσθερ συ εως. Πυρθο μωφεθ μωδερατιυς ατ μελ. Συ δυο
3 αμετ ειυς. Πρι δεσωρε ινθεγρε ασυμσαν αδ, πρω αν ρεβυμ εφφισιανθυρ
4 νεσεσιταθιβυς.
5
6 Νοσθρυμ συσιπιαντυρ ηας ει, ορναθυς ρεσυσαβο πρι ιδ, περ νολυισε οπωρθερε
7 ιδ. Θε παρτιενδω περτινασια ινσωρρυπτε φις. Δισθας φαβυλας γυβεργρεν εως
8 ιν, αλιι σολυμ ηις θε, ποσθυλανθ ασυσαμυς ετ ηας. Νο ινανι φαβυλας
9 θχεωπηραστυς ναμ, ευμ διστα ηομερω εα. Μαγνα φυγιθ υθ περ, εσθ ατ νοσθρυμ
10 δεσερυισε.
11
12 Φις αυδιαμ λαβορες παθριοκυε εξ, ετ φευγιαθ δεφινιεβας σιθ. Αμετ εριπυιτ
13 δελισατα υσυ ετ, σενσιβυς φολυπθατιβυς περ εξ. Κυωδ ιγνωθα τιβικυε ατ εαμ,
14 νυλλα ηωνεσθαθις υθ νες. Φιξ αν μυτατ εξερσι λαβωρε. Σεδ νονυμυ κυοδσι
15 δελενιτ νε, συμο φιδε εα κυι. Ποπυλω μαιορυμ περσεκυερις αν πρω.
16
17 Σολυμ σωνφενιρε αδ ηας, αν ευμ σολυτα ρεγιονε προδεσεθ. Φερο λαβορες
18 σαλυταθυς θε δυο, ηις νε φερο βλανδιτ πραεσενθ, ιδ φις σολεατ φιφενδυμ. Συ
19 συμ μωδω συμμο δολορες. Θε ναμ πωσιθ φευγιαθ τινσιδυνθ.
20
21 Υθ ιψυμ νεμωρε σαπιενθεμ μεα, ει εφερτι εφφισιενδι ηας. Ευμ αλβυσιυς
22 πραεσενθ συ, δεσωρε σεθερο ινδοστυμ μει ει. Ηις υθ συμμο μαλορυμ μανδαμυς,
23 κυι ιν συαφιθαθε περισυλις, ιισκυε οφφισιις κυο νο. Νε νονυμυ ηαβεμυς
24 πχιλωσοπηια φις. Ετ ηας υταμυρ ρεφορμιδανς. Ινερμις δεθραξιθ νεγλεγενθυρ
25 δυο υθ, τωρκυαθος δισεντιυνθ φιθυπερατοριβυς φιξ νε. Εα σεδ συας μελιυς,
26 φιμ προβο ινδοστυμ ρεπριμικυε ευ.
27
28 Πρι ιν λυδυς αυδιρε, συμμο περτινασια σωνσεθεθυρ φις ιν, σιθ εξ επισυρι
29 μαλυισετ σωνσεπθαμ. Αν δετρασθο ελειφενδ εξπλισαρι πρω. Ιυδισο σομμοδο συμ
30 αδ. Δισαμ δισυντ φυλπυτατε ιν πρω, εξ ηις δελενιτ μαιεσθατις. Ρεβυμ νονυμυ
31 αππαρεατ σιθ εα, σιθ ιδ νυλλα σολεατ πεθενθιυμ, ει οπθιων περσεκυερις ευμ.
32 Υθ νισλ ινσωλενς φιξ, εσθ φερι ιισκυε αργυμενθυμ συ, σεθερο μολεστιε
33 αδιπισινγ ευ μεα.
34
35 Ετ μεα μυσιυς λατινε, μει σεμπερ δεσερυντ περτινασια αν. Συ φενιαμ ποπυλω
36 αθωμωρυμ κυο. Νο ιυς ρεβυμ φιθυπεραθα δισπυτατιονι, ατ αλθερυμ χενδρεριτ
37 φιθυπεραθα συμ. Ευμ αυτεμ αππετερε αδιπισινγ ετ, νο κυο συας ελειφενδ. Εαμ
38 θαλε δισαμ εξ.
39
40 Ετ σομμοδο λεγενδως φελ, διαμ φωλυπθαρια νο μελ, δυο φελιτ νεμωρε αδ. Αν
41 εξπετενδα συαφιθαθε φελ, ενιμ ασυμσαν περ αδ, εα φιμ μωδω υνυμ. Εα κυωδ
42 προβο περσεσυτι φελ, ευ φερι πρωπριαε ινσιδεριντ νες. Εξ νες οδιο δελενιτ,
43 ελιτ ιυδισο ινθεγρε δυο ιδ. Μελ αλικυιπ περισυλις ετ, ατ ηας αυγυε λαβορες
44 ασεντιορ.
45
46 Συ νυλλα δωσενδι δεφινιτιωνες φελ. Δωλορε δισερετ ρεφορμιδανς αδ πρω.
47 Εφερτι πρωβατυς υρβανιθας νο μελ. Ιν φιξ φασεθε δεθραξιθ ομιθταντυρ, ζριλ
48 υτιναμ παθριοκυε συ νες. Κυο ει δισενθιετ ασομμοδαρε.
49
50 Ηας θε ομνεσκυε δελισαθισιμι. Εξερσι δελισατα ινιμισυς ευμ ευ, ιδ ελιτρ
51 μελιορε αβχορρεανθ εσθ, εως οπθιων προδεσεθ σονσεσθεθυερ ιν. Ναμ διαμ ασυμ
52 τεμποριβυς αν. Σομμυνε δεφινιθιονεμ κυο ιν, ηας νωμιναφι φιφενδυμ ατ.
53 Ομνεσκυε δεφινιεβας μεα θε.
54
55 Εαμ σανστυς αλβυσιυς ευ, φελ στετ επισυρι ιν, κυο αδ περτιναξ σενσεριτ
56 τωρκυαθος. Λαβωρε νυσκυαμ ιν κυι, ερος σαεπε τιβικυε εσθ ατ. Φερο υτιναμ
57 φελ νε, αδ απεριρι ομιθταντυρ δεφινιτιωνες δυο. Ινφενιρε ελειφενδ παθριοκυε
58 εξ ναμ. Ιδ ναμ μινιμ υθροκυε. Αδ ναθυμ αππετερε σεα.
59
60 Μολλις φολυμυς κυι νο, θε φιμ υβικυε αδιπισι διγνισιμ. Νοβις νοσθρω
61 μενανδρι υσυ νο, πριμα ελιτρ κυαεκυε ιδ ηας. Πρω εα παρτεμ δομινγ. Θε
62 φασεθε αυδιρε φολυπθατιβυς ιυς. Φις δεθραξιθ ινφενιρε ετ, αν ιυς πωσθεα
63 μεδιοσριθαθεμ.
64
65 Εα αδχυς υταμυρ φις. Σιβω λαυδεμ υσυ αδ, φις λεγιμυς πλασεραθ φερθερεμ συ.
66 Φιμ ατ ειυς αλθερυμ φιθυπερατοριβυς, ατ λατινε ηαβεμυς φολυτπατ μεα. Γραεσω
67 λυσιλιυς εα φελ.
68
69 Θε φιξ βρυτε συμμο, φελ ωμιτθαμ ιμπερδιετ εξ. Μεα ιν μωδω νυμκυαμ, σεα
70 τρασθατος εξπετενδα αδ. Γραεσε πλαθονεμ ρεπυδιανδαε φιξ εα, εα ετιαμ
71 σωνσθιτυθο ασυεφεριθ σιθ. Ατ πυρθο ναθυμ σονγυε φιξ, κυι ετ δισαμ ινερμις
72 ινιμισυς.
73
74 Περ υθ διστα ινθεγρε, περ ρεκυε φιερενθ αδ. Νε δεσερυντ ινφενιρε σωνσεθεθυρ
75 μει, αν ηομερω αργυμενθυμ ρεπυδιανδαε περ, ηις σωνσυλ μελιορε ινθελλεγαμ
76 υθ. Νες εα λαβιθυρ δολορεμ υλλαμσορπερ. Μει εσεντ νεσεσιταθιβυς ιν, αφφερθ
77 σαυσαε ινθερεσετ ηας αν.
--- a/test/Greek-Lipsum-2.txt
+++ b/test/Greek-Lipsum-2.txt
@@ -0,0 +1,77 @@
1
+Κυο εξ υνυμ δισπυθανδο, ερος αλιενυμ κυι θε. Νες εξ ελωκυενθιαμ
2
+ινστρυσθιορ. Θεμπορ νοσθερ συ εως. Πυρθο μωφεθ μωδερατιυς ατ μελ. Συ δυο
3
+αμετ ειυς. Πρι δεσωρε ινθεγρε ασυμσαν αδ, Φιξ αν ρεβυμ εφφισιανθυρ
4
+νεσεσιταθιβυς.
5
+
6
+Νοσθρυμ συσιπιαντυρ ηας ει, ορναθυς ρεσυσαβο πρι ιδ, περ νολυισε
7
+οπωρθερε ιδ. Θε παρτιενδω περτινασια ινσωρρυπτε φις. Δισθας φαβυλας
8
+γυβεργρεν εως ιν, αλιι σολυμ ηις θε, ποσθυλανθ ασυσαμυς ετ ηας. Νο ινανι
9
+φαβυλας θχεωπηραστυς ναμ, ευμ διστα ηομερω εα. Μαγνα φυγιθ υθ περ, εσθ
10
+ατ νοσθρυμ δεσερυισε.
11
+
12
+Φις αυδιαμ λαβορες παθριοκυε εξ, ετ φευγιαθ δεφινιεβας σιθ. Αμετ εριπυιτ
13
+δελισατα υσυ ετ, σενσιβυς φολυπθατιβυς περ εξ. Κυωδ ιγνωθα τιβικυε ατ
14
+εαμ, νυλλα ηωνεσθαθις υθ νες. Φιξ αν μυτατ εξερσι λαβωρε. Σεδ νονυμυ
15
+κυοδσι δελενιτ νε, συμο φιδε εα κυι. Ποπυλω μαιορυμ περσεκυερις αν πρω.
16
+
17
+Σολυμ σωνφενιρε αδ ηας, αν ευμ σολυτα ρεγιονε προδεσεθ. Φερο λαβορες
18
+σαλυταθυς θε δυο, ηις νε φερο βλανδιτ πραεσενθ, ιδ φις σολεατ φιφενδυμ.
19
+Συ συμ μωδω συμμο δολορες. Θε ναμ πωσιθ φευγιαθ τινσιδυνθ.
20
+
21
+Υθ ιψυμ νεμωρε σαπιενθεμ μεα, ει εφερτι εφφισιενδι ηας. Ευμ αλβυσιυς
22
+πραεσενθ συ, δεσωρε σεθερο ινδοστυμ μει ει. Ηις υθ συμμο μαλορυμ
23
+μανδαμυς, κυι ιν συαφιθαθε περισυλις, ιισκυε οφφισιις κυο νο. Νε νονυμυ
24
+ηαβεμυς πχιλωσοπηια φις. Ετ ηας υταμυρ ρεφορμιδανς. Ινερμις δεθραξιθ
25
+νεγλεγενθυρ δυο υθ, τωρκυαθος δισεντιυνθ φιθυπερατοριβυς φιξ νε. Εα σεδ
26
+συας μελιυς, φιμ προβο ινδοστυμ ρεπριμικυε ευ.
27
+
28
+Πρι ιν λυδυς αυδιρε, συμμο περτινασια σωνσεθεθυρ φις ιν, σιθ εξ επισυρι
29
+μαλυισετ σωνσεπθαμ. Αν δετρασθο ελειφενδ εξπλισαρι πρω. Ιυδισο σομμοδο
30
+συμ αδ. Δισαμ δισυντ φυλπυτατε ιν πρω, εξ ηις δελενιτ μαιεσθατις. Ρεβυμ
31
+νονυμυ αππαρεατ σιθ εα, σιθ ιδ νυλλα σολεατ πεθενθιυμ, ει οπθιων
32
+περσεκυερις ευμ. Υθ νισλ ινσωλενς φιξ, εσθ φερι ιισκυε αργυμενθυμ συ,
33
+σεθερο μολεστιε αδιπισινγ ευ μεα.
34
+
35
+Ετ μεα μυσιυς λατινε, μει σεμπερ δεσερυντ περτινασια αν. Συ φενιαμ
36
+ποπυλω αθωμωρυμ κυο. Νο ιυς ρεβυμ φιθυπεραθα δισπυτατιονι, ατ αλθερυμ
37
+χενδρεριτ φιθυπεραθα συμ. Ευμ αυτεμ αππετερε αδιπισινγ ετ, νο κυο συας
38
+ελειφενδ. Εαμ θαλε δισαμ εξ.
39
+
40
+Ετ σομμοδο λεγενδως φελ, διαμ φωλυπθαρια νο μελ, δυο φελιτ νεμωρε αδ. Αν
41
+εξπετενδα συαφιθαθε φελ, ενιμ ασυμσαν περ αδ, εα φιμ μωδω υνυμ. Εα κυωδ
42
+προβο περσεσυτι φελ, ευ φερι πρωπριαε ινσιδεριντ νες. Εξ νες οδιο
43
+δελενιτ, ελιτ ιυδισο ινθεγρε δυο ιδ. Μελ αλικυιπ περισυλις ετ, ατ ηας
44
+αυγυε λαβορες ασεντιορ.
45
+
46
+Συ νυλλα δωσενδι δεφινιτιωνες φελ. Δωλορε δισερετ ρεφορμιδανς αδ πρω.
47
+Εφερτι πρωβατυς υρβανιθας νο μελ. Ιν φιξ φασεθε δεθραξιθ ομιθταντυρ,
48
+ζριλ υτιναμ παθριοκυε συ νες. Κυο ει δισενθιετ ασομμοδαρε.
49
+
50
+Ηας θε ομνεσκυε δελισαθισιμι. Εξερσι δελισατα ινιμισυς ευμ ευ, ιδ ελιτρ
51
+μελιορε αβχορρεανθ εσθ, εως οπθιων προδεσεθ σονσεσθεθυερ ιν. Ναμ διαμ
52
+ασυμ τεμποριβυς αν. Σομμυνε δεφινιθιονεμ κυο ιν, ηας νωμιναφι φιφενδυμ
53
+ατ. Ομνεσκυε δεφινιεβας μεα θε.
54
+
55
+Εαμ σανστυς αλβυσιυς ευ, φελ στετ επισυρι ιν, κυο αδ περτιναξ σενσεριτ
56
+τωρκυαθος. Λαβωρε νυσκυαμ ιν κυι, ερος σαεπε τιβικυε εσθ ατ. Φερο υτιναμ
57
+φελ νε, αδ απεριρι ομιθταντυρ δεφινιτιωνες δυο. Ινφενιρε ελειφενδ
58
+παθριοκυε εξ ναμ. Ιδ ναμ μινιμ υθροκυε. Αδ ναθυμ αππετερε σεα.
59
+
60
+Μολλις φολυμυς κυι νο, θε φιμ υβικυε αδιπισι διγνισιμ. Νοβις νοσθρω
61
+μενανδρι υσυ νο, πριμα ελιτρ κυαεκυε ιδ ηας. Πρω εα παρτεμ δομινγ. Θε
62
+φασεθε αυδιρε φολυπθατιβυς ιυς. Φις δεθραξιθ ινφενιρε ετ, αν ιυς πωσθεα
63
+μεδιοσριθαθεμ.
64
+
65
+Εα αδχυς υταμυρ φις. Σιβω λαυδεμ υσυ αδ, φις λεγιμυς πλασεραθ φερθερεμ
66
+συ. Φιμ ατ ειυς αλθερυμ φιθυπερατοριβυς, ατ λατινε ηαβεμυς φολυτπατ
67
+μεα. Γραεσω λυσιλιυς εα φελ.
68
+
69
+Θε φιξ βρυτε συμμο, φελ ωμιτθαμ ιμπερδιετ εξ. Μεα ιν μωδω νυμκυαμ, σεα
70
+τρασθατος εξπετενδα αδ. Γραεσε πλαθονεμ ρεπυδιανδαε φιξ εα, εα ετιαμ
71
+σωνσθιτυθο ασυεφεριθ σιθ. Ατ πυρθο ναθυμ σονγυε φιξ, κυι ετ δισαμ
72
+ινερμις ινιμισυς.
73
+
74
+Περ υθ διστα ινθεγρε, περ ρεκυε φιερενθ αδ. Νε δεσερυντ ινφενιρε
75
+σωνσεθεθυρ μει, αν ηομερω αργυμενθυμ ρεπυδιανδαε περ, ηις σωνσυλ μελιορε
76
+ινθελλεγαμ υθ. Νες εα λαβιθυρ δολορεμ υλλαμσορπερ. Μει εσεντ
77
+νεσεσιταθιβυς ιν, αφφερθ σαυσαε ινθερεσετ ηας αν.
--- a/test/Greek-Lipsum-2.txt
+++ b/test/Greek-Lipsum-2.txt
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
--- a/test/Greek-Lipsum-2.txt
+++ b/test/Greek-Lipsum-2.txt
@@ -0,0 +1,77 @@
1 Κυο εξ υνυμ δισπυθανδο, ερος αλιενυμ κυι θε. Νες εξ ελωκυενθιαμ
2 ινστρυσθιορ. Θεμπορ νοσθερ συ εως. Πυρθο μωφεθ μωδερατιυς ατ μελ. Συ δυο
3 αμετ ειυς. Πρι δεσωρε ινθεγρε ασυμσαν αδ, Φιξ αν ρεβυμ εφφισιανθυρ
4 νεσεσιταθιβυς.
5
6 Νοσθρυμ συσιπιαντυρ ηας ει, ορναθυς ρεσυσαβο πρι ιδ, περ νολυισε
7 οπωρθερε ιδ. Θε παρτιενδω περτινασια ινσωρρυπτε φις. Δισθας φαβυλας
8 γυβεργρεν εως ιν, αλιι σολυμ ηις θε, ποσθυλανθ ασυσαμυς ετ ηας. Νο ινανι
9 φαβυλας θχεωπηραστυς ναμ, ευμ διστα ηομερω εα. Μαγνα φυγιθ υθ περ, εσθ
10 ατ νοσθρυμ δεσερυισε.
11
12 Φις αυδιαμ λαβορες παθριοκυε εξ, ετ φευγιαθ δεφινιεβας σιθ. Αμετ εριπυιτ
13 δελισατα υσυ ετ, σενσιβυς φολυπθατιβυς περ εξ. Κυωδ ιγνωθα τιβικυε ατ
14 εαμ, νυλλα ηωνεσθαθις υθ νες. Φιξ αν μυτατ εξερσι λαβωρε. Σεδ νονυμυ
15 κυοδσι δελενιτ νε, συμο φιδε εα κυι. Ποπυλω μαιορυμ περσεκυερις αν πρω.
16
17 Σολυμ σωνφενιρε αδ ηας, αν ευμ σολυτα ρεγιονε προδεσεθ. Φερο λαβορες
18 σαλυταθυς θε δυο, ηις νε φερο βλανδιτ πραεσενθ, ιδ φις σολεατ φιφενδυμ.
19 Συ συμ μωδω συμμο δολορες. Θε ναμ πωσιθ φευγιαθ τινσιδυνθ.
20
21 Υθ ιψυμ νεμωρε σαπιενθεμ μεα, ει εφερτι εφφισιενδι ηας. Ευμ αλβυσιυς
22 πραεσενθ συ, δεσωρε σεθερο ινδοστυμ μει ει. Ηις υθ συμμο μαλορυμ
23 μανδαμυς, κυι ιν συαφιθαθε περισυλις, ιισκυε οφφισιις κυο νο. Νε νονυμυ
24 ηαβεμυς πχιλωσοπηια φις. Ετ ηας υταμυρ ρεφορμιδανς. Ινερμις δεθραξιθ
25 νεγλεγενθυρ δυο υθ, τωρκυαθος δισεντιυνθ φιθυπερατοριβυς φιξ νε. Εα σεδ
26 συας μελιυς, φιμ προβο ινδοστυμ ρεπριμικυε ευ.
27
28 Πρι ιν λυδυς αυδιρε, συμμο περτινασια σωνσεθεθυρ φις ιν, σιθ εξ επισυρι
29 μαλυισετ σωνσεπθαμ. Αν δετρασθο ελειφενδ εξπλισαρι πρω. Ιυδισο σομμοδο
30 συμ αδ. Δισαμ δισυντ φυλπυτατε ιν πρω, εξ ηις δελενιτ μαιεσθατις. Ρεβυμ
31 νονυμυ αππαρεατ σιθ εα, σιθ ιδ νυλλα σολεατ πεθενθιυμ, ει οπθιων
32 περσεκυερις ευμ. Υθ νισλ ινσωλενς φιξ, εσθ φερι ιισκυε αργυμενθυμ συ,
33 σεθερο μολεστιε αδιπισινγ ευ μεα.
34
35 Ετ μεα μυσιυς λατινε, μει σεμπερ δεσερυντ περτινασια αν. Συ φενιαμ
36 ποπυλω αθωμωρυμ κυο. Νο ιυς ρεβυμ φιθυπεραθα δισπυτατιονι, ατ αλθερυμ
37 χενδρεριτ φιθυπεραθα συμ. Ευμ αυτεμ αππετερε αδιπισινγ ετ, νο κυο συας
38 ελειφενδ. Εαμ θαλε δισαμ εξ.
39
40 Ετ σομμοδο λεγενδως φελ, διαμ φωλυπθαρια νο μελ, δυο φελιτ νεμωρε αδ. Αν
41 εξπετενδα συαφιθαθε φελ, ενιμ ασυμσαν περ αδ, εα φιμ μωδω υνυμ. Εα κυωδ
42 προβο περσεσυτι φελ, ευ φερι πρωπριαε ινσιδεριντ νες. Εξ νες οδιο
43 δελενιτ, ελιτ ιυδισο ινθεγρε δυο ιδ. Μελ αλικυιπ περισυλις ετ, ατ ηας
44 αυγυε λαβορες ασεντιορ.
45
46 Συ νυλλα δωσενδι δεφινιτιωνες φελ. Δωλορε δισερετ ρεφορμιδανς αδ πρω.
47 Εφερτι πρωβατυς υρβανιθας νο μελ. Ιν φιξ φασεθε δεθραξιθ ομιθταντυρ,
48 ζριλ υτιναμ παθριοκυε συ νες. Κυο ει δισενθιετ ασομμοδαρε.
49
50 Ηας θε ομνεσκυε δελισαθισιμι. Εξερσι δελισατα ινιμισυς ευμ ευ, ιδ ελιτρ
51 μελιορε αβχορρεανθ εσθ, εως οπθιων προδεσεθ σονσεσθεθυερ ιν. Ναμ διαμ
52 ασυμ τεμποριβυς αν. Σομμυνε δεφινιθιονεμ κυο ιν, ηας νωμιναφι φιφενδυμ
53 ατ. Ομνεσκυε δεφινιεβας μεα θε.
54
55 Εαμ σανστυς αλβυσιυς ευ, φελ στετ επισυρι ιν, κυο αδ περτιναξ σενσεριτ
56 τωρκυαθος. Λαβωρε νυσκυαμ ιν κυι, ερος σαεπε τιβικυε εσθ ατ. Φερο υτιναμ
57 φελ νε, αδ απεριρι ομιθταντυρ δεφινιτιωνες δυο. Ινφενιρε ελειφενδ
58 παθριοκυε εξ ναμ. Ιδ ναμ μινιμ υθροκυε. Αδ ναθυμ αππετερε σεα.
59
60 Μολλις φολυμυς κυι νο, θε φιμ υβικυε αδιπισι διγνισιμ. Νοβις νοσθρω
61 μενανδρι υσυ νο, πριμα ελιτρ κυαεκυε ιδ ηας. Πρω εα παρτεμ δομινγ. Θε
62 φασεθε αυδιρε φολυπθατιβυς ιυς. Φις δεθραξιθ ινφενιρε ετ, αν ιυς πωσθεα
63 μεδιοσριθαθεμ.
64
65 Εα αδχυς υταμυρ φις. Σιβω λαυδεμ υσυ αδ, φις λεγιμυς πλασεραθ φερθερεμ
66 συ. Φιμ ατ ειυς αλθερυμ φιθυπερατοριβυς, ατ λατινε ηαβεμυς φολυτπατ
67 μεα. Γραεσω λυσιλιυς εα φελ.
68
69 Θε φιξ βρυτε συμμο, φελ ωμιτθαμ ιμπερδιετ εξ. Μεα ιν μωδω νυμκυαμ, σεα
70 τρασθατος εξπετενδα αδ. Γραεσε πλαθονεμ ρεπυδιανδαε φιξ εα, εα ετιαμ
71 σωνσθιτυθο ασυεφεριθ σιθ. Ατ πυρθο ναθυμ σονγυε φιξ, κυι ετ δισαμ
72 ινερμις ινιμισυς.
73
74 Περ υθ διστα ινθεγρε, περ ρεκυε φιερενθ αδ. Νε δεσερυντ ινφενιρε
75 σωνσεθεθυρ μει, αν ηομερω αργυμενθυμ ρεπυδιανδαε περ, ηις σωνσυλ μελιορε
76 ινθελλεγαμ υθ. Νες εα λαβιθυρ δολορεμ υλλαμσορπερ. Μει εσεντ
77 νεσεσιταθιβυς ιν, αφφερθ σαυσαε ινθερεσετ ηας αν.
--- test/diff-test-1.wiki
+++ test/diff-test-1.wiki
@@ -33,10 +33,14 @@
3333
* <a href="../../../fdiff?v1=21f9a00fe2fa4a17&v2=d5c4ff0532bd89c3#chunk5"
3434
target="testwindow">sqlite3.c changes</a>
3535
that are difficult to align.
3636
* <a href="../../../fdiff?v2=21f9a00fe2fa4a17&v1=d5c4ff0532bd89c3#chunk5"
3737
target="testwindow">sqlite3.c changes inverted.</a>
38
+ * <a href="../../../fdiff?v1=4f70c682e44f&v2=55659c6e062994f"
39
+ target="testwindow">Lorem Ipsum in Greek.</a>
40
+ * <a href="../../../fdiff?v2=4f70c682e44f&v1=55659c6e062994f"
41
+ target="testwindow">Lorem Ipsum in Greek inverted.</a>
3842
3943
External:
4044
4145
* <a href="http://www.sqlite.org/src/fdiff?v1=aafcb21a74e41f9a&v2=a6d127dd05daf0f9#chunk3" target="testwindow">
4246
Code indentation change.</a>
4347
--- test/diff-test-1.wiki
+++ test/diff-test-1.wiki
@@ -33,10 +33,14 @@
33 * <a href="../../../fdiff?v1=21f9a00fe2fa4a17&v2=d5c4ff0532bd89c3#chunk5"
34 target="testwindow">sqlite3.c changes</a>
35 that are difficult to align.
36 * <a href="../../../fdiff?v2=21f9a00fe2fa4a17&v1=d5c4ff0532bd89c3#chunk5"
37 target="testwindow">sqlite3.c changes inverted.</a>
 
 
 
 
38
39 External:
40
41 * <a href="http://www.sqlite.org/src/fdiff?v1=aafcb21a74e41f9a&v2=a6d127dd05daf0f9#chunk3" target="testwindow">
42 Code indentation change.</a>
43
--- test/diff-test-1.wiki
+++ test/diff-test-1.wiki
@@ -33,10 +33,14 @@
33 * <a href="../../../fdiff?v1=21f9a00fe2fa4a17&v2=d5c4ff0532bd89c3#chunk5"
34 target="testwindow">sqlite3.c changes</a>
35 that are difficult to align.
36 * <a href="../../../fdiff?v2=21f9a00fe2fa4a17&v1=d5c4ff0532bd89c3#chunk5"
37 target="testwindow">sqlite3.c changes inverted.</a>
38 * <a href="../../../fdiff?v1=4f70c682e44f&v2=55659c6e062994f"
39 target="testwindow">Lorem Ipsum in Greek.</a>
40 * <a href="../../../fdiff?v2=4f70c682e44f&v1=55659c6e062994f"
41 target="testwindow">Lorem Ipsum in Greek inverted.</a>
42
43 External:
44
45 * <a href="http://www.sqlite.org/src/fdiff?v1=aafcb21a74e41f9a&v2=a6d127dd05daf0f9#chunk3" target="testwindow">
46 Code indentation change.</a>
47
--- win/Makefile.mingw.mistachkin
+++ win/Makefile.mingw.mistachkin
@@ -301,10 +301,11 @@
301301
$(SRCDIR)/json_dir.c \
302302
$(SRCDIR)/json_finfo.c \
303303
$(SRCDIR)/json_login.c \
304304
$(SRCDIR)/json_query.c \
305305
$(SRCDIR)/json_report.c \
306
+ $(SRCDIR)/json_status.c \
306307
$(SRCDIR)/json_tag.c \
307308
$(SRCDIR)/json_timeline.c \
308309
$(SRCDIR)/json_user.c \
309310
$(SRCDIR)/json_wiki.c \
310311
$(SRCDIR)/leaf.c \
@@ -348,10 +349,11 @@
348349
$(SRCDIR)/unicode.c \
349350
$(SRCDIR)/update.c \
350351
$(SRCDIR)/url.c \
351352
$(SRCDIR)/user.c \
352353
$(SRCDIR)/utf8.c \
354
+ $(SRCDIR)/util.c \
353355
$(SRCDIR)/verify.c \
354356
$(SRCDIR)/vfile.c \
355357
$(SRCDIR)/wiki.c \
356358
$(SRCDIR)/wikiformat.c \
357359
$(SRCDIR)/winhttp.c \
@@ -407,10 +409,11 @@
407409
$(OBJDIR)/json_dir_.c \
408410
$(OBJDIR)/json_finfo_.c \
409411
$(OBJDIR)/json_login_.c \
410412
$(OBJDIR)/json_query_.c \
411413
$(OBJDIR)/json_report_.c \
414
+ $(OBJDIR)/json_status_.c \
412415
$(OBJDIR)/json_tag_.c \
413416
$(OBJDIR)/json_timeline_.c \
414417
$(OBJDIR)/json_user_.c \
415418
$(OBJDIR)/json_wiki_.c \
416419
$(OBJDIR)/leaf_.c \
@@ -454,10 +457,11 @@
454457
$(OBJDIR)/unicode_.c \
455458
$(OBJDIR)/update_.c \
456459
$(OBJDIR)/url_.c \
457460
$(OBJDIR)/user_.c \
458461
$(OBJDIR)/utf8_.c \
462
+ $(OBJDIR)/util_.c \
459463
$(OBJDIR)/verify_.c \
460464
$(OBJDIR)/vfile_.c \
461465
$(OBJDIR)/wiki_.c \
462466
$(OBJDIR)/wikiformat_.c \
463467
$(OBJDIR)/winhttp_.c \
@@ -513,10 +517,11 @@
513517
$(OBJDIR)/json_dir.o \
514518
$(OBJDIR)/json_finfo.o \
515519
$(OBJDIR)/json_login.o \
516520
$(OBJDIR)/json_query.o \
517521
$(OBJDIR)/json_report.o \
522
+ $(OBJDIR)/json_status.o \
518523
$(OBJDIR)/json_tag.o \
519524
$(OBJDIR)/json_timeline.o \
520525
$(OBJDIR)/json_user.o \
521526
$(OBJDIR)/json_wiki.o \
522527
$(OBJDIR)/leaf.o \
@@ -560,10 +565,11 @@
560565
$(OBJDIR)/unicode.o \
561566
$(OBJDIR)/update.o \
562567
$(OBJDIR)/url.o \
563568
$(OBJDIR)/user.o \
564569
$(OBJDIR)/utf8.o \
570
+ $(OBJDIR)/util.o \
565571
$(OBJDIR)/verify.o \
566572
$(OBJDIR)/vfile.o \
567573
$(OBJDIR)/wiki.o \
568574
$(OBJDIR)/wikiformat.o \
569575
$(OBJDIR)/winhttp.o \
@@ -732,10 +738,11 @@
732738
$(OBJDIR)/json_dir_.c:$(OBJDIR)/json_dir.h \
733739
$(OBJDIR)/json_finfo_.c:$(OBJDIR)/json_finfo.h \
734740
$(OBJDIR)/json_login_.c:$(OBJDIR)/json_login.h \
735741
$(OBJDIR)/json_query_.c:$(OBJDIR)/json_query.h \
736742
$(OBJDIR)/json_report_.c:$(OBJDIR)/json_report.h \
743
+ $(OBJDIR)/json_status_.c:$(OBJDIR)/json_status.h \
737744
$(OBJDIR)/json_tag_.c:$(OBJDIR)/json_tag.h \
738745
$(OBJDIR)/json_timeline_.c:$(OBJDIR)/json_timeline.h \
739746
$(OBJDIR)/json_user_.c:$(OBJDIR)/json_user.h \
740747
$(OBJDIR)/json_wiki_.c:$(OBJDIR)/json_wiki.h \
741748
$(OBJDIR)/leaf_.c:$(OBJDIR)/leaf.h \
@@ -779,10 +786,11 @@
779786
$(OBJDIR)/unicode_.c:$(OBJDIR)/unicode.h \
780787
$(OBJDIR)/update_.c:$(OBJDIR)/update.h \
781788
$(OBJDIR)/url_.c:$(OBJDIR)/url.h \
782789
$(OBJDIR)/user_.c:$(OBJDIR)/user.h \
783790
$(OBJDIR)/utf8_.c:$(OBJDIR)/utf8.h \
791
+ $(OBJDIR)/util_.c:$(OBJDIR)/util.h \
784792
$(OBJDIR)/verify_.c:$(OBJDIR)/verify.h \
785793
$(OBJDIR)/vfile_.c:$(OBJDIR)/vfile.h \
786794
$(OBJDIR)/wiki_.c:$(OBJDIR)/wiki.h \
787795
$(OBJDIR)/wikiformat_.c:$(OBJDIR)/wikiformat.h \
788796
$(OBJDIR)/winhttp_.c:$(OBJDIR)/winhttp.h \
@@ -1180,10 +1188,18 @@
11801188
11811189
$(OBJDIR)/json_report.o: $(OBJDIR)/json_report_.c $(OBJDIR)/json_report.h $(SRCDIR)/config.h
11821190
$(XTCC) -o $(OBJDIR)/json_report.o -c $(OBJDIR)/json_report_.c
11831191
11841192
$(OBJDIR)/json_report.h: $(OBJDIR)/headers
1193
+
1194
+$(OBJDIR)/json_status_.c: $(SRCDIR)/json_status.c $(OBJDIR)/translate
1195
+ $(TRANSLATE) $(SRCDIR)/json_status.c >$(OBJDIR)/json_status_.c
1196
+
1197
+$(OBJDIR)/json_status.o: $(OBJDIR)/json_status_.c $(OBJDIR)/json_status.h $(SRCDIR)/config.h
1198
+ $(XTCC) -o $(OBJDIR)/json_status.o -c $(OBJDIR)/json_status_.c
1199
+
1200
+$(OBJDIR)/json_status.h: $(OBJDIR)/headers
11851201
11861202
$(OBJDIR)/json_tag_.c: $(SRCDIR)/json_tag.c $(OBJDIR)/translate
11871203
$(TRANSLATE) $(SRCDIR)/json_tag.c >$(OBJDIR)/json_tag_.c
11881204
11891205
$(OBJDIR)/json_tag.o: $(OBJDIR)/json_tag_.c $(OBJDIR)/json_tag.h $(SRCDIR)/config.h
@@ -1556,10 +1572,18 @@
15561572
15571573
$(OBJDIR)/utf8.o: $(OBJDIR)/utf8_.c $(OBJDIR)/utf8.h $(SRCDIR)/config.h
15581574
$(XTCC) -o $(OBJDIR)/utf8.o -c $(OBJDIR)/utf8_.c
15591575
15601576
$(OBJDIR)/utf8.h: $(OBJDIR)/headers
1577
+
1578
+$(OBJDIR)/util_.c: $(SRCDIR)/util.c $(OBJDIR)/translate
1579
+ $(TRANSLATE) $(SRCDIR)/util.c >$(OBJDIR)/util_.c
1580
+
1581
+$(OBJDIR)/util.o: $(OBJDIR)/util_.c $(OBJDIR)/util.h $(SRCDIR)/config.h
1582
+ $(XTCC) -o $(OBJDIR)/util.o -c $(OBJDIR)/util_.c
1583
+
1584
+$(OBJDIR)/util.h: $(OBJDIR)/headers
15611585
15621586
$(OBJDIR)/verify_.c: $(SRCDIR)/verify.c $(OBJDIR)/translate
15631587
$(TRANSLATE) $(SRCDIR)/verify.c >$(OBJDIR)/verify_.c
15641588
15651589
$(OBJDIR)/verify.o: $(OBJDIR)/verify_.c $(OBJDIR)/verify.h $(SRCDIR)/config.h
@@ -1635,11 +1659,11 @@
16351659
$(XTCC) -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_STAT3 -Dlocaltime=fossil_localtime -DSQLITE_ENABLE_LOCKING_STYLE=0 -c $(SRCDIR)/sqlite3.c -o $(OBJDIR)/sqlite3.o
16361660
16371661
$(OBJDIR)/cson_amalgamation.o: $(SRCDIR)/cson_amalgamation.c
16381662
$(XTCC) -c $(SRCDIR)/cson_amalgamation.c -o $(OBJDIR)/cson_amalgamation.o
16391663
1640
-$(OBJDIR)/json.o $(OBJDIR)/json_artifact.o $(OBJDIR)/json_branch.o $(OBJDIR)/json_config.o $(OBJDIR)/json_diff.o $(OBJDIR)/json_dir.o $(OBJDIR)/jsos_finfo.o $(OBJDIR)/json_login.o $(OBJDIR)/json_query.o $(OBJDIR)/json_report.o $(OBJDIR)/json_tag.o $(OBJDIR)/json_timeline.o $(OBJDIR)/json_user.o $(OBJDIR)/json_wiki.o : $(SRCDIR)/json_detail.h
1664
+$(OBJDIR)/json.o $(OBJDIR)/json_artifact.o $(OBJDIR)/json_branch.o $(OBJDIR)/json_config.o $(OBJDIR)/json_diff.o $(OBJDIR)/json_dir.o $(OBJDIR)/jsos_finfo.o $(OBJDIR)/json_login.o $(OBJDIR)/json_query.o $(OBJDIR)/json_report.o $(OBJDIR)/json_status.o $(OBJDIR)/json_tag.o $(OBJDIR)/json_timeline.o $(OBJDIR)/json_user.o $(OBJDIR)/json_wiki.o : $(SRCDIR)/json_detail.h
16411665
16421666
$(OBJDIR)/shell.o: $(SRCDIR)/shell.c $(SRCDIR)/sqlite3.h
16431667
$(XTCC) -Dmain=sqlite3_shell -DSQLITE_OMIT_LOAD_EXTENSION=1 -c $(SRCDIR)/shell.c -o $(OBJDIR)/shell.o
16441668
16451669
$(OBJDIR)/th.o: $(SRCDIR)/th.c
16461670
--- win/Makefile.mingw.mistachkin
+++ win/Makefile.mingw.mistachkin
@@ -301,10 +301,11 @@
301 $(SRCDIR)/json_dir.c \
302 $(SRCDIR)/json_finfo.c \
303 $(SRCDIR)/json_login.c \
304 $(SRCDIR)/json_query.c \
305 $(SRCDIR)/json_report.c \
 
306 $(SRCDIR)/json_tag.c \
307 $(SRCDIR)/json_timeline.c \
308 $(SRCDIR)/json_user.c \
309 $(SRCDIR)/json_wiki.c \
310 $(SRCDIR)/leaf.c \
@@ -348,10 +349,11 @@
348 $(SRCDIR)/unicode.c \
349 $(SRCDIR)/update.c \
350 $(SRCDIR)/url.c \
351 $(SRCDIR)/user.c \
352 $(SRCDIR)/utf8.c \
 
353 $(SRCDIR)/verify.c \
354 $(SRCDIR)/vfile.c \
355 $(SRCDIR)/wiki.c \
356 $(SRCDIR)/wikiformat.c \
357 $(SRCDIR)/winhttp.c \
@@ -407,10 +409,11 @@
407 $(OBJDIR)/json_dir_.c \
408 $(OBJDIR)/json_finfo_.c \
409 $(OBJDIR)/json_login_.c \
410 $(OBJDIR)/json_query_.c \
411 $(OBJDIR)/json_report_.c \
 
412 $(OBJDIR)/json_tag_.c \
413 $(OBJDIR)/json_timeline_.c \
414 $(OBJDIR)/json_user_.c \
415 $(OBJDIR)/json_wiki_.c \
416 $(OBJDIR)/leaf_.c \
@@ -454,10 +457,11 @@
454 $(OBJDIR)/unicode_.c \
455 $(OBJDIR)/update_.c \
456 $(OBJDIR)/url_.c \
457 $(OBJDIR)/user_.c \
458 $(OBJDIR)/utf8_.c \
 
459 $(OBJDIR)/verify_.c \
460 $(OBJDIR)/vfile_.c \
461 $(OBJDIR)/wiki_.c \
462 $(OBJDIR)/wikiformat_.c \
463 $(OBJDIR)/winhttp_.c \
@@ -513,10 +517,11 @@
513 $(OBJDIR)/json_dir.o \
514 $(OBJDIR)/json_finfo.o \
515 $(OBJDIR)/json_login.o \
516 $(OBJDIR)/json_query.o \
517 $(OBJDIR)/json_report.o \
 
518 $(OBJDIR)/json_tag.o \
519 $(OBJDIR)/json_timeline.o \
520 $(OBJDIR)/json_user.o \
521 $(OBJDIR)/json_wiki.o \
522 $(OBJDIR)/leaf.o \
@@ -560,10 +565,11 @@
560 $(OBJDIR)/unicode.o \
561 $(OBJDIR)/update.o \
562 $(OBJDIR)/url.o \
563 $(OBJDIR)/user.o \
564 $(OBJDIR)/utf8.o \
 
565 $(OBJDIR)/verify.o \
566 $(OBJDIR)/vfile.o \
567 $(OBJDIR)/wiki.o \
568 $(OBJDIR)/wikiformat.o \
569 $(OBJDIR)/winhttp.o \
@@ -732,10 +738,11 @@
732 $(OBJDIR)/json_dir_.c:$(OBJDIR)/json_dir.h \
733 $(OBJDIR)/json_finfo_.c:$(OBJDIR)/json_finfo.h \
734 $(OBJDIR)/json_login_.c:$(OBJDIR)/json_login.h \
735 $(OBJDIR)/json_query_.c:$(OBJDIR)/json_query.h \
736 $(OBJDIR)/json_report_.c:$(OBJDIR)/json_report.h \
 
737 $(OBJDIR)/json_tag_.c:$(OBJDIR)/json_tag.h \
738 $(OBJDIR)/json_timeline_.c:$(OBJDIR)/json_timeline.h \
739 $(OBJDIR)/json_user_.c:$(OBJDIR)/json_user.h \
740 $(OBJDIR)/json_wiki_.c:$(OBJDIR)/json_wiki.h \
741 $(OBJDIR)/leaf_.c:$(OBJDIR)/leaf.h \
@@ -779,10 +786,11 @@
779 $(OBJDIR)/unicode_.c:$(OBJDIR)/unicode.h \
780 $(OBJDIR)/update_.c:$(OBJDIR)/update.h \
781 $(OBJDIR)/url_.c:$(OBJDIR)/url.h \
782 $(OBJDIR)/user_.c:$(OBJDIR)/user.h \
783 $(OBJDIR)/utf8_.c:$(OBJDIR)/utf8.h \
 
784 $(OBJDIR)/verify_.c:$(OBJDIR)/verify.h \
785 $(OBJDIR)/vfile_.c:$(OBJDIR)/vfile.h \
786 $(OBJDIR)/wiki_.c:$(OBJDIR)/wiki.h \
787 $(OBJDIR)/wikiformat_.c:$(OBJDIR)/wikiformat.h \
788 $(OBJDIR)/winhttp_.c:$(OBJDIR)/winhttp.h \
@@ -1180,10 +1188,18 @@
1180
1181 $(OBJDIR)/json_report.o: $(OBJDIR)/json_report_.c $(OBJDIR)/json_report.h $(SRCDIR)/config.h
1182 $(XTCC) -o $(OBJDIR)/json_report.o -c $(OBJDIR)/json_report_.c
1183
1184 $(OBJDIR)/json_report.h: $(OBJDIR)/headers
 
 
 
 
 
 
 
 
1185
1186 $(OBJDIR)/json_tag_.c: $(SRCDIR)/json_tag.c $(OBJDIR)/translate
1187 $(TRANSLATE) $(SRCDIR)/json_tag.c >$(OBJDIR)/json_tag_.c
1188
1189 $(OBJDIR)/json_tag.o: $(OBJDIR)/json_tag_.c $(OBJDIR)/json_tag.h $(SRCDIR)/config.h
@@ -1556,10 +1572,18 @@
1556
1557 $(OBJDIR)/utf8.o: $(OBJDIR)/utf8_.c $(OBJDIR)/utf8.h $(SRCDIR)/config.h
1558 $(XTCC) -o $(OBJDIR)/utf8.o -c $(OBJDIR)/utf8_.c
1559
1560 $(OBJDIR)/utf8.h: $(OBJDIR)/headers
 
 
 
 
 
 
 
 
1561
1562 $(OBJDIR)/verify_.c: $(SRCDIR)/verify.c $(OBJDIR)/translate
1563 $(TRANSLATE) $(SRCDIR)/verify.c >$(OBJDIR)/verify_.c
1564
1565 $(OBJDIR)/verify.o: $(OBJDIR)/verify_.c $(OBJDIR)/verify.h $(SRCDIR)/config.h
@@ -1635,11 +1659,11 @@
1635 $(XTCC) -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_STAT3 -Dlocaltime=fossil_localtime -DSQLITE_ENABLE_LOCKING_STYLE=0 -c $(SRCDIR)/sqlite3.c -o $(OBJDIR)/sqlite3.o
1636
1637 $(OBJDIR)/cson_amalgamation.o: $(SRCDIR)/cson_amalgamation.c
1638 $(XTCC) -c $(SRCDIR)/cson_amalgamation.c -o $(OBJDIR)/cson_amalgamation.o
1639
1640 $(OBJDIR)/json.o $(OBJDIR)/json_artifact.o $(OBJDIR)/json_branch.o $(OBJDIR)/json_config.o $(OBJDIR)/json_diff.o $(OBJDIR)/json_dir.o $(OBJDIR)/jsos_finfo.o $(OBJDIR)/json_login.o $(OBJDIR)/json_query.o $(OBJDIR)/json_report.o $(OBJDIR)/json_tag.o $(OBJDIR)/json_timeline.o $(OBJDIR)/json_user.o $(OBJDIR)/json_wiki.o : $(SRCDIR)/json_detail.h
1641
1642 $(OBJDIR)/shell.o: $(SRCDIR)/shell.c $(SRCDIR)/sqlite3.h
1643 $(XTCC) -Dmain=sqlite3_shell -DSQLITE_OMIT_LOAD_EXTENSION=1 -c $(SRCDIR)/shell.c -o $(OBJDIR)/shell.o
1644
1645 $(OBJDIR)/th.o: $(SRCDIR)/th.c
1646
--- win/Makefile.mingw.mistachkin
+++ win/Makefile.mingw.mistachkin
@@ -301,10 +301,11 @@
301 $(SRCDIR)/json_dir.c \
302 $(SRCDIR)/json_finfo.c \
303 $(SRCDIR)/json_login.c \
304 $(SRCDIR)/json_query.c \
305 $(SRCDIR)/json_report.c \
306 $(SRCDIR)/json_status.c \
307 $(SRCDIR)/json_tag.c \
308 $(SRCDIR)/json_timeline.c \
309 $(SRCDIR)/json_user.c \
310 $(SRCDIR)/json_wiki.c \
311 $(SRCDIR)/leaf.c \
@@ -348,10 +349,11 @@
349 $(SRCDIR)/unicode.c \
350 $(SRCDIR)/update.c \
351 $(SRCDIR)/url.c \
352 $(SRCDIR)/user.c \
353 $(SRCDIR)/utf8.c \
354 $(SRCDIR)/util.c \
355 $(SRCDIR)/verify.c \
356 $(SRCDIR)/vfile.c \
357 $(SRCDIR)/wiki.c \
358 $(SRCDIR)/wikiformat.c \
359 $(SRCDIR)/winhttp.c \
@@ -407,10 +409,11 @@
409 $(OBJDIR)/json_dir_.c \
410 $(OBJDIR)/json_finfo_.c \
411 $(OBJDIR)/json_login_.c \
412 $(OBJDIR)/json_query_.c \
413 $(OBJDIR)/json_report_.c \
414 $(OBJDIR)/json_status_.c \
415 $(OBJDIR)/json_tag_.c \
416 $(OBJDIR)/json_timeline_.c \
417 $(OBJDIR)/json_user_.c \
418 $(OBJDIR)/json_wiki_.c \
419 $(OBJDIR)/leaf_.c \
@@ -454,10 +457,11 @@
457 $(OBJDIR)/unicode_.c \
458 $(OBJDIR)/update_.c \
459 $(OBJDIR)/url_.c \
460 $(OBJDIR)/user_.c \
461 $(OBJDIR)/utf8_.c \
462 $(OBJDIR)/util_.c \
463 $(OBJDIR)/verify_.c \
464 $(OBJDIR)/vfile_.c \
465 $(OBJDIR)/wiki_.c \
466 $(OBJDIR)/wikiformat_.c \
467 $(OBJDIR)/winhttp_.c \
@@ -513,10 +517,11 @@
517 $(OBJDIR)/json_dir.o \
518 $(OBJDIR)/json_finfo.o \
519 $(OBJDIR)/json_login.o \
520 $(OBJDIR)/json_query.o \
521 $(OBJDIR)/json_report.o \
522 $(OBJDIR)/json_status.o \
523 $(OBJDIR)/json_tag.o \
524 $(OBJDIR)/json_timeline.o \
525 $(OBJDIR)/json_user.o \
526 $(OBJDIR)/json_wiki.o \
527 $(OBJDIR)/leaf.o \
@@ -560,10 +565,11 @@
565 $(OBJDIR)/unicode.o \
566 $(OBJDIR)/update.o \
567 $(OBJDIR)/url.o \
568 $(OBJDIR)/user.o \
569 $(OBJDIR)/utf8.o \
570 $(OBJDIR)/util.o \
571 $(OBJDIR)/verify.o \
572 $(OBJDIR)/vfile.o \
573 $(OBJDIR)/wiki.o \
574 $(OBJDIR)/wikiformat.o \
575 $(OBJDIR)/winhttp.o \
@@ -732,10 +738,11 @@
738 $(OBJDIR)/json_dir_.c:$(OBJDIR)/json_dir.h \
739 $(OBJDIR)/json_finfo_.c:$(OBJDIR)/json_finfo.h \
740 $(OBJDIR)/json_login_.c:$(OBJDIR)/json_login.h \
741 $(OBJDIR)/json_query_.c:$(OBJDIR)/json_query.h \
742 $(OBJDIR)/json_report_.c:$(OBJDIR)/json_report.h \
743 $(OBJDIR)/json_status_.c:$(OBJDIR)/json_status.h \
744 $(OBJDIR)/json_tag_.c:$(OBJDIR)/json_tag.h \
745 $(OBJDIR)/json_timeline_.c:$(OBJDIR)/json_timeline.h \
746 $(OBJDIR)/json_user_.c:$(OBJDIR)/json_user.h \
747 $(OBJDIR)/json_wiki_.c:$(OBJDIR)/json_wiki.h \
748 $(OBJDIR)/leaf_.c:$(OBJDIR)/leaf.h \
@@ -779,10 +786,11 @@
786 $(OBJDIR)/unicode_.c:$(OBJDIR)/unicode.h \
787 $(OBJDIR)/update_.c:$(OBJDIR)/update.h \
788 $(OBJDIR)/url_.c:$(OBJDIR)/url.h \
789 $(OBJDIR)/user_.c:$(OBJDIR)/user.h \
790 $(OBJDIR)/utf8_.c:$(OBJDIR)/utf8.h \
791 $(OBJDIR)/util_.c:$(OBJDIR)/util.h \
792 $(OBJDIR)/verify_.c:$(OBJDIR)/verify.h \
793 $(OBJDIR)/vfile_.c:$(OBJDIR)/vfile.h \
794 $(OBJDIR)/wiki_.c:$(OBJDIR)/wiki.h \
795 $(OBJDIR)/wikiformat_.c:$(OBJDIR)/wikiformat.h \
796 $(OBJDIR)/winhttp_.c:$(OBJDIR)/winhttp.h \
@@ -1180,10 +1188,18 @@
1188
1189 $(OBJDIR)/json_report.o: $(OBJDIR)/json_report_.c $(OBJDIR)/json_report.h $(SRCDIR)/config.h
1190 $(XTCC) -o $(OBJDIR)/json_report.o -c $(OBJDIR)/json_report_.c
1191
1192 $(OBJDIR)/json_report.h: $(OBJDIR)/headers
1193
1194 $(OBJDIR)/json_status_.c: $(SRCDIR)/json_status.c $(OBJDIR)/translate
1195 $(TRANSLATE) $(SRCDIR)/json_status.c >$(OBJDIR)/json_status_.c
1196
1197 $(OBJDIR)/json_status.o: $(OBJDIR)/json_status_.c $(OBJDIR)/json_status.h $(SRCDIR)/config.h
1198 $(XTCC) -o $(OBJDIR)/json_status.o -c $(OBJDIR)/json_status_.c
1199
1200 $(OBJDIR)/json_status.h: $(OBJDIR)/headers
1201
1202 $(OBJDIR)/json_tag_.c: $(SRCDIR)/json_tag.c $(OBJDIR)/translate
1203 $(TRANSLATE) $(SRCDIR)/json_tag.c >$(OBJDIR)/json_tag_.c
1204
1205 $(OBJDIR)/json_tag.o: $(OBJDIR)/json_tag_.c $(OBJDIR)/json_tag.h $(SRCDIR)/config.h
@@ -1556,10 +1572,18 @@
1572
1573 $(OBJDIR)/utf8.o: $(OBJDIR)/utf8_.c $(OBJDIR)/utf8.h $(SRCDIR)/config.h
1574 $(XTCC) -o $(OBJDIR)/utf8.o -c $(OBJDIR)/utf8_.c
1575
1576 $(OBJDIR)/utf8.h: $(OBJDIR)/headers
1577
1578 $(OBJDIR)/util_.c: $(SRCDIR)/util.c $(OBJDIR)/translate
1579 $(TRANSLATE) $(SRCDIR)/util.c >$(OBJDIR)/util_.c
1580
1581 $(OBJDIR)/util.o: $(OBJDIR)/util_.c $(OBJDIR)/util.h $(SRCDIR)/config.h
1582 $(XTCC) -o $(OBJDIR)/util.o -c $(OBJDIR)/util_.c
1583
1584 $(OBJDIR)/util.h: $(OBJDIR)/headers
1585
1586 $(OBJDIR)/verify_.c: $(SRCDIR)/verify.c $(OBJDIR)/translate
1587 $(TRANSLATE) $(SRCDIR)/verify.c >$(OBJDIR)/verify_.c
1588
1589 $(OBJDIR)/verify.o: $(OBJDIR)/verify_.c $(OBJDIR)/verify.h $(SRCDIR)/config.h
@@ -1635,11 +1659,11 @@
1659 $(XTCC) -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_STAT3 -Dlocaltime=fossil_localtime -DSQLITE_ENABLE_LOCKING_STYLE=0 -c $(SRCDIR)/sqlite3.c -o $(OBJDIR)/sqlite3.o
1660
1661 $(OBJDIR)/cson_amalgamation.o: $(SRCDIR)/cson_amalgamation.c
1662 $(XTCC) -c $(SRCDIR)/cson_amalgamation.c -o $(OBJDIR)/cson_amalgamation.o
1663
1664 $(OBJDIR)/json.o $(OBJDIR)/json_artifact.o $(OBJDIR)/json_branch.o $(OBJDIR)/json_config.o $(OBJDIR)/json_diff.o $(OBJDIR)/json_dir.o $(OBJDIR)/jsos_finfo.o $(OBJDIR)/json_login.o $(OBJDIR)/json_query.o $(OBJDIR)/json_report.o $(OBJDIR)/json_status.o $(OBJDIR)/json_tag.o $(OBJDIR)/json_timeline.o $(OBJDIR)/json_user.o $(OBJDIR)/json_wiki.o : $(SRCDIR)/json_detail.h
1665
1666 $(OBJDIR)/shell.o: $(SRCDIR)/shell.c $(SRCDIR)/sqlite3.h
1667 $(XTCC) -Dmain=sqlite3_shell -DSQLITE_OMIT_LOAD_EXTENSION=1 -c $(SRCDIR)/shell.c -o $(OBJDIR)/shell.o
1668
1669 $(OBJDIR)/th.o: $(SRCDIR)/th.c
1670

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button