Fossil SCM

Rename --ignore-space-at-eol (from Git) to -Z|--ignore-trailing-space (gnu diff). Add --ignore-all-space as well (doesn't behave exactly like GNU's option yet)

jan.nijtmans 2014-03-07 09:01 strip-trailing-cr merge
Commit d9e79f685bf4c7c3d7c45c48bdb65a01497ff002
+11 -1
--- src/config.h
+++ src/config.h
@@ -105,11 +105,21 @@
105105
# else
106106
# define COMPILER_NAME "msc"
107107
# endif
108108
# elif defined(__MINGW32__)
109109
# if !defined(COMPILER_VERSION)
110
-# if defined(__MINGW32_VERSION)
110
+# if defined(__MINGW_VERSION)
111
+# if defined(__GNUC__)
112
+# if defined(__VERSION__)
113
+# define COMPILER_VERSION COMPILER_STRINGIFY(__MINGW_VERSION) "-gcc-" __VERSION__
114
+# else
115
+# define COMPILER_VERSION COMPILER_STRINGIFY(__MINGW_VERSION) "-gcc"
116
+# endif
117
+# else
118
+# define COMPILER_VERSION COMPILER_STRINGIFY(__MINGW_VERSION)
119
+# endif
120
+# elif defined(__MINGW32_VERSION)
111121
# if defined(__GNUC__)
112122
# if defined(__VERSION__)
113123
# define COMPILER_VERSION COMPILER_STRINGIFY(__MINGW32_VERSION) "-gcc-" __VERSION__
114124
# else
115125
# define COMPILER_VERSION COMPILER_STRINGIFY(__MINGW32_VERSION) "-gcc"
116126
--- src/config.h
+++ src/config.h
@@ -105,11 +105,21 @@
105 # else
106 # define COMPILER_NAME "msc"
107 # endif
108 # elif defined(__MINGW32__)
109 # if !defined(COMPILER_VERSION)
110 # if defined(__MINGW32_VERSION)
 
 
 
 
 
 
 
 
 
 
111 # if defined(__GNUC__)
112 # if defined(__VERSION__)
113 # define COMPILER_VERSION COMPILER_STRINGIFY(__MINGW32_VERSION) "-gcc-" __VERSION__
114 # else
115 # define COMPILER_VERSION COMPILER_STRINGIFY(__MINGW32_VERSION) "-gcc"
116
--- src/config.h
+++ src/config.h
@@ -105,11 +105,21 @@
105 # else
106 # define COMPILER_NAME "msc"
107 # endif
108 # elif defined(__MINGW32__)
109 # if !defined(COMPILER_VERSION)
110 # if defined(__MINGW_VERSION)
111 # if defined(__GNUC__)
112 # if defined(__VERSION__)
113 # define COMPILER_VERSION COMPILER_STRINGIFY(__MINGW_VERSION) "-gcc-" __VERSION__
114 # else
115 # define COMPILER_VERSION COMPILER_STRINGIFY(__MINGW_VERSION) "-gcc"
116 # endif
117 # else
118 # define COMPILER_VERSION COMPILER_STRINGIFY(__MINGW_VERSION)
119 # endif
120 # elif defined(__MINGW32_VERSION)
121 # if defined(__GNUC__)
122 # if defined(__VERSION__)
123 # define COMPILER_VERSION COMPILER_STRINGIFY(__MINGW32_VERSION) "-gcc-" __VERSION__
124 # else
125 # define COMPILER_VERSION COMPILER_STRINGIFY(__MINGW32_VERSION) "-gcc"
126
+62 -38
--- src/diff.c
+++ src/diff.c
@@ -28,12 +28,13 @@
2828
** Flag parameters to the text_diff() routine used to control the formatting
2929
** of the diff output.
3030
*/
3131
#define DIFF_CONTEXT_MASK ((u64)0x0000ffff) /* Lines of context. Default if 0 */
3232
#define DIFF_WIDTH_MASK ((u64)0x00ff0000) /* side-by-side column width */
33
-#define DIFF_IGNORE_SOLWS ((u64)0x01000000) /* Ignore start-of-line whitespace */
33
+#define DIFF_STRIP_EOLCR ((u64)0x01000000) /* Strip trailing CR */
3434
#define DIFF_IGNORE_EOLWS ((u64)0x02000000) /* Ignore end-of-line whitespace */
35
+#define DIFF_IGNORE_ALLWS ((u64)0x03000000) /* Ignore all whitespace */
3536
#define DIFF_SIDEBYSIDE ((u64)0x04000000) /* Generate a side-by-side diff */
3637
#define DIFF_VERBOSE ((u64)0x08000000) /* Missing shown as empty files */
3738
#define DIFF_INLINE ((u64)0x00000000) /* Inline (not side-by-side) diff */
3839
#define DIFF_BRIEF ((u64)0x10000000) /* Show filenames only */
3940
#define DIFF_HTML ((u64)0x20000000) /* Render for HTML */
@@ -40,11 +41,10 @@
4041
#define DIFF_LINENO ((u64)0x40000000) /* Show line numbers */
4142
#define DIFF_NOOPT (((u64)0x01)<<32) /* Suppress optimizations (debug) */
4243
#define DIFF_INVERT (((u64)0x02)<<32) /* Invert the diff (debug) */
4344
#define DIFF_CONTEXT_EX (((u64)0x04)<<32) /* Use context even if zero */
4445
#define DIFF_NOTTOOBIG (((u64)0x08)<<32) /* Only display if not too big */
45
-#define DIFF_STRIP_EOLCR (((u64)0x10)<<32) /* Strip trailing CR */
4646
4747
/*
4848
** These error messages are shared in multiple locations. They are defined
4949
** here for consistency.
5050
*/
@@ -172,11 +172,11 @@
172172
if( diffFlags & DIFF_IGNORE_EOLWS ){
173173
while( k>0 && fossil_isspace(z[k-1]) ){ k--; }
174174
}else if( diffFlags & DIFF_STRIP_EOLCR ){
175175
if( k>0 && z[k-1]=='\r' ){ k--; }
176176
}
177
- if( diffFlags & DIFF_IGNORE_SOLWS ){
177
+ if( (diffFlags & DIFF_IGNORE_ALLWS)==DIFF_IGNORE_ALLWS ){
178178
while( s<k && fossil_isspace(z[s]) ){
179179
if( z[s]=='\t' ){
180180
indent = ((indent+9)/8)*8;
181181
}else if( z[s]==' ' ){
182182
indent++;
@@ -1792,11 +1792,11 @@
17921792
if( diffFlags & DIFF_INVERT ){
17931793
Blob *pTemp = pA_Blob;
17941794
pA_Blob = pB_Blob;
17951795
pB_Blob = pTemp;
17961796
}
1797
- ignoreWs = (diffFlags & (DIFF_IGNORE_SOLWS|DIFF_IGNORE_EOLWS))!=0;
1797
+ ignoreWs = (diffFlags & DIFF_IGNORE_EOLWS)!=0;
17981798
blob_to_utf8_no_bom(pA_Blob, 0);
17991799
blob_to_utf8_no_bom(pB_Blob, 0);
18001800
18011801
/* Prepare the input files */
18021802
memset(&c, 0, sizeof(c));
@@ -1862,28 +1862,36 @@
18621862
18631863
/*
18641864
** Process diff-related command-line options and return an appropriate
18651865
** "diffFlags" integer.
18661866
**
1867
-** --brief Show filenames only DIFF_BRIEF
1868
-** --context|-c N N lines of context. DIFF_CONTEXT_MASK
1869
-** --html Format for HTML DIFF_HTML
1870
-** --invert Invert the diff DIFF_INVERT
1871
-** --ignore-space-at-eol Ignore eol-whitespaces DIFF_IGNORE_EOLWS
1872
-** --ignore-space-at-sol Ignore sol-whitespaces DIFF_IGNORE_SOLWS
1873
-** --linenum|-n Show line numbers DIFF_LINENO
1874
-** --noopt Disable optimization DIFF_NOOPT
1875
-** --side-by-side|-y Side-by-side diff. DIFF_SIDEBYSIDE
1876
-** --strip-trailing-cr Strip trailing CR DIFF_IGNORE_EOLCR
1877
-** --unified Unified diff. ~DIFF_SIDEBYSIDE
1878
-** -w Ignore all whitespaces DIFF_IGNORE_EOLWS|DIFF_IGNORE_SOLWS
1879
-** --width|-W N N character lines. DIFF_WIDTH_MASK
1867
+** --brief Show filenames only DIFF_BRIEF
1868
+** --context|-c N N lines of context. DIFF_CONTEXT_MASK
1869
+** --html Format for HTML DIFF_HTML
1870
+** --invert Invert the diff DIFF_INVERT
1871
+** --linenum|-n Show line numbers DIFF_LINENO
1872
+** --noopt Disable optimization DIFF_NOOPT
1873
+** --side-by-side|-y Side-by-side diff. DIFF_SIDEBYSIDE
1874
+** --strip-trailing-cr Strip trailing CR DIFF_STRIP_EOLCR
1875
+** --unified Unified diff. ~DIFF_SIDEBYSIDE
1876
+** --width|-W N N character lines. DIFF_WIDTH_MASK
1877
+** -w|--ignore-all-space Ignore all white space DIFF_IGNORE_ALLWS
1878
+** -Z|--ignore-trailing-space Ignore eol-whitespaces DIFF_IGNORE_EOLWS
18801879
*/
18811880
u64 diff_options(void){
18821881
u64 diffFlags = 0;
18831882
const char *z;
18841883
int f;
1884
+ if( find_option("strip-trailing-cr",0,0)!=0 ){
1885
+ diffFlags = DIFF_STRIP_EOLCR;
1886
+ }
1887
+ if( find_option("ignore-trailing-space","Z",0)!=0 ){
1888
+ diffFlags = DIFF_IGNORE_EOLWS; /* stronger than DIFF_STRIP_EOLCR */
1889
+ }
1890
+ if( find_option("ignore-all-space","w",0)!=0 ){
1891
+ diffFlags = DIFF_IGNORE_ALLWS; /* stronger than DIFF_IGNORE_EOLWS */
1892
+ }
18851893
if( find_option("side-by-side","y",0)!=0 ) diffFlags |= DIFF_SIDEBYSIDE;
18861894
if( find_option("unified",0,0)!=0 ) diffFlags &= ~DIFF_SIDEBYSIDE;
18871895
if( (z = find_option("context","c",1))!=0 && (f = atoi(z))>=0 ){
18881896
if( f > DIFF_CONTEXT_MASK ) f = DIFF_CONTEXT_MASK;
18891897
diffFlags |= f + DIFF_CONTEXT_EX;
@@ -1892,14 +1900,10 @@
18921900
f *= DIFF_CONTEXT_MASK+1;
18931901
if( f > DIFF_WIDTH_MASK ) f = DIFF_CONTEXT_MASK;
18941902
diffFlags |= f;
18951903
}
18961904
if( find_option("html",0,0)!=0 ) diffFlags |= DIFF_HTML;
1897
- if( find_option("ignore-space-at-sol",0,0)!=0 ) diffFlags |= DIFF_IGNORE_SOLWS;
1898
- if( find_option("ignore-space-at-eol",0,0)!=0 ) diffFlags |= DIFF_IGNORE_EOLWS;
1899
- if( find_option("strip-trailing-cr",0,0)!=0 ) diffFlags |= DIFF_STRIP_EOLCR;
1900
- if( find_option("w",0,0)!=0 ) diffFlags |= (DIFF_IGNORE_EOLWS|DIFF_IGNORE_SOLWS);
19011905
if( find_option("linenum","n",0)!=0 ) diffFlags |= DIFF_LINENO;
19021906
if( find_option("noopt",0,0)!=0 ) diffFlags |= DIFF_NOOPT;
19031907
if( find_option("invert",0,0)!=0 ) diffFlags |= DIFF_INVERT;
19041908
if( find_option("brief",0,0)!=0 ) diffFlags |= DIFF_BRIEF;
19051909
return diffFlags;
@@ -2001,16 +2005,16 @@
20012005
/*
20022006
** Initialize the annotation process by specifying the file that is
20032007
** to be annotated. The annotator takes control of the input Blob and
20042008
** will release it when it is finished with it.
20052009
*/
2006
-static int annotation_start(Annotator *p, Blob *pInput){
2010
+static int annotation_start(Annotator *p, Blob *pInput, u64 diffFlags){
20072011
int i;
20082012
20092013
memset(p, 0, sizeof(*p));
20102014
p->c.aTo = break_into_lines(blob_str(pInput), blob_size(pInput),&p->c.nTo,
2011
- 0);
2015
+ diffFlags);
20122016
if( p->c.aTo==0 ){
20132017
return 1;
20142018
}
20152019
p->aOrig = fossil_malloc( sizeof(p->aOrig[0])*p->c.nTo );
20162020
for(i=0; i<p->c.nTo; i++){
@@ -2028,17 +2032,17 @@
20282032
** being annotated. Do another step of the annotation. Return true
20292033
** if additional annotation is required. zPName is the tag to insert
20302034
** on each line of the file being annotated that was contributed by
20312035
** pParent. Memory to hold zPName is leaked.
20322036
*/
2033
-static int annotation_step(Annotator *p, Blob *pParent, int iVers){
2037
+static int annotation_step(Annotator *p, Blob *pParent, int iVers, u64 diffFlags){
20342038
int i, j;
20352039
int lnTo;
20362040
20372041
/* Prepare the parent file to be diffed */
20382042
p->c.aFrom = break_into_lines(blob_str(pParent), blob_size(pParent),
2039
- &p->c.nFrom, 0);
2043
+ &p->c.nFrom, diffFlags);
20402044
if( p->c.aFrom==0 ){
20412045
return 1;
20422046
}
20432047
20442048
/* Compute the differences going from pParent to the file being
@@ -2085,11 +2089,12 @@
20852089
static void annotate_file(
20862090
Annotator *p, /* The annotator */
20872091
int fnid, /* The name of the file to be annotated */
20882092
int mid, /* Use the version of the file in this check-in */
20892093
int iLimit, /* Limit the number of levels if greater than zero */
2090
- int annFlags /* Flags to alter the annotation */
2094
+ int annFlags, /* Flags to alter the annotation */
2095
+ u64 diffFlags /* Flags to alter the whitespace handling */
20912096
){
20922097
Blob toAnnotate; /* Text of the final (mid) version of the file */
20932098
Blob step; /* Text of previous revision */
20942099
int rid; /* Artifact ID of the file being annotated */
20952100
Stmt q; /* Query returning all ancestor versions */
@@ -2103,11 +2108,11 @@
21032108
}
21042109
if( !content_get(rid, &toAnnotate) ){
21052110
fossil_fatal("unable to retrieve content of artifact #%d", rid);
21062111
}
21072112
if( iLimit<=0 ) iLimit = 1000000000;
2108
- annotation_start(p, &toAnnotate);
2113
+ annotation_start(p, &toAnnotate, diffFlags);
21092114
db_begin_transaction();
21102115
db_multi_exec(
21112116
"CREATE TEMP TABLE IF NOT EXISTS vseen(rid INTEGER PRIMARY KEY);"
21122117
"DELETE FROM vseen;"
21132118
);
@@ -2137,11 +2142,11 @@
21372142
p->aVers[p->nVers].zMUuid = fossil_strdup(db_column_text(&q, 1));
21382143
p->aVers[p->nVers].zDate = fossil_strdup(db_column_text(&q, 2));
21392144
p->aVers[p->nVers].zUser = fossil_strdup(db_column_text(&q, 3));
21402145
if( p->nVers ){
21412146
content_get(rid, &step);
2142
- annotation_step(p, &step, p->nVers-1);
2147
+ annotation_step(p, &step, p->nVers-1, diffFlags);
21432148
blob_reset(&step);
21442149
}
21452150
p->nVers++;
21462151
db_bind_int(&ins, ":rid", rid);
21472152
db_step(&ins);
@@ -2177,10 +2182,11 @@
21772182
}
21782183
21792184
/*
21802185
** WEBPAGE: annotate
21812186
** WEBPAGE: blame
2187
+** WEBPAGE: praise
21822188
**
21832189
** Query parameters:
21842190
**
21852191
** checkin=ID The manifest ID at which to start the annotation
21862192
** filename=FILENAME The filename.
@@ -2193,17 +2199,19 @@
21932199
int fnid;
21942200
int i;
21952201
int iLimit; /* Depth limit */
21962202
int annFlags = ANN_FILE_ANCEST;
21972203
int showLog = 0; /* True to display the log */
2204
+ int ignoreWs = 0; /* Ignore whitespace */
2205
+ u64 diffFlags = DIFF_STRIP_EOLCR; /* diff flags for ignore whitespace */
21982206
const char *zFilename; /* Name of file to annotate */
21992207
const char *zCI; /* The check-in containing zFilename */
22002208
Annotator ann;
22012209
HQuery url;
22022210
struct AnnVers *p;
22032211
unsigned clr1, clr2, clr;
2204
- int bBlame = g.zPath[0]=='b';/* True for BLAME output. False for ANNOTATE. */
2212
+ int bBlame = g.zPath[0]!='a';/* True for BLAME output. False for ANNOTATE. */
22052213
22062214
/* Gather query parameters */
22072215
showLog = atoi(PD("log","1"));
22082216
login_check_credentials();
22092217
if( !g.perm.Read ){ login_needed(); return; }
@@ -2212,17 +2220,19 @@
22122220
zFilename = P("filename");
22132221
fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", zFilename);
22142222
if( mid==0 || fnid==0 ){ fossil_redirect_home(); }
22152223
iLimit = atoi(PD("limit","20"));
22162224
if( P("filevers") ) annFlags |= ANN_FILE_VERS;
2225
+ ignoreWs = P("w")!=0;
2226
+ if( ignoreWs ) diffFlags |= DIFF_IGNORE_ALLWS;
22172227
if( !db_exists("SELECT 1 FROM mlink WHERE mid=%d AND fnid=%d",mid,fnid) ){
22182228
fossil_redirect_home();
22192229
}
22202230
22212231
/* compute the annotation */
22222232
compute_direct_ancestors(mid, 10000000);
2223
- annotate_file(&ann, fnid, mid, iLimit, annFlags);
2233
+ annotate_file(&ann, fnid, mid, iLimit, annFlags, diffFlags);
22242234
zCI = ann.aVers[0].zMUuid;
22252235
22262236
/* generate the web page */
22272237
style_header("Annotation For %h", zFilename);
22282238
if( bBlame ){
@@ -2234,10 +2244,18 @@
22342244
url_add_parameter(&url, "filename", zFilename);
22352245
if( iLimit!=20 ){
22362246
url_add_parameter(&url, "limit", sqlite3_mprintf("%d", iLimit));
22372247
}
22382248
url_add_parameter(&url, "log", showLog ? "1" : "0");
2249
+ if( ignoreWs ){
2250
+ url_add_parameter(&url, "w", "");
2251
+ style_submenu_element("Show Whitespace Changes", "Show Whitespace Changes",
2252
+ "%s", url_render(&url, "w", 0, 0, 0));
2253
+ }else{
2254
+ style_submenu_element("Ignore Whitespace", "Ignore Whitespace",
2255
+ "%s", url_render(&url, "w", "", 0, 0));
2256
+ }
22392257
if( showLog ){
22402258
style_submenu_element("Hide Log", "Hide Log",
22412259
"%s", url_render(&url, "log", "0", 0, 0));
22422260
}else{
22432261
style_submenu_element("Show Log", "Show Log",
@@ -2347,22 +2365,25 @@
23472365
}
23482366
23492367
/*
23502368
** COMMAND: annotate
23512369
** COMMAND: blame
2370
+** COMMAND: praise
23522371
**
2353
-** %fossil (annotate|blame) ?OPTIONS? FILENAME
2372
+** %fossil (annotate|blame|praise) ?OPTIONS? FILENAME
23542373
**
23552374
** Output the text of a file with markings to show when each line of
23562375
** the file was last modified. The "annotate" command shows line numbers
2357
-** and omits the username. The "blame" command shows the user who made each
2358
-** checkin and omits the line number.
2376
+** and omits the username. The "blame" and "praise" commands show the user
2377
+** who made each checkin and omits the line number.
23592378
**
23602379
** Options:
2361
-** --filevers Show file version numbers rather than check-in versions
2362
-** -l|--log List all versions analyzed
2363
-** -n|--limit N Only look backwards in time by N versions
2380
+** --filevers Show file version numbers rather than check-in versions
2381
+** -l|--log List all versions analyzed
2382
+** -n|--limit N Only look backwards in time by N versions
2383
+** -w|--ignore-all-space Ignore white space when comparing lines
2384
+** -Z|--ignore-trailing-space Ignore whitespace at line end
23642385
**
23652386
** See also: info, finfo, timeline
23662387
*/
23672388
void annotate_cmd(void){
23682389
int fnid; /* Filename ID */
@@ -2374,19 +2395,22 @@
23742395
Annotator ann; /* The annotation of the file */
23752396
int i; /* Loop counter */
23762397
const char *zLimit; /* The value to the -n|--limit option */
23772398
int iLimit; /* How far back in time to look */
23782399
int showLog; /* True to show the log */
2400
+ u64 diffFlags = DIFF_STRIP_EOLCR;/* Flags to control whitespace handling */
23792401
int fileVers; /* Show file version instead of check-in versions */
23802402
int annFlags = 0; /* Flags to control annotation properties */
23812403
int bBlame = 0; /* True for BLAME output. False for ANNOTATE. */
23822404
2383
- bBlame = g.argv[1][0]=='b';
2405
+ bBlame = g.argv[1][0]!='a';
23842406
zLimit = find_option("limit","n",1);
23852407
if( zLimit==0 || zLimit[0]==0 ) zLimit = "-1";
23862408
iLimit = atoi(zLimit);
23872409
showLog = find_option("log","l",0)!=0;
2410
+ if( find_option("ignore-trailing-space","Z",0)!=0 ) diffFlags = DIFF_IGNORE_EOLWS;
2411
+ if( find_option("w",0,0)!=0 ) diffFlags |= DIFF_IGNORE_ALLWS;
23882412
fileVers = find_option("filevers",0,0)!=0;
23892413
db_must_be_within_tree();
23902414
if( g.argc<3 ) {
23912415
usage("FILENAME");
23922416
}
@@ -2412,11 +2436,11 @@
24122436
fid, fnid);
24132437
if( mid==0 ){
24142438
fossil_fatal("unable to find manifest");
24152439
}
24162440
annFlags |= ANN_FILE_ANCEST;
2417
- annotate_file(&ann, fnid, mid, iLimit, annFlags);
2441
+ annotate_file(&ann, fnid, mid, iLimit, annFlags, diffFlags);
24182442
if( showLog ){
24192443
struct AnnVers *p;
24202444
for(p=ann.aVers, i=0; i<ann.nVers; i++, p++){
24212445
fossil_print("version %3d: %s %.10s file %.10s\n",
24222446
i+1, p->zDate, p->zMUuid, p->zFUuid);
24232447
--- src/diff.c
+++ src/diff.c
@@ -28,12 +28,13 @@
28 ** Flag parameters to the text_diff() routine used to control the formatting
29 ** of the diff output.
30 */
31 #define DIFF_CONTEXT_MASK ((u64)0x0000ffff) /* Lines of context. Default if 0 */
32 #define DIFF_WIDTH_MASK ((u64)0x00ff0000) /* side-by-side column width */
33 #define DIFF_IGNORE_SOLWS ((u64)0x01000000) /* Ignore start-of-line whitespace */
34 #define DIFF_IGNORE_EOLWS ((u64)0x02000000) /* Ignore end-of-line whitespace */
 
35 #define DIFF_SIDEBYSIDE ((u64)0x04000000) /* Generate a side-by-side diff */
36 #define DIFF_VERBOSE ((u64)0x08000000) /* Missing shown as empty files */
37 #define DIFF_INLINE ((u64)0x00000000) /* Inline (not side-by-side) diff */
38 #define DIFF_BRIEF ((u64)0x10000000) /* Show filenames only */
39 #define DIFF_HTML ((u64)0x20000000) /* Render for HTML */
@@ -40,11 +41,10 @@
40 #define DIFF_LINENO ((u64)0x40000000) /* Show line numbers */
41 #define DIFF_NOOPT (((u64)0x01)<<32) /* Suppress optimizations (debug) */
42 #define DIFF_INVERT (((u64)0x02)<<32) /* Invert the diff (debug) */
43 #define DIFF_CONTEXT_EX (((u64)0x04)<<32) /* Use context even if zero */
44 #define DIFF_NOTTOOBIG (((u64)0x08)<<32) /* Only display if not too big */
45 #define DIFF_STRIP_EOLCR (((u64)0x10)<<32) /* Strip trailing CR */
46
47 /*
48 ** These error messages are shared in multiple locations. They are defined
49 ** here for consistency.
50 */
@@ -172,11 +172,11 @@
172 if( diffFlags & DIFF_IGNORE_EOLWS ){
173 while( k>0 && fossil_isspace(z[k-1]) ){ k--; }
174 }else if( diffFlags & DIFF_STRIP_EOLCR ){
175 if( k>0 && z[k-1]=='\r' ){ k--; }
176 }
177 if( diffFlags & DIFF_IGNORE_SOLWS ){
178 while( s<k && fossil_isspace(z[s]) ){
179 if( z[s]=='\t' ){
180 indent = ((indent+9)/8)*8;
181 }else if( z[s]==' ' ){
182 indent++;
@@ -1792,11 +1792,11 @@
1792 if( diffFlags & DIFF_INVERT ){
1793 Blob *pTemp = pA_Blob;
1794 pA_Blob = pB_Blob;
1795 pB_Blob = pTemp;
1796 }
1797 ignoreWs = (diffFlags & (DIFF_IGNORE_SOLWS|DIFF_IGNORE_EOLWS))!=0;
1798 blob_to_utf8_no_bom(pA_Blob, 0);
1799 blob_to_utf8_no_bom(pB_Blob, 0);
1800
1801 /* Prepare the input files */
1802 memset(&c, 0, sizeof(c));
@@ -1862,28 +1862,36 @@
1862
1863 /*
1864 ** Process diff-related command-line options and return an appropriate
1865 ** "diffFlags" integer.
1866 **
1867 ** --brief Show filenames only DIFF_BRIEF
1868 ** --context|-c N N lines of context. DIFF_CONTEXT_MASK
1869 ** --html Format for HTML DIFF_HTML
1870 ** --invert Invert the diff DIFF_INVERT
1871 ** --ignore-space-at-eol Ignore eol-whitespaces DIFF_IGNORE_EOLWS
1872 ** --ignore-space-at-sol Ignore sol-whitespaces DIFF_IGNORE_SOLWS
1873 ** --linenum|-n Show line numbers DIFF_LINENO
1874 ** --noopt Disable optimization DIFF_NOOPT
1875 ** --side-by-side|-y Side-by-side diff. DIFF_SIDEBYSIDE
1876 ** --strip-trailing-cr Strip trailing CR DIFF_IGNORE_EOLCR
1877 ** --unified Unified diff. ~DIFF_SIDEBYSIDE
1878 ** -w Ignore all whitespaces DIFF_IGNORE_EOLWS|DIFF_IGNORE_SOLWS
1879 ** --width|-W N N character lines. DIFF_WIDTH_MASK
1880 */
1881 u64 diff_options(void){
1882 u64 diffFlags = 0;
1883 const char *z;
1884 int f;
 
 
 
 
 
 
 
 
 
1885 if( find_option("side-by-side","y",0)!=0 ) diffFlags |= DIFF_SIDEBYSIDE;
1886 if( find_option("unified",0,0)!=0 ) diffFlags &= ~DIFF_SIDEBYSIDE;
1887 if( (z = find_option("context","c",1))!=0 && (f = atoi(z))>=0 ){
1888 if( f > DIFF_CONTEXT_MASK ) f = DIFF_CONTEXT_MASK;
1889 diffFlags |= f + DIFF_CONTEXT_EX;
@@ -1892,14 +1900,10 @@
1892 f *= DIFF_CONTEXT_MASK+1;
1893 if( f > DIFF_WIDTH_MASK ) f = DIFF_CONTEXT_MASK;
1894 diffFlags |= f;
1895 }
1896 if( find_option("html",0,0)!=0 ) diffFlags |= DIFF_HTML;
1897 if( find_option("ignore-space-at-sol",0,0)!=0 ) diffFlags |= DIFF_IGNORE_SOLWS;
1898 if( find_option("ignore-space-at-eol",0,0)!=0 ) diffFlags |= DIFF_IGNORE_EOLWS;
1899 if( find_option("strip-trailing-cr",0,0)!=0 ) diffFlags |= DIFF_STRIP_EOLCR;
1900 if( find_option("w",0,0)!=0 ) diffFlags |= (DIFF_IGNORE_EOLWS|DIFF_IGNORE_SOLWS);
1901 if( find_option("linenum","n",0)!=0 ) diffFlags |= DIFF_LINENO;
1902 if( find_option("noopt",0,0)!=0 ) diffFlags |= DIFF_NOOPT;
1903 if( find_option("invert",0,0)!=0 ) diffFlags |= DIFF_INVERT;
1904 if( find_option("brief",0,0)!=0 ) diffFlags |= DIFF_BRIEF;
1905 return diffFlags;
@@ -2001,16 +2005,16 @@
2001 /*
2002 ** Initialize the annotation process by specifying the file that is
2003 ** to be annotated. The annotator takes control of the input Blob and
2004 ** will release it when it is finished with it.
2005 */
2006 static int annotation_start(Annotator *p, Blob *pInput){
2007 int i;
2008
2009 memset(p, 0, sizeof(*p));
2010 p->c.aTo = break_into_lines(blob_str(pInput), blob_size(pInput),&p->c.nTo,
2011 0);
2012 if( p->c.aTo==0 ){
2013 return 1;
2014 }
2015 p->aOrig = fossil_malloc( sizeof(p->aOrig[0])*p->c.nTo );
2016 for(i=0; i<p->c.nTo; i++){
@@ -2028,17 +2032,17 @@
2028 ** being annotated. Do another step of the annotation. Return true
2029 ** if additional annotation is required. zPName is the tag to insert
2030 ** on each line of the file being annotated that was contributed by
2031 ** pParent. Memory to hold zPName is leaked.
2032 */
2033 static int annotation_step(Annotator *p, Blob *pParent, int iVers){
2034 int i, j;
2035 int lnTo;
2036
2037 /* Prepare the parent file to be diffed */
2038 p->c.aFrom = break_into_lines(blob_str(pParent), blob_size(pParent),
2039 &p->c.nFrom, 0);
2040 if( p->c.aFrom==0 ){
2041 return 1;
2042 }
2043
2044 /* Compute the differences going from pParent to the file being
@@ -2085,11 +2089,12 @@
2085 static void annotate_file(
2086 Annotator *p, /* The annotator */
2087 int fnid, /* The name of the file to be annotated */
2088 int mid, /* Use the version of the file in this check-in */
2089 int iLimit, /* Limit the number of levels if greater than zero */
2090 int annFlags /* Flags to alter the annotation */
 
2091 ){
2092 Blob toAnnotate; /* Text of the final (mid) version of the file */
2093 Blob step; /* Text of previous revision */
2094 int rid; /* Artifact ID of the file being annotated */
2095 Stmt q; /* Query returning all ancestor versions */
@@ -2103,11 +2108,11 @@
2103 }
2104 if( !content_get(rid, &toAnnotate) ){
2105 fossil_fatal("unable to retrieve content of artifact #%d", rid);
2106 }
2107 if( iLimit<=0 ) iLimit = 1000000000;
2108 annotation_start(p, &toAnnotate);
2109 db_begin_transaction();
2110 db_multi_exec(
2111 "CREATE TEMP TABLE IF NOT EXISTS vseen(rid INTEGER PRIMARY KEY);"
2112 "DELETE FROM vseen;"
2113 );
@@ -2137,11 +2142,11 @@
2137 p->aVers[p->nVers].zMUuid = fossil_strdup(db_column_text(&q, 1));
2138 p->aVers[p->nVers].zDate = fossil_strdup(db_column_text(&q, 2));
2139 p->aVers[p->nVers].zUser = fossil_strdup(db_column_text(&q, 3));
2140 if( p->nVers ){
2141 content_get(rid, &step);
2142 annotation_step(p, &step, p->nVers-1);
2143 blob_reset(&step);
2144 }
2145 p->nVers++;
2146 db_bind_int(&ins, ":rid", rid);
2147 db_step(&ins);
@@ -2177,10 +2182,11 @@
2177 }
2178
2179 /*
2180 ** WEBPAGE: annotate
2181 ** WEBPAGE: blame
 
2182 **
2183 ** Query parameters:
2184 **
2185 ** checkin=ID The manifest ID at which to start the annotation
2186 ** filename=FILENAME The filename.
@@ -2193,17 +2199,19 @@
2193 int fnid;
2194 int i;
2195 int iLimit; /* Depth limit */
2196 int annFlags = ANN_FILE_ANCEST;
2197 int showLog = 0; /* True to display the log */
 
 
2198 const char *zFilename; /* Name of file to annotate */
2199 const char *zCI; /* The check-in containing zFilename */
2200 Annotator ann;
2201 HQuery url;
2202 struct AnnVers *p;
2203 unsigned clr1, clr2, clr;
2204 int bBlame = g.zPath[0]=='b';/* True for BLAME output. False for ANNOTATE. */
2205
2206 /* Gather query parameters */
2207 showLog = atoi(PD("log","1"));
2208 login_check_credentials();
2209 if( !g.perm.Read ){ login_needed(); return; }
@@ -2212,17 +2220,19 @@
2212 zFilename = P("filename");
2213 fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", zFilename);
2214 if( mid==0 || fnid==0 ){ fossil_redirect_home(); }
2215 iLimit = atoi(PD("limit","20"));
2216 if( P("filevers") ) annFlags |= ANN_FILE_VERS;
 
 
2217 if( !db_exists("SELECT 1 FROM mlink WHERE mid=%d AND fnid=%d",mid,fnid) ){
2218 fossil_redirect_home();
2219 }
2220
2221 /* compute the annotation */
2222 compute_direct_ancestors(mid, 10000000);
2223 annotate_file(&ann, fnid, mid, iLimit, annFlags);
2224 zCI = ann.aVers[0].zMUuid;
2225
2226 /* generate the web page */
2227 style_header("Annotation For %h", zFilename);
2228 if( bBlame ){
@@ -2234,10 +2244,18 @@
2234 url_add_parameter(&url, "filename", zFilename);
2235 if( iLimit!=20 ){
2236 url_add_parameter(&url, "limit", sqlite3_mprintf("%d", iLimit));
2237 }
2238 url_add_parameter(&url, "log", showLog ? "1" : "0");
 
 
 
 
 
 
 
 
2239 if( showLog ){
2240 style_submenu_element("Hide Log", "Hide Log",
2241 "%s", url_render(&url, "log", "0", 0, 0));
2242 }else{
2243 style_submenu_element("Show Log", "Show Log",
@@ -2347,22 +2365,25 @@
2347 }
2348
2349 /*
2350 ** COMMAND: annotate
2351 ** COMMAND: blame
 
2352 **
2353 ** %fossil (annotate|blame) ?OPTIONS? FILENAME
2354 **
2355 ** Output the text of a file with markings to show when each line of
2356 ** the file was last modified. The "annotate" command shows line numbers
2357 ** and omits the username. The "blame" command shows the user who made each
2358 ** checkin and omits the line number.
2359 **
2360 ** Options:
2361 ** --filevers Show file version numbers rather than check-in versions
2362 ** -l|--log List all versions analyzed
2363 ** -n|--limit N Only look backwards in time by N versions
 
 
2364 **
2365 ** See also: info, finfo, timeline
2366 */
2367 void annotate_cmd(void){
2368 int fnid; /* Filename ID */
@@ -2374,19 +2395,22 @@
2374 Annotator ann; /* The annotation of the file */
2375 int i; /* Loop counter */
2376 const char *zLimit; /* The value to the -n|--limit option */
2377 int iLimit; /* How far back in time to look */
2378 int showLog; /* True to show the log */
 
2379 int fileVers; /* Show file version instead of check-in versions */
2380 int annFlags = 0; /* Flags to control annotation properties */
2381 int bBlame = 0; /* True for BLAME output. False for ANNOTATE. */
2382
2383 bBlame = g.argv[1][0]=='b';
2384 zLimit = find_option("limit","n",1);
2385 if( zLimit==0 || zLimit[0]==0 ) zLimit = "-1";
2386 iLimit = atoi(zLimit);
2387 showLog = find_option("log","l",0)!=0;
 
 
2388 fileVers = find_option("filevers",0,0)!=0;
2389 db_must_be_within_tree();
2390 if( g.argc<3 ) {
2391 usage("FILENAME");
2392 }
@@ -2412,11 +2436,11 @@
2412 fid, fnid);
2413 if( mid==0 ){
2414 fossil_fatal("unable to find manifest");
2415 }
2416 annFlags |= ANN_FILE_ANCEST;
2417 annotate_file(&ann, fnid, mid, iLimit, annFlags);
2418 if( showLog ){
2419 struct AnnVers *p;
2420 for(p=ann.aVers, i=0; i<ann.nVers; i++, p++){
2421 fossil_print("version %3d: %s %.10s file %.10s\n",
2422 i+1, p->zDate, p->zMUuid, p->zFUuid);
2423
--- src/diff.c
+++ src/diff.c
@@ -28,12 +28,13 @@
28 ** Flag parameters to the text_diff() routine used to control the formatting
29 ** of the diff output.
30 */
31 #define DIFF_CONTEXT_MASK ((u64)0x0000ffff) /* Lines of context. Default if 0 */
32 #define DIFF_WIDTH_MASK ((u64)0x00ff0000) /* side-by-side column width */
33 #define DIFF_STRIP_EOLCR ((u64)0x01000000) /* Strip trailing CR */
34 #define DIFF_IGNORE_EOLWS ((u64)0x02000000) /* Ignore end-of-line whitespace */
35 #define DIFF_IGNORE_ALLWS ((u64)0x03000000) /* Ignore all whitespace */
36 #define DIFF_SIDEBYSIDE ((u64)0x04000000) /* Generate a side-by-side diff */
37 #define DIFF_VERBOSE ((u64)0x08000000) /* Missing shown as empty files */
38 #define DIFF_INLINE ((u64)0x00000000) /* Inline (not side-by-side) diff */
39 #define DIFF_BRIEF ((u64)0x10000000) /* Show filenames only */
40 #define DIFF_HTML ((u64)0x20000000) /* Render for HTML */
@@ -40,11 +41,10 @@
41 #define DIFF_LINENO ((u64)0x40000000) /* Show line numbers */
42 #define DIFF_NOOPT (((u64)0x01)<<32) /* Suppress optimizations (debug) */
43 #define DIFF_INVERT (((u64)0x02)<<32) /* Invert the diff (debug) */
44 #define DIFF_CONTEXT_EX (((u64)0x04)<<32) /* Use context even if zero */
45 #define DIFF_NOTTOOBIG (((u64)0x08)<<32) /* Only display if not too big */
 
46
47 /*
48 ** These error messages are shared in multiple locations. They are defined
49 ** here for consistency.
50 */
@@ -172,11 +172,11 @@
172 if( diffFlags & DIFF_IGNORE_EOLWS ){
173 while( k>0 && fossil_isspace(z[k-1]) ){ k--; }
174 }else if( diffFlags & DIFF_STRIP_EOLCR ){
175 if( k>0 && z[k-1]=='\r' ){ k--; }
176 }
177 if( (diffFlags & DIFF_IGNORE_ALLWS)==DIFF_IGNORE_ALLWS ){
178 while( s<k && fossil_isspace(z[s]) ){
179 if( z[s]=='\t' ){
180 indent = ((indent+9)/8)*8;
181 }else if( z[s]==' ' ){
182 indent++;
@@ -1792,11 +1792,11 @@
1792 if( diffFlags & DIFF_INVERT ){
1793 Blob *pTemp = pA_Blob;
1794 pA_Blob = pB_Blob;
1795 pB_Blob = pTemp;
1796 }
1797 ignoreWs = (diffFlags & DIFF_IGNORE_EOLWS)!=0;
1798 blob_to_utf8_no_bom(pA_Blob, 0);
1799 blob_to_utf8_no_bom(pB_Blob, 0);
1800
1801 /* Prepare the input files */
1802 memset(&c, 0, sizeof(c));
@@ -1862,28 +1862,36 @@
1862
1863 /*
1864 ** Process diff-related command-line options and return an appropriate
1865 ** "diffFlags" integer.
1866 **
1867 ** --brief Show filenames only DIFF_BRIEF
1868 ** --context|-c N N lines of context. DIFF_CONTEXT_MASK
1869 ** --html Format for HTML DIFF_HTML
1870 ** --invert Invert the diff DIFF_INVERT
1871 ** --linenum|-n Show line numbers DIFF_LINENO
1872 ** --noopt Disable optimization DIFF_NOOPT
1873 ** --side-by-side|-y Side-by-side diff. DIFF_SIDEBYSIDE
1874 ** --strip-trailing-cr Strip trailing CR DIFF_STRIP_EOLCR
1875 ** --unified Unified diff. ~DIFF_SIDEBYSIDE
1876 ** --width|-W N N character lines. DIFF_WIDTH_MASK
1877 ** -w|--ignore-all-space Ignore all white space DIFF_IGNORE_ALLWS
1878 ** -Z|--ignore-trailing-space Ignore eol-whitespaces DIFF_IGNORE_EOLWS
 
1879 */
1880 u64 diff_options(void){
1881 u64 diffFlags = 0;
1882 const char *z;
1883 int f;
1884 if( find_option("strip-trailing-cr",0,0)!=0 ){
1885 diffFlags = DIFF_STRIP_EOLCR;
1886 }
1887 if( find_option("ignore-trailing-space","Z",0)!=0 ){
1888 diffFlags = DIFF_IGNORE_EOLWS; /* stronger than DIFF_STRIP_EOLCR */
1889 }
1890 if( find_option("ignore-all-space","w",0)!=0 ){
1891 diffFlags = DIFF_IGNORE_ALLWS; /* stronger than DIFF_IGNORE_EOLWS */
1892 }
1893 if( find_option("side-by-side","y",0)!=0 ) diffFlags |= DIFF_SIDEBYSIDE;
1894 if( find_option("unified",0,0)!=0 ) diffFlags &= ~DIFF_SIDEBYSIDE;
1895 if( (z = find_option("context","c",1))!=0 && (f = atoi(z))>=0 ){
1896 if( f > DIFF_CONTEXT_MASK ) f = DIFF_CONTEXT_MASK;
1897 diffFlags |= f + DIFF_CONTEXT_EX;
@@ -1892,14 +1900,10 @@
1900 f *= DIFF_CONTEXT_MASK+1;
1901 if( f > DIFF_WIDTH_MASK ) f = DIFF_CONTEXT_MASK;
1902 diffFlags |= f;
1903 }
1904 if( find_option("html",0,0)!=0 ) diffFlags |= DIFF_HTML;
 
 
 
 
1905 if( find_option("linenum","n",0)!=0 ) diffFlags |= DIFF_LINENO;
1906 if( find_option("noopt",0,0)!=0 ) diffFlags |= DIFF_NOOPT;
1907 if( find_option("invert",0,0)!=0 ) diffFlags |= DIFF_INVERT;
1908 if( find_option("brief",0,0)!=0 ) diffFlags |= DIFF_BRIEF;
1909 return diffFlags;
@@ -2001,16 +2005,16 @@
2005 /*
2006 ** Initialize the annotation process by specifying the file that is
2007 ** to be annotated. The annotator takes control of the input Blob and
2008 ** will release it when it is finished with it.
2009 */
2010 static int annotation_start(Annotator *p, Blob *pInput, u64 diffFlags){
2011 int i;
2012
2013 memset(p, 0, sizeof(*p));
2014 p->c.aTo = break_into_lines(blob_str(pInput), blob_size(pInput),&p->c.nTo,
2015 diffFlags);
2016 if( p->c.aTo==0 ){
2017 return 1;
2018 }
2019 p->aOrig = fossil_malloc( sizeof(p->aOrig[0])*p->c.nTo );
2020 for(i=0; i<p->c.nTo; i++){
@@ -2028,17 +2032,17 @@
2032 ** being annotated. Do another step of the annotation. Return true
2033 ** if additional annotation is required. zPName is the tag to insert
2034 ** on each line of the file being annotated that was contributed by
2035 ** pParent. Memory to hold zPName is leaked.
2036 */
2037 static int annotation_step(Annotator *p, Blob *pParent, int iVers, u64 diffFlags){
2038 int i, j;
2039 int lnTo;
2040
2041 /* Prepare the parent file to be diffed */
2042 p->c.aFrom = break_into_lines(blob_str(pParent), blob_size(pParent),
2043 &p->c.nFrom, diffFlags);
2044 if( p->c.aFrom==0 ){
2045 return 1;
2046 }
2047
2048 /* Compute the differences going from pParent to the file being
@@ -2085,11 +2089,12 @@
2089 static void annotate_file(
2090 Annotator *p, /* The annotator */
2091 int fnid, /* The name of the file to be annotated */
2092 int mid, /* Use the version of the file in this check-in */
2093 int iLimit, /* Limit the number of levels if greater than zero */
2094 int annFlags, /* Flags to alter the annotation */
2095 u64 diffFlags /* Flags to alter the whitespace handling */
2096 ){
2097 Blob toAnnotate; /* Text of the final (mid) version of the file */
2098 Blob step; /* Text of previous revision */
2099 int rid; /* Artifact ID of the file being annotated */
2100 Stmt q; /* Query returning all ancestor versions */
@@ -2103,11 +2108,11 @@
2108 }
2109 if( !content_get(rid, &toAnnotate) ){
2110 fossil_fatal("unable to retrieve content of artifact #%d", rid);
2111 }
2112 if( iLimit<=0 ) iLimit = 1000000000;
2113 annotation_start(p, &toAnnotate, diffFlags);
2114 db_begin_transaction();
2115 db_multi_exec(
2116 "CREATE TEMP TABLE IF NOT EXISTS vseen(rid INTEGER PRIMARY KEY);"
2117 "DELETE FROM vseen;"
2118 );
@@ -2137,11 +2142,11 @@
2142 p->aVers[p->nVers].zMUuid = fossil_strdup(db_column_text(&q, 1));
2143 p->aVers[p->nVers].zDate = fossil_strdup(db_column_text(&q, 2));
2144 p->aVers[p->nVers].zUser = fossil_strdup(db_column_text(&q, 3));
2145 if( p->nVers ){
2146 content_get(rid, &step);
2147 annotation_step(p, &step, p->nVers-1, diffFlags);
2148 blob_reset(&step);
2149 }
2150 p->nVers++;
2151 db_bind_int(&ins, ":rid", rid);
2152 db_step(&ins);
@@ -2177,10 +2182,11 @@
2182 }
2183
2184 /*
2185 ** WEBPAGE: annotate
2186 ** WEBPAGE: blame
2187 ** WEBPAGE: praise
2188 **
2189 ** Query parameters:
2190 **
2191 ** checkin=ID The manifest ID at which to start the annotation
2192 ** filename=FILENAME The filename.
@@ -2193,17 +2199,19 @@
2199 int fnid;
2200 int i;
2201 int iLimit; /* Depth limit */
2202 int annFlags = ANN_FILE_ANCEST;
2203 int showLog = 0; /* True to display the log */
2204 int ignoreWs = 0; /* Ignore whitespace */
2205 u64 diffFlags = DIFF_STRIP_EOLCR; /* diff flags for ignore whitespace */
2206 const char *zFilename; /* Name of file to annotate */
2207 const char *zCI; /* The check-in containing zFilename */
2208 Annotator ann;
2209 HQuery url;
2210 struct AnnVers *p;
2211 unsigned clr1, clr2, clr;
2212 int bBlame = g.zPath[0]!='a';/* True for BLAME output. False for ANNOTATE. */
2213
2214 /* Gather query parameters */
2215 showLog = atoi(PD("log","1"));
2216 login_check_credentials();
2217 if( !g.perm.Read ){ login_needed(); return; }
@@ -2212,17 +2220,19 @@
2220 zFilename = P("filename");
2221 fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", zFilename);
2222 if( mid==0 || fnid==0 ){ fossil_redirect_home(); }
2223 iLimit = atoi(PD("limit","20"));
2224 if( P("filevers") ) annFlags |= ANN_FILE_VERS;
2225 ignoreWs = P("w")!=0;
2226 if( ignoreWs ) diffFlags |= DIFF_IGNORE_ALLWS;
2227 if( !db_exists("SELECT 1 FROM mlink WHERE mid=%d AND fnid=%d",mid,fnid) ){
2228 fossil_redirect_home();
2229 }
2230
2231 /* compute the annotation */
2232 compute_direct_ancestors(mid, 10000000);
2233 annotate_file(&ann, fnid, mid, iLimit, annFlags, diffFlags);
2234 zCI = ann.aVers[0].zMUuid;
2235
2236 /* generate the web page */
2237 style_header("Annotation For %h", zFilename);
2238 if( bBlame ){
@@ -2234,10 +2244,18 @@
2244 url_add_parameter(&url, "filename", zFilename);
2245 if( iLimit!=20 ){
2246 url_add_parameter(&url, "limit", sqlite3_mprintf("%d", iLimit));
2247 }
2248 url_add_parameter(&url, "log", showLog ? "1" : "0");
2249 if( ignoreWs ){
2250 url_add_parameter(&url, "w", "");
2251 style_submenu_element("Show Whitespace Changes", "Show Whitespace Changes",
2252 "%s", url_render(&url, "w", 0, 0, 0));
2253 }else{
2254 style_submenu_element("Ignore Whitespace", "Ignore Whitespace",
2255 "%s", url_render(&url, "w", "", 0, 0));
2256 }
2257 if( showLog ){
2258 style_submenu_element("Hide Log", "Hide Log",
2259 "%s", url_render(&url, "log", "0", 0, 0));
2260 }else{
2261 style_submenu_element("Show Log", "Show Log",
@@ -2347,22 +2365,25 @@
2365 }
2366
2367 /*
2368 ** COMMAND: annotate
2369 ** COMMAND: blame
2370 ** COMMAND: praise
2371 **
2372 ** %fossil (annotate|blame|praise) ?OPTIONS? FILENAME
2373 **
2374 ** Output the text of a file with markings to show when each line of
2375 ** the file was last modified. The "annotate" command shows line numbers
2376 ** and omits the username. The "blame" and "praise" commands show the user
2377 ** who made each checkin and omits the line number.
2378 **
2379 ** Options:
2380 ** --filevers Show file version numbers rather than check-in versions
2381 ** -l|--log List all versions analyzed
2382 ** -n|--limit N Only look backwards in time by N versions
2383 ** -w|--ignore-all-space Ignore white space when comparing lines
2384 ** -Z|--ignore-trailing-space Ignore whitespace at line end
2385 **
2386 ** See also: info, finfo, timeline
2387 */
2388 void annotate_cmd(void){
2389 int fnid; /* Filename ID */
@@ -2374,19 +2395,22 @@
2395 Annotator ann; /* The annotation of the file */
2396 int i; /* Loop counter */
2397 const char *zLimit; /* The value to the -n|--limit option */
2398 int iLimit; /* How far back in time to look */
2399 int showLog; /* True to show the log */
2400 u64 diffFlags = DIFF_STRIP_EOLCR;/* Flags to control whitespace handling */
2401 int fileVers; /* Show file version instead of check-in versions */
2402 int annFlags = 0; /* Flags to control annotation properties */
2403 int bBlame = 0; /* True for BLAME output. False for ANNOTATE. */
2404
2405 bBlame = g.argv[1][0]!='a';
2406 zLimit = find_option("limit","n",1);
2407 if( zLimit==0 || zLimit[0]==0 ) zLimit = "-1";
2408 iLimit = atoi(zLimit);
2409 showLog = find_option("log","l",0)!=0;
2410 if( find_option("ignore-trailing-space","Z",0)!=0 ) diffFlags = DIFF_IGNORE_EOLWS;
2411 if( find_option("w",0,0)!=0 ) diffFlags |= DIFF_IGNORE_ALLWS;
2412 fileVers = find_option("filevers",0,0)!=0;
2413 db_must_be_within_tree();
2414 if( g.argc<3 ) {
2415 usage("FILENAME");
2416 }
@@ -2412,11 +2436,11 @@
2436 fid, fnid);
2437 if( mid==0 ){
2438 fossil_fatal("unable to find manifest");
2439 }
2440 annFlags |= ANN_FILE_ANCEST;
2441 annotate_file(&ann, fnid, mid, iLimit, annFlags, diffFlags);
2442 if( showLog ){
2443 struct AnnVers *p;
2444 for(p=ann.aVers, i=0; i<ann.nVers; i++, p++){
2445 fossil_print("version %3d: %s %.10s file %.10s\n",
2446 i+1, p->zDate, p->zMUuid, p->zFUuid);
2447
+62 -38
--- src/diff.c
+++ src/diff.c
@@ -28,12 +28,13 @@
2828
** Flag parameters to the text_diff() routine used to control the formatting
2929
** of the diff output.
3030
*/
3131
#define DIFF_CONTEXT_MASK ((u64)0x0000ffff) /* Lines of context. Default if 0 */
3232
#define DIFF_WIDTH_MASK ((u64)0x00ff0000) /* side-by-side column width */
33
-#define DIFF_IGNORE_SOLWS ((u64)0x01000000) /* Ignore start-of-line whitespace */
33
+#define DIFF_STRIP_EOLCR ((u64)0x01000000) /* Strip trailing CR */
3434
#define DIFF_IGNORE_EOLWS ((u64)0x02000000) /* Ignore end-of-line whitespace */
35
+#define DIFF_IGNORE_ALLWS ((u64)0x03000000) /* Ignore all whitespace */
3536
#define DIFF_SIDEBYSIDE ((u64)0x04000000) /* Generate a side-by-side diff */
3637
#define DIFF_VERBOSE ((u64)0x08000000) /* Missing shown as empty files */
3738
#define DIFF_INLINE ((u64)0x00000000) /* Inline (not side-by-side) diff */
3839
#define DIFF_BRIEF ((u64)0x10000000) /* Show filenames only */
3940
#define DIFF_HTML ((u64)0x20000000) /* Render for HTML */
@@ -40,11 +41,10 @@
4041
#define DIFF_LINENO ((u64)0x40000000) /* Show line numbers */
4142
#define DIFF_NOOPT (((u64)0x01)<<32) /* Suppress optimizations (debug) */
4243
#define DIFF_INVERT (((u64)0x02)<<32) /* Invert the diff (debug) */
4344
#define DIFF_CONTEXT_EX (((u64)0x04)<<32) /* Use context even if zero */
4445
#define DIFF_NOTTOOBIG (((u64)0x08)<<32) /* Only display if not too big */
45
-#define DIFF_STRIP_EOLCR (((u64)0x10)<<32) /* Strip trailing CR */
4646
4747
/*
4848
** These error messages are shared in multiple locations. They are defined
4949
** here for consistency.
5050
*/
@@ -172,11 +172,11 @@
172172
if( diffFlags & DIFF_IGNORE_EOLWS ){
173173
while( k>0 && fossil_isspace(z[k-1]) ){ k--; }
174174
}else if( diffFlags & DIFF_STRIP_EOLCR ){
175175
if( k>0 && z[k-1]=='\r' ){ k--; }
176176
}
177
- if( diffFlags & DIFF_IGNORE_SOLWS ){
177
+ if( (diffFlags & DIFF_IGNORE_ALLWS)==DIFF_IGNORE_ALLWS ){
178178
while( s<k && fossil_isspace(z[s]) ){
179179
if( z[s]=='\t' ){
180180
indent = ((indent+9)/8)*8;
181181
}else if( z[s]==' ' ){
182182
indent++;
@@ -1792,11 +1792,11 @@
17921792
if( diffFlags & DIFF_INVERT ){
17931793
Blob *pTemp = pA_Blob;
17941794
pA_Blob = pB_Blob;
17951795
pB_Blob = pTemp;
17961796
}
1797
- ignoreWs = (diffFlags & (DIFF_IGNORE_SOLWS|DIFF_IGNORE_EOLWS))!=0;
1797
+ ignoreWs = (diffFlags & DIFF_IGNORE_EOLWS)!=0;
17981798
blob_to_utf8_no_bom(pA_Blob, 0);
17991799
blob_to_utf8_no_bom(pB_Blob, 0);
18001800
18011801
/* Prepare the input files */
18021802
memset(&c, 0, sizeof(c));
@@ -1862,28 +1862,36 @@
18621862
18631863
/*
18641864
** Process diff-related command-line options and return an appropriate
18651865
** "diffFlags" integer.
18661866
**
1867
-** --brief Show filenames only DIFF_BRIEF
1868
-** --context|-c N N lines of context. DIFF_CONTEXT_MASK
1869
-** --html Format for HTML DIFF_HTML
1870
-** --invert Invert the diff DIFF_INVERT
1871
-** --ignore-space-at-eol Ignore eol-whitespaces DIFF_IGNORE_EOLWS
1872
-** --ignore-space-at-sol Ignore sol-whitespaces DIFF_IGNORE_SOLWS
1873
-** --linenum|-n Show line numbers DIFF_LINENO
1874
-** --noopt Disable optimization DIFF_NOOPT
1875
-** --side-by-side|-y Side-by-side diff. DIFF_SIDEBYSIDE
1876
-** --strip-trailing-cr Strip trailing CR DIFF_IGNORE_EOLCR
1877
-** --unified Unified diff. ~DIFF_SIDEBYSIDE
1878
-** -w Ignore all whitespaces DIFF_IGNORE_EOLWS|DIFF_IGNORE_SOLWS
1879
-** --width|-W N N character lines. DIFF_WIDTH_MASK
1867
+** --brief Show filenames only DIFF_BRIEF
1868
+** --context|-c N N lines of context. DIFF_CONTEXT_MASK
1869
+** --html Format for HTML DIFF_HTML
1870
+** --invert Invert the diff DIFF_INVERT
1871
+** --linenum|-n Show line numbers DIFF_LINENO
1872
+** --noopt Disable optimization DIFF_NOOPT
1873
+** --side-by-side|-y Side-by-side diff. DIFF_SIDEBYSIDE
1874
+** --strip-trailing-cr Strip trailing CR DIFF_STRIP_EOLCR
1875
+** --unified Unified diff. ~DIFF_SIDEBYSIDE
1876
+** --width|-W N N character lines. DIFF_WIDTH_MASK
1877
+** -w|--ignore-all-space Ignore all white space DIFF_IGNORE_ALLWS
1878
+** -Z|--ignore-trailing-space Ignore eol-whitespaces DIFF_IGNORE_EOLWS
18801879
*/
18811880
u64 diff_options(void){
18821881
u64 diffFlags = 0;
18831882
const char *z;
18841883
int f;
1884
+ if( find_option("strip-trailing-cr",0,0)!=0 ){
1885
+ diffFlags = DIFF_STRIP_EOLCR;
1886
+ }
1887
+ if( find_option("ignore-trailing-space","Z",0)!=0 ){
1888
+ diffFlags = DIFF_IGNORE_EOLWS; /* stronger than DIFF_STRIP_EOLCR */
1889
+ }
1890
+ if( find_option("ignore-all-space","w",0)!=0 ){
1891
+ diffFlags = DIFF_IGNORE_ALLWS; /* stronger than DIFF_IGNORE_EOLWS */
1892
+ }
18851893
if( find_option("side-by-side","y",0)!=0 ) diffFlags |= DIFF_SIDEBYSIDE;
18861894
if( find_option("unified",0,0)!=0 ) diffFlags &= ~DIFF_SIDEBYSIDE;
18871895
if( (z = find_option("context","c",1))!=0 && (f = atoi(z))>=0 ){
18881896
if( f > DIFF_CONTEXT_MASK ) f = DIFF_CONTEXT_MASK;
18891897
diffFlags |= f + DIFF_CONTEXT_EX;
@@ -1892,14 +1900,10 @@
18921900
f *= DIFF_CONTEXT_MASK+1;
18931901
if( f > DIFF_WIDTH_MASK ) f = DIFF_CONTEXT_MASK;
18941902
diffFlags |= f;
18951903
}
18961904
if( find_option("html",0,0)!=0 ) diffFlags |= DIFF_HTML;
1897
- if( find_option("ignore-space-at-sol",0,0)!=0 ) diffFlags |= DIFF_IGNORE_SOLWS;
1898
- if( find_option("ignore-space-at-eol",0,0)!=0 ) diffFlags |= DIFF_IGNORE_EOLWS;
1899
- if( find_option("strip-trailing-cr",0,0)!=0 ) diffFlags |= DIFF_STRIP_EOLCR;
1900
- if( find_option("w",0,0)!=0 ) diffFlags |= (DIFF_IGNORE_EOLWS|DIFF_IGNORE_SOLWS);
19011905
if( find_option("linenum","n",0)!=0 ) diffFlags |= DIFF_LINENO;
19021906
if( find_option("noopt",0,0)!=0 ) diffFlags |= DIFF_NOOPT;
19031907
if( find_option("invert",0,0)!=0 ) diffFlags |= DIFF_INVERT;
19041908
if( find_option("brief",0,0)!=0 ) diffFlags |= DIFF_BRIEF;
19051909
return diffFlags;
@@ -2001,16 +2005,16 @@
20012005
/*
20022006
** Initialize the annotation process by specifying the file that is
20032007
** to be annotated. The annotator takes control of the input Blob and
20042008
** will release it when it is finished with it.
20052009
*/
2006
-static int annotation_start(Annotator *p, Blob *pInput){
2010
+static int annotation_start(Annotator *p, Blob *pInput, u64 diffFlags){
20072011
int i;
20082012
20092013
memset(p, 0, sizeof(*p));
20102014
p->c.aTo = break_into_lines(blob_str(pInput), blob_size(pInput),&p->c.nTo,
2011
- 0);
2015
+ diffFlags);
20122016
if( p->c.aTo==0 ){
20132017
return 1;
20142018
}
20152019
p->aOrig = fossil_malloc( sizeof(p->aOrig[0])*p->c.nTo );
20162020
for(i=0; i<p->c.nTo; i++){
@@ -2028,17 +2032,17 @@
20282032
** being annotated. Do another step of the annotation. Return true
20292033
** if additional annotation is required. zPName is the tag to insert
20302034
** on each line of the file being annotated that was contributed by
20312035
** pParent. Memory to hold zPName is leaked.
20322036
*/
2033
-static int annotation_step(Annotator *p, Blob *pParent, int iVers){
2037
+static int annotation_step(Annotator *p, Blob *pParent, int iVers, u64 diffFlags){
20342038
int i, j;
20352039
int lnTo;
20362040
20372041
/* Prepare the parent file to be diffed */
20382042
p->c.aFrom = break_into_lines(blob_str(pParent), blob_size(pParent),
2039
- &p->c.nFrom, 0);
2043
+ &p->c.nFrom, diffFlags);
20402044
if( p->c.aFrom==0 ){
20412045
return 1;
20422046
}
20432047
20442048
/* Compute the differences going from pParent to the file being
@@ -2085,11 +2089,12 @@
20852089
static void annotate_file(
20862090
Annotator *p, /* The annotator */
20872091
int fnid, /* The name of the file to be annotated */
20882092
int mid, /* Use the version of the file in this check-in */
20892093
int iLimit, /* Limit the number of levels if greater than zero */
2090
- int annFlags /* Flags to alter the annotation */
2094
+ int annFlags, /* Flags to alter the annotation */
2095
+ u64 diffFlags /* Flags to alter the whitespace handling */
20912096
){
20922097
Blob toAnnotate; /* Text of the final (mid) version of the file */
20932098
Blob step; /* Text of previous revision */
20942099
int rid; /* Artifact ID of the file being annotated */
20952100
Stmt q; /* Query returning all ancestor versions */
@@ -2103,11 +2108,11 @@
21032108
}
21042109
if( !content_get(rid, &toAnnotate) ){
21052110
fossil_fatal("unable to retrieve content of artifact #%d", rid);
21062111
}
21072112
if( iLimit<=0 ) iLimit = 1000000000;
2108
- annotation_start(p, &toAnnotate);
2113
+ annotation_start(p, &toAnnotate, diffFlags);
21092114
db_begin_transaction();
21102115
db_multi_exec(
21112116
"CREATE TEMP TABLE IF NOT EXISTS vseen(rid INTEGER PRIMARY KEY);"
21122117
"DELETE FROM vseen;"
21132118
);
@@ -2137,11 +2142,11 @@
21372142
p->aVers[p->nVers].zMUuid = fossil_strdup(db_column_text(&q, 1));
21382143
p->aVers[p->nVers].zDate = fossil_strdup(db_column_text(&q, 2));
21392144
p->aVers[p->nVers].zUser = fossil_strdup(db_column_text(&q, 3));
21402145
if( p->nVers ){
21412146
content_get(rid, &step);
2142
- annotation_step(p, &step, p->nVers-1);
2147
+ annotation_step(p, &step, p->nVers-1, diffFlags);
21432148
blob_reset(&step);
21442149
}
21452150
p->nVers++;
21462151
db_bind_int(&ins, ":rid", rid);
21472152
db_step(&ins);
@@ -2177,10 +2182,11 @@
21772182
}
21782183
21792184
/*
21802185
** WEBPAGE: annotate
21812186
** WEBPAGE: blame
2187
+** WEBPAGE: praise
21822188
**
21832189
** Query parameters:
21842190
**
21852191
** checkin=ID The manifest ID at which to start the annotation
21862192
** filename=FILENAME The filename.
@@ -2193,17 +2199,19 @@
21932199
int fnid;
21942200
int i;
21952201
int iLimit; /* Depth limit */
21962202
int annFlags = ANN_FILE_ANCEST;
21972203
int showLog = 0; /* True to display the log */
2204
+ int ignoreWs = 0; /* Ignore whitespace */
2205
+ u64 diffFlags = DIFF_STRIP_EOLCR; /* diff flags for ignore whitespace */
21982206
const char *zFilename; /* Name of file to annotate */
21992207
const char *zCI; /* The check-in containing zFilename */
22002208
Annotator ann;
22012209
HQuery url;
22022210
struct AnnVers *p;
22032211
unsigned clr1, clr2, clr;
2204
- int bBlame = g.zPath[0]=='b';/* True for BLAME output. False for ANNOTATE. */
2212
+ int bBlame = g.zPath[0]!='a';/* True for BLAME output. False for ANNOTATE. */
22052213
22062214
/* Gather query parameters */
22072215
showLog = atoi(PD("log","1"));
22082216
login_check_credentials();
22092217
if( !g.perm.Read ){ login_needed(); return; }
@@ -2212,17 +2220,19 @@
22122220
zFilename = P("filename");
22132221
fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", zFilename);
22142222
if( mid==0 || fnid==0 ){ fossil_redirect_home(); }
22152223
iLimit = atoi(PD("limit","20"));
22162224
if( P("filevers") ) annFlags |= ANN_FILE_VERS;
2225
+ ignoreWs = P("w")!=0;
2226
+ if( ignoreWs ) diffFlags |= DIFF_IGNORE_ALLWS;
22172227
if( !db_exists("SELECT 1 FROM mlink WHERE mid=%d AND fnid=%d",mid,fnid) ){
22182228
fossil_redirect_home();
22192229
}
22202230
22212231
/* compute the annotation */
22222232
compute_direct_ancestors(mid, 10000000);
2223
- annotate_file(&ann, fnid, mid, iLimit, annFlags);
2233
+ annotate_file(&ann, fnid, mid, iLimit, annFlags, diffFlags);
22242234
zCI = ann.aVers[0].zMUuid;
22252235
22262236
/* generate the web page */
22272237
style_header("Annotation For %h", zFilename);
22282238
if( bBlame ){
@@ -2234,10 +2244,18 @@
22342244
url_add_parameter(&url, "filename", zFilename);
22352245
if( iLimit!=20 ){
22362246
url_add_parameter(&url, "limit", sqlite3_mprintf("%d", iLimit));
22372247
}
22382248
url_add_parameter(&url, "log", showLog ? "1" : "0");
2249
+ if( ignoreWs ){
2250
+ url_add_parameter(&url, "w", "");
2251
+ style_submenu_element("Show Whitespace Changes", "Show Whitespace Changes",
2252
+ "%s", url_render(&url, "w", 0, 0, 0));
2253
+ }else{
2254
+ style_submenu_element("Ignore Whitespace", "Ignore Whitespace",
2255
+ "%s", url_render(&url, "w", "", 0, 0));
2256
+ }
22392257
if( showLog ){
22402258
style_submenu_element("Hide Log", "Hide Log",
22412259
"%s", url_render(&url, "log", "0", 0, 0));
22422260
}else{
22432261
style_submenu_element("Show Log", "Show Log",
@@ -2347,22 +2365,25 @@
23472365
}
23482366
23492367
/*
23502368
** COMMAND: annotate
23512369
** COMMAND: blame
2370
+** COMMAND: praise
23522371
**
2353
-** %fossil (annotate|blame) ?OPTIONS? FILENAME
2372
+** %fossil (annotate|blame|praise) ?OPTIONS? FILENAME
23542373
**
23552374
** Output the text of a file with markings to show when each line of
23562375
** the file was last modified. The "annotate" command shows line numbers
2357
-** and omits the username. The "blame" command shows the user who made each
2358
-** checkin and omits the line number.
2376
+** and omits the username. The "blame" and "praise" commands show the user
2377
+** who made each checkin and omits the line number.
23592378
**
23602379
** Options:
2361
-** --filevers Show file version numbers rather than check-in versions
2362
-** -l|--log List all versions analyzed
2363
-** -n|--limit N Only look backwards in time by N versions
2380
+** --filevers Show file version numbers rather than check-in versions
2381
+** -l|--log List all versions analyzed
2382
+** -n|--limit N Only look backwards in time by N versions
2383
+** -w|--ignore-all-space Ignore white space when comparing lines
2384
+** -Z|--ignore-trailing-space Ignore whitespace at line end
23642385
**
23652386
** See also: info, finfo, timeline
23662387
*/
23672388
void annotate_cmd(void){
23682389
int fnid; /* Filename ID */
@@ -2374,19 +2395,22 @@
23742395
Annotator ann; /* The annotation of the file */
23752396
int i; /* Loop counter */
23762397
const char *zLimit; /* The value to the -n|--limit option */
23772398
int iLimit; /* How far back in time to look */
23782399
int showLog; /* True to show the log */
2400
+ u64 diffFlags = DIFF_STRIP_EOLCR;/* Flags to control whitespace handling */
23792401
int fileVers; /* Show file version instead of check-in versions */
23802402
int annFlags = 0; /* Flags to control annotation properties */
23812403
int bBlame = 0; /* True for BLAME output. False for ANNOTATE. */
23822404
2383
- bBlame = g.argv[1][0]=='b';
2405
+ bBlame = g.argv[1][0]!='a';
23842406
zLimit = find_option("limit","n",1);
23852407
if( zLimit==0 || zLimit[0]==0 ) zLimit = "-1";
23862408
iLimit = atoi(zLimit);
23872409
showLog = find_option("log","l",0)!=0;
2410
+ if( find_option("ignore-trailing-space","Z",0)!=0 ) diffFlags = DIFF_IGNORE_EOLWS;
2411
+ if( find_option("w",0,0)!=0 ) diffFlags |= DIFF_IGNORE_ALLWS;
23882412
fileVers = find_option("filevers",0,0)!=0;
23892413
db_must_be_within_tree();
23902414
if( g.argc<3 ) {
23912415
usage("FILENAME");
23922416
}
@@ -2412,11 +2436,11 @@
24122436
fid, fnid);
24132437
if( mid==0 ){
24142438
fossil_fatal("unable to find manifest");
24152439
}
24162440
annFlags |= ANN_FILE_ANCEST;
2417
- annotate_file(&ann, fnid, mid, iLimit, annFlags);
2441
+ annotate_file(&ann, fnid, mid, iLimit, annFlags, diffFlags);
24182442
if( showLog ){
24192443
struct AnnVers *p;
24202444
for(p=ann.aVers, i=0; i<ann.nVers; i++, p++){
24212445
fossil_print("version %3d: %s %.10s file %.10s\n",
24222446
i+1, p->zDate, p->zMUuid, p->zFUuid);
24232447
--- src/diff.c
+++ src/diff.c
@@ -28,12 +28,13 @@
28 ** Flag parameters to the text_diff() routine used to control the formatting
29 ** of the diff output.
30 */
31 #define DIFF_CONTEXT_MASK ((u64)0x0000ffff) /* Lines of context. Default if 0 */
32 #define DIFF_WIDTH_MASK ((u64)0x00ff0000) /* side-by-side column width */
33 #define DIFF_IGNORE_SOLWS ((u64)0x01000000) /* Ignore start-of-line whitespace */
34 #define DIFF_IGNORE_EOLWS ((u64)0x02000000) /* Ignore end-of-line whitespace */
 
35 #define DIFF_SIDEBYSIDE ((u64)0x04000000) /* Generate a side-by-side diff */
36 #define DIFF_VERBOSE ((u64)0x08000000) /* Missing shown as empty files */
37 #define DIFF_INLINE ((u64)0x00000000) /* Inline (not side-by-side) diff */
38 #define DIFF_BRIEF ((u64)0x10000000) /* Show filenames only */
39 #define DIFF_HTML ((u64)0x20000000) /* Render for HTML */
@@ -40,11 +41,10 @@
40 #define DIFF_LINENO ((u64)0x40000000) /* Show line numbers */
41 #define DIFF_NOOPT (((u64)0x01)<<32) /* Suppress optimizations (debug) */
42 #define DIFF_INVERT (((u64)0x02)<<32) /* Invert the diff (debug) */
43 #define DIFF_CONTEXT_EX (((u64)0x04)<<32) /* Use context even if zero */
44 #define DIFF_NOTTOOBIG (((u64)0x08)<<32) /* Only display if not too big */
45 #define DIFF_STRIP_EOLCR (((u64)0x10)<<32) /* Strip trailing CR */
46
47 /*
48 ** These error messages are shared in multiple locations. They are defined
49 ** here for consistency.
50 */
@@ -172,11 +172,11 @@
172 if( diffFlags & DIFF_IGNORE_EOLWS ){
173 while( k>0 && fossil_isspace(z[k-1]) ){ k--; }
174 }else if( diffFlags & DIFF_STRIP_EOLCR ){
175 if( k>0 && z[k-1]=='\r' ){ k--; }
176 }
177 if( diffFlags & DIFF_IGNORE_SOLWS ){
178 while( s<k && fossil_isspace(z[s]) ){
179 if( z[s]=='\t' ){
180 indent = ((indent+9)/8)*8;
181 }else if( z[s]==' ' ){
182 indent++;
@@ -1792,11 +1792,11 @@
1792 if( diffFlags & DIFF_INVERT ){
1793 Blob *pTemp = pA_Blob;
1794 pA_Blob = pB_Blob;
1795 pB_Blob = pTemp;
1796 }
1797 ignoreWs = (diffFlags & (DIFF_IGNORE_SOLWS|DIFF_IGNORE_EOLWS))!=0;
1798 blob_to_utf8_no_bom(pA_Blob, 0);
1799 blob_to_utf8_no_bom(pB_Blob, 0);
1800
1801 /* Prepare the input files */
1802 memset(&c, 0, sizeof(c));
@@ -1862,28 +1862,36 @@
1862
1863 /*
1864 ** Process diff-related command-line options and return an appropriate
1865 ** "diffFlags" integer.
1866 **
1867 ** --brief Show filenames only DIFF_BRIEF
1868 ** --context|-c N N lines of context. DIFF_CONTEXT_MASK
1869 ** --html Format for HTML DIFF_HTML
1870 ** --invert Invert the diff DIFF_INVERT
1871 ** --ignore-space-at-eol Ignore eol-whitespaces DIFF_IGNORE_EOLWS
1872 ** --ignore-space-at-sol Ignore sol-whitespaces DIFF_IGNORE_SOLWS
1873 ** --linenum|-n Show line numbers DIFF_LINENO
1874 ** --noopt Disable optimization DIFF_NOOPT
1875 ** --side-by-side|-y Side-by-side diff. DIFF_SIDEBYSIDE
1876 ** --strip-trailing-cr Strip trailing CR DIFF_IGNORE_EOLCR
1877 ** --unified Unified diff. ~DIFF_SIDEBYSIDE
1878 ** -w Ignore all whitespaces DIFF_IGNORE_EOLWS|DIFF_IGNORE_SOLWS
1879 ** --width|-W N N character lines. DIFF_WIDTH_MASK
1880 */
1881 u64 diff_options(void){
1882 u64 diffFlags = 0;
1883 const char *z;
1884 int f;
 
 
 
 
 
 
 
 
 
1885 if( find_option("side-by-side","y",0)!=0 ) diffFlags |= DIFF_SIDEBYSIDE;
1886 if( find_option("unified",0,0)!=0 ) diffFlags &= ~DIFF_SIDEBYSIDE;
1887 if( (z = find_option("context","c",1))!=0 && (f = atoi(z))>=0 ){
1888 if( f > DIFF_CONTEXT_MASK ) f = DIFF_CONTEXT_MASK;
1889 diffFlags |= f + DIFF_CONTEXT_EX;
@@ -1892,14 +1900,10 @@
1892 f *= DIFF_CONTEXT_MASK+1;
1893 if( f > DIFF_WIDTH_MASK ) f = DIFF_CONTEXT_MASK;
1894 diffFlags |= f;
1895 }
1896 if( find_option("html",0,0)!=0 ) diffFlags |= DIFF_HTML;
1897 if( find_option("ignore-space-at-sol",0,0)!=0 ) diffFlags |= DIFF_IGNORE_SOLWS;
1898 if( find_option("ignore-space-at-eol",0,0)!=0 ) diffFlags |= DIFF_IGNORE_EOLWS;
1899 if( find_option("strip-trailing-cr",0,0)!=0 ) diffFlags |= DIFF_STRIP_EOLCR;
1900 if( find_option("w",0,0)!=0 ) diffFlags |= (DIFF_IGNORE_EOLWS|DIFF_IGNORE_SOLWS);
1901 if( find_option("linenum","n",0)!=0 ) diffFlags |= DIFF_LINENO;
1902 if( find_option("noopt",0,0)!=0 ) diffFlags |= DIFF_NOOPT;
1903 if( find_option("invert",0,0)!=0 ) diffFlags |= DIFF_INVERT;
1904 if( find_option("brief",0,0)!=0 ) diffFlags |= DIFF_BRIEF;
1905 return diffFlags;
@@ -2001,16 +2005,16 @@
2001 /*
2002 ** Initialize the annotation process by specifying the file that is
2003 ** to be annotated. The annotator takes control of the input Blob and
2004 ** will release it when it is finished with it.
2005 */
2006 static int annotation_start(Annotator *p, Blob *pInput){
2007 int i;
2008
2009 memset(p, 0, sizeof(*p));
2010 p->c.aTo = break_into_lines(blob_str(pInput), blob_size(pInput),&p->c.nTo,
2011 0);
2012 if( p->c.aTo==0 ){
2013 return 1;
2014 }
2015 p->aOrig = fossil_malloc( sizeof(p->aOrig[0])*p->c.nTo );
2016 for(i=0; i<p->c.nTo; i++){
@@ -2028,17 +2032,17 @@
2028 ** being annotated. Do another step of the annotation. Return true
2029 ** if additional annotation is required. zPName is the tag to insert
2030 ** on each line of the file being annotated that was contributed by
2031 ** pParent. Memory to hold zPName is leaked.
2032 */
2033 static int annotation_step(Annotator *p, Blob *pParent, int iVers){
2034 int i, j;
2035 int lnTo;
2036
2037 /* Prepare the parent file to be diffed */
2038 p->c.aFrom = break_into_lines(blob_str(pParent), blob_size(pParent),
2039 &p->c.nFrom, 0);
2040 if( p->c.aFrom==0 ){
2041 return 1;
2042 }
2043
2044 /* Compute the differences going from pParent to the file being
@@ -2085,11 +2089,12 @@
2085 static void annotate_file(
2086 Annotator *p, /* The annotator */
2087 int fnid, /* The name of the file to be annotated */
2088 int mid, /* Use the version of the file in this check-in */
2089 int iLimit, /* Limit the number of levels if greater than zero */
2090 int annFlags /* Flags to alter the annotation */
 
2091 ){
2092 Blob toAnnotate; /* Text of the final (mid) version of the file */
2093 Blob step; /* Text of previous revision */
2094 int rid; /* Artifact ID of the file being annotated */
2095 Stmt q; /* Query returning all ancestor versions */
@@ -2103,11 +2108,11 @@
2103 }
2104 if( !content_get(rid, &toAnnotate) ){
2105 fossil_fatal("unable to retrieve content of artifact #%d", rid);
2106 }
2107 if( iLimit<=0 ) iLimit = 1000000000;
2108 annotation_start(p, &toAnnotate);
2109 db_begin_transaction();
2110 db_multi_exec(
2111 "CREATE TEMP TABLE IF NOT EXISTS vseen(rid INTEGER PRIMARY KEY);"
2112 "DELETE FROM vseen;"
2113 );
@@ -2137,11 +2142,11 @@
2137 p->aVers[p->nVers].zMUuid = fossil_strdup(db_column_text(&q, 1));
2138 p->aVers[p->nVers].zDate = fossil_strdup(db_column_text(&q, 2));
2139 p->aVers[p->nVers].zUser = fossil_strdup(db_column_text(&q, 3));
2140 if( p->nVers ){
2141 content_get(rid, &step);
2142 annotation_step(p, &step, p->nVers-1);
2143 blob_reset(&step);
2144 }
2145 p->nVers++;
2146 db_bind_int(&ins, ":rid", rid);
2147 db_step(&ins);
@@ -2177,10 +2182,11 @@
2177 }
2178
2179 /*
2180 ** WEBPAGE: annotate
2181 ** WEBPAGE: blame
 
2182 **
2183 ** Query parameters:
2184 **
2185 ** checkin=ID The manifest ID at which to start the annotation
2186 ** filename=FILENAME The filename.
@@ -2193,17 +2199,19 @@
2193 int fnid;
2194 int i;
2195 int iLimit; /* Depth limit */
2196 int annFlags = ANN_FILE_ANCEST;
2197 int showLog = 0; /* True to display the log */
 
 
2198 const char *zFilename; /* Name of file to annotate */
2199 const char *zCI; /* The check-in containing zFilename */
2200 Annotator ann;
2201 HQuery url;
2202 struct AnnVers *p;
2203 unsigned clr1, clr2, clr;
2204 int bBlame = g.zPath[0]=='b';/* True for BLAME output. False for ANNOTATE. */
2205
2206 /* Gather query parameters */
2207 showLog = atoi(PD("log","1"));
2208 login_check_credentials();
2209 if( !g.perm.Read ){ login_needed(); return; }
@@ -2212,17 +2220,19 @@
2212 zFilename = P("filename");
2213 fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", zFilename);
2214 if( mid==0 || fnid==0 ){ fossil_redirect_home(); }
2215 iLimit = atoi(PD("limit","20"));
2216 if( P("filevers") ) annFlags |= ANN_FILE_VERS;
 
 
2217 if( !db_exists("SELECT 1 FROM mlink WHERE mid=%d AND fnid=%d",mid,fnid) ){
2218 fossil_redirect_home();
2219 }
2220
2221 /* compute the annotation */
2222 compute_direct_ancestors(mid, 10000000);
2223 annotate_file(&ann, fnid, mid, iLimit, annFlags);
2224 zCI = ann.aVers[0].zMUuid;
2225
2226 /* generate the web page */
2227 style_header("Annotation For %h", zFilename);
2228 if( bBlame ){
@@ -2234,10 +2244,18 @@
2234 url_add_parameter(&url, "filename", zFilename);
2235 if( iLimit!=20 ){
2236 url_add_parameter(&url, "limit", sqlite3_mprintf("%d", iLimit));
2237 }
2238 url_add_parameter(&url, "log", showLog ? "1" : "0");
 
 
 
 
 
 
 
 
2239 if( showLog ){
2240 style_submenu_element("Hide Log", "Hide Log",
2241 "%s", url_render(&url, "log", "0", 0, 0));
2242 }else{
2243 style_submenu_element("Show Log", "Show Log",
@@ -2347,22 +2365,25 @@
2347 }
2348
2349 /*
2350 ** COMMAND: annotate
2351 ** COMMAND: blame
 
2352 **
2353 ** %fossil (annotate|blame) ?OPTIONS? FILENAME
2354 **
2355 ** Output the text of a file with markings to show when each line of
2356 ** the file was last modified. The "annotate" command shows line numbers
2357 ** and omits the username. The "blame" command shows the user who made each
2358 ** checkin and omits the line number.
2359 **
2360 ** Options:
2361 ** --filevers Show file version numbers rather than check-in versions
2362 ** -l|--log List all versions analyzed
2363 ** -n|--limit N Only look backwards in time by N versions
 
 
2364 **
2365 ** See also: info, finfo, timeline
2366 */
2367 void annotate_cmd(void){
2368 int fnid; /* Filename ID */
@@ -2374,19 +2395,22 @@
2374 Annotator ann; /* The annotation of the file */
2375 int i; /* Loop counter */
2376 const char *zLimit; /* The value to the -n|--limit option */
2377 int iLimit; /* How far back in time to look */
2378 int showLog; /* True to show the log */
 
2379 int fileVers; /* Show file version instead of check-in versions */
2380 int annFlags = 0; /* Flags to control annotation properties */
2381 int bBlame = 0; /* True for BLAME output. False for ANNOTATE. */
2382
2383 bBlame = g.argv[1][0]=='b';
2384 zLimit = find_option("limit","n",1);
2385 if( zLimit==0 || zLimit[0]==0 ) zLimit = "-1";
2386 iLimit = atoi(zLimit);
2387 showLog = find_option("log","l",0)!=0;
 
 
2388 fileVers = find_option("filevers",0,0)!=0;
2389 db_must_be_within_tree();
2390 if( g.argc<3 ) {
2391 usage("FILENAME");
2392 }
@@ -2412,11 +2436,11 @@
2412 fid, fnid);
2413 if( mid==0 ){
2414 fossil_fatal("unable to find manifest");
2415 }
2416 annFlags |= ANN_FILE_ANCEST;
2417 annotate_file(&ann, fnid, mid, iLimit, annFlags);
2418 if( showLog ){
2419 struct AnnVers *p;
2420 for(p=ann.aVers, i=0; i<ann.nVers; i++, p++){
2421 fossil_print("version %3d: %s %.10s file %.10s\n",
2422 i+1, p->zDate, p->zMUuid, p->zFUuid);
2423
--- src/diff.c
+++ src/diff.c
@@ -28,12 +28,13 @@
28 ** Flag parameters to the text_diff() routine used to control the formatting
29 ** of the diff output.
30 */
31 #define DIFF_CONTEXT_MASK ((u64)0x0000ffff) /* Lines of context. Default if 0 */
32 #define DIFF_WIDTH_MASK ((u64)0x00ff0000) /* side-by-side column width */
33 #define DIFF_STRIP_EOLCR ((u64)0x01000000) /* Strip trailing CR */
34 #define DIFF_IGNORE_EOLWS ((u64)0x02000000) /* Ignore end-of-line whitespace */
35 #define DIFF_IGNORE_ALLWS ((u64)0x03000000) /* Ignore all whitespace */
36 #define DIFF_SIDEBYSIDE ((u64)0x04000000) /* Generate a side-by-side diff */
37 #define DIFF_VERBOSE ((u64)0x08000000) /* Missing shown as empty files */
38 #define DIFF_INLINE ((u64)0x00000000) /* Inline (not side-by-side) diff */
39 #define DIFF_BRIEF ((u64)0x10000000) /* Show filenames only */
40 #define DIFF_HTML ((u64)0x20000000) /* Render for HTML */
@@ -40,11 +41,10 @@
41 #define DIFF_LINENO ((u64)0x40000000) /* Show line numbers */
42 #define DIFF_NOOPT (((u64)0x01)<<32) /* Suppress optimizations (debug) */
43 #define DIFF_INVERT (((u64)0x02)<<32) /* Invert the diff (debug) */
44 #define DIFF_CONTEXT_EX (((u64)0x04)<<32) /* Use context even if zero */
45 #define DIFF_NOTTOOBIG (((u64)0x08)<<32) /* Only display if not too big */
 
46
47 /*
48 ** These error messages are shared in multiple locations. They are defined
49 ** here for consistency.
50 */
@@ -172,11 +172,11 @@
172 if( diffFlags & DIFF_IGNORE_EOLWS ){
173 while( k>0 && fossil_isspace(z[k-1]) ){ k--; }
174 }else if( diffFlags & DIFF_STRIP_EOLCR ){
175 if( k>0 && z[k-1]=='\r' ){ k--; }
176 }
177 if( (diffFlags & DIFF_IGNORE_ALLWS)==DIFF_IGNORE_ALLWS ){
178 while( s<k && fossil_isspace(z[s]) ){
179 if( z[s]=='\t' ){
180 indent = ((indent+9)/8)*8;
181 }else if( z[s]==' ' ){
182 indent++;
@@ -1792,11 +1792,11 @@
1792 if( diffFlags & DIFF_INVERT ){
1793 Blob *pTemp = pA_Blob;
1794 pA_Blob = pB_Blob;
1795 pB_Blob = pTemp;
1796 }
1797 ignoreWs = (diffFlags & DIFF_IGNORE_EOLWS)!=0;
1798 blob_to_utf8_no_bom(pA_Blob, 0);
1799 blob_to_utf8_no_bom(pB_Blob, 0);
1800
1801 /* Prepare the input files */
1802 memset(&c, 0, sizeof(c));
@@ -1862,28 +1862,36 @@
1862
1863 /*
1864 ** Process diff-related command-line options and return an appropriate
1865 ** "diffFlags" integer.
1866 **
1867 ** --brief Show filenames only DIFF_BRIEF
1868 ** --context|-c N N lines of context. DIFF_CONTEXT_MASK
1869 ** --html Format for HTML DIFF_HTML
1870 ** --invert Invert the diff DIFF_INVERT
1871 ** --linenum|-n Show line numbers DIFF_LINENO
1872 ** --noopt Disable optimization DIFF_NOOPT
1873 ** --side-by-side|-y Side-by-side diff. DIFF_SIDEBYSIDE
1874 ** --strip-trailing-cr Strip trailing CR DIFF_STRIP_EOLCR
1875 ** --unified Unified diff. ~DIFF_SIDEBYSIDE
1876 ** --width|-W N N character lines. DIFF_WIDTH_MASK
1877 ** -w|--ignore-all-space Ignore all white space DIFF_IGNORE_ALLWS
1878 ** -Z|--ignore-trailing-space Ignore eol-whitespaces DIFF_IGNORE_EOLWS
 
1879 */
1880 u64 diff_options(void){
1881 u64 diffFlags = 0;
1882 const char *z;
1883 int f;
1884 if( find_option("strip-trailing-cr",0,0)!=0 ){
1885 diffFlags = DIFF_STRIP_EOLCR;
1886 }
1887 if( find_option("ignore-trailing-space","Z",0)!=0 ){
1888 diffFlags = DIFF_IGNORE_EOLWS; /* stronger than DIFF_STRIP_EOLCR */
1889 }
1890 if( find_option("ignore-all-space","w",0)!=0 ){
1891 diffFlags = DIFF_IGNORE_ALLWS; /* stronger than DIFF_IGNORE_EOLWS */
1892 }
1893 if( find_option("side-by-side","y",0)!=0 ) diffFlags |= DIFF_SIDEBYSIDE;
1894 if( find_option("unified",0,0)!=0 ) diffFlags &= ~DIFF_SIDEBYSIDE;
1895 if( (z = find_option("context","c",1))!=0 && (f = atoi(z))>=0 ){
1896 if( f > DIFF_CONTEXT_MASK ) f = DIFF_CONTEXT_MASK;
1897 diffFlags |= f + DIFF_CONTEXT_EX;
@@ -1892,14 +1900,10 @@
1900 f *= DIFF_CONTEXT_MASK+1;
1901 if( f > DIFF_WIDTH_MASK ) f = DIFF_CONTEXT_MASK;
1902 diffFlags |= f;
1903 }
1904 if( find_option("html",0,0)!=0 ) diffFlags |= DIFF_HTML;
 
 
 
 
1905 if( find_option("linenum","n",0)!=0 ) diffFlags |= DIFF_LINENO;
1906 if( find_option("noopt",0,0)!=0 ) diffFlags |= DIFF_NOOPT;
1907 if( find_option("invert",0,0)!=0 ) diffFlags |= DIFF_INVERT;
1908 if( find_option("brief",0,0)!=0 ) diffFlags |= DIFF_BRIEF;
1909 return diffFlags;
@@ -2001,16 +2005,16 @@
2005 /*
2006 ** Initialize the annotation process by specifying the file that is
2007 ** to be annotated. The annotator takes control of the input Blob and
2008 ** will release it when it is finished with it.
2009 */
2010 static int annotation_start(Annotator *p, Blob *pInput, u64 diffFlags){
2011 int i;
2012
2013 memset(p, 0, sizeof(*p));
2014 p->c.aTo = break_into_lines(blob_str(pInput), blob_size(pInput),&p->c.nTo,
2015 diffFlags);
2016 if( p->c.aTo==0 ){
2017 return 1;
2018 }
2019 p->aOrig = fossil_malloc( sizeof(p->aOrig[0])*p->c.nTo );
2020 for(i=0; i<p->c.nTo; i++){
@@ -2028,17 +2032,17 @@
2032 ** being annotated. Do another step of the annotation. Return true
2033 ** if additional annotation is required. zPName is the tag to insert
2034 ** on each line of the file being annotated that was contributed by
2035 ** pParent. Memory to hold zPName is leaked.
2036 */
2037 static int annotation_step(Annotator *p, Blob *pParent, int iVers, u64 diffFlags){
2038 int i, j;
2039 int lnTo;
2040
2041 /* Prepare the parent file to be diffed */
2042 p->c.aFrom = break_into_lines(blob_str(pParent), blob_size(pParent),
2043 &p->c.nFrom, diffFlags);
2044 if( p->c.aFrom==0 ){
2045 return 1;
2046 }
2047
2048 /* Compute the differences going from pParent to the file being
@@ -2085,11 +2089,12 @@
2089 static void annotate_file(
2090 Annotator *p, /* The annotator */
2091 int fnid, /* The name of the file to be annotated */
2092 int mid, /* Use the version of the file in this check-in */
2093 int iLimit, /* Limit the number of levels if greater than zero */
2094 int annFlags, /* Flags to alter the annotation */
2095 u64 diffFlags /* Flags to alter the whitespace handling */
2096 ){
2097 Blob toAnnotate; /* Text of the final (mid) version of the file */
2098 Blob step; /* Text of previous revision */
2099 int rid; /* Artifact ID of the file being annotated */
2100 Stmt q; /* Query returning all ancestor versions */
@@ -2103,11 +2108,11 @@
2108 }
2109 if( !content_get(rid, &toAnnotate) ){
2110 fossil_fatal("unable to retrieve content of artifact #%d", rid);
2111 }
2112 if( iLimit<=0 ) iLimit = 1000000000;
2113 annotation_start(p, &toAnnotate, diffFlags);
2114 db_begin_transaction();
2115 db_multi_exec(
2116 "CREATE TEMP TABLE IF NOT EXISTS vseen(rid INTEGER PRIMARY KEY);"
2117 "DELETE FROM vseen;"
2118 );
@@ -2137,11 +2142,11 @@
2142 p->aVers[p->nVers].zMUuid = fossil_strdup(db_column_text(&q, 1));
2143 p->aVers[p->nVers].zDate = fossil_strdup(db_column_text(&q, 2));
2144 p->aVers[p->nVers].zUser = fossil_strdup(db_column_text(&q, 3));
2145 if( p->nVers ){
2146 content_get(rid, &step);
2147 annotation_step(p, &step, p->nVers-1, diffFlags);
2148 blob_reset(&step);
2149 }
2150 p->nVers++;
2151 db_bind_int(&ins, ":rid", rid);
2152 db_step(&ins);
@@ -2177,10 +2182,11 @@
2182 }
2183
2184 /*
2185 ** WEBPAGE: annotate
2186 ** WEBPAGE: blame
2187 ** WEBPAGE: praise
2188 **
2189 ** Query parameters:
2190 **
2191 ** checkin=ID The manifest ID at which to start the annotation
2192 ** filename=FILENAME The filename.
@@ -2193,17 +2199,19 @@
2199 int fnid;
2200 int i;
2201 int iLimit; /* Depth limit */
2202 int annFlags = ANN_FILE_ANCEST;
2203 int showLog = 0; /* True to display the log */
2204 int ignoreWs = 0; /* Ignore whitespace */
2205 u64 diffFlags = DIFF_STRIP_EOLCR; /* diff flags for ignore whitespace */
2206 const char *zFilename; /* Name of file to annotate */
2207 const char *zCI; /* The check-in containing zFilename */
2208 Annotator ann;
2209 HQuery url;
2210 struct AnnVers *p;
2211 unsigned clr1, clr2, clr;
2212 int bBlame = g.zPath[0]!='a';/* True for BLAME output. False for ANNOTATE. */
2213
2214 /* Gather query parameters */
2215 showLog = atoi(PD("log","1"));
2216 login_check_credentials();
2217 if( !g.perm.Read ){ login_needed(); return; }
@@ -2212,17 +2220,19 @@
2220 zFilename = P("filename");
2221 fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", zFilename);
2222 if( mid==0 || fnid==0 ){ fossil_redirect_home(); }
2223 iLimit = atoi(PD("limit","20"));
2224 if( P("filevers") ) annFlags |= ANN_FILE_VERS;
2225 ignoreWs = P("w")!=0;
2226 if( ignoreWs ) diffFlags |= DIFF_IGNORE_ALLWS;
2227 if( !db_exists("SELECT 1 FROM mlink WHERE mid=%d AND fnid=%d",mid,fnid) ){
2228 fossil_redirect_home();
2229 }
2230
2231 /* compute the annotation */
2232 compute_direct_ancestors(mid, 10000000);
2233 annotate_file(&ann, fnid, mid, iLimit, annFlags, diffFlags);
2234 zCI = ann.aVers[0].zMUuid;
2235
2236 /* generate the web page */
2237 style_header("Annotation For %h", zFilename);
2238 if( bBlame ){
@@ -2234,10 +2244,18 @@
2244 url_add_parameter(&url, "filename", zFilename);
2245 if( iLimit!=20 ){
2246 url_add_parameter(&url, "limit", sqlite3_mprintf("%d", iLimit));
2247 }
2248 url_add_parameter(&url, "log", showLog ? "1" : "0");
2249 if( ignoreWs ){
2250 url_add_parameter(&url, "w", "");
2251 style_submenu_element("Show Whitespace Changes", "Show Whitespace Changes",
2252 "%s", url_render(&url, "w", 0, 0, 0));
2253 }else{
2254 style_submenu_element("Ignore Whitespace", "Ignore Whitespace",
2255 "%s", url_render(&url, "w", "", 0, 0));
2256 }
2257 if( showLog ){
2258 style_submenu_element("Hide Log", "Hide Log",
2259 "%s", url_render(&url, "log", "0", 0, 0));
2260 }else{
2261 style_submenu_element("Show Log", "Show Log",
@@ -2347,22 +2365,25 @@
2365 }
2366
2367 /*
2368 ** COMMAND: annotate
2369 ** COMMAND: blame
2370 ** COMMAND: praise
2371 **
2372 ** %fossil (annotate|blame|praise) ?OPTIONS? FILENAME
2373 **
2374 ** Output the text of a file with markings to show when each line of
2375 ** the file was last modified. The "annotate" command shows line numbers
2376 ** and omits the username. The "blame" and "praise" commands show the user
2377 ** who made each checkin and omits the line number.
2378 **
2379 ** Options:
2380 ** --filevers Show file version numbers rather than check-in versions
2381 ** -l|--log List all versions analyzed
2382 ** -n|--limit N Only look backwards in time by N versions
2383 ** -w|--ignore-all-space Ignore white space when comparing lines
2384 ** -Z|--ignore-trailing-space Ignore whitespace at line end
2385 **
2386 ** See also: info, finfo, timeline
2387 */
2388 void annotate_cmd(void){
2389 int fnid; /* Filename ID */
@@ -2374,19 +2395,22 @@
2395 Annotator ann; /* The annotation of the file */
2396 int i; /* Loop counter */
2397 const char *zLimit; /* The value to the -n|--limit option */
2398 int iLimit; /* How far back in time to look */
2399 int showLog; /* True to show the log */
2400 u64 diffFlags = DIFF_STRIP_EOLCR;/* Flags to control whitespace handling */
2401 int fileVers; /* Show file version instead of check-in versions */
2402 int annFlags = 0; /* Flags to control annotation properties */
2403 int bBlame = 0; /* True for BLAME output. False for ANNOTATE. */
2404
2405 bBlame = g.argv[1][0]!='a';
2406 zLimit = find_option("limit","n",1);
2407 if( zLimit==0 || zLimit[0]==0 ) zLimit = "-1";
2408 iLimit = atoi(zLimit);
2409 showLog = find_option("log","l",0)!=0;
2410 if( find_option("ignore-trailing-space","Z",0)!=0 ) diffFlags = DIFF_IGNORE_EOLWS;
2411 if( find_option("w",0,0)!=0 ) diffFlags |= DIFF_IGNORE_ALLWS;
2412 fileVers = find_option("filevers",0,0)!=0;
2413 db_must_be_within_tree();
2414 if( g.argc<3 ) {
2415 usage("FILENAME");
2416 }
@@ -2412,11 +2436,11 @@
2436 fid, fnid);
2437 if( mid==0 ){
2438 fossil_fatal("unable to find manifest");
2439 }
2440 annFlags |= ANN_FILE_ANCEST;
2441 annotate_file(&ann, fnid, mid, iLimit, annFlags, diffFlags);
2442 if( showLog ){
2443 struct AnnVers *p;
2444 for(p=ann.aVers, i=0; i<ann.nVers; i++, p++){
2445 fossil_print("version %3d: %s %.10s file %.10s\n",
2446 i+1, p->zDate, p->zMUuid, p->zFUuid);
2447
+16 -18
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -1089,28 +1089,26 @@
10891089
** The "--binary" option causes files matching the glob PATTERN to be treated
10901090
** as binary when considering if they should be used with external diff program.
10911091
** This option overrides the "binary-glob" setting.
10921092
**
10931093
** Options:
1094
-** --binary PATTERN Treat files that match the glob PATTERN as binary
1095
-** --branch BRANCH Show diff of all changes on BRANCH
1096
-** --brief Show filenames only
1097
-** --context|-c N Use N lines of context
1098
-** --diff-binary BOOL Include binary files when using external commands
1099
-** --from|-r VERSION select VERSION as source for the diff
1100
-** --ignore-space-at-eol Ignore changes to end-of-line whitespace
1101
-** --ignore-space-at-sol Ignore changes to start-of-line whitespace
1102
-** --internal|-i use internal diff logic
1103
-** --side-by-side|-y side-by-side diff
1104
-** --strip-trailing-cr Strip trailing CR
1105
-** --tk Launch a Tcl/Tk GUI for display
1106
-** --to VERSION select VERSION as target for the diff
1107
-** --unified unified diff
1108
-** -v|--verbose output complete text of added or deleted files
1109
-** -w Ignore changes to start-of-line and end-of-line
1110
-** whitespace
1111
-** -W|--width Width of lines in side-by-side diff
1094
+** --binary PATTERN Treat files that match the glob PATTERN as binary
1095
+** --branch BRANCH Show diff of all changes on BRANCH
1096
+** --brief Show filenames only
1097
+** --context|-c N Use N lines of context
1098
+** --diff-binary BOOL Include binary files when using external commands
1099
+** --from|-r VERSION select VERSION as source for the diff
1100
+** --internal|-i use internal diff logic
1101
+** --side-by-side|-y side-by-side diff
1102
+** --strip-trailing-cr Strip trailing CR
1103
+** --tk Launch a Tcl/Tk GUI for display
1104
+** --to VERSION select VERSION as target for the diff
1105
+** --unified unified diff
1106
+** -v|--verbose output complete text of added or deleted files
1107
+** -w|--ignore-all-space Ignore white space when comparing lines
1108
+** -W|--width <num> Width of lines in side-by-side diff
1109
+** -Z|--ignore-trailing-space Ignore whitespace at line end
11121110
*/
11131111
void diff_cmd(void){
11141112
int isGDiff; /* True for gdiff. False for normal diff */
11151113
int isInternDiff; /* True for internal diff */
11161114
int verboseFlag; /* True if -v or --verbose flag is used */
11171115
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -1089,28 +1089,26 @@
1089 ** The "--binary" option causes files matching the glob PATTERN to be treated
1090 ** as binary when considering if they should be used with external diff program.
1091 ** This option overrides the "binary-glob" setting.
1092 **
1093 ** Options:
1094 ** --binary PATTERN Treat files that match the glob PATTERN as binary
1095 ** --branch BRANCH Show diff of all changes on BRANCH
1096 ** --brief Show filenames only
1097 ** --context|-c N Use N lines of context
1098 ** --diff-binary BOOL Include binary files when using external commands
1099 ** --from|-r VERSION select VERSION as source for the diff
1100 ** --ignore-space-at-eol Ignore changes to end-of-line whitespace
1101 ** --ignore-space-at-sol Ignore changes to start-of-line whitespace
1102 ** --internal|-i use internal diff logic
1103 ** --side-by-side|-y side-by-side diff
1104 ** --strip-trailing-cr Strip trailing CR
1105 ** --tk Launch a Tcl/Tk GUI for display
1106 ** --to VERSION select VERSION as target for the diff
1107 ** --unified unified diff
1108 ** -v|--verbose output complete text of added or deleted files
1109 ** -w Ignore changes to start-of-line and end-of-line
1110 ** whitespace
1111 ** -W|--width Width of lines in side-by-side diff
1112 */
1113 void diff_cmd(void){
1114 int isGDiff; /* True for gdiff. False for normal diff */
1115 int isInternDiff; /* True for internal diff */
1116 int verboseFlag; /* True if -v or --verbose flag is used */
1117
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -1089,28 +1089,26 @@
1089 ** The "--binary" option causes files matching the glob PATTERN to be treated
1090 ** as binary when considering if they should be used with external diff program.
1091 ** This option overrides the "binary-glob" setting.
1092 **
1093 ** Options:
1094 ** --binary PATTERN Treat files that match the glob PATTERN as binary
1095 ** --branch BRANCH Show diff of all changes on BRANCH
1096 ** --brief Show filenames only
1097 ** --context|-c N Use N lines of context
1098 ** --diff-binary BOOL Include binary files when using external commands
1099 ** --from|-r VERSION select VERSION as source for the diff
1100 ** --internal|-i use internal diff logic
1101 ** --side-by-side|-y side-by-side diff
1102 ** --strip-trailing-cr Strip trailing CR
1103 ** --tk Launch a Tcl/Tk GUI for display
1104 ** --to VERSION select VERSION as target for the diff
1105 ** --unified unified diff
1106 ** -v|--verbose output complete text of added or deleted files
1107 ** -w|--ignore-all-space Ignore white space when comparing lines
1108 ** -W|--width <num> Width of lines in side-by-side diff
1109 ** -Z|--ignore-trailing-space Ignore whitespace at line end
 
 
1110 */
1111 void diff_cmd(void){
1112 int isGDiff; /* True for gdiff. False for normal diff */
1113 int isInternDiff; /* True for internal diff */
1114 int verboseFlag; /* True if -v or --verbose flag is used */
1115
+16 -18
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -1089,28 +1089,26 @@
10891089
** The "--binary" option causes files matching the glob PATTERN to be treated
10901090
** as binary when considering if they should be used with external diff program.
10911091
** This option overrides the "binary-glob" setting.
10921092
**
10931093
** Options:
1094
-** --binary PATTERN Treat files that match the glob PATTERN as binary
1095
-** --branch BRANCH Show diff of all changes on BRANCH
1096
-** --brief Show filenames only
1097
-** --context|-c N Use N lines of context
1098
-** --diff-binary BOOL Include binary files when using external commands
1099
-** --from|-r VERSION select VERSION as source for the diff
1100
-** --ignore-space-at-eol Ignore changes to end-of-line whitespace
1101
-** --ignore-space-at-sol Ignore changes to start-of-line whitespace
1102
-** --internal|-i use internal diff logic
1103
-** --side-by-side|-y side-by-side diff
1104
-** --strip-trailing-cr Strip trailing CR
1105
-** --tk Launch a Tcl/Tk GUI for display
1106
-** --to VERSION select VERSION as target for the diff
1107
-** --unified unified diff
1108
-** -v|--verbose output complete text of added or deleted files
1109
-** -w Ignore changes to start-of-line and end-of-line
1110
-** whitespace
1111
-** -W|--width Width of lines in side-by-side diff
1094
+** --binary PATTERN Treat files that match the glob PATTERN as binary
1095
+** --branch BRANCH Show diff of all changes on BRANCH
1096
+** --brief Show filenames only
1097
+** --context|-c N Use N lines of context
1098
+** --diff-binary BOOL Include binary files when using external commands
1099
+** --from|-r VERSION select VERSION as source for the diff
1100
+** --internal|-i use internal diff logic
1101
+** --side-by-side|-y side-by-side diff
1102
+** --strip-trailing-cr Strip trailing CR
1103
+** --tk Launch a Tcl/Tk GUI for display
1104
+** --to VERSION select VERSION as target for the diff
1105
+** --unified unified diff
1106
+** -v|--verbose output complete text of added or deleted files
1107
+** -w|--ignore-all-space Ignore white space when comparing lines
1108
+** -W|--width <num> Width of lines in side-by-side diff
1109
+** -Z|--ignore-trailing-space Ignore whitespace at line end
11121110
*/
11131111
void diff_cmd(void){
11141112
int isGDiff; /* True for gdiff. False for normal diff */
11151113
int isInternDiff; /* True for internal diff */
11161114
int verboseFlag; /* True if -v or --verbose flag is used */
11171115
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -1089,28 +1089,26 @@
1089 ** The "--binary" option causes files matching the glob PATTERN to be treated
1090 ** as binary when considering if they should be used with external diff program.
1091 ** This option overrides the "binary-glob" setting.
1092 **
1093 ** Options:
1094 ** --binary PATTERN Treat files that match the glob PATTERN as binary
1095 ** --branch BRANCH Show diff of all changes on BRANCH
1096 ** --brief Show filenames only
1097 ** --context|-c N Use N lines of context
1098 ** --diff-binary BOOL Include binary files when using external commands
1099 ** --from|-r VERSION select VERSION as source for the diff
1100 ** --ignore-space-at-eol Ignore changes to end-of-line whitespace
1101 ** --ignore-space-at-sol Ignore changes to start-of-line whitespace
1102 ** --internal|-i use internal diff logic
1103 ** --side-by-side|-y side-by-side diff
1104 ** --strip-trailing-cr Strip trailing CR
1105 ** --tk Launch a Tcl/Tk GUI for display
1106 ** --to VERSION select VERSION as target for the diff
1107 ** --unified unified diff
1108 ** -v|--verbose output complete text of added or deleted files
1109 ** -w Ignore changes to start-of-line and end-of-line
1110 ** whitespace
1111 ** -W|--width Width of lines in side-by-side diff
1112 */
1113 void diff_cmd(void){
1114 int isGDiff; /* True for gdiff. False for normal diff */
1115 int isInternDiff; /* True for internal diff */
1116 int verboseFlag; /* True if -v or --verbose flag is used */
1117
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -1089,28 +1089,26 @@
1089 ** The "--binary" option causes files matching the glob PATTERN to be treated
1090 ** as binary when considering if they should be used with external diff program.
1091 ** This option overrides the "binary-glob" setting.
1092 **
1093 ** Options:
1094 ** --binary PATTERN Treat files that match the glob PATTERN as binary
1095 ** --branch BRANCH Show diff of all changes on BRANCH
1096 ** --brief Show filenames only
1097 ** --context|-c N Use N lines of context
1098 ** --diff-binary BOOL Include binary files when using external commands
1099 ** --from|-r VERSION select VERSION as source for the diff
1100 ** --internal|-i use internal diff logic
1101 ** --side-by-side|-y side-by-side diff
1102 ** --strip-trailing-cr Strip trailing CR
1103 ** --tk Launch a Tcl/Tk GUI for display
1104 ** --to VERSION select VERSION as target for the diff
1105 ** --unified unified diff
1106 ** -v|--verbose output complete text of added or deleted files
1107 ** -w|--ignore-all-space Ignore white space when comparing lines
1108 ** -W|--width <num> Width of lines in side-by-side diff
1109 ** -Z|--ignore-trailing-space Ignore whitespace at line end
 
 
1110 */
1111 void diff_cmd(void){
1112 int isGDiff; /* True for gdiff. False for normal diff */
1113 int isInternDiff; /* True for internal diff */
1114 int verboseFlag; /* True if -v or --verbose flag is used */
1115
+5 -5
--- src/info.c
+++ src/info.c
@@ -460,11 +460,11 @@
460460
}else{
461461
diffFlags = DIFF_INLINE;
462462
}
463463
464464
if( P("w") ){
465
- diffFlags |= (DIFF_IGNORE_SOLWS|DIFF_IGNORE_EOLWS);
465
+ diffFlags |= DIFF_IGNORE_ALLWS;
466466
}
467467
/* "dc" query parameter determines lines of context */
468468
x = atoi(PD("dc","7"));
469469
if( x<0 || x>DIFF_CONTEXT_MASK ) x = DIFF_CONTEXT_MASK;
470470
diffFlags += x;
@@ -678,11 +678,11 @@
678678
verboseFlag = !verboseFlag;
679679
zPage = "ci";
680680
zPageHide = "vinfo";
681681
}
682682
diffFlags = construct_diff_flags(verboseFlag, sideBySide);
683
- zW = (diffFlags&(DIFF_IGNORE_SOLWS|DIFF_IGNORE_EOLWS))?"&w":"";
683
+ zW = (diffFlags&DIFF_IGNORE_ALLWS)?"&w":"";
684684
if( verboseFlag ){
685685
@ %z(xhref("class='button'","%R/%s/%T",zPageHide,zName))
686686
@ Hide&nbsp;Diffs</a>
687687
if( sideBySide ){
688688
@ %z(xhref("class='button'","%R/%s/%T?sbs=0%s",zPage,zName,zW))
@@ -988,11 +988,11 @@
988988
zTo = P("to");
989989
if(zGlob && !*zGlob){
990990
zGlob = NULL;
991991
}
992992
diffFlags = construct_diff_flags(verboseFlag, sideBySide);
993
- zW = (diffFlags&(DIFF_IGNORE_SOLWS|DIFF_IGNORE_EOLWS))?"&w":"";
993
+ zW = (diffFlags&DIFF_IGNORE_ALLWS)?"&w":"";
994994
if( sideBySide || verboseFlag ){
995995
style_submenu_element("Hide Diff", "hidediff",
996996
"%R/vdiff?from=%T&to=%T&sbs=0%s%T%s",
997997
zFrom, zTo,
998998
zGlob ? "&glob=" : "", zGlob ? zGlob : "", zW);
@@ -1382,13 +1382,13 @@
13821382
zV1 = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", v1);
13831383
zV2 = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", v2);
13841384
diffFlags = construct_diff_flags(1, sideBySide) | DIFF_HTML;
13851385
13861386
style_header("Diff");
1387
- zW = (diffFlags&(DIFF_IGNORE_SOLWS|DIFF_IGNORE_EOLWS))?"&w":"";
1387
+ zW = (diffFlags&DIFF_IGNORE_ALLWS)?"&w":"";
13881388
if( *zW ){
1389
- diffFlags |= (DIFF_IGNORE_SOLWS|DIFF_IGNORE_EOLWS);
1389
+ diffFlags |= DIFF_IGNORE_ALLWS;
13901390
style_submenu_element("Show Whitespace Changes", "Show Whitespace Changes",
13911391
"%s/fdiff?v1=%T&v2=%T&sbs=%d",
13921392
g.zTop, P("v1"), P("v2"), sideBySide);
13931393
}else{
13941394
style_submenu_element("Ignore Whitespace", "Ignore Whitespace",
13951395
--- src/info.c
+++ src/info.c
@@ -460,11 +460,11 @@
460 }else{
461 diffFlags = DIFF_INLINE;
462 }
463
464 if( P("w") ){
465 diffFlags |= (DIFF_IGNORE_SOLWS|DIFF_IGNORE_EOLWS);
466 }
467 /* "dc" query parameter determines lines of context */
468 x = atoi(PD("dc","7"));
469 if( x<0 || x>DIFF_CONTEXT_MASK ) x = DIFF_CONTEXT_MASK;
470 diffFlags += x;
@@ -678,11 +678,11 @@
678 verboseFlag = !verboseFlag;
679 zPage = "ci";
680 zPageHide = "vinfo";
681 }
682 diffFlags = construct_diff_flags(verboseFlag, sideBySide);
683 zW = (diffFlags&(DIFF_IGNORE_SOLWS|DIFF_IGNORE_EOLWS))?"&w":"";
684 if( verboseFlag ){
685 @ %z(xhref("class='button'","%R/%s/%T",zPageHide,zName))
686 @ Hide&nbsp;Diffs</a>
687 if( sideBySide ){
688 @ %z(xhref("class='button'","%R/%s/%T?sbs=0%s",zPage,zName,zW))
@@ -988,11 +988,11 @@
988 zTo = P("to");
989 if(zGlob && !*zGlob){
990 zGlob = NULL;
991 }
992 diffFlags = construct_diff_flags(verboseFlag, sideBySide);
993 zW = (diffFlags&(DIFF_IGNORE_SOLWS|DIFF_IGNORE_EOLWS))?"&w":"";
994 if( sideBySide || verboseFlag ){
995 style_submenu_element("Hide Diff", "hidediff",
996 "%R/vdiff?from=%T&to=%T&sbs=0%s%T%s",
997 zFrom, zTo,
998 zGlob ? "&glob=" : "", zGlob ? zGlob : "", zW);
@@ -1382,13 +1382,13 @@
1382 zV1 = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", v1);
1383 zV2 = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", v2);
1384 diffFlags = construct_diff_flags(1, sideBySide) | DIFF_HTML;
1385
1386 style_header("Diff");
1387 zW = (diffFlags&(DIFF_IGNORE_SOLWS|DIFF_IGNORE_EOLWS))?"&w":"";
1388 if( *zW ){
1389 diffFlags |= (DIFF_IGNORE_SOLWS|DIFF_IGNORE_EOLWS);
1390 style_submenu_element("Show Whitespace Changes", "Show Whitespace Changes",
1391 "%s/fdiff?v1=%T&v2=%T&sbs=%d",
1392 g.zTop, P("v1"), P("v2"), sideBySide);
1393 }else{
1394 style_submenu_element("Ignore Whitespace", "Ignore Whitespace",
1395
--- src/info.c
+++ src/info.c
@@ -460,11 +460,11 @@
460 }else{
461 diffFlags = DIFF_INLINE;
462 }
463
464 if( P("w") ){
465 diffFlags |= DIFF_IGNORE_ALLWS;
466 }
467 /* "dc" query parameter determines lines of context */
468 x = atoi(PD("dc","7"));
469 if( x<0 || x>DIFF_CONTEXT_MASK ) x = DIFF_CONTEXT_MASK;
470 diffFlags += x;
@@ -678,11 +678,11 @@
678 verboseFlag = !verboseFlag;
679 zPage = "ci";
680 zPageHide = "vinfo";
681 }
682 diffFlags = construct_diff_flags(verboseFlag, sideBySide);
683 zW = (diffFlags&DIFF_IGNORE_ALLWS)?"&w":"";
684 if( verboseFlag ){
685 @ %z(xhref("class='button'","%R/%s/%T",zPageHide,zName))
686 @ Hide&nbsp;Diffs</a>
687 if( sideBySide ){
688 @ %z(xhref("class='button'","%R/%s/%T?sbs=0%s",zPage,zName,zW))
@@ -988,11 +988,11 @@
988 zTo = P("to");
989 if(zGlob && !*zGlob){
990 zGlob = NULL;
991 }
992 diffFlags = construct_diff_flags(verboseFlag, sideBySide);
993 zW = (diffFlags&DIFF_IGNORE_ALLWS)?"&w":"";
994 if( sideBySide || verboseFlag ){
995 style_submenu_element("Hide Diff", "hidediff",
996 "%R/vdiff?from=%T&to=%T&sbs=0%s%T%s",
997 zFrom, zTo,
998 zGlob ? "&glob=" : "", zGlob ? zGlob : "", zW);
@@ -1382,13 +1382,13 @@
1382 zV1 = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", v1);
1383 zV2 = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", v2);
1384 diffFlags = construct_diff_flags(1, sideBySide) | DIFF_HTML;
1385
1386 style_header("Diff");
1387 zW = (diffFlags&DIFF_IGNORE_ALLWS)?"&w":"";
1388 if( *zW ){
1389 diffFlags |= DIFF_IGNORE_ALLWS;
1390 style_submenu_element("Show Whitespace Changes", "Show Whitespace Changes",
1391 "%s/fdiff?v1=%T&v2=%T&sbs=%d",
1392 g.zTop, P("v1"), P("v2"), sideBySide);
1393 }else{
1394 style_submenu_element("Ignore Whitespace", "Ignore Whitespace",
1395
+5 -5
--- src/info.c
+++ src/info.c
@@ -460,11 +460,11 @@
460460
}else{
461461
diffFlags = DIFF_INLINE;
462462
}
463463
464464
if( P("w") ){
465
- diffFlags |= (DIFF_IGNORE_SOLWS|DIFF_IGNORE_EOLWS);
465
+ diffFlags |= DIFF_IGNORE_ALLWS;
466466
}
467467
/* "dc" query parameter determines lines of context */
468468
x = atoi(PD("dc","7"));
469469
if( x<0 || x>DIFF_CONTEXT_MASK ) x = DIFF_CONTEXT_MASK;
470470
diffFlags += x;
@@ -678,11 +678,11 @@
678678
verboseFlag = !verboseFlag;
679679
zPage = "ci";
680680
zPageHide = "vinfo";
681681
}
682682
diffFlags = construct_diff_flags(verboseFlag, sideBySide);
683
- zW = (diffFlags&(DIFF_IGNORE_SOLWS|DIFF_IGNORE_EOLWS))?"&w":"";
683
+ zW = (diffFlags&DIFF_IGNORE_ALLWS)?"&w":"";
684684
if( verboseFlag ){
685685
@ %z(xhref("class='button'","%R/%s/%T",zPageHide,zName))
686686
@ Hide&nbsp;Diffs</a>
687687
if( sideBySide ){
688688
@ %z(xhref("class='button'","%R/%s/%T?sbs=0%s",zPage,zName,zW))
@@ -988,11 +988,11 @@
988988
zTo = P("to");
989989
if(zGlob && !*zGlob){
990990
zGlob = NULL;
991991
}
992992
diffFlags = construct_diff_flags(verboseFlag, sideBySide);
993
- zW = (diffFlags&(DIFF_IGNORE_SOLWS|DIFF_IGNORE_EOLWS))?"&w":"";
993
+ zW = (diffFlags&DIFF_IGNORE_ALLWS)?"&w":"";
994994
if( sideBySide || verboseFlag ){
995995
style_submenu_element("Hide Diff", "hidediff",
996996
"%R/vdiff?from=%T&to=%T&sbs=0%s%T%s",
997997
zFrom, zTo,
998998
zGlob ? "&glob=" : "", zGlob ? zGlob : "", zW);
@@ -1382,13 +1382,13 @@
13821382
zV1 = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", v1);
13831383
zV2 = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", v2);
13841384
diffFlags = construct_diff_flags(1, sideBySide) | DIFF_HTML;
13851385
13861386
style_header("Diff");
1387
- zW = (diffFlags&(DIFF_IGNORE_SOLWS|DIFF_IGNORE_EOLWS))?"&w":"";
1387
+ zW = (diffFlags&DIFF_IGNORE_ALLWS)?"&w":"";
13881388
if( *zW ){
1389
- diffFlags |= (DIFF_IGNORE_SOLWS|DIFF_IGNORE_EOLWS);
1389
+ diffFlags |= DIFF_IGNORE_ALLWS;
13901390
style_submenu_element("Show Whitespace Changes", "Show Whitespace Changes",
13911391
"%s/fdiff?v1=%T&v2=%T&sbs=%d",
13921392
g.zTop, P("v1"), P("v2"), sideBySide);
13931393
}else{
13941394
style_submenu_element("Ignore Whitespace", "Ignore Whitespace",
13951395
--- src/info.c
+++ src/info.c
@@ -460,11 +460,11 @@
460 }else{
461 diffFlags = DIFF_INLINE;
462 }
463
464 if( P("w") ){
465 diffFlags |= (DIFF_IGNORE_SOLWS|DIFF_IGNORE_EOLWS);
466 }
467 /* "dc" query parameter determines lines of context */
468 x = atoi(PD("dc","7"));
469 if( x<0 || x>DIFF_CONTEXT_MASK ) x = DIFF_CONTEXT_MASK;
470 diffFlags += x;
@@ -678,11 +678,11 @@
678 verboseFlag = !verboseFlag;
679 zPage = "ci";
680 zPageHide = "vinfo";
681 }
682 diffFlags = construct_diff_flags(verboseFlag, sideBySide);
683 zW = (diffFlags&(DIFF_IGNORE_SOLWS|DIFF_IGNORE_EOLWS))?"&w":"";
684 if( verboseFlag ){
685 @ %z(xhref("class='button'","%R/%s/%T",zPageHide,zName))
686 @ Hide&nbsp;Diffs</a>
687 if( sideBySide ){
688 @ %z(xhref("class='button'","%R/%s/%T?sbs=0%s",zPage,zName,zW))
@@ -988,11 +988,11 @@
988 zTo = P("to");
989 if(zGlob && !*zGlob){
990 zGlob = NULL;
991 }
992 diffFlags = construct_diff_flags(verboseFlag, sideBySide);
993 zW = (diffFlags&(DIFF_IGNORE_SOLWS|DIFF_IGNORE_EOLWS))?"&w":"";
994 if( sideBySide || verboseFlag ){
995 style_submenu_element("Hide Diff", "hidediff",
996 "%R/vdiff?from=%T&to=%T&sbs=0%s%T%s",
997 zFrom, zTo,
998 zGlob ? "&glob=" : "", zGlob ? zGlob : "", zW);
@@ -1382,13 +1382,13 @@
1382 zV1 = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", v1);
1383 zV2 = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", v2);
1384 diffFlags = construct_diff_flags(1, sideBySide) | DIFF_HTML;
1385
1386 style_header("Diff");
1387 zW = (diffFlags&(DIFF_IGNORE_SOLWS|DIFF_IGNORE_EOLWS))?"&w":"";
1388 if( *zW ){
1389 diffFlags |= (DIFF_IGNORE_SOLWS|DIFF_IGNORE_EOLWS);
1390 style_submenu_element("Show Whitespace Changes", "Show Whitespace Changes",
1391 "%s/fdiff?v1=%T&v2=%T&sbs=%d",
1392 g.zTop, P("v1"), P("v2"), sideBySide);
1393 }else{
1394 style_submenu_element("Ignore Whitespace", "Ignore Whitespace",
1395
--- src/info.c
+++ src/info.c
@@ -460,11 +460,11 @@
460 }else{
461 diffFlags = DIFF_INLINE;
462 }
463
464 if( P("w") ){
465 diffFlags |= DIFF_IGNORE_ALLWS;
466 }
467 /* "dc" query parameter determines lines of context */
468 x = atoi(PD("dc","7"));
469 if( x<0 || x>DIFF_CONTEXT_MASK ) x = DIFF_CONTEXT_MASK;
470 diffFlags += x;
@@ -678,11 +678,11 @@
678 verboseFlag = !verboseFlag;
679 zPage = "ci";
680 zPageHide = "vinfo";
681 }
682 diffFlags = construct_diff_flags(verboseFlag, sideBySide);
683 zW = (diffFlags&DIFF_IGNORE_ALLWS)?"&w":"";
684 if( verboseFlag ){
685 @ %z(xhref("class='button'","%R/%s/%T",zPageHide,zName))
686 @ Hide&nbsp;Diffs</a>
687 if( sideBySide ){
688 @ %z(xhref("class='button'","%R/%s/%T?sbs=0%s",zPage,zName,zW))
@@ -988,11 +988,11 @@
988 zTo = P("to");
989 if(zGlob && !*zGlob){
990 zGlob = NULL;
991 }
992 diffFlags = construct_diff_flags(verboseFlag, sideBySide);
993 zW = (diffFlags&DIFF_IGNORE_ALLWS)?"&w":"";
994 if( sideBySide || verboseFlag ){
995 style_submenu_element("Hide Diff", "hidediff",
996 "%R/vdiff?from=%T&to=%T&sbs=0%s%T%s",
997 zFrom, zTo,
998 zGlob ? "&glob=" : "", zGlob ? zGlob : "", zW);
@@ -1382,13 +1382,13 @@
1382 zV1 = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", v1);
1383 zV2 = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", v2);
1384 diffFlags = construct_diff_flags(1, sideBySide) | DIFF_HTML;
1385
1386 style_header("Diff");
1387 zW = (diffFlags&DIFF_IGNORE_ALLWS)?"&w":"";
1388 if( *zW ){
1389 diffFlags |= DIFF_IGNORE_ALLWS;
1390 style_submenu_element("Show Whitespace Changes", "Show Whitespace Changes",
1391 "%s/fdiff?v1=%T&v2=%T&sbs=%d",
1392 g.zTop, P("v1"), P("v2"), sideBySide);
1393 }else{
1394 style_submenu_element("Ignore Whitespace", "Ignore Whitespace",
1395
--- src/makemake.tcl
+++ src/makemake.tcl
@@ -798,11 +798,11 @@
798798
writeln "\t\$(XTCC) -o \$(OBJDIR)/$s.o -c \$(OBJDIR)/${s}_.c\n"
799799
writeln "\$(OBJDIR)/${s}.h:\t\$(OBJDIR)/headers\n"
800800
}
801801
802802
set MINGW_SQLITE_OPTIONS $SQLITE_OPTIONS
803
-lappend MINGW_SQLITE_OPTIONS -D_HAVE_SQLITE_CONFIG_H
803
+lappend MINGW_SQLITE_OPTIONS -D_HAVE__MINGW_H
804804
lappend MINGW_SQLITE_OPTIONS -DSQLITE_USE_MALLOC_H
805805
lappend MINGW_SQLITE_OPTIONS -DSQLITE_USE_MSIZE
806806
807807
set j " \\\n "
808808
writeln "SQLITE_OPTIONS = [join $MINGW_SQLITE_OPTIONS $j]\n"
809809
--- src/makemake.tcl
+++ src/makemake.tcl
@@ -798,11 +798,11 @@
798 writeln "\t\$(XTCC) -o \$(OBJDIR)/$s.o -c \$(OBJDIR)/${s}_.c\n"
799 writeln "\$(OBJDIR)/${s}.h:\t\$(OBJDIR)/headers\n"
800 }
801
802 set MINGW_SQLITE_OPTIONS $SQLITE_OPTIONS
803 lappend MINGW_SQLITE_OPTIONS -D_HAVE_SQLITE_CONFIG_H
804 lappend MINGW_SQLITE_OPTIONS -DSQLITE_USE_MALLOC_H
805 lappend MINGW_SQLITE_OPTIONS -DSQLITE_USE_MSIZE
806
807 set j " \\\n "
808 writeln "SQLITE_OPTIONS = [join $MINGW_SQLITE_OPTIONS $j]\n"
809
--- src/makemake.tcl
+++ src/makemake.tcl
@@ -798,11 +798,11 @@
798 writeln "\t\$(XTCC) -o \$(OBJDIR)/$s.o -c \$(OBJDIR)/${s}_.c\n"
799 writeln "\$(OBJDIR)/${s}.h:\t\$(OBJDIR)/headers\n"
800 }
801
802 set MINGW_SQLITE_OPTIONS $SQLITE_OPTIONS
803 lappend MINGW_SQLITE_OPTIONS -D_HAVE__MINGW_H
804 lappend MINGW_SQLITE_OPTIONS -DSQLITE_USE_MALLOC_H
805 lappend MINGW_SQLITE_OPTIONS -DSQLITE_USE_MSIZE
806
807 set j " \\\n "
808 writeln "SQLITE_OPTIONS = [join $MINGW_SQLITE_OPTIONS $j]\n"
809
+6 -3
--- src/shell.c
+++ src/shell.c
@@ -1182,10 +1182,11 @@
11821182
** itself by 2 spaces.
11831183
**
11841184
** * For each "Goto", if the jump destination is earlier in the program
11851185
** and ends on one of:
11861186
** Yield SeekGt SeekLt RowSetRead Rewind
1187
+** or if the P1 parameter is one instead of zero,
11871188
** then indent all opcodes between the earlier instruction
11881189
** and "Goto" by 2 spaces.
11891190
*/
11901191
static void explain_data_prepare(struct callback_data *p, sqlite3_stmt *pSql){
11911192
const char *zSql; /* The text of the SQL statement */
@@ -1229,11 +1230,13 @@
12291230
p->nIndent = iOp+1;
12301231
12311232
if( str_in_array(zOp, azNext) ){
12321233
for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
12331234
}
1234
- if( str_in_array(zOp, azGoto) && p2op<p->nIndent && abYield[p2op] ){
1235
+ if( str_in_array(zOp, azGoto) && p2op<p->nIndent
1236
+ && (abYield[p2op] || sqlite3_column_int(pSql, 2))
1237
+ ){
12351238
for(i=p2op+1; i<iOp; i++) p->aiIndent[i] += 2;
12361239
}
12371240
}
12381241
12391242
p->iIndent = 0;
@@ -3815,12 +3818,12 @@
38153818
"Enter \".help\" for usage hints.\n",
38163819
sqlite3_libversion(), sqlite3_sourceid()
38173820
);
38183821
if( warnInmemoryDb ){
38193822
printf("Connected to a ");
3820
- printBold("transient in-memory database.");
3821
- printf("\nUse \".open FILENAME\" to reopen on a "
3823
+ printBold("transient in-memory database");
3824
+ printf(".\nUse \".open FILENAME\" to reopen on a "
38223825
"persistent database.\n");
38233826
}
38243827
zHome = find_home_dir();
38253828
if( zHome ){
38263829
nHistory = strlen30(zHome) + 20;
38273830
--- src/shell.c
+++ src/shell.c
@@ -1182,10 +1182,11 @@
1182 ** itself by 2 spaces.
1183 **
1184 ** * For each "Goto", if the jump destination is earlier in the program
1185 ** and ends on one of:
1186 ** Yield SeekGt SeekLt RowSetRead Rewind
 
1187 ** then indent all opcodes between the earlier instruction
1188 ** and "Goto" by 2 spaces.
1189 */
1190 static void explain_data_prepare(struct callback_data *p, sqlite3_stmt *pSql){
1191 const char *zSql; /* The text of the SQL statement */
@@ -1229,11 +1230,13 @@
1229 p->nIndent = iOp+1;
1230
1231 if( str_in_array(zOp, azNext) ){
1232 for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
1233 }
1234 if( str_in_array(zOp, azGoto) && p2op<p->nIndent && abYield[p2op] ){
 
 
1235 for(i=p2op+1; i<iOp; i++) p->aiIndent[i] += 2;
1236 }
1237 }
1238
1239 p->iIndent = 0;
@@ -3815,12 +3818,12 @@
3815 "Enter \".help\" for usage hints.\n",
3816 sqlite3_libversion(), sqlite3_sourceid()
3817 );
3818 if( warnInmemoryDb ){
3819 printf("Connected to a ");
3820 printBold("transient in-memory database.");
3821 printf("\nUse \".open FILENAME\" to reopen on a "
3822 "persistent database.\n");
3823 }
3824 zHome = find_home_dir();
3825 if( zHome ){
3826 nHistory = strlen30(zHome) + 20;
3827
--- src/shell.c
+++ src/shell.c
@@ -1182,10 +1182,11 @@
1182 ** itself by 2 spaces.
1183 **
1184 ** * For each "Goto", if the jump destination is earlier in the program
1185 ** and ends on one of:
1186 ** Yield SeekGt SeekLt RowSetRead Rewind
1187 ** or if the P1 parameter is one instead of zero,
1188 ** then indent all opcodes between the earlier instruction
1189 ** and "Goto" by 2 spaces.
1190 */
1191 static void explain_data_prepare(struct callback_data *p, sqlite3_stmt *pSql){
1192 const char *zSql; /* The text of the SQL statement */
@@ -1229,11 +1230,13 @@
1230 p->nIndent = iOp+1;
1231
1232 if( str_in_array(zOp, azNext) ){
1233 for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
1234 }
1235 if( str_in_array(zOp, azGoto) && p2op<p->nIndent
1236 && (abYield[p2op] || sqlite3_column_int(pSql, 2))
1237 ){
1238 for(i=p2op+1; i<iOp; i++) p->aiIndent[i] += 2;
1239 }
1240 }
1241
1242 p->iIndent = 0;
@@ -3815,12 +3818,12 @@
3818 "Enter \".help\" for usage hints.\n",
3819 sqlite3_libversion(), sqlite3_sourceid()
3820 );
3821 if( warnInmemoryDb ){
3822 printf("Connected to a ");
3823 printBold("transient in-memory database");
3824 printf(".\nUse \".open FILENAME\" to reopen on a "
3825 "persistent database.\n");
3826 }
3827 zHome = find_home_dir();
3828 if( zHome ){
3829 nHistory = strlen30(zHome) + 20;
3830
+105 -17
--- src/sqlite3.c
+++ src/sqlite3.c
@@ -73,12 +73,45 @@
7373
# define _FILE_OFFSET_BITS 64
7474
# endif
7575
# define _LARGEFILE_SOURCE 1
7676
#endif
7777
78
+/*
79
+** For MinGW, check to see if we can include the header file containing its
80
+** version information, among other things. Normally, this internal MinGW
81
+** header file would [only] be included automatically by other MinGW header
82
+** files; however, the contained version information is now required by this
83
+** header file to work around binary compatibility issues (see below) and
84
+** this is the only known way to reliably obtain it. This entire #if block
85
+** would be completely unnecessary if there was any other way of detecting
86
+** MinGW via their preprocessor (e.g. if they customized their GCC to define
87
+** some MinGW-specific macros). When compiling for MinGW, either the
88
+** _HAVE_MINGW_H or _HAVE__MINGW_H (note the extra underscore) macro must be
89
+** defined; otherwise, detection of conditions specific to MinGW will be
90
+** disabled.
91
+*/
92
+#if defined(_HAVE_MINGW_H)
93
+# include "mingw.h"
94
+#elif defined(_HAVE__MINGW_H)
95
+# include "_mingw.h"
96
+#endif
97
+
98
+/*
99
+** For MinGW version 4.x (and higher), check to see if the _USE_32BIT_TIME_T
100
+** define is required to maintain binary compatibility with the MSVC runtime
101
+** library in use (e.g. for Windows XP).
102
+*/
103
+#if !defined(_USE_32BIT_TIME_T) && !defined(_USE_64BIT_TIME_T) && \
104
+ defined(_WIN32) && !defined(_WIN64) && \
105
+ defined(__MINGW_MAJOR_VERSION) && __MINGW_MAJOR_VERSION >= 4 && \
106
+ defined(__MSVCRT__)
107
+# define _USE_32BIT_TIME_T
108
+#endif
109
+
78110
/* The public SQLite interface. The _FILE_OFFSET_BITS macro must appear
79
-** first in QNX.
111
+** first in QNX. Also, the _USE_32BIT_TIME_T macro must appear first for
112
+** MinGW.
80113
*/
81114
/************** Include sqlite3.h in the middle of sqliteInt.h ***************/
82115
/************** Begin file sqlite3.h *****************************************/
83116
/*
84117
** 2001 September 15
@@ -189,11 +222,11 @@
189222
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
190223
** [sqlite_version()] and [sqlite_source_id()].
191224
*/
192225
#define SQLITE_VERSION "3.8.4"
193226
#define SQLITE_VERSION_NUMBER 3008004
194
-#define SQLITE_SOURCE_ID "2014-03-05 19:04:46 0723effc9ccae7c660fb847b36ce9324e0cb5042"
227
+#define SQLITE_SOURCE_ID "2014-03-06 13:38:37 0a4200f95cf46ad620b9fd91f4444114a0c74730"
195228
196229
/*
197230
** CAPI3REF: Run-Time Library Version Numbers
198231
** KEYWORDS: sqlite3_version, sqlite3_sourceid
199232
**
@@ -36451,12 +36484,29 @@
3645136484
** Interfaces for opening a shared library, finding entry points
3645236485
** within the shared library, and closing the shared library.
3645336486
*/
3645436487
static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){
3645536488
HANDLE h;
36489
+#if defined(__CYGWIN__)
36490
+ int nFull = pVfs->mxPathname+1;
36491
+ char *zFull = sqlite3MallocZero( nFull );
36492
+ void *zConverted = 0;
36493
+ if( zFull==0 ){
36494
+ OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0));
36495
+ return 0;
36496
+ }
36497
+ if( winFullPathname(pVfs, zFilename, nFull, zFull)!=SQLITE_OK ){
36498
+ sqlite3_free(zFull);
36499
+ OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0));
36500
+ return 0;
36501
+ }
36502
+ zConverted = winConvertFromUtf8Filename(zFull);
36503
+ sqlite3_free(zFull);
36504
+#else
3645636505
void *zConverted = winConvertFromUtf8Filename(zFilename);
3645736506
UNUSED_PARAMETER(pVfs);
36507
+#endif
3645836508
if( zConverted==0 ){
3645936509
OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0));
3646036510
return 0;
3646136511
}
3646236512
if( osIsNT() ){
@@ -55338,11 +55388,11 @@
5533855388
assert( pIdxKey->default_rc==1
5533955389
|| pIdxKey->default_rc==0
5534055390
|| pIdxKey->default_rc==-1
5534155391
);
5534255392
}else{
55343
- xRecordCompare = 0; /* Not actually used. Avoids a compiler warning. */
55393
+ xRecordCompare = 0; /* All keys are integers */
5534455394
}
5534555395
5534655396
rc = moveToRoot(pCur);
5534755397
if( rc ){
5534855398
return rc;
@@ -62528,10 +62578,14 @@
6252862578
** sqlite3MemRelease() were called from here. With -O2, this jumps
6252962579
** to 6.6 percent. The test case is inserting 1000 rows into a table
6253062580
** with no indexes using a single prepared INSERT statement, bind()
6253162581
** and reset(). Inserts are grouped into a transaction.
6253262582
*/
62583
+ testcase( p->flags & MEM_Agg );
62584
+ testcase( p->flags & MEM_Dyn );
62585
+ testcase( p->flags & MEM_Frame );
62586
+ testcase( p->flags & MEM_RowSet );
6253362587
if( p->flags&(MEM_Agg|MEM_Dyn|MEM_Frame|MEM_RowSet) ){
6253462588
sqlite3VdbeMemRelease(p);
6253562589
}else if( p->zMalloc ){
6253662590
sqlite3DbFree(db, p->zMalloc);
6253762591
p->zMalloc = 0;
@@ -64256,31 +64310,36 @@
6425664310
break;
6425764311
}
6425864312
case 1: { /* 1-byte signed integer */
6425964313
pMem->u.i = ONE_BYTE_INT(buf);
6426064314
pMem->flags = MEM_Int;
64315
+ testcase( pMem->u.i<0 );
6426164316
return 1;
6426264317
}
6426364318
case 2: { /* 2-byte signed integer */
6426464319
pMem->u.i = TWO_BYTE_INT(buf);
6426564320
pMem->flags = MEM_Int;
64321
+ testcase( pMem->u.i<0 );
6426664322
return 2;
6426764323
}
6426864324
case 3: { /* 3-byte signed integer */
6426964325
pMem->u.i = THREE_BYTE_INT(buf);
6427064326
pMem->flags = MEM_Int;
64327
+ testcase( pMem->u.i<0 );
6427164328
return 3;
6427264329
}
6427364330
case 4: { /* 4-byte signed integer */
6427464331
y = FOUR_BYTE_UINT(buf);
6427564332
pMem->u.i = (i64)*(int*)&y;
6427664333
pMem->flags = MEM_Int;
64334
+ testcase( pMem->u.i<0 );
6427764335
return 4;
6427864336
}
6427964337
case 5: { /* 6-byte signed integer */
6428064338
pMem->u.i = FOUR_BYTE_UINT(buf+2) + (((i64)1)<<32)*TWO_BYTE_INT(buf);
6428164339
pMem->flags = MEM_Int;
64340
+ testcase( pMem->u.i<0 );
6428264341
return 6;
6428364342
}
6428464343
case 6: /* 8-byte signed integer */
6428564344
case 7: { /* IEEE floating point */
6428664345
#if !defined(NDEBUG) && !defined(SQLITE_OMIT_FLOATING_POINT)
@@ -64299,10 +64358,11 @@
6429964358
y = FOUR_BYTE_UINT(buf+4);
6430064359
x = (x<<32) | y;
6430164360
if( serial_type==6 ){
6430264361
pMem->u.i = *(i64*)&x;
6430364362
pMem->flags = MEM_Int;
64363
+ testcase( pMem->u.i<0 );
6430464364
}else{
6430564365
assert( sizeof(x)==8 && sizeof(pMem->r)==8 );
6430664366
swapMixedEndianFloat(x);
6430764367
memcpy(&pMem->r, &x, sizeof(x));
6430864368
pMem->flags = sqlite3IsNaN(pMem->r) ? MEM_Null : MEM_Real;
@@ -64644,24 +64704,30 @@
6464464704
u32 y;
6464564705
assert( CORRUPT_DB || (serial_type>=1 && serial_type<=9 && serial_type!=7) );
6464664706
switch( serial_type ){
6464764707
case 0:
6464864708
case 1:
64709
+ testcase( aKey[0]&0x80 );
6464964710
return ONE_BYTE_INT(aKey);
6465064711
case 2:
64712
+ testcase( aKey[0]&0x80 );
6465164713
return TWO_BYTE_INT(aKey);
6465264714
case 3:
64715
+ testcase( aKey[0]&0x80 );
6465364716
return THREE_BYTE_INT(aKey);
6465464717
case 4: {
64718
+ testcase( aKey[0]&0x80 );
6465564719
y = FOUR_BYTE_UINT(aKey);
6465664720
return (i64)*(int*)&y;
6465764721
}
6465864722
case 5: {
64723
+ testcase( aKey[0]&0x80 );
6465964724
return FOUR_BYTE_UINT(aKey+2) + (((i64)1)<<32)*TWO_BYTE_INT(aKey);
6466064725
}
6466164726
case 6: {
6466264727
u64 x = FOUR_BYTE_UINT(aKey);
64728
+ testcase( aKey[0]&0x80 );
6466364729
x = (x<<32) | FOUR_BYTE_UINT(aKey+4);
6466464730
return (i64)*(i64*)&x;
6466564731
}
6466664732
}
6466764733
@@ -64725,10 +64791,11 @@
6472564791
u32 serial_type;
6472664792
6472764793
/* RHS is an integer */
6472864794
if( pRhs->flags & MEM_Int ){
6472964795
serial_type = aKey1[idx1];
64796
+ testcase( serial_type==12 );
6473064797
if( serial_type>=12 ){
6473164798
rc = +1;
6473264799
}else if( serial_type==0 ){
6473364800
rc = -1;
6473464801
}else if( serial_type==7 ){
@@ -64775,16 +64842,19 @@
6477564842
}
6477664843
6477764844
/* RHS is a string */
6477864845
else if( pRhs->flags & MEM_Str ){
6477964846
getVarint32(&aKey1[idx1], serial_type);
64847
+ testcase( serial_type==12 );
6478064848
if( serial_type<12 ){
6478164849
rc = -1;
6478264850
}else if( !(serial_type & 0x01) ){
6478364851
rc = +1;
6478464852
}else{
6478564853
mem1.n = (serial_type - 12) / 2;
64854
+ testcase( (d1+mem1.n)==(unsigned)nKey1 );
64855
+ testcase( (d1+mem1.n+1)==(unsigned)nKey1 );
6478664856
if( (d1+mem1.n) > (unsigned)nKey1 ){
6478764857
rc = 1; /* Corruption */
6478864858
}else if( pKeyInfo->aColl[i] ){
6478964859
mem1.enc = pKeyInfo->enc;
6479064860
mem1.db = pKeyInfo->db;
@@ -64800,14 +64870,17 @@
6480064870
}
6480164871
6480264872
/* RHS is a blob */
6480364873
else if( pRhs->flags & MEM_Blob ){
6480464874
getVarint32(&aKey1[idx1], serial_type);
64875
+ testcase( serial_type==12 );
6480564876
if( serial_type<12 || (serial_type & 0x01) ){
6480664877
rc = -1;
6480764878
}else{
6480864879
int nStr = (serial_type - 12) / 2;
64880
+ testcase( (d1+nStr)==(unsigned)nKey1 );
64881
+ testcase( (d1+nStr+1)==(unsigned)nKey1 );
6480964882
if( (d1+nStr) > (unsigned)nKey1 ){
6481064883
rc = 1; /* Corruption */
6481164884
}else{
6481264885
int nCmp = MIN(nStr, pRhs->n);
6481364886
rc = memcmp(&aKey1[d1], pRhs->z, nCmp);
@@ -64877,33 +64950,39 @@
6487764950
6487864951
assert( bSkip==0 );
6487964952
switch( serial_type ){
6488064953
case 1: { /* 1-byte signed integer */
6488164954
lhs = ONE_BYTE_INT(aKey);
64955
+ testcase( lhs<0 );
6488264956
break;
6488364957
}
6488464958
case 2: { /* 2-byte signed integer */
6488564959
lhs = TWO_BYTE_INT(aKey);
64960
+ testcase( lhs<0 );
6488664961
break;
6488764962
}
6488864963
case 3: { /* 3-byte signed integer */
6488964964
lhs = THREE_BYTE_INT(aKey);
64965
+ testcase( lhs<0 );
6489064966
break;
6489164967
}
6489264968
case 4: { /* 4-byte signed integer */
6489364969
y = FOUR_BYTE_UINT(aKey);
6489464970
lhs = (i64)*(int*)&y;
64971
+ testcase( lhs<0 );
6489564972
break;
6489664973
}
6489764974
case 5: { /* 6-byte signed integer */
6489864975
lhs = FOUR_BYTE_UINT(aKey+2) + (((i64)1)<<32)*TWO_BYTE_INT(aKey);
64976
+ testcase( lhs<0 );
6489964977
break;
6490064978
}
6490164979
case 6: { /* 8-byte signed integer */
6490264980
x = FOUR_BYTE_UINT(aKey);
6490364981
x = (x<<32) | FOUR_BYTE_UINT(aKey+4);
6490464982
lhs = *(i64*)&x;
64983
+ testcase( lhs<0 );
6490564984
break;
6490664985
}
6490764986
case 8:
6490864987
lhs = 0;
6490964988
break;
@@ -65036,13 +65115,15 @@
6503665115
p->r2 = 1;
6503765116
}
6503865117
if( (flags & MEM_Int) ){
6503965118
return vdbeRecordCompareInt;
6504065119
}
65041
- if( (flags & (MEM_Int|MEM_Real|MEM_Null|MEM_Blob))==0
65042
- && p->pKeyInfo->aColl[0]==0
65043
- ){
65120
+ testcase( flags & MEM_Real );
65121
+ testcase( flags & MEM_Null );
65122
+ testcase( flags & MEM_Blob );
65123
+ if( (flags & (MEM_Real|MEM_Null|MEM_Blob))==0 && p->pKeyInfo->aColl[0]==0 ){
65124
+ assert( flags & MEM_Str );
6504465125
return vdbeRecordCompareString;
6504565126
}
6504665127
}
6504765128
6504865129
return sqlite3VdbeRecordCompare;
@@ -66945,11 +67026,11 @@
6694567026
** value of the cell. This macro verifies that shallow copies are
6694667027
** not misused. A shallow copy of a string or blob just copies a
6694767028
** pointer to the string or blob, not the content. If the original
6694867029
** is changed while the copy is still in use, the string or blob might
6694967030
** be changed out from under the copy. This macro verifies that nothing
66950
-** like that every happens.
67031
+** like that ever happens.
6695167032
*/
6695267033
#ifdef SQLITE_DEBUG
6695367034
# define memAboutToChange(P,M) sqlite3VdbeMemAboutToChange(P,M)
6695467035
#else
6695567036
# define memAboutToChange(P,M)
@@ -67677,10 +67758,15 @@
6767767758
**
6767867759
** An unconditional jump to address P2.
6767967760
** The next instruction executed will be
6768067761
** the one at index P2 from the beginning of
6768167762
** the program.
67763
+**
67764
+** The P1 parameter is not actually used by this opcode. However, it
67765
+** is sometimes set to 1 instead of 0 as a hint to the command-line shell
67766
+** that this Goto is the bottom of a loop and that the lines from P2 down
67767
+** to the current line should be indented for EXPLAIN output.
6768267768
*/
6768367769
case OP_Goto: { /* jump */
6768467770
pc = pOp->p2 - 1;
6768567771
6768667772
/* Opcodes that are used as the bottom of a loop (OP_Next, OP_Prev,
@@ -69172,12 +69258,12 @@
6917269258
6917369259
/* Opcode: Once P1 P2 * * *
6917469260
**
6917569261
** Check if OP_Once flag P1 is set. If so, jump to instruction P2. Otherwise,
6917669262
** set the flag and fall through to the next instruction. In other words,
69177
-** this opcode causes all following up codes up through P2 (but not including
69178
-** P2) to run just once and skipped on subsequent times through the loop.
69263
+** this opcode causes all following opcodes up through P2 (but not including
69264
+** P2) to run just once and to be skipped on subsequent times through the loop.
6917969265
*/
6918069266
case OP_Once: { /* jump */
6918169267
assert( pOp->p1<p->nOnceFlag );
6918269268
VdbeBranchTaken(p->aOnceFlag[pOp->p1]!=0, 2);
6918369269
if( p->aOnceFlag[pOp->p1] ){
@@ -83266,11 +83352,14 @@
8326683352
VdbeCoverage(v);
8326783353
callStatGet(v, regStat4, STAT_GET_NEQ, regEq);
8326883354
callStatGet(v, regStat4, STAT_GET_NLT, regLt);
8326983355
callStatGet(v, regStat4, STAT_GET_NDLT, regDLt);
8327083356
sqlite3VdbeAddOp4Int(v, seekOp, iTabCur, addrNext, regSampleRowid, 0);
83271
- VdbeCoverage(v);
83357
+ /* We know that the regSampleRowid row exists because it was read by
83358
+ ** the previous loop. Thus the not-found jump of seekOp will never
83359
+ ** be taken */
83360
+ VdbeCoverageNeverTaken(v);
8327283361
#ifdef SQLITE_ENABLE_STAT3
8327383362
sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur,
8327483363
pIdx->aiColumn[0], regSample);
8327583364
#else
8327683365
for(i=0; i<nCol; i++){
@@ -83280,11 +83369,11 @@
8328083369
sqlite3VdbeAddOp3(v, OP_MakeRecord, regCol, nCol+1, regSample);
8328183370
#endif
8328283371
sqlite3VdbeAddOp3(v, OP_MakeRecord, regTabname, 6, regTemp);
8328383372
sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur+1, regNewRowid);
8328483373
sqlite3VdbeAddOp3(v, OP_Insert, iStatCur+1, regTemp, regNewRowid);
83285
- sqlite3VdbeAddOp2(v, OP_Goto, 0, addrNext);
83374
+ sqlite3VdbeAddOp2(v, OP_Goto, 1, addrNext); /* P1==1 for end-of-loop */
8328683375
sqlite3VdbeJumpHere(v, addrIsNull);
8328783376
}
8328883377
#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
8328983378
8329083379
/* End of analysis */
@@ -93446,17 +93535,17 @@
9344693535
9344793536
/*
9344893537
** Compute the affinity string for table pTab, if it has not already been
9344993538
** computed. As an optimization, omit trailing SQLITE_AFF_NONE affinities.
9345093539
**
93451
-** If the affinity exists (if it is no entirely SQLITE_AFF_NONE values and
93540
+** If the affinity exists (if it is no entirely SQLITE_AFF_NONE values) and
9345293541
** if iReg>0 then code an OP_Affinity opcode that will set the affinities
9345393542
** for register iReg and following. Or if affinities exists and iReg==0,
9345493543
** then just set the P4 operand of the previous opcode (which should be
9345593544
** an OP_MakeRecord) to the affinity string.
9345693545
**
93457
-** A column affinity string has one character column:
93546
+** A column affinity string has one character per column:
9345893547
**
9345993548
** Character Column affinity
9346093549
** ------------------------------
9346193550
** 'a' TEXT
9346293551
** 'b' NONE
@@ -93493,14 +93582,13 @@
9349393582
}
9349493583
}
9349593584
9349693585
/*
9349793586
** Return non-zero if the table pTab in database iDb or any of its indices
93498
-** have been opened at any point in the VDBE program beginning at location
93499
-** iStartAddr throught the end of the program. This is used to see if
93587
+** have been opened at any point in the VDBE program. This is used to see if
9350093588
** a statement of the form "INSERT INTO <iDb, pTab> SELECT ..." can
93501
-** run without using temporary table for the results of the SELECT.
93589
+** run without using a temporary table for the results of the SELECT.
9350293590
*/
9350393591
static int readsTable(Parse *p, int iDb, Table *pTab){
9350493592
Vdbe *v = sqlite3GetVdbe(p);
9350593593
int i;
9350693594
int iEnd = sqlite3VdbeCurrentAddr(v);
@@ -112351,17 +112439,17 @@
112351112439
}
112352112440
if( pLoop->wsFlags & WHERE_TOP_LIMIT ){
112353112441
pRangeEnd = pLoop->aLTerm[j++];
112354112442
nExtraReg = 1;
112355112443
if( pRangeStart==0
112356
- && (pRangeEnd->wtFlags & TERM_VNULL)==0
112357112444
&& (j = pIdx->aiColumn[nEq])>=0
112358112445
&& pIdx->pTable->aCol[j].notNull==0
112359112446
){
112360112447
bSeekPastNull = 1;
112361112448
}
112362112449
}
112450
+ assert( pRangeEnd==0 || (pRangeEnd->wtFlags & TERM_VNULL)==0 );
112363112451
112364112452
/* Generate code to evaluate all constraint terms using == or IN
112365112453
** and store the values of those terms in an array of registers
112366112454
** starting at regBase.
112367112455
*/
112368112456
--- src/sqlite3.c
+++ src/sqlite3.c
@@ -73,12 +73,45 @@
73 # define _FILE_OFFSET_BITS 64
74 # endif
75 # define _LARGEFILE_SOURCE 1
76 #endif
77
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78 /* The public SQLite interface. The _FILE_OFFSET_BITS macro must appear
79 ** first in QNX.
 
80 */
81 /************** Include sqlite3.h in the middle of sqliteInt.h ***************/
82 /************** Begin file sqlite3.h *****************************************/
83 /*
84 ** 2001 September 15
@@ -189,11 +222,11 @@
189 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
190 ** [sqlite_version()] and [sqlite_source_id()].
191 */
192 #define SQLITE_VERSION "3.8.4"
193 #define SQLITE_VERSION_NUMBER 3008004
194 #define SQLITE_SOURCE_ID "2014-03-05 19:04:46 0723effc9ccae7c660fb847b36ce9324e0cb5042"
195
196 /*
197 ** CAPI3REF: Run-Time Library Version Numbers
198 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
199 **
@@ -36451,12 +36484,29 @@
36451 ** Interfaces for opening a shared library, finding entry points
36452 ** within the shared library, and closing the shared library.
36453 */
36454 static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){
36455 HANDLE h;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36456 void *zConverted = winConvertFromUtf8Filename(zFilename);
36457 UNUSED_PARAMETER(pVfs);
 
36458 if( zConverted==0 ){
36459 OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0));
36460 return 0;
36461 }
36462 if( osIsNT() ){
@@ -55338,11 +55388,11 @@
55338 assert( pIdxKey->default_rc==1
55339 || pIdxKey->default_rc==0
55340 || pIdxKey->default_rc==-1
55341 );
55342 }else{
55343 xRecordCompare = 0; /* Not actually used. Avoids a compiler warning. */
55344 }
55345
55346 rc = moveToRoot(pCur);
55347 if( rc ){
55348 return rc;
@@ -62528,10 +62578,14 @@
62528 ** sqlite3MemRelease() were called from here. With -O2, this jumps
62529 ** to 6.6 percent. The test case is inserting 1000 rows into a table
62530 ** with no indexes using a single prepared INSERT statement, bind()
62531 ** and reset(). Inserts are grouped into a transaction.
62532 */
 
 
 
 
62533 if( p->flags&(MEM_Agg|MEM_Dyn|MEM_Frame|MEM_RowSet) ){
62534 sqlite3VdbeMemRelease(p);
62535 }else if( p->zMalloc ){
62536 sqlite3DbFree(db, p->zMalloc);
62537 p->zMalloc = 0;
@@ -64256,31 +64310,36 @@
64256 break;
64257 }
64258 case 1: { /* 1-byte signed integer */
64259 pMem->u.i = ONE_BYTE_INT(buf);
64260 pMem->flags = MEM_Int;
 
64261 return 1;
64262 }
64263 case 2: { /* 2-byte signed integer */
64264 pMem->u.i = TWO_BYTE_INT(buf);
64265 pMem->flags = MEM_Int;
 
64266 return 2;
64267 }
64268 case 3: { /* 3-byte signed integer */
64269 pMem->u.i = THREE_BYTE_INT(buf);
64270 pMem->flags = MEM_Int;
 
64271 return 3;
64272 }
64273 case 4: { /* 4-byte signed integer */
64274 y = FOUR_BYTE_UINT(buf);
64275 pMem->u.i = (i64)*(int*)&y;
64276 pMem->flags = MEM_Int;
 
64277 return 4;
64278 }
64279 case 5: { /* 6-byte signed integer */
64280 pMem->u.i = FOUR_BYTE_UINT(buf+2) + (((i64)1)<<32)*TWO_BYTE_INT(buf);
64281 pMem->flags = MEM_Int;
 
64282 return 6;
64283 }
64284 case 6: /* 8-byte signed integer */
64285 case 7: { /* IEEE floating point */
64286 #if !defined(NDEBUG) && !defined(SQLITE_OMIT_FLOATING_POINT)
@@ -64299,10 +64358,11 @@
64299 y = FOUR_BYTE_UINT(buf+4);
64300 x = (x<<32) | y;
64301 if( serial_type==6 ){
64302 pMem->u.i = *(i64*)&x;
64303 pMem->flags = MEM_Int;
 
64304 }else{
64305 assert( sizeof(x)==8 && sizeof(pMem->r)==8 );
64306 swapMixedEndianFloat(x);
64307 memcpy(&pMem->r, &x, sizeof(x));
64308 pMem->flags = sqlite3IsNaN(pMem->r) ? MEM_Null : MEM_Real;
@@ -64644,24 +64704,30 @@
64644 u32 y;
64645 assert( CORRUPT_DB || (serial_type>=1 && serial_type<=9 && serial_type!=7) );
64646 switch( serial_type ){
64647 case 0:
64648 case 1:
 
64649 return ONE_BYTE_INT(aKey);
64650 case 2:
 
64651 return TWO_BYTE_INT(aKey);
64652 case 3:
 
64653 return THREE_BYTE_INT(aKey);
64654 case 4: {
 
64655 y = FOUR_BYTE_UINT(aKey);
64656 return (i64)*(int*)&y;
64657 }
64658 case 5: {
 
64659 return FOUR_BYTE_UINT(aKey+2) + (((i64)1)<<32)*TWO_BYTE_INT(aKey);
64660 }
64661 case 6: {
64662 u64 x = FOUR_BYTE_UINT(aKey);
 
64663 x = (x<<32) | FOUR_BYTE_UINT(aKey+4);
64664 return (i64)*(i64*)&x;
64665 }
64666 }
64667
@@ -64725,10 +64791,11 @@
64725 u32 serial_type;
64726
64727 /* RHS is an integer */
64728 if( pRhs->flags & MEM_Int ){
64729 serial_type = aKey1[idx1];
 
64730 if( serial_type>=12 ){
64731 rc = +1;
64732 }else if( serial_type==0 ){
64733 rc = -1;
64734 }else if( serial_type==7 ){
@@ -64775,16 +64842,19 @@
64775 }
64776
64777 /* RHS is a string */
64778 else if( pRhs->flags & MEM_Str ){
64779 getVarint32(&aKey1[idx1], serial_type);
 
64780 if( serial_type<12 ){
64781 rc = -1;
64782 }else if( !(serial_type & 0x01) ){
64783 rc = +1;
64784 }else{
64785 mem1.n = (serial_type - 12) / 2;
 
 
64786 if( (d1+mem1.n) > (unsigned)nKey1 ){
64787 rc = 1; /* Corruption */
64788 }else if( pKeyInfo->aColl[i] ){
64789 mem1.enc = pKeyInfo->enc;
64790 mem1.db = pKeyInfo->db;
@@ -64800,14 +64870,17 @@
64800 }
64801
64802 /* RHS is a blob */
64803 else if( pRhs->flags & MEM_Blob ){
64804 getVarint32(&aKey1[idx1], serial_type);
 
64805 if( serial_type<12 || (serial_type & 0x01) ){
64806 rc = -1;
64807 }else{
64808 int nStr = (serial_type - 12) / 2;
 
 
64809 if( (d1+nStr) > (unsigned)nKey1 ){
64810 rc = 1; /* Corruption */
64811 }else{
64812 int nCmp = MIN(nStr, pRhs->n);
64813 rc = memcmp(&aKey1[d1], pRhs->z, nCmp);
@@ -64877,33 +64950,39 @@
64877
64878 assert( bSkip==0 );
64879 switch( serial_type ){
64880 case 1: { /* 1-byte signed integer */
64881 lhs = ONE_BYTE_INT(aKey);
 
64882 break;
64883 }
64884 case 2: { /* 2-byte signed integer */
64885 lhs = TWO_BYTE_INT(aKey);
 
64886 break;
64887 }
64888 case 3: { /* 3-byte signed integer */
64889 lhs = THREE_BYTE_INT(aKey);
 
64890 break;
64891 }
64892 case 4: { /* 4-byte signed integer */
64893 y = FOUR_BYTE_UINT(aKey);
64894 lhs = (i64)*(int*)&y;
 
64895 break;
64896 }
64897 case 5: { /* 6-byte signed integer */
64898 lhs = FOUR_BYTE_UINT(aKey+2) + (((i64)1)<<32)*TWO_BYTE_INT(aKey);
 
64899 break;
64900 }
64901 case 6: { /* 8-byte signed integer */
64902 x = FOUR_BYTE_UINT(aKey);
64903 x = (x<<32) | FOUR_BYTE_UINT(aKey+4);
64904 lhs = *(i64*)&x;
 
64905 break;
64906 }
64907 case 8:
64908 lhs = 0;
64909 break;
@@ -65036,13 +65115,15 @@
65036 p->r2 = 1;
65037 }
65038 if( (flags & MEM_Int) ){
65039 return vdbeRecordCompareInt;
65040 }
65041 if( (flags & (MEM_Int|MEM_Real|MEM_Null|MEM_Blob))==0
65042 && p->pKeyInfo->aColl[0]==0
65043 ){
 
 
65044 return vdbeRecordCompareString;
65045 }
65046 }
65047
65048 return sqlite3VdbeRecordCompare;
@@ -66945,11 +67026,11 @@
66945 ** value of the cell. This macro verifies that shallow copies are
66946 ** not misused. A shallow copy of a string or blob just copies a
66947 ** pointer to the string or blob, not the content. If the original
66948 ** is changed while the copy is still in use, the string or blob might
66949 ** be changed out from under the copy. This macro verifies that nothing
66950 ** like that every happens.
66951 */
66952 #ifdef SQLITE_DEBUG
66953 # define memAboutToChange(P,M) sqlite3VdbeMemAboutToChange(P,M)
66954 #else
66955 # define memAboutToChange(P,M)
@@ -67677,10 +67758,15 @@
67677 **
67678 ** An unconditional jump to address P2.
67679 ** The next instruction executed will be
67680 ** the one at index P2 from the beginning of
67681 ** the program.
 
 
 
 
 
67682 */
67683 case OP_Goto: { /* jump */
67684 pc = pOp->p2 - 1;
67685
67686 /* Opcodes that are used as the bottom of a loop (OP_Next, OP_Prev,
@@ -69172,12 +69258,12 @@
69172
69173 /* Opcode: Once P1 P2 * * *
69174 **
69175 ** Check if OP_Once flag P1 is set. If so, jump to instruction P2. Otherwise,
69176 ** set the flag and fall through to the next instruction. In other words,
69177 ** this opcode causes all following up codes up through P2 (but not including
69178 ** P2) to run just once and skipped on subsequent times through the loop.
69179 */
69180 case OP_Once: { /* jump */
69181 assert( pOp->p1<p->nOnceFlag );
69182 VdbeBranchTaken(p->aOnceFlag[pOp->p1]!=0, 2);
69183 if( p->aOnceFlag[pOp->p1] ){
@@ -83266,11 +83352,14 @@
83266 VdbeCoverage(v);
83267 callStatGet(v, regStat4, STAT_GET_NEQ, regEq);
83268 callStatGet(v, regStat4, STAT_GET_NLT, regLt);
83269 callStatGet(v, regStat4, STAT_GET_NDLT, regDLt);
83270 sqlite3VdbeAddOp4Int(v, seekOp, iTabCur, addrNext, regSampleRowid, 0);
83271 VdbeCoverage(v);
 
 
 
83272 #ifdef SQLITE_ENABLE_STAT3
83273 sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur,
83274 pIdx->aiColumn[0], regSample);
83275 #else
83276 for(i=0; i<nCol; i++){
@@ -83280,11 +83369,11 @@
83280 sqlite3VdbeAddOp3(v, OP_MakeRecord, regCol, nCol+1, regSample);
83281 #endif
83282 sqlite3VdbeAddOp3(v, OP_MakeRecord, regTabname, 6, regTemp);
83283 sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur+1, regNewRowid);
83284 sqlite3VdbeAddOp3(v, OP_Insert, iStatCur+1, regTemp, regNewRowid);
83285 sqlite3VdbeAddOp2(v, OP_Goto, 0, addrNext);
83286 sqlite3VdbeJumpHere(v, addrIsNull);
83287 }
83288 #endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
83289
83290 /* End of analysis */
@@ -93446,17 +93535,17 @@
93446
93447 /*
93448 ** Compute the affinity string for table pTab, if it has not already been
93449 ** computed. As an optimization, omit trailing SQLITE_AFF_NONE affinities.
93450 **
93451 ** If the affinity exists (if it is no entirely SQLITE_AFF_NONE values and
93452 ** if iReg>0 then code an OP_Affinity opcode that will set the affinities
93453 ** for register iReg and following. Or if affinities exists and iReg==0,
93454 ** then just set the P4 operand of the previous opcode (which should be
93455 ** an OP_MakeRecord) to the affinity string.
93456 **
93457 ** A column affinity string has one character column:
93458 **
93459 ** Character Column affinity
93460 ** ------------------------------
93461 ** 'a' TEXT
93462 ** 'b' NONE
@@ -93493,14 +93582,13 @@
93493 }
93494 }
93495
93496 /*
93497 ** Return non-zero if the table pTab in database iDb or any of its indices
93498 ** have been opened at any point in the VDBE program beginning at location
93499 ** iStartAddr throught the end of the program. This is used to see if
93500 ** a statement of the form "INSERT INTO <iDb, pTab> SELECT ..." can
93501 ** run without using temporary table for the results of the SELECT.
93502 */
93503 static int readsTable(Parse *p, int iDb, Table *pTab){
93504 Vdbe *v = sqlite3GetVdbe(p);
93505 int i;
93506 int iEnd = sqlite3VdbeCurrentAddr(v);
@@ -112351,17 +112439,17 @@
112351 }
112352 if( pLoop->wsFlags & WHERE_TOP_LIMIT ){
112353 pRangeEnd = pLoop->aLTerm[j++];
112354 nExtraReg = 1;
112355 if( pRangeStart==0
112356 && (pRangeEnd->wtFlags & TERM_VNULL)==0
112357 && (j = pIdx->aiColumn[nEq])>=0
112358 && pIdx->pTable->aCol[j].notNull==0
112359 ){
112360 bSeekPastNull = 1;
112361 }
112362 }
 
112363
112364 /* Generate code to evaluate all constraint terms using == or IN
112365 ** and store the values of those terms in an array of registers
112366 ** starting at regBase.
112367 */
112368
--- src/sqlite3.c
+++ src/sqlite3.c
@@ -73,12 +73,45 @@
73 # define _FILE_OFFSET_BITS 64
74 # endif
75 # define _LARGEFILE_SOURCE 1
76 #endif
77
78 /*
79 ** For MinGW, check to see if we can include the header file containing its
80 ** version information, among other things. Normally, this internal MinGW
81 ** header file would [only] be included automatically by other MinGW header
82 ** files; however, the contained version information is now required by this
83 ** header file to work around binary compatibility issues (see below) and
84 ** this is the only known way to reliably obtain it. This entire #if block
85 ** would be completely unnecessary if there was any other way of detecting
86 ** MinGW via their preprocessor (e.g. if they customized their GCC to define
87 ** some MinGW-specific macros). When compiling for MinGW, either the
88 ** _HAVE_MINGW_H or _HAVE__MINGW_H (note the extra underscore) macro must be
89 ** defined; otherwise, detection of conditions specific to MinGW will be
90 ** disabled.
91 */
92 #if defined(_HAVE_MINGW_H)
93 # include "mingw.h"
94 #elif defined(_HAVE__MINGW_H)
95 # include "_mingw.h"
96 #endif
97
98 /*
99 ** For MinGW version 4.x (and higher), check to see if the _USE_32BIT_TIME_T
100 ** define is required to maintain binary compatibility with the MSVC runtime
101 ** library in use (e.g. for Windows XP).
102 */
103 #if !defined(_USE_32BIT_TIME_T) && !defined(_USE_64BIT_TIME_T) && \
104 defined(_WIN32) && !defined(_WIN64) && \
105 defined(__MINGW_MAJOR_VERSION) && __MINGW_MAJOR_VERSION >= 4 && \
106 defined(__MSVCRT__)
107 # define _USE_32BIT_TIME_T
108 #endif
109
110 /* The public SQLite interface. The _FILE_OFFSET_BITS macro must appear
111 ** first in QNX. Also, the _USE_32BIT_TIME_T macro must appear first for
112 ** MinGW.
113 */
114 /************** Include sqlite3.h in the middle of sqliteInt.h ***************/
115 /************** Begin file sqlite3.h *****************************************/
116 /*
117 ** 2001 September 15
@@ -189,11 +222,11 @@
222 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
223 ** [sqlite_version()] and [sqlite_source_id()].
224 */
225 #define SQLITE_VERSION "3.8.4"
226 #define SQLITE_VERSION_NUMBER 3008004
227 #define SQLITE_SOURCE_ID "2014-03-06 13:38:37 0a4200f95cf46ad620b9fd91f4444114a0c74730"
228
229 /*
230 ** CAPI3REF: Run-Time Library Version Numbers
231 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
232 **
@@ -36451,12 +36484,29 @@
36484 ** Interfaces for opening a shared library, finding entry points
36485 ** within the shared library, and closing the shared library.
36486 */
36487 static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){
36488 HANDLE h;
36489 #if defined(__CYGWIN__)
36490 int nFull = pVfs->mxPathname+1;
36491 char *zFull = sqlite3MallocZero( nFull );
36492 void *zConverted = 0;
36493 if( zFull==0 ){
36494 OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0));
36495 return 0;
36496 }
36497 if( winFullPathname(pVfs, zFilename, nFull, zFull)!=SQLITE_OK ){
36498 sqlite3_free(zFull);
36499 OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0));
36500 return 0;
36501 }
36502 zConverted = winConvertFromUtf8Filename(zFull);
36503 sqlite3_free(zFull);
36504 #else
36505 void *zConverted = winConvertFromUtf8Filename(zFilename);
36506 UNUSED_PARAMETER(pVfs);
36507 #endif
36508 if( zConverted==0 ){
36509 OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0));
36510 return 0;
36511 }
36512 if( osIsNT() ){
@@ -55338,11 +55388,11 @@
55388 assert( pIdxKey->default_rc==1
55389 || pIdxKey->default_rc==0
55390 || pIdxKey->default_rc==-1
55391 );
55392 }else{
55393 xRecordCompare = 0; /* All keys are integers */
55394 }
55395
55396 rc = moveToRoot(pCur);
55397 if( rc ){
55398 return rc;
@@ -62528,10 +62578,14 @@
62578 ** sqlite3MemRelease() were called from here. With -O2, this jumps
62579 ** to 6.6 percent. The test case is inserting 1000 rows into a table
62580 ** with no indexes using a single prepared INSERT statement, bind()
62581 ** and reset(). Inserts are grouped into a transaction.
62582 */
62583 testcase( p->flags & MEM_Agg );
62584 testcase( p->flags & MEM_Dyn );
62585 testcase( p->flags & MEM_Frame );
62586 testcase( p->flags & MEM_RowSet );
62587 if( p->flags&(MEM_Agg|MEM_Dyn|MEM_Frame|MEM_RowSet) ){
62588 sqlite3VdbeMemRelease(p);
62589 }else if( p->zMalloc ){
62590 sqlite3DbFree(db, p->zMalloc);
62591 p->zMalloc = 0;
@@ -64256,31 +64310,36 @@
64310 break;
64311 }
64312 case 1: { /* 1-byte signed integer */
64313 pMem->u.i = ONE_BYTE_INT(buf);
64314 pMem->flags = MEM_Int;
64315 testcase( pMem->u.i<0 );
64316 return 1;
64317 }
64318 case 2: { /* 2-byte signed integer */
64319 pMem->u.i = TWO_BYTE_INT(buf);
64320 pMem->flags = MEM_Int;
64321 testcase( pMem->u.i<0 );
64322 return 2;
64323 }
64324 case 3: { /* 3-byte signed integer */
64325 pMem->u.i = THREE_BYTE_INT(buf);
64326 pMem->flags = MEM_Int;
64327 testcase( pMem->u.i<0 );
64328 return 3;
64329 }
64330 case 4: { /* 4-byte signed integer */
64331 y = FOUR_BYTE_UINT(buf);
64332 pMem->u.i = (i64)*(int*)&y;
64333 pMem->flags = MEM_Int;
64334 testcase( pMem->u.i<0 );
64335 return 4;
64336 }
64337 case 5: { /* 6-byte signed integer */
64338 pMem->u.i = FOUR_BYTE_UINT(buf+2) + (((i64)1)<<32)*TWO_BYTE_INT(buf);
64339 pMem->flags = MEM_Int;
64340 testcase( pMem->u.i<0 );
64341 return 6;
64342 }
64343 case 6: /* 8-byte signed integer */
64344 case 7: { /* IEEE floating point */
64345 #if !defined(NDEBUG) && !defined(SQLITE_OMIT_FLOATING_POINT)
@@ -64299,10 +64358,11 @@
64358 y = FOUR_BYTE_UINT(buf+4);
64359 x = (x<<32) | y;
64360 if( serial_type==6 ){
64361 pMem->u.i = *(i64*)&x;
64362 pMem->flags = MEM_Int;
64363 testcase( pMem->u.i<0 );
64364 }else{
64365 assert( sizeof(x)==8 && sizeof(pMem->r)==8 );
64366 swapMixedEndianFloat(x);
64367 memcpy(&pMem->r, &x, sizeof(x));
64368 pMem->flags = sqlite3IsNaN(pMem->r) ? MEM_Null : MEM_Real;
@@ -64644,24 +64704,30 @@
64704 u32 y;
64705 assert( CORRUPT_DB || (serial_type>=1 && serial_type<=9 && serial_type!=7) );
64706 switch( serial_type ){
64707 case 0:
64708 case 1:
64709 testcase( aKey[0]&0x80 );
64710 return ONE_BYTE_INT(aKey);
64711 case 2:
64712 testcase( aKey[0]&0x80 );
64713 return TWO_BYTE_INT(aKey);
64714 case 3:
64715 testcase( aKey[0]&0x80 );
64716 return THREE_BYTE_INT(aKey);
64717 case 4: {
64718 testcase( aKey[0]&0x80 );
64719 y = FOUR_BYTE_UINT(aKey);
64720 return (i64)*(int*)&y;
64721 }
64722 case 5: {
64723 testcase( aKey[0]&0x80 );
64724 return FOUR_BYTE_UINT(aKey+2) + (((i64)1)<<32)*TWO_BYTE_INT(aKey);
64725 }
64726 case 6: {
64727 u64 x = FOUR_BYTE_UINT(aKey);
64728 testcase( aKey[0]&0x80 );
64729 x = (x<<32) | FOUR_BYTE_UINT(aKey+4);
64730 return (i64)*(i64*)&x;
64731 }
64732 }
64733
@@ -64725,10 +64791,11 @@
64791 u32 serial_type;
64792
64793 /* RHS is an integer */
64794 if( pRhs->flags & MEM_Int ){
64795 serial_type = aKey1[idx1];
64796 testcase( serial_type==12 );
64797 if( serial_type>=12 ){
64798 rc = +1;
64799 }else if( serial_type==0 ){
64800 rc = -1;
64801 }else if( serial_type==7 ){
@@ -64775,16 +64842,19 @@
64842 }
64843
64844 /* RHS is a string */
64845 else if( pRhs->flags & MEM_Str ){
64846 getVarint32(&aKey1[idx1], serial_type);
64847 testcase( serial_type==12 );
64848 if( serial_type<12 ){
64849 rc = -1;
64850 }else if( !(serial_type & 0x01) ){
64851 rc = +1;
64852 }else{
64853 mem1.n = (serial_type - 12) / 2;
64854 testcase( (d1+mem1.n)==(unsigned)nKey1 );
64855 testcase( (d1+mem1.n+1)==(unsigned)nKey1 );
64856 if( (d1+mem1.n) > (unsigned)nKey1 ){
64857 rc = 1; /* Corruption */
64858 }else if( pKeyInfo->aColl[i] ){
64859 mem1.enc = pKeyInfo->enc;
64860 mem1.db = pKeyInfo->db;
@@ -64800,14 +64870,17 @@
64870 }
64871
64872 /* RHS is a blob */
64873 else if( pRhs->flags & MEM_Blob ){
64874 getVarint32(&aKey1[idx1], serial_type);
64875 testcase( serial_type==12 );
64876 if( serial_type<12 || (serial_type & 0x01) ){
64877 rc = -1;
64878 }else{
64879 int nStr = (serial_type - 12) / 2;
64880 testcase( (d1+nStr)==(unsigned)nKey1 );
64881 testcase( (d1+nStr+1)==(unsigned)nKey1 );
64882 if( (d1+nStr) > (unsigned)nKey1 ){
64883 rc = 1; /* Corruption */
64884 }else{
64885 int nCmp = MIN(nStr, pRhs->n);
64886 rc = memcmp(&aKey1[d1], pRhs->z, nCmp);
@@ -64877,33 +64950,39 @@
64950
64951 assert( bSkip==0 );
64952 switch( serial_type ){
64953 case 1: { /* 1-byte signed integer */
64954 lhs = ONE_BYTE_INT(aKey);
64955 testcase( lhs<0 );
64956 break;
64957 }
64958 case 2: { /* 2-byte signed integer */
64959 lhs = TWO_BYTE_INT(aKey);
64960 testcase( lhs<0 );
64961 break;
64962 }
64963 case 3: { /* 3-byte signed integer */
64964 lhs = THREE_BYTE_INT(aKey);
64965 testcase( lhs<0 );
64966 break;
64967 }
64968 case 4: { /* 4-byte signed integer */
64969 y = FOUR_BYTE_UINT(aKey);
64970 lhs = (i64)*(int*)&y;
64971 testcase( lhs<0 );
64972 break;
64973 }
64974 case 5: { /* 6-byte signed integer */
64975 lhs = FOUR_BYTE_UINT(aKey+2) + (((i64)1)<<32)*TWO_BYTE_INT(aKey);
64976 testcase( lhs<0 );
64977 break;
64978 }
64979 case 6: { /* 8-byte signed integer */
64980 x = FOUR_BYTE_UINT(aKey);
64981 x = (x<<32) | FOUR_BYTE_UINT(aKey+4);
64982 lhs = *(i64*)&x;
64983 testcase( lhs<0 );
64984 break;
64985 }
64986 case 8:
64987 lhs = 0;
64988 break;
@@ -65036,13 +65115,15 @@
65115 p->r2 = 1;
65116 }
65117 if( (flags & MEM_Int) ){
65118 return vdbeRecordCompareInt;
65119 }
65120 testcase( flags & MEM_Real );
65121 testcase( flags & MEM_Null );
65122 testcase( flags & MEM_Blob );
65123 if( (flags & (MEM_Real|MEM_Null|MEM_Blob))==0 && p->pKeyInfo->aColl[0]==0 ){
65124 assert( flags & MEM_Str );
65125 return vdbeRecordCompareString;
65126 }
65127 }
65128
65129 return sqlite3VdbeRecordCompare;
@@ -66945,11 +67026,11 @@
67026 ** value of the cell. This macro verifies that shallow copies are
67027 ** not misused. A shallow copy of a string or blob just copies a
67028 ** pointer to the string or blob, not the content. If the original
67029 ** is changed while the copy is still in use, the string or blob might
67030 ** be changed out from under the copy. This macro verifies that nothing
67031 ** like that ever happens.
67032 */
67033 #ifdef SQLITE_DEBUG
67034 # define memAboutToChange(P,M) sqlite3VdbeMemAboutToChange(P,M)
67035 #else
67036 # define memAboutToChange(P,M)
@@ -67677,10 +67758,15 @@
67758 **
67759 ** An unconditional jump to address P2.
67760 ** The next instruction executed will be
67761 ** the one at index P2 from the beginning of
67762 ** the program.
67763 **
67764 ** The P1 parameter is not actually used by this opcode. However, it
67765 ** is sometimes set to 1 instead of 0 as a hint to the command-line shell
67766 ** that this Goto is the bottom of a loop and that the lines from P2 down
67767 ** to the current line should be indented for EXPLAIN output.
67768 */
67769 case OP_Goto: { /* jump */
67770 pc = pOp->p2 - 1;
67771
67772 /* Opcodes that are used as the bottom of a loop (OP_Next, OP_Prev,
@@ -69172,12 +69258,12 @@
69258
69259 /* Opcode: Once P1 P2 * * *
69260 **
69261 ** Check if OP_Once flag P1 is set. If so, jump to instruction P2. Otherwise,
69262 ** set the flag and fall through to the next instruction. In other words,
69263 ** this opcode causes all following opcodes up through P2 (but not including
69264 ** P2) to run just once and to be skipped on subsequent times through the loop.
69265 */
69266 case OP_Once: { /* jump */
69267 assert( pOp->p1<p->nOnceFlag );
69268 VdbeBranchTaken(p->aOnceFlag[pOp->p1]!=0, 2);
69269 if( p->aOnceFlag[pOp->p1] ){
@@ -83266,11 +83352,14 @@
83352 VdbeCoverage(v);
83353 callStatGet(v, regStat4, STAT_GET_NEQ, regEq);
83354 callStatGet(v, regStat4, STAT_GET_NLT, regLt);
83355 callStatGet(v, regStat4, STAT_GET_NDLT, regDLt);
83356 sqlite3VdbeAddOp4Int(v, seekOp, iTabCur, addrNext, regSampleRowid, 0);
83357 /* We know that the regSampleRowid row exists because it was read by
83358 ** the previous loop. Thus the not-found jump of seekOp will never
83359 ** be taken */
83360 VdbeCoverageNeverTaken(v);
83361 #ifdef SQLITE_ENABLE_STAT3
83362 sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur,
83363 pIdx->aiColumn[0], regSample);
83364 #else
83365 for(i=0; i<nCol; i++){
@@ -83280,11 +83369,11 @@
83369 sqlite3VdbeAddOp3(v, OP_MakeRecord, regCol, nCol+1, regSample);
83370 #endif
83371 sqlite3VdbeAddOp3(v, OP_MakeRecord, regTabname, 6, regTemp);
83372 sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur+1, regNewRowid);
83373 sqlite3VdbeAddOp3(v, OP_Insert, iStatCur+1, regTemp, regNewRowid);
83374 sqlite3VdbeAddOp2(v, OP_Goto, 1, addrNext); /* P1==1 for end-of-loop */
83375 sqlite3VdbeJumpHere(v, addrIsNull);
83376 }
83377 #endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
83378
83379 /* End of analysis */
@@ -93446,17 +93535,17 @@
93535
93536 /*
93537 ** Compute the affinity string for table pTab, if it has not already been
93538 ** computed. As an optimization, omit trailing SQLITE_AFF_NONE affinities.
93539 **
93540 ** If the affinity exists (if it is no entirely SQLITE_AFF_NONE values) and
93541 ** if iReg>0 then code an OP_Affinity opcode that will set the affinities
93542 ** for register iReg and following. Or if affinities exists and iReg==0,
93543 ** then just set the P4 operand of the previous opcode (which should be
93544 ** an OP_MakeRecord) to the affinity string.
93545 **
93546 ** A column affinity string has one character per column:
93547 **
93548 ** Character Column affinity
93549 ** ------------------------------
93550 ** 'a' TEXT
93551 ** 'b' NONE
@@ -93493,14 +93582,13 @@
93582 }
93583 }
93584
93585 /*
93586 ** Return non-zero if the table pTab in database iDb or any of its indices
93587 ** have been opened at any point in the VDBE program. This is used to see if
 
93588 ** a statement of the form "INSERT INTO <iDb, pTab> SELECT ..." can
93589 ** run without using a temporary table for the results of the SELECT.
93590 */
93591 static int readsTable(Parse *p, int iDb, Table *pTab){
93592 Vdbe *v = sqlite3GetVdbe(p);
93593 int i;
93594 int iEnd = sqlite3VdbeCurrentAddr(v);
@@ -112351,17 +112439,17 @@
112439 }
112440 if( pLoop->wsFlags & WHERE_TOP_LIMIT ){
112441 pRangeEnd = pLoop->aLTerm[j++];
112442 nExtraReg = 1;
112443 if( pRangeStart==0
 
112444 && (j = pIdx->aiColumn[nEq])>=0
112445 && pIdx->pTable->aCol[j].notNull==0
112446 ){
112447 bSeekPastNull = 1;
112448 }
112449 }
112450 assert( pRangeEnd==0 || (pRangeEnd->wtFlags & TERM_VNULL)==0 );
112451
112452 /* Generate code to evaluate all constraint terms using == or IN
112453 ** and store the values of those terms in an array of registers
112454 ** starting at regBase.
112455 */
112456
+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.8.4"
111111
#define SQLITE_VERSION_NUMBER 3008004
112
-#define SQLITE_SOURCE_ID "2014-03-05 19:04:46 0723effc9ccae7c660fb847b36ce9324e0cb5042"
112
+#define SQLITE_SOURCE_ID "2014-03-06 13:38:37 0a4200f95cf46ad620b9fd91f4444114a0c74730"
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.8.4"
111 #define SQLITE_VERSION_NUMBER 3008004
112 #define SQLITE_SOURCE_ID "2014-03-05 19:04:46 0723effc9ccae7c660fb847b36ce9324e0cb5042"
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.8.4"
111 #define SQLITE_VERSION_NUMBER 3008004
112 #define SQLITE_SOURCE_ID "2014-03-06 13:38:37 0a4200f95cf46ad620b9fd91f4444114a0c74730"
113
114 /*
115 ** CAPI3REF: Run-Time Library Version Numbers
116 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
117 **
118
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -1704,11 +1704,11 @@
17041704
-DSQLITE_ENABLE_LOCKING_STYLE=0 \
17051705
-DSQLITE_THREADSAFE=0 \
17061706
-DSQLITE_DEFAULT_FILE_FORMAT=4 \
17071707
-DSQLITE_OMIT_DEPRECATED \
17081708
-DSQLITE_ENABLE_EXPLAIN_COMMENTS \
1709
- -D_HAVE_SQLITE_CONFIG_H \
1709
+ -D_HAVE__MINGW_H \
17101710
-DSQLITE_USE_MALLOC_H \
17111711
-DSQLITE_USE_MSIZE
17121712
17131713
SHELL_OPTIONS = -Dmain=sqlite3_shell \
17141714
-DSQLITE_OMIT_LOAD_EXTENSION=1 \
17151715
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -1704,11 +1704,11 @@
1704 -DSQLITE_ENABLE_LOCKING_STYLE=0 \
1705 -DSQLITE_THREADSAFE=0 \
1706 -DSQLITE_DEFAULT_FILE_FORMAT=4 \
1707 -DSQLITE_OMIT_DEPRECATED \
1708 -DSQLITE_ENABLE_EXPLAIN_COMMENTS \
1709 -D_HAVE_SQLITE_CONFIG_H \
1710 -DSQLITE_USE_MALLOC_H \
1711 -DSQLITE_USE_MSIZE
1712
1713 SHELL_OPTIONS = -Dmain=sqlite3_shell \
1714 -DSQLITE_OMIT_LOAD_EXTENSION=1 \
1715
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -1704,11 +1704,11 @@
1704 -DSQLITE_ENABLE_LOCKING_STYLE=0 \
1705 -DSQLITE_THREADSAFE=0 \
1706 -DSQLITE_DEFAULT_FILE_FORMAT=4 \
1707 -DSQLITE_OMIT_DEPRECATED \
1708 -DSQLITE_ENABLE_EXPLAIN_COMMENTS \
1709 -D_HAVE__MINGW_H \
1710 -DSQLITE_USE_MALLOC_H \
1711 -DSQLITE_USE_MSIZE
1712
1713 SHELL_OPTIONS = -Dmain=sqlite3_shell \
1714 -DSQLITE_OMIT_LOAD_EXTENSION=1 \
1715
--- win/Makefile.mingw.mistachkin
+++ win/Makefile.mingw.mistachkin
@@ -1704,11 +1704,11 @@
17041704
-DSQLITE_ENABLE_LOCKING_STYLE=0 \
17051705
-DSQLITE_THREADSAFE=0 \
17061706
-DSQLITE_DEFAULT_FILE_FORMAT=4 \
17071707
-DSQLITE_OMIT_DEPRECATED \
17081708
-DSQLITE_ENABLE_EXPLAIN_COMMENTS \
1709
- -D_HAVE_SQLITE_CONFIG_H \
1709
+ -D_HAVE__MINGW_H \
17101710
-DSQLITE_USE_MALLOC_H \
17111711
-DSQLITE_USE_MSIZE
17121712
17131713
SHELL_OPTIONS = -Dmain=sqlite3_shell \
17141714
-DSQLITE_OMIT_LOAD_EXTENSION=1 \
17151715
--- win/Makefile.mingw.mistachkin
+++ win/Makefile.mingw.mistachkin
@@ -1704,11 +1704,11 @@
1704 -DSQLITE_ENABLE_LOCKING_STYLE=0 \
1705 -DSQLITE_THREADSAFE=0 \
1706 -DSQLITE_DEFAULT_FILE_FORMAT=4 \
1707 -DSQLITE_OMIT_DEPRECATED \
1708 -DSQLITE_ENABLE_EXPLAIN_COMMENTS \
1709 -D_HAVE_SQLITE_CONFIG_H \
1710 -DSQLITE_USE_MALLOC_H \
1711 -DSQLITE_USE_MSIZE
1712
1713 SHELL_OPTIONS = -Dmain=sqlite3_shell \
1714 -DSQLITE_OMIT_LOAD_EXTENSION=1 \
1715
--- win/Makefile.mingw.mistachkin
+++ win/Makefile.mingw.mistachkin
@@ -1704,11 +1704,11 @@
1704 -DSQLITE_ENABLE_LOCKING_STYLE=0 \
1705 -DSQLITE_THREADSAFE=0 \
1706 -DSQLITE_DEFAULT_FILE_FORMAT=4 \
1707 -DSQLITE_OMIT_DEPRECATED \
1708 -DSQLITE_ENABLE_EXPLAIN_COMMENTS \
1709 -D_HAVE__MINGW_H \
1710 -DSQLITE_USE_MALLOC_H \
1711 -DSQLITE_USE_MSIZE
1712
1713 SHELL_OPTIONS = -Dmain=sqlite3_shell \
1714 -DSQLITE_OMIT_LOAD_EXTENSION=1 \
1715
--- www/changes.wiki
+++ www/changes.wiki
@@ -11,13 +11,17 @@
1111
filter links.
1212
* The [/help/info | info command] now shows leaf status of the checkout.
1313
* Add support for tunneling https through a http proxy (Ticket [e854101c4f]).
1414
* Add option --empty to the "[/help?cmd=open | fossil open]" command.
1515
* Enhanced [/help?cmd=/fileage|the fileage page] to support a glob parameter.
16
- * Add --ignore-space-at-sol and --ignore-space-at-eol options to [/help?cmd=diff|fossil (g)diff],
17
- [/help?cmd=stash|fossil stash diff]. The option -w activates both of them.
18
- * Add button "Ignore Whitespace" to /ci, /vdiff and /fdiff UI pages.
16
+ * Add -w|--ignore-all-space and -Z|--ignore-trailing-space options to
17
+ [/help?cmd=annotate|fossil annotate], [/help?cmd=blame|fossil blame],
18
+ [/help?cmd=diff|fossil (g)diff], [/help?cmd=stash|fossil stash diff].
19
+ * Add --strip-trailing-cr options to [/help?cmd=diff|fossil (g)diff] and
20
+ [/help?cmd=stash|fossil stash diff].
21
+ * Add button "Ignore Whitespace" to /annotate, /blame, /ci, /fdiff
22
+ and /vdiff UI pages.
1923
2024
<h2>Changes For Version 1.28 (2014-01-27)</h2>
2125
* Enhance [/help?cmd=/reports | /reports] to support event type filtering.
2226
* When cloning a repository, the user name passed via the URL (if any)
2327
is now used as the default local admin user's name.
2428
--- www/changes.wiki
+++ www/changes.wiki
@@ -11,13 +11,17 @@
11 filter links.
12 * The [/help/info | info command] now shows leaf status of the checkout.
13 * Add support for tunneling https through a http proxy (Ticket [e854101c4f]).
14 * Add option --empty to the "[/help?cmd=open | fossil open]" command.
15 * Enhanced [/help?cmd=/fileage|the fileage page] to support a glob parameter.
16 * Add --ignore-space-at-sol and --ignore-space-at-eol options to [/help?cmd=diff|fossil (g)diff],
17 [/help?cmd=stash|fossil stash diff]. The option -w activates both of them.
18 * Add button "Ignore Whitespace" to /ci, /vdiff and /fdiff UI pages.
 
 
 
 
19
20 <h2>Changes For Version 1.28 (2014-01-27)</h2>
21 * Enhance [/help?cmd=/reports | /reports] to support event type filtering.
22 * When cloning a repository, the user name passed via the URL (if any)
23 is now used as the default local admin user's name.
24
--- www/changes.wiki
+++ www/changes.wiki
@@ -11,13 +11,17 @@
11 filter links.
12 * The [/help/info | info command] now shows leaf status of the checkout.
13 * Add support for tunneling https through a http proxy (Ticket [e854101c4f]).
14 * Add option --empty to the "[/help?cmd=open | fossil open]" command.
15 * Enhanced [/help?cmd=/fileage|the fileage page] to support a glob parameter.
16 * Add -w|--ignore-all-space and -Z|--ignore-trailing-space options to
17 [/help?cmd=annotate|fossil annotate], [/help?cmd=blame|fossil blame],
18 [/help?cmd=diff|fossil (g)diff], [/help?cmd=stash|fossil stash diff].
19 * Add --strip-trailing-cr options to [/help?cmd=diff|fossil (g)diff] and
20 [/help?cmd=stash|fossil stash diff].
21 * Add button "Ignore Whitespace" to /annotate, /blame, /ci, /fdiff
22 and /vdiff UI pages.
23
24 <h2>Changes For Version 1.28 (2014-01-27)</h2>
25 * Enhance [/help?cmd=/reports | /reports] to support event type filtering.
26 * When cloning a repository, the user name passed via the URL (if any)
27 is now used as the default local admin user's name.
28
--- www/changes.wiki
+++ www/changes.wiki
@@ -11,13 +11,17 @@
1111
filter links.
1212
* The [/help/info | info command] now shows leaf status of the checkout.
1313
* Add support for tunneling https through a http proxy (Ticket [e854101c4f]).
1414
* Add option --empty to the "[/help?cmd=open | fossil open]" command.
1515
* Enhanced [/help?cmd=/fileage|the fileage page] to support a glob parameter.
16
- * Add --ignore-space-at-sol and --ignore-space-at-eol options to [/help?cmd=diff|fossil (g)diff],
17
- [/help?cmd=stash|fossil stash diff]. The option -w activates both of them.
18
- * Add button "Ignore Whitespace" to /ci, /vdiff and /fdiff UI pages.
16
+ * Add -w|--ignore-all-space and -Z|--ignore-trailing-space options to
17
+ [/help?cmd=annotate|fossil annotate], [/help?cmd=blame|fossil blame],
18
+ [/help?cmd=diff|fossil (g)diff], [/help?cmd=stash|fossil stash diff].
19
+ * Add --strip-trailing-cr options to [/help?cmd=diff|fossil (g)diff] and
20
+ [/help?cmd=stash|fossil stash diff].
21
+ * Add button "Ignore Whitespace" to /annotate, /blame, /ci, /fdiff
22
+ and /vdiff UI pages.
1923
2024
<h2>Changes For Version 1.28 (2014-01-27)</h2>
2125
* Enhance [/help?cmd=/reports | /reports] to support event type filtering.
2226
* When cloning a repository, the user name passed via the URL (if any)
2327
is now used as the default local admin user's name.
2428
--- www/changes.wiki
+++ www/changes.wiki
@@ -11,13 +11,17 @@
11 filter links.
12 * The [/help/info | info command] now shows leaf status of the checkout.
13 * Add support for tunneling https through a http proxy (Ticket [e854101c4f]).
14 * Add option --empty to the "[/help?cmd=open | fossil open]" command.
15 * Enhanced [/help?cmd=/fileage|the fileage page] to support a glob parameter.
16 * Add --ignore-space-at-sol and --ignore-space-at-eol options to [/help?cmd=diff|fossil (g)diff],
17 [/help?cmd=stash|fossil stash diff]. The option -w activates both of them.
18 * Add button "Ignore Whitespace" to /ci, /vdiff and /fdiff UI pages.
 
 
 
 
19
20 <h2>Changes For Version 1.28 (2014-01-27)</h2>
21 * Enhance [/help?cmd=/reports | /reports] to support event type filtering.
22 * When cloning a repository, the user name passed via the URL (if any)
23 is now used as the default local admin user's name.
24
--- www/changes.wiki
+++ www/changes.wiki
@@ -11,13 +11,17 @@
11 filter links.
12 * The [/help/info | info command] now shows leaf status of the checkout.
13 * Add support for tunneling https through a http proxy (Ticket [e854101c4f]).
14 * Add option --empty to the "[/help?cmd=open | fossil open]" command.
15 * Enhanced [/help?cmd=/fileage|the fileage page] to support a glob parameter.
16 * Add -w|--ignore-all-space and -Z|--ignore-trailing-space options to
17 [/help?cmd=annotate|fossil annotate], [/help?cmd=blame|fossil blame],
18 [/help?cmd=diff|fossil (g)diff], [/help?cmd=stash|fossil stash diff].
19 * Add --strip-trailing-cr options to [/help?cmd=diff|fossil (g)diff] and
20 [/help?cmd=stash|fossil stash diff].
21 * Add button "Ignore Whitespace" to /annotate, /blame, /ci, /fdiff
22 and /vdiff UI pages.
23
24 <h2>Changes For Version 1.28 (2014-01-27)</h2>
25 * Enhance [/help?cmd=/reports | /reports] to support event type filtering.
26 * When cloning a repository, the user name passed via the URL (if any)
27 is now used as the default local admin user's name.
28

Keyboard Shortcuts

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