Fossil SCM

Merge the updated side-by-side diff logic into trunk.

drh 2013-07-17 12:02 trunk merge
Commit d70ea7ef9c879c74ae2e99a284817d2774b08e8f
+2
--- src/blob.c
+++ src/blob.c
@@ -1096,11 +1096,13 @@
10961096
** to be UTF-8 already, so no conversion is done.
10971097
*/
10981098
void blob_to_utf8_no_bom(Blob *pBlob, int useMbcs){
10991099
char *zUtf8;
11001100
int bomSize = 0;
1101
+#if defined(_WIN32) || defined(__CYGWIN__)
11011102
int bomReverse = 0;
1103
+#endif
11021104
if( starts_with_utf8_bom(pBlob, &bomSize) ){
11031105
struct Blob temp;
11041106
zUtf8 = blob_str(pBlob) + bomSize;
11051107
blob_zero(&temp);
11061108
blob_append(&temp, zUtf8, -1);
11071109
--- src/blob.c
+++ src/blob.c
@@ -1096,11 +1096,13 @@
1096 ** to be UTF-8 already, so no conversion is done.
1097 */
1098 void blob_to_utf8_no_bom(Blob *pBlob, int useMbcs){
1099 char *zUtf8;
1100 int bomSize = 0;
 
1101 int bomReverse = 0;
 
1102 if( starts_with_utf8_bom(pBlob, &bomSize) ){
1103 struct Blob temp;
1104 zUtf8 = blob_str(pBlob) + bomSize;
1105 blob_zero(&temp);
1106 blob_append(&temp, zUtf8, -1);
1107
--- src/blob.c
+++ src/blob.c
@@ -1096,11 +1096,13 @@
1096 ** to be UTF-8 already, so no conversion is done.
1097 */
1098 void blob_to_utf8_no_bom(Blob *pBlob, int useMbcs){
1099 char *zUtf8;
1100 int bomSize = 0;
1101 #if defined(_WIN32) || defined(__CYGWIN__)
1102 int bomReverse = 0;
1103 #endif
1104 if( starts_with_utf8_bom(pBlob, &bomSize) ){
1105 struct Blob temp;
1106 zUtf8 = blob_str(pBlob) + bomSize;
1107 blob_zero(&temp);
1108 blob_append(&temp, zUtf8, -1);
1109
+201 -515
--- src/diff.c
+++ src/diff.c
@@ -51,47 +51,20 @@
5151
"cannot compute difference between binary files\n"
5252
5353
#define DIFF_CANNOT_COMPUTE_SYMLINK \
5454
"cannot compute difference between symlink and regular file\n"
5555
56
-#define DIFF_TOO_MANY_CHANGES_TXT \
56
+#define DIFF_TOO_MANY_CHANGES \
5757
"more than 10,000 changes\n"
5858
59
-#define DIFF_TOO_MANY_CHANGES_HTML \
60
- "<p class='generalError'>More than 10,000 changes</p>\n"
61
-
62
-/*
63
-** This macro is designed to return non-zero if the specified blob contains
64
-** data that MAY be binary in nature; otherwise, zero will be returned.
65
-*/
66
-#define looks_like_binary(blob) \
67
- ((looks_like_utf8((blob), LOOK_BINARY) & LOOK_BINARY) != LOOK_NONE)
68
-
69
-/*
70
-** Output flags for the looks_like_utf8() and looks_like_utf16() routines used
71
-** to convey status information about the blob content.
72
-*/
73
-#define LOOK_NONE ((int)0x00000000) /* Nothing special was found. */
74
-#define LOOK_NUL ((int)0x00000001) /* One or more NUL chars were found. */
75
-#define LOOK_CR ((int)0x00000002) /* One or more CR chars were found. */
76
-#define LOOK_LONE_CR ((int)0x00000004) /* An unpaired CR char was found. */
77
-#define LOOK_LF ((int)0x00000008) /* One or more LF chars were found. */
78
-#define LOOK_LONE_LF ((int)0x00000010) /* An unpaired LF char was found. */
79
-#define LOOK_CRLF ((int)0x00000020) /* One or more CR/LF pairs were found. */
80
-#define LOOK_LONG ((int)0x00000040) /* An over length line was found. */
81
-#define LOOK_ODD ((int)0x00000080) /* An odd number of bytes was found. */
82
-#define LOOK_SHORT ((int)0x00000100) /* Unable to perform full check. */
83
-#define LOOK_INVALID ((int)0x00000200) /* Invalid sequence was found. */
84
-#define LOOK_BINARY (LOOK_NUL | LOOK_LONG | LOOK_SHORT) /* May be binary. */
85
-#define LOOK_EOL (LOOK_LONE_CR | LOOK_LONE_LF | LOOK_CRLF) /* Line seps. */
86
-#endif /* INTERFACE */
87
-
8859
/*
8960
** Maximum length of a line in a text file, in bytes. (2**13 = 8192 bytes)
9061
*/
9162
#define LENGTH_MASK_SZ 13
9263
#define LENGTH_MASK ((1<<LENGTH_MASK_SZ)-1)
64
+
65
+#endif /* INTERFACE */
9366
9467
/*
9568
** Information about each line of a file being diffed.
9669
**
9770
** The lower LENGTH_MASK_SZ bits of the hash (DLine.h) are the length
@@ -204,282 +177,10 @@
204177
/* Return results */
205178
*pnLine = nLine;
206179
return a;
207180
}
208181
209
-/*
210
-** This function attempts to scan each logical line within the blob to
211
-** determine the type of content it appears to contain. The return value
212
-** is a combination of one or more of the LOOK_XXX flags (see above):
213
-**
214
-** !LOOK_BINARY -- The content appears to consist entirely of text; however,
215
-** the encoding may not be UTF-8.
216
-**
217
-** LOOK_BINARY -- The content appears to be binary because it contains one
218
-** or more embedded NUL characters or an extremely long line.
219
-** Since this function does not understand UTF-16, it may
220
-** falsely consider UTF-16 text to be binary.
221
-**
222
-** Additional flags (i.e. those other than the ones included in LOOK_BINARY)
223
-** may be present in the result as well; however, they should not impact the
224
-** determination of text versus binary content.
225
-**
226
-************************************ WARNING **********************************
227
-**
228
-** This function does not validate that the blob content is properly formed
229
-** UTF-8. It assumes that all code points are the same size. It does not
230
-** validate any code points. It makes no attempt to detect if any [invalid]
231
-** switches between UTF-8 and other encodings occur.
232
-**
233
-** The only code points that this function cares about are the NUL character,
234
-** carriage-return, and line-feed.
235
-**
236
-** This function examines the contents of the blob until one of the flags
237
-** specified in "stopFlags" is set.
238
-**
239
-************************************ WARNING **********************************
240
-*/
241
-int looks_like_utf8(const Blob *pContent, int stopFlags){
242
- const char *z = blob_buffer(pContent);
243
- unsigned int n = blob_size(pContent);
244
- int j, c, flags = LOOK_NONE; /* Assume UTF-8 text, prove otherwise */
245
-
246
- if( n==0 ) return flags; /* Empty file -> text */
247
- c = *z;
248
- if( c==0 ){
249
- flags |= LOOK_NUL; /* NUL character in a file -> binary */
250
- }else if( c=='\r' ){
251
- flags |= LOOK_CR;
252
- if( n<=1 || z[1]!='\n' ){
253
- flags |= LOOK_LONE_CR; /* More chars, next char is not LF */
254
- }
255
- }
256
- j = (c!='\n');
257
- if( !j ) flags |= (LOOK_LF | LOOK_LONE_LF); /* Found LF as first char */
258
- while( !(flags&stopFlags) && --n>0 ){
259
- int c2 = c;
260
- c = *++z; ++j;
261
- if( c==0 ){
262
- flags |= LOOK_NUL; /* NUL character in a file -> binary */
263
- }else if( c=='\n' ){
264
- flags |= LOOK_LF;
265
- if( c2=='\r' ){
266
- flags |= (LOOK_CR | LOOK_CRLF); /* Found LF preceded by CR */
267
- }else{
268
- flags |= LOOK_LONE_LF;
269
- }
270
- if( j>LENGTH_MASK ){
271
- flags |= LOOK_LONG; /* Very long line -> binary */
272
- }
273
- j = 0;
274
- }else if( c=='\r' ){
275
- flags |= LOOK_CR;
276
- if( n<=1 || z[1]!='\n' ){
277
- flags |= LOOK_LONE_CR; /* More chars, next char is not LF */
278
- }
279
- }
280
- }
281
- if( n ){
282
- flags |= LOOK_SHORT; /* The whole blob was not examined */
283
- }
284
- if( j>LENGTH_MASK ){
285
- flags |= LOOK_LONG; /* Very long line -> binary */
286
- }
287
- return flags;
288
-}
289
-
290
-/*
291
-** Define the type needed to represent a Unicode (UTF-16) character.
292
-*/
293
-#ifndef WCHAR_T
294
-# ifdef _WIN32
295
-# define WCHAR_T wchar_t
296
-# else
297
-# define WCHAR_T unsigned short
298
-# endif
299
-#endif
300
-
301
-/*
302
-** Maximum length of a line in a text file, in UTF-16 characters. (4096)
303
-** The number of bytes represented by this value cannot exceed LENGTH_MASK
304
-** bytes, because that is the line buffer size used by the diff engine.
305
-*/
306
-#define UTF16_LENGTH_MASK_SZ (LENGTH_MASK_SZ-(sizeof(WCHAR_T)-sizeof(char)))
307
-#define UTF16_LENGTH_MASK ((1<<UTF16_LENGTH_MASK_SZ)-1)
308
-
309
-/*
310
-** This macro is used to swap the byte order of a UTF-16 character in the
311
-** looks_like_utf16() function.
312
-*/
313
-#define UTF16_SWAP(ch) ((((ch) << 8) & 0xFF00) | (((ch) >> 8) & 0xFF))
314
-#define UTF16_SWAP_IF(expr,ch) ((expr) ? UTF16_SWAP((ch)) : (ch))
315
-
316
-/*
317
-** This function attempts to scan each logical line within the blob to
318
-** determine the type of content it appears to contain. The return value
319
-** is a combination of one or more of the LOOK_XXX flags (see above):
320
-**
321
-** !LOOK_BINARY -- The content appears to consist entirely of text; however,
322
-** the encoding may not be UTF-16.
323
-**
324
-** LOOK_BINARY -- The content appears to be binary because it contains one
325
-** or more embedded NUL characters or an extremely long line.
326
-** Since this function does not understand UTF-8, it may
327
-** falsely consider UTF-8 text to be binary.
328
-**
329
-** Additional flags (i.e. those other than the ones included in LOOK_BINARY)
330
-** may be present in the result as well; however, they should not impact the
331
-** determination of text versus binary content.
332
-**
333
-************************************ WARNING **********************************
334
-**
335
-** This function does not validate that the blob content is properly formed
336
-** UTF-16. It assumes that all code points are the same size. It does not
337
-** validate any code points. It makes no attempt to detect if any [invalid]
338
-** switches between the UTF-16be and UTF-16le encodings occur.
339
-**
340
-** The only code points that this function cares about are the NUL character,
341
-** carriage-return, and line-feed.
342
-**
343
-** This function examines the contents of the blob until one of the flags
344
-** specified in "stopFlags" is set.
345
-**
346
-************************************ WARNING **********************************
347
-*/
348
-int looks_like_utf16(const Blob *pContent, int bReverse, int stopFlags){
349
- const WCHAR_T *z = (WCHAR_T *)blob_buffer(pContent);
350
- unsigned int n = blob_size(pContent);
351
- int j, c, flags = LOOK_NONE; /* Assume UTF-16 text, prove otherwise */
352
-
353
- if( n==0 ) return flags; /* Empty file -> text */
354
- if( n%sizeof(WCHAR_T) ){
355
- flags |= LOOK_ODD; /* Odd number of bytes -> binary (UTF-8?) */
356
- if( n<sizeof(WCHAR_T) ) return flags; /* One byte -> binary (UTF-8?) */
357
- }
358
- c = *z;
359
- if( bReverse ){
360
- c = UTF16_SWAP(c);
361
- }
362
- if( c==0 ){
363
- flags |= LOOK_NUL; /* NUL character in a file -> binary */
364
- }else if( c=='\r' ){
365
- flags |= LOOK_CR;
366
- if( n<(2*sizeof(WCHAR_T)) || UTF16_SWAP_IF(bReverse, z[1])!='\n' ){
367
- flags |= LOOK_LONE_CR; /* More chars, next char is not LF */
368
- }
369
- }
370
- j = (c!='\n');
371
- if( !j ) flags |= (LOOK_LF | LOOK_LONE_LF); /* Found LF as first char */
372
- while( 1 ){
373
- int c2 = c;
374
- if( flags&stopFlags ) break;
375
- n -= sizeof(WCHAR_T);
376
- if( n<sizeof(WCHAR_T) ) break;
377
- c = *++z;
378
- if( bReverse ){
379
- c = UTF16_SWAP(c);
380
- }
381
- ++j;
382
- if( c==0 ){
383
- flags |= LOOK_NUL; /* NUL character in a file -> binary */
384
- }else if( c=='\n' ){
385
- flags |= LOOK_LF;
386
- if( c2=='\r' ){
387
- flags |= (LOOK_CR | LOOK_CRLF); /* Found LF preceded by CR */
388
- }else{
389
- flags |= LOOK_LONE_LF;
390
- }
391
- if( j>UTF16_LENGTH_MASK ){
392
- flags |= LOOK_LONG; /* Very long line -> binary */
393
- }
394
- j = 0;
395
- }else if( c=='\r' ){
396
- flags |= LOOK_CR;
397
- if( n<(2*sizeof(WCHAR_T)) || UTF16_SWAP_IF(bReverse, z[1])!='\n' ){
398
- flags |= LOOK_LONE_CR; /* More chars, next char is not LF */
399
- }
400
- }
401
- }
402
- if( n ){
403
- flags |= LOOK_SHORT; /* The whole blob was not examined */
404
- }
405
- if( j>UTF16_LENGTH_MASK ){
406
- flags |= LOOK_LONG; /* Very long line -> binary */
407
- }
408
- return flags;
409
-}
410
-
411
-/*
412
-** This function returns an array of bytes representing the byte-order-mark
413
-** for UTF-8.
414
-*/
415
-const unsigned char *get_utf8_bom(int *pnByte){
416
- static const unsigned char bom[] = {
417
- 0xEF, 0xBB, 0xBF, 0x00, 0x00, 0x00
418
- };
419
- if( pnByte ) *pnByte = 3;
420
- return bom;
421
-}
422
-
423
-/*
424
-** This function returns non-zero if the blob starts with a UTF-8
425
-** byte-order-mark (BOM).
426
-*/
427
-int starts_with_utf8_bom(const Blob *pContent, int *pnByte){
428
- const char *z = blob_buffer(pContent);
429
- int bomSize = 0;
430
- const unsigned char *bom = get_utf8_bom(&bomSize);
431
-
432
- if( pnByte ) *pnByte = bomSize;
433
- if( blob_size(pContent)<bomSize ) return 0;
434
- return memcmp(z, bom, bomSize)==0;
435
-}
436
-
437
-/*
438
-** This function returns non-zero if the blob starts with a UTF-16
439
-** byte-order-mark (BOM), either in the endianness of the machine
440
-** or in reversed byte order. The UTF-32 BOM is ruled out by checking
441
-** if the UTF-16 BOM is not immediately followed by (utf16) 0.
442
-** pnByte is only set when the function returns 1.
443
-**
444
-** pbReverse is always set, even when no BOM is found. Without a BOM,
445
-** it is set to 1 on little-endian and 0 on big-endian platforms. See
446
-** clause D98 of conformance (section 3.10) of the Unicode standard.
447
-*/
448
-int starts_with_utf16_bom(
449
- const Blob *pContent, /* IN: Blob content to perform BOM detection on. */
450
- int *pnByte, /* OUT: The number of bytes used for the BOM. */
451
- int *pbReverse /* OUT: Non-zero for BOM in reverse byte-order. */
452
-){
453
- const unsigned short *z = (unsigned short *)blob_buffer(pContent);
454
- int bomSize = sizeof(unsigned short);
455
- int size = blob_size(pContent);
456
-
457
- if( size<bomSize ) goto noBom; /* No: cannot read BOM. */
458
- if( size>=(2*bomSize) && z[1]==0 ) goto noBom; /* No: possible UTF-32. */
459
- if( z[0]==0xfeff ){
460
- if( pbReverse ) *pbReverse = 0;
461
- }else if( z[0]==0xfffe ){
462
- if( pbReverse ) *pbReverse = 1;
463
- }else{
464
- static const int one = 1;
465
- noBom:
466
- if( pbReverse ) *pbReverse = *(char *) &one;
467
- return 0; /* No: UTF-16 byte-order-mark not found. */
468
- }
469
- if( pnByte ) *pnByte = bomSize;
470
- return 1; /* Yes. */
471
-}
472
-
473
-/*
474
-** Returns non-zero if the specified content could be valid UTF-16.
475
-*/
476
-int could_be_utf16(const Blob *pContent, int *pbReverse){
477
- return (blob_size(pContent) % sizeof(WCHAR_T) == 0) ?
478
- starts_with_utf16_bom(pContent, 0, pbReverse) : 0;
479
-}
480
-
481182
/*
482183
** Return true if two DLine elements are identical.
483184
*/
484185
static int same_dline(DLine *pA, DLine *pB){
485186
return pA->h==pB->h && memcmp(pA->z,pB->z,pA->h & LENGTH_MASK)==0;
@@ -576,11 +277,11 @@
576277
int mxr; /* Maximum value for r */
577278
int na, nb; /* Number of lines shown from A and B */
578279
int i, j; /* Loop counters */
579280
int m; /* Number of lines to output */
580281
int skip; /* Number of lines to skip */
581
- int nChunk = 0; /* Number of diff chunks seen so far */
282
+ static int nChunk = 0; /* Number of diff chunks seen so far */
582283
int nContext; /* Number of lines of context */
583284
int showLn; /* Show line numbers */
584285
int html; /* Render as HTML */
585286
int showDivider = 0; /* True to show the divider between diff blocks */
586287
@@ -657,14 +358,14 @@
657358
if( !showDivider ){
658359
/* Do not show a top divider */
659360
showDivider = 1;
660361
}else if( html ){
661362
blob_appendf(pOut, "<span class=\"diffhr\">%.80c</span>\n", '.');
662
- blob_appendf(pOut, "<a name=\"chunk%d\"></a>\n", nChunk);
663363
}else{
664364
blob_appendf(pOut, "%.80c\n", '.');
665365
}
366
+ if( html ) blob_appendf(pOut, "<span id=\"chunk%d\"></span>", nChunk);
666367
}else{
667368
if( html ) blob_appendf(pOut, "<span class=\"diffln\">");
668369
/*
669370
* If the patch changes an empty file or results in an empty file,
670371
* the block header must use 0,0 as position indicator and not 1,0.
@@ -727,12 +428,11 @@
727428
/*
728429
** Status of a single output line
729430
*/
730431
typedef struct SbsLine SbsLine;
731432
struct SbsLine {
732
- char *zLine; /* The output line under construction */
733
- int n; /* Index of next unused slot in the zLine[] */
433
+ Blob *apCols[5]; /* Array of pointers to output columns */
734434
int width; /* Maximum width of a column in the output */
735435
unsigned char escHtml; /* True to escape html characters */
736436
int iStart; /* Write zStart prior to character iStart */
737437
const char *zStart; /* A <span> tag */
738438
int iEnd; /* Write </span> prior to character iEnd */
@@ -741,125 +441,155 @@
741441
int iEnd2; /* Write </span> prior to character iEnd2 */
742442
ReCompiled *pRe; /* Only colorize matching lines, if not NULL */
743443
};
744444
745445
/*
746
-** Flags for sbsWriteText()
446
+** Column indices for SbsLine.apCols[]
447
+*/
448
+#define SBS_LNA 0 /* Left line number */
449
+#define SBS_TXTA 1 /* Left text */
450
+#define SBS_MKR 2 /* Middle separator column */
451
+#define SBS_LNB 3 /* Right line number */
452
+#define SBS_TXTB 4 /* Right text */
453
+
454
+/*
455
+** Append newlines to all columns.
456
+*/
457
+static void sbsWriteNewlines(SbsLine *p){
458
+ int i;
459
+ for( i=p->escHtml ? SBS_LNA : SBS_TXTB; i<=SBS_TXTB; i++ ){
460
+ blob_append(p->apCols[i], "\n", 1);
461
+ }
462
+}
463
+
464
+/*
465
+** Append n spaces to the column.
747466
*/
748
-#define SBS_NEWLINE 0x0001 /* End with \n\000 */
749
-#define SBS_PAD 0x0002 /* Pad output to width spaces */
467
+static void sbsWriteSpace(SbsLine *p, int n, int col){
468
+ blob_appendf(p->apCols[col], "%*s", n, "");
469
+}
750470
751471
/*
752
-** Write up to width characters of pLine into p->zLine[]. Translate tabs into
753
-** spaces. Add a newline if SBS_NEWLINE is set. Translate HTML characters
754
-** if SBS_HTML is set. Pad the rendering out width bytes if SBS_PAD is set.
472
+** Write the text of pLine into column iCol of p.
473
+**
474
+** If outputting HTML, write the full line. Otherwise, only write the
475
+** width characters. Translate tabs into spaces. Add newlines if col
476
+** is SBS_TXTB. Translate HTML characters if escHtml is true. Pad the
477
+** rendering to width bytes if col is SBS_TXTA and escHtml is false.
755478
**
756479
** This comment contains multibyte unicode characters (ü, Æ, ð) in order
757480
** to test the ability of the diff code to handle such characters.
758481
*/
759
-static void sbsWriteText(SbsLine *p, DLine *pLine, unsigned flags){
482
+static void sbsWriteText(SbsLine *p, DLine *pLine, int col){
483
+ Blob *pCol = p->apCols[col];
760484
int n = pLine->h & LENGTH_MASK;
761485
int i; /* Number of input characters consumed */
762
- int j; /* Number of output characters generated */
763486
int k; /* Cursor position */
764487
int needEndSpan = 0;
765488
const char *zIn = pLine->z;
766
- char *z = &p->zLine[p->n];
767489
int w = p->width;
768490
int colorize = p->escHtml;
769491
if( colorize && p->pRe && re_dline_match(p->pRe, pLine, 1)==0 ){
770492
colorize = 0;
771493
}
772
- for(i=j=k=0; k<w && i<n; i++, k++){
494
+ for(i=k=0; (p->escHtml || k<w) && i<n; i++, k++){
773495
char c = zIn[i];
774496
if( colorize ){
775497
if( i==p->iStart ){
776498
int x = strlen(p->zStart);
777
- memcpy(z+j, p->zStart, x);
778
- j += x;
499
+ blob_append(pCol, p->zStart, x);
779500
needEndSpan = 1;
780501
if( p->iStart2 ){
781502
p->iStart = p->iStart2;
782503
p->zStart = p->zStart2;
783504
p->iStart2 = 0;
784505
}
785506
}else if( i==p->iEnd ){
786
- memcpy(z+j, "</span>", 7);
787
- j += 7;
507
+ blob_append(pCol, "</span>", 7);
788508
needEndSpan = 0;
789509
if( p->iEnd2 ){
790510
p->iEnd = p->iEnd2;
791511
p->iEnd2 = 0;
792512
}
793513
}
794514
}
795515
if( c=='\t' ){
796
- z[j++] = ' ';
797
- while( (k&7)!=7 && k<w ){ z[j++] = ' '; k++; }
516
+ blob_append(pCol, " ", 1);
517
+ while( (k&7)!=7 && (p->escHtml || k<w) ){
518
+ blob_append(pCol, " ", 1);
519
+ k++;
520
+ }
798521
}else if( c=='\r' || c=='\f' ){
799
- z[j++] = ' ';
522
+ blob_append(pCol, " ", 1);
800523
}else if( c=='<' && p->escHtml ){
801
- memcpy(&z[j], "&lt;", 4);
802
- j += 4;
524
+ blob_append(pCol, "&lt;", 4);
803525
}else if( c=='&' && p->escHtml ){
804
- memcpy(&z[j], "&amp;", 5);
805
- j += 5;
526
+ blob_append(pCol, "&amp;", 5);
806527
}else if( c=='>' && p->escHtml ){
807
- memcpy(&z[j], "&gt;", 4);
808
- j += 4;
528
+ blob_append(pCol, "&gt;", 4);
809529
}else if( c=='"' && p->escHtml ){
810
- memcpy(&z[j], "&quot;", 6);
811
- j += 6;
530
+ blob_append(pCol, "&quot;", 6);
812531
}else{
813
- z[j++] = c;
532
+ blob_append(pCol, &zIn[i], 1);
814533
if( (c&0xc0)==0x80 ) k--;
815534
}
816535
}
817536
if( needEndSpan ){
818
- memcpy(&z[j], "</span>", 7);
819
- j += 7;
820
- }
821
- if( (flags & SBS_PAD)!=0 ){
822
- while( k<w ){ k++; z[j++] = ' '; }
823
- }
824
- if( flags & SBS_NEWLINE ){
825
- z[j++] = '\n';
826
- }
827
- p->n += j;
828
-}
829
-
830
-/*
831
-** Append a string to an SbSLine without coding, interpretation, or padding.
832
-*/
833
-static void sbsWrite(SbsLine *p, const char *zIn, int nIn){
834
- memcpy(p->zLine+p->n, zIn, nIn);
835
- p->n += nIn;
836
-}
837
-
838
-/*
839
-** Append n spaces to the string.
840
-*/
841
-static void sbsWriteSpace(SbsLine *p, int n){
842
- while( n-- ) p->zLine[p->n++] = ' ';
843
-}
844
-
845
-/*
846
-** Append a string to the output only if we are rendering HTML.
847
-*/
848
-static void sbsWriteHtml(SbsLine *p, const char *zIn){
849
- if( p->escHtml ) sbsWrite(p, zIn, strlen(zIn));
850
-}
851
-
852
-/*
853
-** Write a 6-digit line number followed by a single space onto the line.
854
-*/
855
-static void sbsWriteLineno(SbsLine *p, int ln){
856
- sbsWriteHtml(p, "<span class=\"diffln\">");
857
- sqlite3_snprintf(7, &p->zLine[p->n], "%5d ", ln+1);
858
- p->n += 6;
859
- sbsWriteHtml(p, "</span>");
860
- p->zLine[p->n++] = ' ';
537
+ blob_append(pCol, "</span>", 7);
538
+ }
539
+ if( col==SBS_TXTB ){
540
+ sbsWriteNewlines(p);
541
+ }else if( !p->escHtml ){
542
+ sbsWriteSpace(p, w-k, SBS_TXTA);
543
+ }
544
+}
545
+
546
+/*
547
+** Append a column to the final output blob.
548
+*/
549
+static void sbsWriteColumn(Blob *pOut, Blob *pCol, int col){
550
+ blob_appendf(pOut,
551
+ "<td><div class=\"diff%scol\">\n"
552
+ "<pre>\n"
553
+ "%s"
554
+ "</pre>\n"
555
+ "</div></td>\n",
556
+ col % 3 ? (col == SBS_MKR ? "mkr" : "txt") : "ln",
557
+ blob_str(pCol)
558
+ );
559
+}
560
+
561
+/*
562
+** Append a separator line to column iCol
563
+*/
564
+static void sbsWriteSep(SbsLine *p, int len, int col){
565
+ char ch = '.';
566
+ if( len<1 ){
567
+ len = 1;
568
+ ch = ' ';
569
+ }
570
+ blob_appendf(p->apCols[col], "<span class=\"diffhr\">%.*c</span>\n", len, ch);
571
+}
572
+
573
+/*
574
+** Append the appropriate marker into the center column of the diff.
575
+*/
576
+static void sbsWriteMarker(SbsLine *p, const char *zTxt, const char *zHtml){
577
+ blob_append(p->apCols[SBS_MKR], p->escHtml ? zHtml : zTxt, -1);
578
+}
579
+
580
+/*
581
+** Append a line number to the column.
582
+*/
583
+static void sbsWriteLineno(SbsLine *p, int ln, int col){
584
+ if( p->escHtml ){
585
+ blob_appendf(p->apCols[col], "%d", ln+1);
586
+ }else{
587
+ char zLn[7];
588
+ sqlite3_snprintf(7, zLn, "%5d ", ln+1);
589
+ blob_appendf(p->apCols[col], "%s ", zLn);
590
+ }
861591
}
862592
863593
/*
864594
** The two text segments zLeft and zRight are known to be different on
865595
** both ends, but they might have a common segment in the middle. If
@@ -1018,43 +748,42 @@
1018748
}
1019749
if( nSuffix==nLeft || nSuffix==nRight ) nPrefix = 0;
1020750
}
1021751
if( nPrefix+nSuffix > nShort ) nPrefix = nShort - nSuffix;
1022752
1023
-
1024753
/* A single chunk of text inserted on the right */
1025754
if( nPrefix+nSuffix==nLeft ){
1026
- sbsWriteLineno(p, lnLeft);
755
+ sbsWriteLineno(p, lnLeft, SBS_LNA);
1027756
p->iStart2 = p->iEnd2 = 0;
1028757
p->iStart = p->iEnd = -1;
1029
- sbsWriteText(p, pLeft, SBS_PAD);
758
+ sbsWriteText(p, pLeft, SBS_TXTA);
1030759
if( nLeft==nRight && zLeft[nLeft]==zRight[nRight] ){
1031
- sbsWrite(p, " ", 3);
760
+ sbsWriteMarker(p, " ", "");
1032761
}else{
1033
- sbsWrite(p, " | ", 3);
762
+ sbsWriteMarker(p, " | ", "|");
1034763
}
1035
- sbsWriteLineno(p, lnRight);
764
+ sbsWriteLineno(p, lnRight, SBS_LNB);
1036765
p->iStart = nPrefix;
1037766
p->iEnd = nRight - nSuffix;
1038767
p->zStart = zClassAdd;
1039
- sbsWriteText(p, pRight, SBS_NEWLINE);
768
+ sbsWriteText(p, pRight, SBS_TXTB);
1040769
return;
1041770
}
1042771
1043772
/* A single chunk of text deleted from the left */
1044773
if( nPrefix+nSuffix==nRight ){
1045774
/* Text deleted from the left */
1046
- sbsWriteLineno(p, lnLeft);
775
+ sbsWriteLineno(p, lnLeft, SBS_LNA);
1047776
p->iStart2 = p->iEnd2 = 0;
1048777
p->iStart = nPrefix;
1049778
p->iEnd = nLeft - nSuffix;
1050779
p->zStart = zClassRm;
1051
- sbsWriteText(p, pLeft, SBS_PAD);
1052
- sbsWrite(p, " | ", 3);
1053
- sbsWriteLineno(p, lnRight);
780
+ sbsWriteText(p, pLeft, SBS_TXTA);
781
+ sbsWriteMarker(p, " | ", "|");
782
+ sbsWriteLineno(p, lnRight, SBS_LNB);
1054783
p->iStart = p->iEnd = -1;
1055
- sbsWriteText(p, pRight, SBS_NEWLINE);
784
+ sbsWriteText(p, pRight, SBS_TXTB);
1056785
return;
1057786
}
1058787
1059788
/* At this point we know that there is a chunk of text that has
1060789
** changed between the left and the right. Check to see if there
@@ -1065,11 +794,11 @@
1065794
if( p->escHtml
1066795
&& nLeftDiff >= 6
1067796
&& nRightDiff >= 6
1068797
&& textLCS(&zLeft[nPrefix], nLeftDiff, &zRight[nPrefix], nRightDiff, aLCS)
1069798
){
1070
- sbsWriteLineno(p, lnLeft);
799
+ sbsWriteLineno(p, lnLeft, SBS_LNA);
1071800
p->iStart = nPrefix;
1072801
p->iEnd = nPrefix + aLCS[0];
1073802
if( aLCS[2]==0 ){
1074803
sbsShiftLeft(p, pLeft->z);
1075804
p->zStart = zClassRm;
@@ -1078,13 +807,13 @@
1078807
}
1079808
p->iStart2 = nPrefix + aLCS[1];
1080809
p->iEnd2 = nLeft - nSuffix;
1081810
p->zStart2 = aLCS[3]==nRightDiff ? zClassRm : zClassChng;
1082811
sbsSimplifyLine(p, zLeft+nPrefix);
1083
- sbsWriteText(p, pLeft, SBS_PAD);
1084
- sbsWrite(p, " | ", 3);
1085
- sbsWriteLineno(p, lnRight);
812
+ sbsWriteText(p, pLeft, SBS_TXTA);
813
+ sbsWriteMarker(p, " | ", "|");
814
+ sbsWriteLineno(p, lnRight, SBS_LNB);
1086815
p->iStart = nPrefix;
1087816
p->iEnd = nPrefix + aLCS[2];
1088817
if( aLCS[0]==0 ){
1089818
sbsShiftLeft(p, pRight->z);
1090819
p->zStart = zClassAdd;
@@ -1093,25 +822,25 @@
1093822
}
1094823
p->iStart2 = nPrefix + aLCS[3];
1095824
p->iEnd2 = nRight - nSuffix;
1096825
p->zStart2 = aLCS[1]==nLeftDiff ? zClassAdd : zClassChng;
1097826
sbsSimplifyLine(p, zRight+nPrefix);
1098
- sbsWriteText(p, pRight, SBS_NEWLINE);
827
+ sbsWriteText(p, pRight, SBS_TXTB);
1099828
return;
1100829
}
1101830
1102831
/* If all else fails, show a single big change between left and right */
1103
- sbsWriteLineno(p, lnLeft);
832
+ sbsWriteLineno(p, lnLeft, SBS_LNA);
1104833
p->iStart2 = p->iEnd2 = 0;
1105834
p->iStart = nPrefix;
1106835
p->iEnd = nLeft - nSuffix;
1107836
p->zStart = zClassChng;
1108
- sbsWriteText(p, pLeft, SBS_PAD);
1109
- sbsWrite(p, " | ", 3);
1110
- sbsWriteLineno(p, lnRight);
837
+ sbsWriteText(p, pLeft, SBS_TXTA);
838
+ sbsWriteMarker(p, " | ", "|");
839
+ sbsWriteLineno(p, lnRight, SBS_LNB);
1111840
p->iEnd = nRight - nSuffix;
1112
- sbsWriteText(p, pRight, SBS_NEWLINE);
841
+ sbsWriteText(p, pRight, SBS_TXTB);
1113842
}
1114843
1115844
/*
1116845
** Minimum of two values
1117846
*/
@@ -1357,30 +1086,40 @@
13571086
int mxr; /* Maximum value for r */
13581087
int na, nb; /* Number of lines shown from A and B */
13591088
int i, j; /* Loop counters */
13601089
int m, ma, mb;/* Number of lines to output */
13611090
int skip; /* Number of lines to skip */
1362
- int nChunk = 0; /* Number of chunks of diff output seen so far */
1091
+ static int nChunk = 0; /* Number of chunks of diff output seen so far */
13631092
SbsLine s; /* Output line buffer */
13641093
int nContext; /* Lines of context above and below each change */
13651094
int showDivider = 0; /* True to show the divider */
1095
+ Blob aCols[5]; /* Array of column blobs */
13661096
13671097
memset(&s, 0, sizeof(s));
13681098
s.width = diff_width(diffFlags);
1369
- s.zLine = fossil_malloc( 15*s.width + 200 );
1370
- if( s.zLine==0 ) return;
13711099
nContext = diff_context_lines(diffFlags);
13721100
s.escHtml = (diffFlags & DIFF_HTML)!=0;
1101
+ if( s.escHtml ){
1102
+ for(i=SBS_LNA; i<=SBS_TXTB; i++){
1103
+ blob_zero(&aCols[i]);
1104
+ s.apCols[i] = &aCols[i];
1105
+ }
1106
+ }else{
1107
+ for(i=SBS_LNA; i<=SBS_TXTB; i++){
1108
+ s.apCols[i] = pOut;
1109
+ }
1110
+ }
13731111
s.pRe = pRe;
13741112
s.iStart = -1;
13751113
s.iStart2 = 0;
13761114
s.iEnd = -1;
13771115
A = p->aFrom;
13781116
B = p->aTo;
13791117
R = p->aEdit;
13801118
mxr = p->nEdit;
13811119
while( mxr>2 && R[mxr-1]==0 && R[mxr-2]==0 ){ mxr -= 3; }
1120
+
13821121
for(r=0; r<mxr; r += 3*nr){
13831122
/* Figure out how many triples to show in a single block */
13841123
for(nr=1; R[r+nr*3]>0 && R[r+nr*3]<nContext*2; nr++){}
13851124
/* printf("r=%d nr=%d\n", r, nr); */
13861125
@@ -1436,35 +1175,39 @@
14361175
}
14371176
14381177
/* Draw the separator between blocks */
14391178
if( showDivider ){
14401179
if( s.escHtml ){
1441
- blob_appendf(pOut, "<span class=\"diffhr\">%.*c</span>\n",
1442
- s.width*2+16, '.');
1180
+ char zLn[10];
1181
+ sqlite3_snprintf(sizeof(zLn), zLn, "%d", a+skip+1);
1182
+ sbsWriteSep(&s, strlen(zLn), SBS_LNA);
1183
+ sbsWriteSep(&s, s.width, SBS_TXTA);
1184
+ sbsWriteSep(&s, 0, SBS_MKR);
1185
+ sqlite3_snprintf(sizeof(zLn), zLn, "%d", b+skip+1);
1186
+ sbsWriteSep(&s, strlen(zLn), SBS_LNB);
1187
+ sbsWriteSep(&s, s.width, SBS_TXTB);
14431188
}else{
14441189
blob_appendf(pOut, "%.*c\n", s.width*2+16, '.');
14451190
}
14461191
}
14471192
showDivider = 1;
14481193
nChunk++;
14491194
if( s.escHtml ){
1450
- blob_appendf(pOut, "<a name=\"chunk%d\"></a>\n", nChunk);
1195
+ blob_appendf(s.apCols[SBS_LNA], "<span id=\"chunk%d\"></span>", nChunk);
14511196
}
14521197
14531198
/* Show the initial common area */
14541199
a += skip;
14551200
b += skip;
14561201
m = R[r] - skip;
14571202
for(j=0; j<m; j++){
1458
- s.n = 0;
1459
- sbsWriteLineno(&s, a+j);
1203
+ sbsWriteLineno(&s, a+j, SBS_LNA);
14601204
s.iStart = s.iEnd = -1;
1461
- sbsWriteText(&s, &A[a+j], SBS_PAD);
1462
- sbsWrite(&s, " ", 3);
1463
- sbsWriteLineno(&s, b+j);
1464
- sbsWriteText(&s, &B[b+j], SBS_NEWLINE);
1465
- blob_append(pOut, s.zLine, s.n);
1205
+ sbsWriteText(&s, &A[a+j], SBS_TXTA);
1206
+ sbsWriteMarker(&s, " ", "");
1207
+ sbsWriteLineno(&s, b+j, SBS_LNB);
1208
+ sbsWriteText(&s, &B[b+j], SBS_TXTB);
14661209
}
14671210
a += m;
14681211
b += m;
14691212
14701213
/* Show the differences */
@@ -1485,87 +1228,71 @@
14851228
14861229
alignment = sbsAlignment(&A[a], ma, &B[b], mb);
14871230
for(j=0; ma+mb>0; j++){
14881231
if( alignment[j]==1 ){
14891232
/* Delete one line from the left */
1490
- s.n = 0;
1491
- sbsWriteLineno(&s, a);
1233
+ sbsWriteLineno(&s, a, SBS_LNA);
14921234
s.iStart = 0;
14931235
s.zStart = "<span class=\"diffrm\">";
14941236
s.iEnd = LENGTH(&A[a]);
1495
- sbsWriteText(&s, &A[a], SBS_PAD);
1496
- if( s.escHtml ){
1497
- sbsWrite(&s, " &lt;\n", 6);
1498
- }else{
1499
- sbsWrite(&s, " <\n", 3);
1500
- }
1501
- blob_append(pOut, s.zLine, s.n);
1237
+ sbsWriteText(&s, &A[a], SBS_TXTA);
1238
+ sbsWriteMarker(&s, " <", "&lt;");
1239
+ sbsWriteNewlines(&s);
15021240
assert( ma>0 );
15031241
ma--;
15041242
a++;
15051243
}else if( alignment[j]==3 ){
15061244
/* The left line is changed into the right line */
1507
- s.n = 0;
15081245
sbsWriteLineChange(&s, &A[a], a, &B[b], b);
1509
- blob_append(pOut, s.zLine, s.n);
15101246
assert( ma>0 && mb>0 );
15111247
ma--;
15121248
mb--;
15131249
a++;
15141250
b++;
15151251
}else if( alignment[j]==2 ){
15161252
/* Insert one line on the right */
1517
- s.n = 0;
1518
- sbsWriteSpace(&s, s.width + 7);
1519
- if( s.escHtml ){
1520
- sbsWrite(&s, " &gt; ", 6);
1521
- }else{
1522
- sbsWrite(&s, " > ", 3);
1523
- }
1524
- sbsWriteLineno(&s, b);
1253
+ if( !s.escHtml ){
1254
+ sbsWriteSpace(&s, s.width + 7, SBS_TXTA);
1255
+ }
1256
+ sbsWriteMarker(&s, " > ", "&gt;");
1257
+ sbsWriteLineno(&s, b, SBS_LNB);
15251258
s.iStart = 0;
15261259
s.zStart = "<span class=\"diffadd\">";
15271260
s.iEnd = LENGTH(&B[b]);
1528
- sbsWriteText(&s, &B[b], SBS_NEWLINE);
1529
- blob_append(pOut, s.zLine, s.n);
1261
+ sbsWriteText(&s, &B[b], SBS_TXTB);
15301262
assert( mb>0 );
15311263
mb--;
15321264
b++;
15331265
}else{
15341266
/* Delete from the left and insert on the right */
1535
- s.n = 0;
1536
- sbsWriteLineno(&s, a);
1267
+ sbsWriteLineno(&s, a, SBS_LNA);
15371268
s.iStart = 0;
15381269
s.zStart = "<span class=\"diffrm\">";
15391270
s.iEnd = LENGTH(&A[a]);
1540
- sbsWriteText(&s, &A[a], SBS_PAD);
1541
- sbsWrite(&s, " | ", 3);
1542
- sbsWriteLineno(&s, b);
1271
+ sbsWriteText(&s, &A[a], SBS_TXTA);
1272
+ sbsWriteMarker(&s, " | ", "|");
1273
+ sbsWriteLineno(&s, b, SBS_LNB);
15431274
s.iStart = 0;
15441275
s.zStart = "<span class=\"diffadd\">";
15451276
s.iEnd = LENGTH(&B[b]);
1546
- sbsWriteText(&s, &B[b], SBS_NEWLINE);
1547
- blob_append(pOut, s.zLine, s.n);
1277
+ sbsWriteText(&s, &B[b], SBS_TXTB);
15481278
ma--;
15491279
mb--;
15501280
a++;
15511281
b++;
15521282
}
1553
-
15541283
}
15551284
fossil_free(alignment);
15561285
if( i<nr-1 ){
15571286
m = R[r+i*3+3];
15581287
for(j=0; j<m; j++){
1559
- s.n = 0;
1560
- sbsWriteLineno(&s, a+j);
1288
+ sbsWriteLineno(&s, a+j, SBS_LNA);
15611289
s.iStart = s.iEnd = -1;
1562
- sbsWriteText(&s, &A[a+j], SBS_PAD);
1563
- sbsWrite(&s, " ", 3);
1564
- sbsWriteLineno(&s, b+j);
1565
- sbsWriteText(&s, &B[b+j], SBS_NEWLINE);
1566
- blob_append(pOut, s.zLine, s.n);
1290
+ sbsWriteText(&s, &A[a+j], SBS_TXTA);
1291
+ sbsWriteMarker(&s, " ", "");
1292
+ sbsWriteLineno(&s, b+j, SBS_LNB);
1293
+ sbsWriteText(&s, &B[b+j], SBS_TXTB);
15671294
}
15681295
b += m;
15691296
a += m;
15701297
}
15711298
}
@@ -1573,21 +1300,27 @@
15731300
/* Show the final common area */
15741301
assert( nr==i );
15751302
m = R[r+nr*3];
15761303
if( m>nContext ) m = nContext;
15771304
for(j=0; j<m; j++){
1578
- s.n = 0;
1579
- sbsWriteLineno(&s, a+j);
1305
+ sbsWriteLineno(&s, a+j, SBS_LNA);
15801306
s.iStart = s.iEnd = -1;
1581
- sbsWriteText(&s, &A[a+j], SBS_PAD);
1582
- sbsWrite(&s, " ", 3);
1583
- sbsWriteLineno(&s, b+j);
1584
- sbsWriteText(&s, &B[b+j], SBS_NEWLINE);
1585
- blob_append(pOut, s.zLine, s.n);
1307
+ sbsWriteText(&s, &A[a+j], SBS_TXTA);
1308
+ sbsWriteMarker(&s, " ", "");
1309
+ sbsWriteLineno(&s, b+j, SBS_LNB);
1310
+ sbsWriteText(&s, &B[b+j], SBS_TXTB);
15861311
}
15871312
}
1588
- free(s.zLine);
1313
+
1314
+ if( s.escHtml && blob_size(s.apCols[SBS_LNA])>0 ){
1315
+ blob_append(pOut, "<table class=\"sbsdiffcols\"><tr>\n", -1);
1316
+ for(i=SBS_LNA; i<=SBS_TXTB; i++){
1317
+ sbsWriteColumn(pOut, s.apCols[i], i);
1318
+ blob_reset(s.apCols[i]);
1319
+ }
1320
+ blob_append(pOut, "</tr></table>\n", -1);
1321
+ }
15891322
}
15901323
15911324
/*
15921325
** Compute the optimal longest common subsequence (LCS) using an
15931326
** exhaustive search. This version of the LCS is only used for
@@ -1990,10 +1723,21 @@
19901723
int diff_width(u64 diffFlags){
19911724
int w = (diffFlags & DIFF_WIDTH_MASK)/(DIFF_CONTEXT_MASK+1);
19921725
if( w==0 ) w = 80;
19931726
return w;
19941727
}
1728
+
1729
+/*
1730
+** Append the error message to pOut.
1731
+*/
1732
+void diff_errmsg(Blob *pOut, const char *msg, int diffFlags){
1733
+ if( diffFlags & DIFF_HTML ){
1734
+ blob_appendf(pOut, "<p class=\"generalError\">%s</p>", msg);
1735
+ }else{
1736
+ blob_append(pOut, msg, -1);
1737
+ }
1738
+}
19951739
19961740
/*
19971741
** Generate a report of the differences between files pA and pB.
19981742
** If pOut is not NULL then a unified diff is appended there. It
19991743
** is assumed that pOut has already been initialized. If pOut is
@@ -2032,11 +1776,11 @@
20321776
&c.nTo, ignoreEolWs);
20331777
if( c.aFrom==0 || c.aTo==0 ){
20341778
fossil_free(c.aFrom);
20351779
fossil_free(c.aTo);
20361780
if( pOut ){
2037
- blob_appendf(pOut, DIFF_CANNOT_COMPUTE_BINARY);
1781
+ diff_errmsg(pOut, DIFF_CANNOT_COMPUTE_BINARY, diffFlags);
20381782
}
20391783
return 0;
20401784
}
20411785
20421786
/* Compute the difference */
@@ -2048,15 +1792,11 @@
20481792
for(i=m=n=0; i<mx; i+=3){ m += a[i]; n += a[i+1]+a[i+2]; }
20491793
if( n>10000 ){
20501794
fossil_free(c.aFrom);
20511795
fossil_free(c.aTo);
20521796
fossil_free(c.aEdit);
2053
- if( diffFlags & DIFF_HTML ){
2054
- blob_append(pOut, DIFF_TOO_MANY_CHANGES_HTML, -1);
2055
- }else{
2056
- blob_append(pOut, DIFF_TOO_MANY_CHANGES_TXT, -1);
2057
- }
1797
+ diff_errmsg(pOut, DIFF_TOO_MANY_CHANGES, diffFlags);
20581798
return 0;
20591799
}
20601800
}
20611801
if( (diffFlags & DIFF_NOOPT)==0 ){
20621802
diff_optimize(&c);
@@ -2159,10 +1899,11 @@
21591899
if( find_option("tk",0,0)!=0 ){
21601900
diff_tk("test-diff", 2);
21611901
return;
21621902
}
21631903
find_option("i",0,0);
1904
+ find_option("v",0,0);
21641905
zRe = find_option("regexp","e",1);
21651906
if( zRe ){
21661907
const char *zErr = re_compile(&pRe, zRe, 0);
21671908
if( zErr ) fossil_fatal("regex error: %s", zErr);
21681909
}
@@ -2616,60 +2357,5 @@
26162357
zPrefix[0] = 0;
26172358
}
26182359
fossil_print("%21s %4d: %.*s\n", zPrefix, i+1, n, z);
26192360
}
26202361
}
2621
-
2622
-/*
2623
-** COMMAND: test-looks-like-utf
2624
-**
2625
-** Usage: %fossil test-looks-like-utf FILENAME
2626
-**
2627
-** Options:
2628
-** --utf8 Ignoring BOM and file size, force UTF-8 checking
2629
-** --utf16 Ignoring BOM and file size, force UTF-16 checking
2630
-**
2631
-** FILENAME is the name of a file to check for textual content in the UTF-8
2632
-** and/or UTF-16 encodings.
2633
-*/
2634
-void looks_like_utf_test_cmd(void){
2635
- Blob blob; /* the contents of the specified file */
2636
- int fUtf8; /* return value of starts_with_utf8_bom() */
2637
- int fUtf16; /* return value of starts_with_utf16_bom() */
2638
- int fUnicode; /* return value of could_be_utf16() */
2639
- int lookFlags; /* output flags from looks_like_utf8/utf16() */
2640
- int bRevUtf16 = 0; /* non-zero -> UTF-16 byte order reversed */
2641
- int bRevUnicode = 0; /* non-zero -> UTF-16 byte order reversed */
2642
- int fForceUtf8 = find_option("utf8",0,0)!=0;
2643
- int fForceUtf16 = find_option("utf16",0,0)!=0;
2644
- if( g.argc!=3 ) usage("FILENAME");
2645
- blob_read_from_file(&blob, g.argv[2]);
2646
- fUtf8 = starts_with_utf8_bom(&blob, 0);
2647
- fUtf16 = starts_with_utf16_bom(&blob, 0, &bRevUtf16);
2648
- if( fForceUtf8 ){
2649
- fUnicode = 0;
2650
- }else{
2651
- fUnicode = could_be_utf16(&blob, &bRevUnicode) || fForceUtf16;
2652
- }
2653
- lookFlags = fUnicode ? looks_like_utf16(&blob, bRevUnicode, 0) :
2654
- looks_like_utf8(&blob, 0);
2655
- fossil_print("File \"%s\" has %d bytes.\n",g.argv[2],blob_size(&blob));
2656
- fossil_print("Starts with UTF-8 BOM: %s\n",fUtf8?"yes":"no");
2657
- fossil_print("Starts with UTF-16 BOM: %s\n",
2658
- fUtf16?(bRevUtf16?"reversed":"yes"):"no");
2659
- fossil_print("Looks like UTF-%s: %s\n",fUnicode?"16":"8",
2660
- (lookFlags&LOOK_BINARY)?"no":"yes");
2661
- fossil_print("Has flag LOOK_NUL: %s\n",(lookFlags&LOOK_NUL)?"yes":"no");
2662
- fossil_print("Has flag LOOK_CR: %s\n",(lookFlags&LOOK_CR)?"yes":"no");
2663
- fossil_print("Has flag LOOK_LONE_CR: %s\n",
2664
- (lookFlags&LOOK_LONE_CR)?"yes":"no");
2665
- fossil_print("Has flag LOOK_LF: %s\n",(lookFlags&LOOK_LF)?"yes":"no");
2666
- fossil_print("Has flag LOOK_LONE_LF: %s\n",
2667
- (lookFlags&LOOK_LONE_LF)?"yes":"no");
2668
- fossil_print("Has flag LOOK_CRLF: %s\n",(lookFlags&LOOK_CRLF)?"yes":"no");
2669
- fossil_print("Has flag LOOK_LONG: %s\n",(lookFlags&LOOK_LONG)?"yes":"no");
2670
- fossil_print("Has flag LOOK_INVALID: %s\n",
2671
- (lookFlags&LOOK_INVALID)?"yes":"no");
2672
- fossil_print("Has flag LOOK_ODD: %s\n",(lookFlags&LOOK_ODD)?"yes":"no");
2673
- fossil_print("Has flag LOOK_SHORT: %s\n",(lookFlags&LOOK_SHORT)?"yes":"no");
2674
- blob_reset(&blob);
2675
-}
26762362
--- src/diff.c
+++ src/diff.c
@@ -51,47 +51,20 @@
51 "cannot compute difference between binary files\n"
52
53 #define DIFF_CANNOT_COMPUTE_SYMLINK \
54 "cannot compute difference between symlink and regular file\n"
55
56 #define DIFF_TOO_MANY_CHANGES_TXT \
57 "more than 10,000 changes\n"
58
59 #define DIFF_TOO_MANY_CHANGES_HTML \
60 "<p class='generalError'>More than 10,000 changes</p>\n"
61
62 /*
63 ** This macro is designed to return non-zero if the specified blob contains
64 ** data that MAY be binary in nature; otherwise, zero will be returned.
65 */
66 #define looks_like_binary(blob) \
67 ((looks_like_utf8((blob), LOOK_BINARY) & LOOK_BINARY) != LOOK_NONE)
68
69 /*
70 ** Output flags for the looks_like_utf8() and looks_like_utf16() routines used
71 ** to convey status information about the blob content.
72 */
73 #define LOOK_NONE ((int)0x00000000) /* Nothing special was found. */
74 #define LOOK_NUL ((int)0x00000001) /* One or more NUL chars were found. */
75 #define LOOK_CR ((int)0x00000002) /* One or more CR chars were found. */
76 #define LOOK_LONE_CR ((int)0x00000004) /* An unpaired CR char was found. */
77 #define LOOK_LF ((int)0x00000008) /* One or more LF chars were found. */
78 #define LOOK_LONE_LF ((int)0x00000010) /* An unpaired LF char was found. */
79 #define LOOK_CRLF ((int)0x00000020) /* One or more CR/LF pairs were found. */
80 #define LOOK_LONG ((int)0x00000040) /* An over length line was found. */
81 #define LOOK_ODD ((int)0x00000080) /* An odd number of bytes was found. */
82 #define LOOK_SHORT ((int)0x00000100) /* Unable to perform full check. */
83 #define LOOK_INVALID ((int)0x00000200) /* Invalid sequence was found. */
84 #define LOOK_BINARY (LOOK_NUL | LOOK_LONG | LOOK_SHORT) /* May be binary. */
85 #define LOOK_EOL (LOOK_LONE_CR | LOOK_LONE_LF | LOOK_CRLF) /* Line seps. */
86 #endif /* INTERFACE */
87
88 /*
89 ** Maximum length of a line in a text file, in bytes. (2**13 = 8192 bytes)
90 */
91 #define LENGTH_MASK_SZ 13
92 #define LENGTH_MASK ((1<<LENGTH_MASK_SZ)-1)
 
 
93
94 /*
95 ** Information about each line of a file being diffed.
96 **
97 ** The lower LENGTH_MASK_SZ bits of the hash (DLine.h) are the length
@@ -204,282 +177,10 @@
204 /* Return results */
205 *pnLine = nLine;
206 return a;
207 }
208
209 /*
210 ** This function attempts to scan each logical line within the blob to
211 ** determine the type of content it appears to contain. The return value
212 ** is a combination of one or more of the LOOK_XXX flags (see above):
213 **
214 ** !LOOK_BINARY -- The content appears to consist entirely of text; however,
215 ** the encoding may not be UTF-8.
216 **
217 ** LOOK_BINARY -- The content appears to be binary because it contains one
218 ** or more embedded NUL characters or an extremely long line.
219 ** Since this function does not understand UTF-16, it may
220 ** falsely consider UTF-16 text to be binary.
221 **
222 ** Additional flags (i.e. those other than the ones included in LOOK_BINARY)
223 ** may be present in the result as well; however, they should not impact the
224 ** determination of text versus binary content.
225 **
226 ************************************ WARNING **********************************
227 **
228 ** This function does not validate that the blob content is properly formed
229 ** UTF-8. It assumes that all code points are the same size. It does not
230 ** validate any code points. It makes no attempt to detect if any [invalid]
231 ** switches between UTF-8 and other encodings occur.
232 **
233 ** The only code points that this function cares about are the NUL character,
234 ** carriage-return, and line-feed.
235 **
236 ** This function examines the contents of the blob until one of the flags
237 ** specified in "stopFlags" is set.
238 **
239 ************************************ WARNING **********************************
240 */
241 int looks_like_utf8(const Blob *pContent, int stopFlags){
242 const char *z = blob_buffer(pContent);
243 unsigned int n = blob_size(pContent);
244 int j, c, flags = LOOK_NONE; /* Assume UTF-8 text, prove otherwise */
245
246 if( n==0 ) return flags; /* Empty file -> text */
247 c = *z;
248 if( c==0 ){
249 flags |= LOOK_NUL; /* NUL character in a file -> binary */
250 }else if( c=='\r' ){
251 flags |= LOOK_CR;
252 if( n<=1 || z[1]!='\n' ){
253 flags |= LOOK_LONE_CR; /* More chars, next char is not LF */
254 }
255 }
256 j = (c!='\n');
257 if( !j ) flags |= (LOOK_LF | LOOK_LONE_LF); /* Found LF as first char */
258 while( !(flags&stopFlags) && --n>0 ){
259 int c2 = c;
260 c = *++z; ++j;
261 if( c==0 ){
262 flags |= LOOK_NUL; /* NUL character in a file -> binary */
263 }else if( c=='\n' ){
264 flags |= LOOK_LF;
265 if( c2=='\r' ){
266 flags |= (LOOK_CR | LOOK_CRLF); /* Found LF preceded by CR */
267 }else{
268 flags |= LOOK_LONE_LF;
269 }
270 if( j>LENGTH_MASK ){
271 flags |= LOOK_LONG; /* Very long line -> binary */
272 }
273 j = 0;
274 }else if( c=='\r' ){
275 flags |= LOOK_CR;
276 if( n<=1 || z[1]!='\n' ){
277 flags |= LOOK_LONE_CR; /* More chars, next char is not LF */
278 }
279 }
280 }
281 if( n ){
282 flags |= LOOK_SHORT; /* The whole blob was not examined */
283 }
284 if( j>LENGTH_MASK ){
285 flags |= LOOK_LONG; /* Very long line -> binary */
286 }
287 return flags;
288 }
289
290 /*
291 ** Define the type needed to represent a Unicode (UTF-16) character.
292 */
293 #ifndef WCHAR_T
294 # ifdef _WIN32
295 # define WCHAR_T wchar_t
296 # else
297 # define WCHAR_T unsigned short
298 # endif
299 #endif
300
301 /*
302 ** Maximum length of a line in a text file, in UTF-16 characters. (4096)
303 ** The number of bytes represented by this value cannot exceed LENGTH_MASK
304 ** bytes, because that is the line buffer size used by the diff engine.
305 */
306 #define UTF16_LENGTH_MASK_SZ (LENGTH_MASK_SZ-(sizeof(WCHAR_T)-sizeof(char)))
307 #define UTF16_LENGTH_MASK ((1<<UTF16_LENGTH_MASK_SZ)-1)
308
309 /*
310 ** This macro is used to swap the byte order of a UTF-16 character in the
311 ** looks_like_utf16() function.
312 */
313 #define UTF16_SWAP(ch) ((((ch) << 8) & 0xFF00) | (((ch) >> 8) & 0xFF))
314 #define UTF16_SWAP_IF(expr,ch) ((expr) ? UTF16_SWAP((ch)) : (ch))
315
316 /*
317 ** This function attempts to scan each logical line within the blob to
318 ** determine the type of content it appears to contain. The return value
319 ** is a combination of one or more of the LOOK_XXX flags (see above):
320 **
321 ** !LOOK_BINARY -- The content appears to consist entirely of text; however,
322 ** the encoding may not be UTF-16.
323 **
324 ** LOOK_BINARY -- The content appears to be binary because it contains one
325 ** or more embedded NUL characters or an extremely long line.
326 ** Since this function does not understand UTF-8, it may
327 ** falsely consider UTF-8 text to be binary.
328 **
329 ** Additional flags (i.e. those other than the ones included in LOOK_BINARY)
330 ** may be present in the result as well; however, they should not impact the
331 ** determination of text versus binary content.
332 **
333 ************************************ WARNING **********************************
334 **
335 ** This function does not validate that the blob content is properly formed
336 ** UTF-16. It assumes that all code points are the same size. It does not
337 ** validate any code points. It makes no attempt to detect if any [invalid]
338 ** switches between the UTF-16be and UTF-16le encodings occur.
339 **
340 ** The only code points that this function cares about are the NUL character,
341 ** carriage-return, and line-feed.
342 **
343 ** This function examines the contents of the blob until one of the flags
344 ** specified in "stopFlags" is set.
345 **
346 ************************************ WARNING **********************************
347 */
348 int looks_like_utf16(const Blob *pContent, int bReverse, int stopFlags){
349 const WCHAR_T *z = (WCHAR_T *)blob_buffer(pContent);
350 unsigned int n = blob_size(pContent);
351 int j, c, flags = LOOK_NONE; /* Assume UTF-16 text, prove otherwise */
352
353 if( n==0 ) return flags; /* Empty file -> text */
354 if( n%sizeof(WCHAR_T) ){
355 flags |= LOOK_ODD; /* Odd number of bytes -> binary (UTF-8?) */
356 if( n<sizeof(WCHAR_T) ) return flags; /* One byte -> binary (UTF-8?) */
357 }
358 c = *z;
359 if( bReverse ){
360 c = UTF16_SWAP(c);
361 }
362 if( c==0 ){
363 flags |= LOOK_NUL; /* NUL character in a file -> binary */
364 }else if( c=='\r' ){
365 flags |= LOOK_CR;
366 if( n<(2*sizeof(WCHAR_T)) || UTF16_SWAP_IF(bReverse, z[1])!='\n' ){
367 flags |= LOOK_LONE_CR; /* More chars, next char is not LF */
368 }
369 }
370 j = (c!='\n');
371 if( !j ) flags |= (LOOK_LF | LOOK_LONE_LF); /* Found LF as first char */
372 while( 1 ){
373 int c2 = c;
374 if( flags&stopFlags ) break;
375 n -= sizeof(WCHAR_T);
376 if( n<sizeof(WCHAR_T) ) break;
377 c = *++z;
378 if( bReverse ){
379 c = UTF16_SWAP(c);
380 }
381 ++j;
382 if( c==0 ){
383 flags |= LOOK_NUL; /* NUL character in a file -> binary */
384 }else if( c=='\n' ){
385 flags |= LOOK_LF;
386 if( c2=='\r' ){
387 flags |= (LOOK_CR | LOOK_CRLF); /* Found LF preceded by CR */
388 }else{
389 flags |= LOOK_LONE_LF;
390 }
391 if( j>UTF16_LENGTH_MASK ){
392 flags |= LOOK_LONG; /* Very long line -> binary */
393 }
394 j = 0;
395 }else if( c=='\r' ){
396 flags |= LOOK_CR;
397 if( n<(2*sizeof(WCHAR_T)) || UTF16_SWAP_IF(bReverse, z[1])!='\n' ){
398 flags |= LOOK_LONE_CR; /* More chars, next char is not LF */
399 }
400 }
401 }
402 if( n ){
403 flags |= LOOK_SHORT; /* The whole blob was not examined */
404 }
405 if( j>UTF16_LENGTH_MASK ){
406 flags |= LOOK_LONG; /* Very long line -> binary */
407 }
408 return flags;
409 }
410
411 /*
412 ** This function returns an array of bytes representing the byte-order-mark
413 ** for UTF-8.
414 */
415 const unsigned char *get_utf8_bom(int *pnByte){
416 static const unsigned char bom[] = {
417 0xEF, 0xBB, 0xBF, 0x00, 0x00, 0x00
418 };
419 if( pnByte ) *pnByte = 3;
420 return bom;
421 }
422
423 /*
424 ** This function returns non-zero if the blob starts with a UTF-8
425 ** byte-order-mark (BOM).
426 */
427 int starts_with_utf8_bom(const Blob *pContent, int *pnByte){
428 const char *z = blob_buffer(pContent);
429 int bomSize = 0;
430 const unsigned char *bom = get_utf8_bom(&bomSize);
431
432 if( pnByte ) *pnByte = bomSize;
433 if( blob_size(pContent)<bomSize ) return 0;
434 return memcmp(z, bom, bomSize)==0;
435 }
436
437 /*
438 ** This function returns non-zero if the blob starts with a UTF-16
439 ** byte-order-mark (BOM), either in the endianness of the machine
440 ** or in reversed byte order. The UTF-32 BOM is ruled out by checking
441 ** if the UTF-16 BOM is not immediately followed by (utf16) 0.
442 ** pnByte is only set when the function returns 1.
443 **
444 ** pbReverse is always set, even when no BOM is found. Without a BOM,
445 ** it is set to 1 on little-endian and 0 on big-endian platforms. See
446 ** clause D98 of conformance (section 3.10) of the Unicode standard.
447 */
448 int starts_with_utf16_bom(
449 const Blob *pContent, /* IN: Blob content to perform BOM detection on. */
450 int *pnByte, /* OUT: The number of bytes used for the BOM. */
451 int *pbReverse /* OUT: Non-zero for BOM in reverse byte-order. */
452 ){
453 const unsigned short *z = (unsigned short *)blob_buffer(pContent);
454 int bomSize = sizeof(unsigned short);
455 int size = blob_size(pContent);
456
457 if( size<bomSize ) goto noBom; /* No: cannot read BOM. */
458 if( size>=(2*bomSize) && z[1]==0 ) goto noBom; /* No: possible UTF-32. */
459 if( z[0]==0xfeff ){
460 if( pbReverse ) *pbReverse = 0;
461 }else if( z[0]==0xfffe ){
462 if( pbReverse ) *pbReverse = 1;
463 }else{
464 static const int one = 1;
465 noBom:
466 if( pbReverse ) *pbReverse = *(char *) &one;
467 return 0; /* No: UTF-16 byte-order-mark not found. */
468 }
469 if( pnByte ) *pnByte = bomSize;
470 return 1; /* Yes. */
471 }
472
473 /*
474 ** Returns non-zero if the specified content could be valid UTF-16.
475 */
476 int could_be_utf16(const Blob *pContent, int *pbReverse){
477 return (blob_size(pContent) % sizeof(WCHAR_T) == 0) ?
478 starts_with_utf16_bom(pContent, 0, pbReverse) : 0;
479 }
480
481 /*
482 ** Return true if two DLine elements are identical.
483 */
484 static int same_dline(DLine *pA, DLine *pB){
485 return pA->h==pB->h && memcmp(pA->z,pB->z,pA->h & LENGTH_MASK)==0;
@@ -576,11 +277,11 @@
576 int mxr; /* Maximum value for r */
577 int na, nb; /* Number of lines shown from A and B */
578 int i, j; /* Loop counters */
579 int m; /* Number of lines to output */
580 int skip; /* Number of lines to skip */
581 int nChunk = 0; /* Number of diff chunks seen so far */
582 int nContext; /* Number of lines of context */
583 int showLn; /* Show line numbers */
584 int html; /* Render as HTML */
585 int showDivider = 0; /* True to show the divider between diff blocks */
586
@@ -657,14 +358,14 @@
657 if( !showDivider ){
658 /* Do not show a top divider */
659 showDivider = 1;
660 }else if( html ){
661 blob_appendf(pOut, "<span class=\"diffhr\">%.80c</span>\n", '.');
662 blob_appendf(pOut, "<a name=\"chunk%d\"></a>\n", nChunk);
663 }else{
664 blob_appendf(pOut, "%.80c\n", '.');
665 }
 
666 }else{
667 if( html ) blob_appendf(pOut, "<span class=\"diffln\">");
668 /*
669 * If the patch changes an empty file or results in an empty file,
670 * the block header must use 0,0 as position indicator and not 1,0.
@@ -727,12 +428,11 @@
727 /*
728 ** Status of a single output line
729 */
730 typedef struct SbsLine SbsLine;
731 struct SbsLine {
732 char *zLine; /* The output line under construction */
733 int n; /* Index of next unused slot in the zLine[] */
734 int width; /* Maximum width of a column in the output */
735 unsigned char escHtml; /* True to escape html characters */
736 int iStart; /* Write zStart prior to character iStart */
737 const char *zStart; /* A <span> tag */
738 int iEnd; /* Write </span> prior to character iEnd */
@@ -741,125 +441,155 @@
741 int iEnd2; /* Write </span> prior to character iEnd2 */
742 ReCompiled *pRe; /* Only colorize matching lines, if not NULL */
743 };
744
745 /*
746 ** Flags for sbsWriteText()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
747 */
748 #define SBS_NEWLINE 0x0001 /* End with \n\000 */
749 #define SBS_PAD 0x0002 /* Pad output to width spaces */
 
750
751 /*
752 ** Write up to width characters of pLine into p->zLine[]. Translate tabs into
753 ** spaces. Add a newline if SBS_NEWLINE is set. Translate HTML characters
754 ** if SBS_HTML is set. Pad the rendering out width bytes if SBS_PAD is set.
 
 
 
755 **
756 ** This comment contains multibyte unicode characters (ü, Æ, ð) in order
757 ** to test the ability of the diff code to handle such characters.
758 */
759 static void sbsWriteText(SbsLine *p, DLine *pLine, unsigned flags){
 
760 int n = pLine->h & LENGTH_MASK;
761 int i; /* Number of input characters consumed */
762 int j; /* Number of output characters generated */
763 int k; /* Cursor position */
764 int needEndSpan = 0;
765 const char *zIn = pLine->z;
766 char *z = &p->zLine[p->n];
767 int w = p->width;
768 int colorize = p->escHtml;
769 if( colorize && p->pRe && re_dline_match(p->pRe, pLine, 1)==0 ){
770 colorize = 0;
771 }
772 for(i=j=k=0; k<w && i<n; i++, k++){
773 char c = zIn[i];
774 if( colorize ){
775 if( i==p->iStart ){
776 int x = strlen(p->zStart);
777 memcpy(z+j, p->zStart, x);
778 j += x;
779 needEndSpan = 1;
780 if( p->iStart2 ){
781 p->iStart = p->iStart2;
782 p->zStart = p->zStart2;
783 p->iStart2 = 0;
784 }
785 }else if( i==p->iEnd ){
786 memcpy(z+j, "</span>", 7);
787 j += 7;
788 needEndSpan = 0;
789 if( p->iEnd2 ){
790 p->iEnd = p->iEnd2;
791 p->iEnd2 = 0;
792 }
793 }
794 }
795 if( c=='\t' ){
796 z[j++] = ' ';
797 while( (k&7)!=7 && k<w ){ z[j++] = ' '; k++; }
 
 
 
798 }else if( c=='\r' || c=='\f' ){
799 z[j++] = ' ';
800 }else if( c=='<' && p->escHtml ){
801 memcpy(&z[j], "&lt;", 4);
802 j += 4;
803 }else if( c=='&' && p->escHtml ){
804 memcpy(&z[j], "&amp;", 5);
805 j += 5;
806 }else if( c=='>' && p->escHtml ){
807 memcpy(&z[j], "&gt;", 4);
808 j += 4;
809 }else if( c=='"' && p->escHtml ){
810 memcpy(&z[j], "&quot;", 6);
811 j += 6;
812 }else{
813 z[j++] = c;
814 if( (c&0xc0)==0x80 ) k--;
815 }
816 }
817 if( needEndSpan ){
818 memcpy(&z[j], "</span>", 7);
819 j += 7;
820 }
821 if( (flags & SBS_PAD)!=0 ){
822 while( k<w ){ k++; z[j++] = ' '; }
823 }
824 if( flags & SBS_NEWLINE ){
825 z[j++] = '\n';
826 }
827 p->n += j;
828 }
829
830 /*
831 ** Append a string to an SbSLine without coding, interpretation, or padding.
832 */
833 static void sbsWrite(SbsLine *p, const char *zIn, int nIn){
834 memcpy(p->zLine+p->n, zIn, nIn);
835 p->n += nIn;
836 }
837
838 /*
839 ** Append n spaces to the string.
840 */
841 static void sbsWriteSpace(SbsLine *p, int n){
842 while( n-- ) p->zLine[p->n++] = ' ';
843 }
844
845 /*
846 ** Append a string to the output only if we are rendering HTML.
847 */
848 static void sbsWriteHtml(SbsLine *p, const char *zIn){
849 if( p->escHtml ) sbsWrite(p, zIn, strlen(zIn));
850 }
851
852 /*
853 ** Write a 6-digit line number followed by a single space onto the line.
854 */
855 static void sbsWriteLineno(SbsLine *p, int ln){
856 sbsWriteHtml(p, "<span class=\"diffln\">");
857 sqlite3_snprintf(7, &p->zLine[p->n], "%5d ", ln+1);
858 p->n += 6;
859 sbsWriteHtml(p, "</span>");
860 p->zLine[p->n++] = ' ';
 
 
 
 
 
 
 
 
 
 
 
861 }
862
863 /*
864 ** The two text segments zLeft and zRight are known to be different on
865 ** both ends, but they might have a common segment in the middle. If
@@ -1018,43 +748,42 @@
1018 }
1019 if( nSuffix==nLeft || nSuffix==nRight ) nPrefix = 0;
1020 }
1021 if( nPrefix+nSuffix > nShort ) nPrefix = nShort - nSuffix;
1022
1023
1024 /* A single chunk of text inserted on the right */
1025 if( nPrefix+nSuffix==nLeft ){
1026 sbsWriteLineno(p, lnLeft);
1027 p->iStart2 = p->iEnd2 = 0;
1028 p->iStart = p->iEnd = -1;
1029 sbsWriteText(p, pLeft, SBS_PAD);
1030 if( nLeft==nRight && zLeft[nLeft]==zRight[nRight] ){
1031 sbsWrite(p, " ", 3);
1032 }else{
1033 sbsWrite(p, " | ", 3);
1034 }
1035 sbsWriteLineno(p, lnRight);
1036 p->iStart = nPrefix;
1037 p->iEnd = nRight - nSuffix;
1038 p->zStart = zClassAdd;
1039 sbsWriteText(p, pRight, SBS_NEWLINE);
1040 return;
1041 }
1042
1043 /* A single chunk of text deleted from the left */
1044 if( nPrefix+nSuffix==nRight ){
1045 /* Text deleted from the left */
1046 sbsWriteLineno(p, lnLeft);
1047 p->iStart2 = p->iEnd2 = 0;
1048 p->iStart = nPrefix;
1049 p->iEnd = nLeft - nSuffix;
1050 p->zStart = zClassRm;
1051 sbsWriteText(p, pLeft, SBS_PAD);
1052 sbsWrite(p, " | ", 3);
1053 sbsWriteLineno(p, lnRight);
1054 p->iStart = p->iEnd = -1;
1055 sbsWriteText(p, pRight, SBS_NEWLINE);
1056 return;
1057 }
1058
1059 /* At this point we know that there is a chunk of text that has
1060 ** changed between the left and the right. Check to see if there
@@ -1065,11 +794,11 @@
1065 if( p->escHtml
1066 && nLeftDiff >= 6
1067 && nRightDiff >= 6
1068 && textLCS(&zLeft[nPrefix], nLeftDiff, &zRight[nPrefix], nRightDiff, aLCS)
1069 ){
1070 sbsWriteLineno(p, lnLeft);
1071 p->iStart = nPrefix;
1072 p->iEnd = nPrefix + aLCS[0];
1073 if( aLCS[2]==0 ){
1074 sbsShiftLeft(p, pLeft->z);
1075 p->zStart = zClassRm;
@@ -1078,13 +807,13 @@
1078 }
1079 p->iStart2 = nPrefix + aLCS[1];
1080 p->iEnd2 = nLeft - nSuffix;
1081 p->zStart2 = aLCS[3]==nRightDiff ? zClassRm : zClassChng;
1082 sbsSimplifyLine(p, zLeft+nPrefix);
1083 sbsWriteText(p, pLeft, SBS_PAD);
1084 sbsWrite(p, " | ", 3);
1085 sbsWriteLineno(p, lnRight);
1086 p->iStart = nPrefix;
1087 p->iEnd = nPrefix + aLCS[2];
1088 if( aLCS[0]==0 ){
1089 sbsShiftLeft(p, pRight->z);
1090 p->zStart = zClassAdd;
@@ -1093,25 +822,25 @@
1093 }
1094 p->iStart2 = nPrefix + aLCS[3];
1095 p->iEnd2 = nRight - nSuffix;
1096 p->zStart2 = aLCS[1]==nLeftDiff ? zClassAdd : zClassChng;
1097 sbsSimplifyLine(p, zRight+nPrefix);
1098 sbsWriteText(p, pRight, SBS_NEWLINE);
1099 return;
1100 }
1101
1102 /* If all else fails, show a single big change between left and right */
1103 sbsWriteLineno(p, lnLeft);
1104 p->iStart2 = p->iEnd2 = 0;
1105 p->iStart = nPrefix;
1106 p->iEnd = nLeft - nSuffix;
1107 p->zStart = zClassChng;
1108 sbsWriteText(p, pLeft, SBS_PAD);
1109 sbsWrite(p, " | ", 3);
1110 sbsWriteLineno(p, lnRight);
1111 p->iEnd = nRight - nSuffix;
1112 sbsWriteText(p, pRight, SBS_NEWLINE);
1113 }
1114
1115 /*
1116 ** Minimum of two values
1117 */
@@ -1357,30 +1086,40 @@
1357 int mxr; /* Maximum value for r */
1358 int na, nb; /* Number of lines shown from A and B */
1359 int i, j; /* Loop counters */
1360 int m, ma, mb;/* Number of lines to output */
1361 int skip; /* Number of lines to skip */
1362 int nChunk = 0; /* Number of chunks of diff output seen so far */
1363 SbsLine s; /* Output line buffer */
1364 int nContext; /* Lines of context above and below each change */
1365 int showDivider = 0; /* True to show the divider */
 
1366
1367 memset(&s, 0, sizeof(s));
1368 s.width = diff_width(diffFlags);
1369 s.zLine = fossil_malloc( 15*s.width + 200 );
1370 if( s.zLine==0 ) return;
1371 nContext = diff_context_lines(diffFlags);
1372 s.escHtml = (diffFlags & DIFF_HTML)!=0;
 
 
 
 
 
 
 
 
 
 
1373 s.pRe = pRe;
1374 s.iStart = -1;
1375 s.iStart2 = 0;
1376 s.iEnd = -1;
1377 A = p->aFrom;
1378 B = p->aTo;
1379 R = p->aEdit;
1380 mxr = p->nEdit;
1381 while( mxr>2 && R[mxr-1]==0 && R[mxr-2]==0 ){ mxr -= 3; }
 
1382 for(r=0; r<mxr; r += 3*nr){
1383 /* Figure out how many triples to show in a single block */
1384 for(nr=1; R[r+nr*3]>0 && R[r+nr*3]<nContext*2; nr++){}
1385 /* printf("r=%d nr=%d\n", r, nr); */
1386
@@ -1436,35 +1175,39 @@
1436 }
1437
1438 /* Draw the separator between blocks */
1439 if( showDivider ){
1440 if( s.escHtml ){
1441 blob_appendf(pOut, "<span class=\"diffhr\">%.*c</span>\n",
1442 s.width*2+16, '.');
 
 
 
 
 
 
1443 }else{
1444 blob_appendf(pOut, "%.*c\n", s.width*2+16, '.');
1445 }
1446 }
1447 showDivider = 1;
1448 nChunk++;
1449 if( s.escHtml ){
1450 blob_appendf(pOut, "<a name=\"chunk%d\"></a>\n", nChunk);
1451 }
1452
1453 /* Show the initial common area */
1454 a += skip;
1455 b += skip;
1456 m = R[r] - skip;
1457 for(j=0; j<m; j++){
1458 s.n = 0;
1459 sbsWriteLineno(&s, a+j);
1460 s.iStart = s.iEnd = -1;
1461 sbsWriteText(&s, &A[a+j], SBS_PAD);
1462 sbsWrite(&s, " ", 3);
1463 sbsWriteLineno(&s, b+j);
1464 sbsWriteText(&s, &B[b+j], SBS_NEWLINE);
1465 blob_append(pOut, s.zLine, s.n);
1466 }
1467 a += m;
1468 b += m;
1469
1470 /* Show the differences */
@@ -1485,87 +1228,71 @@
1485
1486 alignment = sbsAlignment(&A[a], ma, &B[b], mb);
1487 for(j=0; ma+mb>0; j++){
1488 if( alignment[j]==1 ){
1489 /* Delete one line from the left */
1490 s.n = 0;
1491 sbsWriteLineno(&s, a);
1492 s.iStart = 0;
1493 s.zStart = "<span class=\"diffrm\">";
1494 s.iEnd = LENGTH(&A[a]);
1495 sbsWriteText(&s, &A[a], SBS_PAD);
1496 if( s.escHtml ){
1497 sbsWrite(&s, " &lt;\n", 6);
1498 }else{
1499 sbsWrite(&s, " <\n", 3);
1500 }
1501 blob_append(pOut, s.zLine, s.n);
1502 assert( ma>0 );
1503 ma--;
1504 a++;
1505 }else if( alignment[j]==3 ){
1506 /* The left line is changed into the right line */
1507 s.n = 0;
1508 sbsWriteLineChange(&s, &A[a], a, &B[b], b);
1509 blob_append(pOut, s.zLine, s.n);
1510 assert( ma>0 && mb>0 );
1511 ma--;
1512 mb--;
1513 a++;
1514 b++;
1515 }else if( alignment[j]==2 ){
1516 /* Insert one line on the right */
1517 s.n = 0;
1518 sbsWriteSpace(&s, s.width + 7);
1519 if( s.escHtml ){
1520 sbsWrite(&s, " &gt; ", 6);
1521 }else{
1522 sbsWrite(&s, " > ", 3);
1523 }
1524 sbsWriteLineno(&s, b);
1525 s.iStart = 0;
1526 s.zStart = "<span class=\"diffadd\">";
1527 s.iEnd = LENGTH(&B[b]);
1528 sbsWriteText(&s, &B[b], SBS_NEWLINE);
1529 blob_append(pOut, s.zLine, s.n);
1530 assert( mb>0 );
1531 mb--;
1532 b++;
1533 }else{
1534 /* Delete from the left and insert on the right */
1535 s.n = 0;
1536 sbsWriteLineno(&s, a);
1537 s.iStart = 0;
1538 s.zStart = "<span class=\"diffrm\">";
1539 s.iEnd = LENGTH(&A[a]);
1540 sbsWriteText(&s, &A[a], SBS_PAD);
1541 sbsWrite(&s, " | ", 3);
1542 sbsWriteLineno(&s, b);
1543 s.iStart = 0;
1544 s.zStart = "<span class=\"diffadd\">";
1545 s.iEnd = LENGTH(&B[b]);
1546 sbsWriteText(&s, &B[b], SBS_NEWLINE);
1547 blob_append(pOut, s.zLine, s.n);
1548 ma--;
1549 mb--;
1550 a++;
1551 b++;
1552 }
1553
1554 }
1555 fossil_free(alignment);
1556 if( i<nr-1 ){
1557 m = R[r+i*3+3];
1558 for(j=0; j<m; j++){
1559 s.n = 0;
1560 sbsWriteLineno(&s, a+j);
1561 s.iStart = s.iEnd = -1;
1562 sbsWriteText(&s, &A[a+j], SBS_PAD);
1563 sbsWrite(&s, " ", 3);
1564 sbsWriteLineno(&s, b+j);
1565 sbsWriteText(&s, &B[b+j], SBS_NEWLINE);
1566 blob_append(pOut, s.zLine, s.n);
1567 }
1568 b += m;
1569 a += m;
1570 }
1571 }
@@ -1573,21 +1300,27 @@
1573 /* Show the final common area */
1574 assert( nr==i );
1575 m = R[r+nr*3];
1576 if( m>nContext ) m = nContext;
1577 for(j=0; j<m; j++){
1578 s.n = 0;
1579 sbsWriteLineno(&s, a+j);
1580 s.iStart = s.iEnd = -1;
1581 sbsWriteText(&s, &A[a+j], SBS_PAD);
1582 sbsWrite(&s, " ", 3);
1583 sbsWriteLineno(&s, b+j);
1584 sbsWriteText(&s, &B[b+j], SBS_NEWLINE);
1585 blob_append(pOut, s.zLine, s.n);
1586 }
1587 }
1588 free(s.zLine);
 
 
 
 
 
 
 
 
1589 }
1590
1591 /*
1592 ** Compute the optimal longest common subsequence (LCS) using an
1593 ** exhaustive search. This version of the LCS is only used for
@@ -1990,10 +1723,21 @@
1990 int diff_width(u64 diffFlags){
1991 int w = (diffFlags & DIFF_WIDTH_MASK)/(DIFF_CONTEXT_MASK+1);
1992 if( w==0 ) w = 80;
1993 return w;
1994 }
 
 
 
 
 
 
 
 
 
 
 
1995
1996 /*
1997 ** Generate a report of the differences between files pA and pB.
1998 ** If pOut is not NULL then a unified diff is appended there. It
1999 ** is assumed that pOut has already been initialized. If pOut is
@@ -2032,11 +1776,11 @@
2032 &c.nTo, ignoreEolWs);
2033 if( c.aFrom==0 || c.aTo==0 ){
2034 fossil_free(c.aFrom);
2035 fossil_free(c.aTo);
2036 if( pOut ){
2037 blob_appendf(pOut, DIFF_CANNOT_COMPUTE_BINARY);
2038 }
2039 return 0;
2040 }
2041
2042 /* Compute the difference */
@@ -2048,15 +1792,11 @@
2048 for(i=m=n=0; i<mx; i+=3){ m += a[i]; n += a[i+1]+a[i+2]; }
2049 if( n>10000 ){
2050 fossil_free(c.aFrom);
2051 fossil_free(c.aTo);
2052 fossil_free(c.aEdit);
2053 if( diffFlags & DIFF_HTML ){
2054 blob_append(pOut, DIFF_TOO_MANY_CHANGES_HTML, -1);
2055 }else{
2056 blob_append(pOut, DIFF_TOO_MANY_CHANGES_TXT, -1);
2057 }
2058 return 0;
2059 }
2060 }
2061 if( (diffFlags & DIFF_NOOPT)==0 ){
2062 diff_optimize(&c);
@@ -2159,10 +1899,11 @@
2159 if( find_option("tk",0,0)!=0 ){
2160 diff_tk("test-diff", 2);
2161 return;
2162 }
2163 find_option("i",0,0);
 
2164 zRe = find_option("regexp","e",1);
2165 if( zRe ){
2166 const char *zErr = re_compile(&pRe, zRe, 0);
2167 if( zErr ) fossil_fatal("regex error: %s", zErr);
2168 }
@@ -2616,60 +2357,5 @@
2616 zPrefix[0] = 0;
2617 }
2618 fossil_print("%21s %4d: %.*s\n", zPrefix, i+1, n, z);
2619 }
2620 }
2621
2622 /*
2623 ** COMMAND: test-looks-like-utf
2624 **
2625 ** Usage: %fossil test-looks-like-utf FILENAME
2626 **
2627 ** Options:
2628 ** --utf8 Ignoring BOM and file size, force UTF-8 checking
2629 ** --utf16 Ignoring BOM and file size, force UTF-16 checking
2630 **
2631 ** FILENAME is the name of a file to check for textual content in the UTF-8
2632 ** and/or UTF-16 encodings.
2633 */
2634 void looks_like_utf_test_cmd(void){
2635 Blob blob; /* the contents of the specified file */
2636 int fUtf8; /* return value of starts_with_utf8_bom() */
2637 int fUtf16; /* return value of starts_with_utf16_bom() */
2638 int fUnicode; /* return value of could_be_utf16() */
2639 int lookFlags; /* output flags from looks_like_utf8/utf16() */
2640 int bRevUtf16 = 0; /* non-zero -> UTF-16 byte order reversed */
2641 int bRevUnicode = 0; /* non-zero -> UTF-16 byte order reversed */
2642 int fForceUtf8 = find_option("utf8",0,0)!=0;
2643 int fForceUtf16 = find_option("utf16",0,0)!=0;
2644 if( g.argc!=3 ) usage("FILENAME");
2645 blob_read_from_file(&blob, g.argv[2]);
2646 fUtf8 = starts_with_utf8_bom(&blob, 0);
2647 fUtf16 = starts_with_utf16_bom(&blob, 0, &bRevUtf16);
2648 if( fForceUtf8 ){
2649 fUnicode = 0;
2650 }else{
2651 fUnicode = could_be_utf16(&blob, &bRevUnicode) || fForceUtf16;
2652 }
2653 lookFlags = fUnicode ? looks_like_utf16(&blob, bRevUnicode, 0) :
2654 looks_like_utf8(&blob, 0);
2655 fossil_print("File \"%s\" has %d bytes.\n",g.argv[2],blob_size(&blob));
2656 fossil_print("Starts with UTF-8 BOM: %s\n",fUtf8?"yes":"no");
2657 fossil_print("Starts with UTF-16 BOM: %s\n",
2658 fUtf16?(bRevUtf16?"reversed":"yes"):"no");
2659 fossil_print("Looks like UTF-%s: %s\n",fUnicode?"16":"8",
2660 (lookFlags&LOOK_BINARY)?"no":"yes");
2661 fossil_print("Has flag LOOK_NUL: %s\n",(lookFlags&LOOK_NUL)?"yes":"no");
2662 fossil_print("Has flag LOOK_CR: %s\n",(lookFlags&LOOK_CR)?"yes":"no");
2663 fossil_print("Has flag LOOK_LONE_CR: %s\n",
2664 (lookFlags&LOOK_LONE_CR)?"yes":"no");
2665 fossil_print("Has flag LOOK_LF: %s\n",(lookFlags&LOOK_LF)?"yes":"no");
2666 fossil_print("Has flag LOOK_LONE_LF: %s\n",
2667 (lookFlags&LOOK_LONE_LF)?"yes":"no");
2668 fossil_print("Has flag LOOK_CRLF: %s\n",(lookFlags&LOOK_CRLF)?"yes":"no");
2669 fossil_print("Has flag LOOK_LONG: %s\n",(lookFlags&LOOK_LONG)?"yes":"no");
2670 fossil_print("Has flag LOOK_INVALID: %s\n",
2671 (lookFlags&LOOK_INVALID)?"yes":"no");
2672 fossil_print("Has flag LOOK_ODD: %s\n",(lookFlags&LOOK_ODD)?"yes":"no");
2673 fossil_print("Has flag LOOK_SHORT: %s\n",(lookFlags&LOOK_SHORT)?"yes":"no");
2674 blob_reset(&blob);
2675 }
2676
--- src/diff.c
+++ src/diff.c
@@ -51,47 +51,20 @@
51 "cannot compute difference between binary files\n"
52
53 #define DIFF_CANNOT_COMPUTE_SYMLINK \
54 "cannot compute difference between symlink and regular file\n"
55
56 #define DIFF_TOO_MANY_CHANGES \
57 "more than 10,000 changes\n"
58
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59 /*
60 ** Maximum length of a line in a text file, in bytes. (2**13 = 8192 bytes)
61 */
62 #define LENGTH_MASK_SZ 13
63 #define LENGTH_MASK ((1<<LENGTH_MASK_SZ)-1)
64
65 #endif /* INTERFACE */
66
67 /*
68 ** Information about each line of a file being diffed.
69 **
70 ** The lower LENGTH_MASK_SZ bits of the hash (DLine.h) are the length
@@ -204,282 +177,10 @@
177 /* Return results */
178 *pnLine = nLine;
179 return a;
180 }
181
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
182 /*
183 ** Return true if two DLine elements are identical.
184 */
185 static int same_dline(DLine *pA, DLine *pB){
186 return pA->h==pB->h && memcmp(pA->z,pB->z,pA->h & LENGTH_MASK)==0;
@@ -576,11 +277,11 @@
277 int mxr; /* Maximum value for r */
278 int na, nb; /* Number of lines shown from A and B */
279 int i, j; /* Loop counters */
280 int m; /* Number of lines to output */
281 int skip; /* Number of lines to skip */
282 static int nChunk = 0; /* Number of diff chunks seen so far */
283 int nContext; /* Number of lines of context */
284 int showLn; /* Show line numbers */
285 int html; /* Render as HTML */
286 int showDivider = 0; /* True to show the divider between diff blocks */
287
@@ -657,14 +358,14 @@
358 if( !showDivider ){
359 /* Do not show a top divider */
360 showDivider = 1;
361 }else if( html ){
362 blob_appendf(pOut, "<span class=\"diffhr\">%.80c</span>\n", '.');
 
363 }else{
364 blob_appendf(pOut, "%.80c\n", '.');
365 }
366 if( html ) blob_appendf(pOut, "<span id=\"chunk%d\"></span>", nChunk);
367 }else{
368 if( html ) blob_appendf(pOut, "<span class=\"diffln\">");
369 /*
370 * If the patch changes an empty file or results in an empty file,
371 * the block header must use 0,0 as position indicator and not 1,0.
@@ -727,12 +428,11 @@
428 /*
429 ** Status of a single output line
430 */
431 typedef struct SbsLine SbsLine;
432 struct SbsLine {
433 Blob *apCols[5]; /* Array of pointers to output columns */
 
434 int width; /* Maximum width of a column in the output */
435 unsigned char escHtml; /* True to escape html characters */
436 int iStart; /* Write zStart prior to character iStart */
437 const char *zStart; /* A <span> tag */
438 int iEnd; /* Write </span> prior to character iEnd */
@@ -741,125 +441,155 @@
441 int iEnd2; /* Write </span> prior to character iEnd2 */
442 ReCompiled *pRe; /* Only colorize matching lines, if not NULL */
443 };
444
445 /*
446 ** Column indices for SbsLine.apCols[]
447 */
448 #define SBS_LNA 0 /* Left line number */
449 #define SBS_TXTA 1 /* Left text */
450 #define SBS_MKR 2 /* Middle separator column */
451 #define SBS_LNB 3 /* Right line number */
452 #define SBS_TXTB 4 /* Right text */
453
454 /*
455 ** Append newlines to all columns.
456 */
457 static void sbsWriteNewlines(SbsLine *p){
458 int i;
459 for( i=p->escHtml ? SBS_LNA : SBS_TXTB; i<=SBS_TXTB; i++ ){
460 blob_append(p->apCols[i], "\n", 1);
461 }
462 }
463
464 /*
465 ** Append n spaces to the column.
466 */
467 static void sbsWriteSpace(SbsLine *p, int n, int col){
468 blob_appendf(p->apCols[col], "%*s", n, "");
469 }
470
471 /*
472 ** Write the text of pLine into column iCol of p.
473 **
474 ** If outputting HTML, write the full line. Otherwise, only write the
475 ** width characters. Translate tabs into spaces. Add newlines if col
476 ** is SBS_TXTB. Translate HTML characters if escHtml is true. Pad the
477 ** rendering to width bytes if col is SBS_TXTA and escHtml is false.
478 **
479 ** This comment contains multibyte unicode characters (ü, Æ, ð) in order
480 ** to test the ability of the diff code to handle such characters.
481 */
482 static void sbsWriteText(SbsLine *p, DLine *pLine, int col){
483 Blob *pCol = p->apCols[col];
484 int n = pLine->h & LENGTH_MASK;
485 int i; /* Number of input characters consumed */
 
486 int k; /* Cursor position */
487 int needEndSpan = 0;
488 const char *zIn = pLine->z;
 
489 int w = p->width;
490 int colorize = p->escHtml;
491 if( colorize && p->pRe && re_dline_match(p->pRe, pLine, 1)==0 ){
492 colorize = 0;
493 }
494 for(i=k=0; (p->escHtml || k<w) && i<n; i++, k++){
495 char c = zIn[i];
496 if( colorize ){
497 if( i==p->iStart ){
498 int x = strlen(p->zStart);
499 blob_append(pCol, p->zStart, x);
 
500 needEndSpan = 1;
501 if( p->iStart2 ){
502 p->iStart = p->iStart2;
503 p->zStart = p->zStart2;
504 p->iStart2 = 0;
505 }
506 }else if( i==p->iEnd ){
507 blob_append(pCol, "</span>", 7);
 
508 needEndSpan = 0;
509 if( p->iEnd2 ){
510 p->iEnd = p->iEnd2;
511 p->iEnd2 = 0;
512 }
513 }
514 }
515 if( c=='\t' ){
516 blob_append(pCol, " ", 1);
517 while( (k&7)!=7 && (p->escHtml || k<w) ){
518 blob_append(pCol, " ", 1);
519 k++;
520 }
521 }else if( c=='\r' || c=='\f' ){
522 blob_append(pCol, " ", 1);
523 }else if( c=='<' && p->escHtml ){
524 blob_append(pCol, "&lt;", 4);
 
525 }else if( c=='&' && p->escHtml ){
526 blob_append(pCol, "&amp;", 5);
 
527 }else if( c=='>' && p->escHtml ){
528 blob_append(pCol, "&gt;", 4);
 
529 }else if( c=='"' && p->escHtml ){
530 blob_append(pCol, "&quot;", 6);
 
531 }else{
532 blob_append(pCol, &zIn[i], 1);
533 if( (c&0xc0)==0x80 ) k--;
534 }
535 }
536 if( needEndSpan ){
537 blob_append(pCol, "</span>", 7);
538 }
539 if( col==SBS_TXTB ){
540 sbsWriteNewlines(p);
541 }else if( !p->escHtml ){
542 sbsWriteSpace(p, w-k, SBS_TXTA);
543 }
544 }
545
546 /*
547 ** Append a column to the final output blob.
548 */
549 static void sbsWriteColumn(Blob *pOut, Blob *pCol, int col){
550 blob_appendf(pOut,
551 "<td><div class=\"diff%scol\">\n"
552 "<pre>\n"
553 "%s"
554 "</pre>\n"
555 "</div></td>\n",
556 col % 3 ? (col == SBS_MKR ? "mkr" : "txt") : "ln",
557 blob_str(pCol)
558 );
559 }
560
561 /*
562 ** Append a separator line to column iCol
563 */
564 static void sbsWriteSep(SbsLine *p, int len, int col){
565 char ch = '.';
566 if( len<1 ){
567 len = 1;
568 ch = ' ';
569 }
570 blob_appendf(p->apCols[col], "<span class=\"diffhr\">%.*c</span>\n", len, ch);
571 }
572
573 /*
574 ** Append the appropriate marker into the center column of the diff.
575 */
576 static void sbsWriteMarker(SbsLine *p, const char *zTxt, const char *zHtml){
577 blob_append(p->apCols[SBS_MKR], p->escHtml ? zHtml : zTxt, -1);
578 }
579
580 /*
581 ** Append a line number to the column.
582 */
583 static void sbsWriteLineno(SbsLine *p, int ln, int col){
584 if( p->escHtml ){
585 blob_appendf(p->apCols[col], "%d", ln+1);
586 }else{
587 char zLn[7];
588 sqlite3_snprintf(7, zLn, "%5d ", ln+1);
589 blob_appendf(p->apCols[col], "%s ", zLn);
590 }
591 }
592
593 /*
594 ** The two text segments zLeft and zRight are known to be different on
595 ** both ends, but they might have a common segment in the middle. If
@@ -1018,43 +748,42 @@
748 }
749 if( nSuffix==nLeft || nSuffix==nRight ) nPrefix = 0;
750 }
751 if( nPrefix+nSuffix > nShort ) nPrefix = nShort - nSuffix;
752
 
753 /* A single chunk of text inserted on the right */
754 if( nPrefix+nSuffix==nLeft ){
755 sbsWriteLineno(p, lnLeft, SBS_LNA);
756 p->iStart2 = p->iEnd2 = 0;
757 p->iStart = p->iEnd = -1;
758 sbsWriteText(p, pLeft, SBS_TXTA);
759 if( nLeft==nRight && zLeft[nLeft]==zRight[nRight] ){
760 sbsWriteMarker(p, " ", "");
761 }else{
762 sbsWriteMarker(p, " | ", "|");
763 }
764 sbsWriteLineno(p, lnRight, SBS_LNB);
765 p->iStart = nPrefix;
766 p->iEnd = nRight - nSuffix;
767 p->zStart = zClassAdd;
768 sbsWriteText(p, pRight, SBS_TXTB);
769 return;
770 }
771
772 /* A single chunk of text deleted from the left */
773 if( nPrefix+nSuffix==nRight ){
774 /* Text deleted from the left */
775 sbsWriteLineno(p, lnLeft, SBS_LNA);
776 p->iStart2 = p->iEnd2 = 0;
777 p->iStart = nPrefix;
778 p->iEnd = nLeft - nSuffix;
779 p->zStart = zClassRm;
780 sbsWriteText(p, pLeft, SBS_TXTA);
781 sbsWriteMarker(p, " | ", "|");
782 sbsWriteLineno(p, lnRight, SBS_LNB);
783 p->iStart = p->iEnd = -1;
784 sbsWriteText(p, pRight, SBS_TXTB);
785 return;
786 }
787
788 /* At this point we know that there is a chunk of text that has
789 ** changed between the left and the right. Check to see if there
@@ -1065,11 +794,11 @@
794 if( p->escHtml
795 && nLeftDiff >= 6
796 && nRightDiff >= 6
797 && textLCS(&zLeft[nPrefix], nLeftDiff, &zRight[nPrefix], nRightDiff, aLCS)
798 ){
799 sbsWriteLineno(p, lnLeft, SBS_LNA);
800 p->iStart = nPrefix;
801 p->iEnd = nPrefix + aLCS[0];
802 if( aLCS[2]==0 ){
803 sbsShiftLeft(p, pLeft->z);
804 p->zStart = zClassRm;
@@ -1078,13 +807,13 @@
807 }
808 p->iStart2 = nPrefix + aLCS[1];
809 p->iEnd2 = nLeft - nSuffix;
810 p->zStart2 = aLCS[3]==nRightDiff ? zClassRm : zClassChng;
811 sbsSimplifyLine(p, zLeft+nPrefix);
812 sbsWriteText(p, pLeft, SBS_TXTA);
813 sbsWriteMarker(p, " | ", "|");
814 sbsWriteLineno(p, lnRight, SBS_LNB);
815 p->iStart = nPrefix;
816 p->iEnd = nPrefix + aLCS[2];
817 if( aLCS[0]==0 ){
818 sbsShiftLeft(p, pRight->z);
819 p->zStart = zClassAdd;
@@ -1093,25 +822,25 @@
822 }
823 p->iStart2 = nPrefix + aLCS[3];
824 p->iEnd2 = nRight - nSuffix;
825 p->zStart2 = aLCS[1]==nLeftDiff ? zClassAdd : zClassChng;
826 sbsSimplifyLine(p, zRight+nPrefix);
827 sbsWriteText(p, pRight, SBS_TXTB);
828 return;
829 }
830
831 /* If all else fails, show a single big change between left and right */
832 sbsWriteLineno(p, lnLeft, SBS_LNA);
833 p->iStart2 = p->iEnd2 = 0;
834 p->iStart = nPrefix;
835 p->iEnd = nLeft - nSuffix;
836 p->zStart = zClassChng;
837 sbsWriteText(p, pLeft, SBS_TXTA);
838 sbsWriteMarker(p, " | ", "|");
839 sbsWriteLineno(p, lnRight, SBS_LNB);
840 p->iEnd = nRight - nSuffix;
841 sbsWriteText(p, pRight, SBS_TXTB);
842 }
843
844 /*
845 ** Minimum of two values
846 */
@@ -1357,30 +1086,40 @@
1086 int mxr; /* Maximum value for r */
1087 int na, nb; /* Number of lines shown from A and B */
1088 int i, j; /* Loop counters */
1089 int m, ma, mb;/* Number of lines to output */
1090 int skip; /* Number of lines to skip */
1091 static int nChunk = 0; /* Number of chunks of diff output seen so far */
1092 SbsLine s; /* Output line buffer */
1093 int nContext; /* Lines of context above and below each change */
1094 int showDivider = 0; /* True to show the divider */
1095 Blob aCols[5]; /* Array of column blobs */
1096
1097 memset(&s, 0, sizeof(s));
1098 s.width = diff_width(diffFlags);
 
 
1099 nContext = diff_context_lines(diffFlags);
1100 s.escHtml = (diffFlags & DIFF_HTML)!=0;
1101 if( s.escHtml ){
1102 for(i=SBS_LNA; i<=SBS_TXTB; i++){
1103 blob_zero(&aCols[i]);
1104 s.apCols[i] = &aCols[i];
1105 }
1106 }else{
1107 for(i=SBS_LNA; i<=SBS_TXTB; i++){
1108 s.apCols[i] = pOut;
1109 }
1110 }
1111 s.pRe = pRe;
1112 s.iStart = -1;
1113 s.iStart2 = 0;
1114 s.iEnd = -1;
1115 A = p->aFrom;
1116 B = p->aTo;
1117 R = p->aEdit;
1118 mxr = p->nEdit;
1119 while( mxr>2 && R[mxr-1]==0 && R[mxr-2]==0 ){ mxr -= 3; }
1120
1121 for(r=0; r<mxr; r += 3*nr){
1122 /* Figure out how many triples to show in a single block */
1123 for(nr=1; R[r+nr*3]>0 && R[r+nr*3]<nContext*2; nr++){}
1124 /* printf("r=%d nr=%d\n", r, nr); */
1125
@@ -1436,35 +1175,39 @@
1175 }
1176
1177 /* Draw the separator between blocks */
1178 if( showDivider ){
1179 if( s.escHtml ){
1180 char zLn[10];
1181 sqlite3_snprintf(sizeof(zLn), zLn, "%d", a+skip+1);
1182 sbsWriteSep(&s, strlen(zLn), SBS_LNA);
1183 sbsWriteSep(&s, s.width, SBS_TXTA);
1184 sbsWriteSep(&s, 0, SBS_MKR);
1185 sqlite3_snprintf(sizeof(zLn), zLn, "%d", b+skip+1);
1186 sbsWriteSep(&s, strlen(zLn), SBS_LNB);
1187 sbsWriteSep(&s, s.width, SBS_TXTB);
1188 }else{
1189 blob_appendf(pOut, "%.*c\n", s.width*2+16, '.');
1190 }
1191 }
1192 showDivider = 1;
1193 nChunk++;
1194 if( s.escHtml ){
1195 blob_appendf(s.apCols[SBS_LNA], "<span id=\"chunk%d\"></span>", nChunk);
1196 }
1197
1198 /* Show the initial common area */
1199 a += skip;
1200 b += skip;
1201 m = R[r] - skip;
1202 for(j=0; j<m; j++){
1203 sbsWriteLineno(&s, a+j, SBS_LNA);
 
1204 s.iStart = s.iEnd = -1;
1205 sbsWriteText(&s, &A[a+j], SBS_TXTA);
1206 sbsWriteMarker(&s, " ", "");
1207 sbsWriteLineno(&s, b+j, SBS_LNB);
1208 sbsWriteText(&s, &B[b+j], SBS_TXTB);
 
1209 }
1210 a += m;
1211 b += m;
1212
1213 /* Show the differences */
@@ -1485,87 +1228,71 @@
1228
1229 alignment = sbsAlignment(&A[a], ma, &B[b], mb);
1230 for(j=0; ma+mb>0; j++){
1231 if( alignment[j]==1 ){
1232 /* Delete one line from the left */
1233 sbsWriteLineno(&s, a, SBS_LNA);
 
1234 s.iStart = 0;
1235 s.zStart = "<span class=\"diffrm\">";
1236 s.iEnd = LENGTH(&A[a]);
1237 sbsWriteText(&s, &A[a], SBS_TXTA);
1238 sbsWriteMarker(&s, " <", "&lt;");
1239 sbsWriteNewlines(&s);
 
 
 
 
1240 assert( ma>0 );
1241 ma--;
1242 a++;
1243 }else if( alignment[j]==3 ){
1244 /* The left line is changed into the right line */
 
1245 sbsWriteLineChange(&s, &A[a], a, &B[b], b);
 
1246 assert( ma>0 && mb>0 );
1247 ma--;
1248 mb--;
1249 a++;
1250 b++;
1251 }else if( alignment[j]==2 ){
1252 /* Insert one line on the right */
1253 if( !s.escHtml ){
1254 sbsWriteSpace(&s, s.width + 7, SBS_TXTA);
1255 }
1256 sbsWriteMarker(&s, " > ", "&gt;");
1257 sbsWriteLineno(&s, b, SBS_LNB);
 
 
 
1258 s.iStart = 0;
1259 s.zStart = "<span class=\"diffadd\">";
1260 s.iEnd = LENGTH(&B[b]);
1261 sbsWriteText(&s, &B[b], SBS_TXTB);
 
1262 assert( mb>0 );
1263 mb--;
1264 b++;
1265 }else{
1266 /* Delete from the left and insert on the right */
1267 sbsWriteLineno(&s, a, SBS_LNA);
 
1268 s.iStart = 0;
1269 s.zStart = "<span class=\"diffrm\">";
1270 s.iEnd = LENGTH(&A[a]);
1271 sbsWriteText(&s, &A[a], SBS_TXTA);
1272 sbsWriteMarker(&s, " | ", "|");
1273 sbsWriteLineno(&s, b, SBS_LNB);
1274 s.iStart = 0;
1275 s.zStart = "<span class=\"diffadd\">";
1276 s.iEnd = LENGTH(&B[b]);
1277 sbsWriteText(&s, &B[b], SBS_TXTB);
 
1278 ma--;
1279 mb--;
1280 a++;
1281 b++;
1282 }
 
1283 }
1284 fossil_free(alignment);
1285 if( i<nr-1 ){
1286 m = R[r+i*3+3];
1287 for(j=0; j<m; j++){
1288 sbsWriteLineno(&s, a+j, SBS_LNA);
 
1289 s.iStart = s.iEnd = -1;
1290 sbsWriteText(&s, &A[a+j], SBS_TXTA);
1291 sbsWriteMarker(&s, " ", "");
1292 sbsWriteLineno(&s, b+j, SBS_LNB);
1293 sbsWriteText(&s, &B[b+j], SBS_TXTB);
 
1294 }
1295 b += m;
1296 a += m;
1297 }
1298 }
@@ -1573,21 +1300,27 @@
1300 /* Show the final common area */
1301 assert( nr==i );
1302 m = R[r+nr*3];
1303 if( m>nContext ) m = nContext;
1304 for(j=0; j<m; j++){
1305 sbsWriteLineno(&s, a+j, SBS_LNA);
 
1306 s.iStart = s.iEnd = -1;
1307 sbsWriteText(&s, &A[a+j], SBS_TXTA);
1308 sbsWriteMarker(&s, " ", "");
1309 sbsWriteLineno(&s, b+j, SBS_LNB);
1310 sbsWriteText(&s, &B[b+j], SBS_TXTB);
 
1311 }
1312 }
1313
1314 if( s.escHtml && blob_size(s.apCols[SBS_LNA])>0 ){
1315 blob_append(pOut, "<table class=\"sbsdiffcols\"><tr>\n", -1);
1316 for(i=SBS_LNA; i<=SBS_TXTB; i++){
1317 sbsWriteColumn(pOut, s.apCols[i], i);
1318 blob_reset(s.apCols[i]);
1319 }
1320 blob_append(pOut, "</tr></table>\n", -1);
1321 }
1322 }
1323
1324 /*
1325 ** Compute the optimal longest common subsequence (LCS) using an
1326 ** exhaustive search. This version of the LCS is only used for
@@ -1990,10 +1723,21 @@
1723 int diff_width(u64 diffFlags){
1724 int w = (diffFlags & DIFF_WIDTH_MASK)/(DIFF_CONTEXT_MASK+1);
1725 if( w==0 ) w = 80;
1726 return w;
1727 }
1728
1729 /*
1730 ** Append the error message to pOut.
1731 */
1732 void diff_errmsg(Blob *pOut, const char *msg, int diffFlags){
1733 if( diffFlags & DIFF_HTML ){
1734 blob_appendf(pOut, "<p class=\"generalError\">%s</p>", msg);
1735 }else{
1736 blob_append(pOut, msg, -1);
1737 }
1738 }
1739
1740 /*
1741 ** Generate a report of the differences between files pA and pB.
1742 ** If pOut is not NULL then a unified diff is appended there. It
1743 ** is assumed that pOut has already been initialized. If pOut is
@@ -2032,11 +1776,11 @@
1776 &c.nTo, ignoreEolWs);
1777 if( c.aFrom==0 || c.aTo==0 ){
1778 fossil_free(c.aFrom);
1779 fossil_free(c.aTo);
1780 if( pOut ){
1781 diff_errmsg(pOut, DIFF_CANNOT_COMPUTE_BINARY, diffFlags);
1782 }
1783 return 0;
1784 }
1785
1786 /* Compute the difference */
@@ -2048,15 +1792,11 @@
1792 for(i=m=n=0; i<mx; i+=3){ m += a[i]; n += a[i+1]+a[i+2]; }
1793 if( n>10000 ){
1794 fossil_free(c.aFrom);
1795 fossil_free(c.aTo);
1796 fossil_free(c.aEdit);
1797 diff_errmsg(pOut, DIFF_TOO_MANY_CHANGES, diffFlags);
 
 
 
 
1798 return 0;
1799 }
1800 }
1801 if( (diffFlags & DIFF_NOOPT)==0 ){
1802 diff_optimize(&c);
@@ -2159,10 +1899,11 @@
1899 if( find_option("tk",0,0)!=0 ){
1900 diff_tk("test-diff", 2);
1901 return;
1902 }
1903 find_option("i",0,0);
1904 find_option("v",0,0);
1905 zRe = find_option("regexp","e",1);
1906 if( zRe ){
1907 const char *zErr = re_compile(&pRe, zRe, 0);
1908 if( zErr ) fossil_fatal("regex error: %s", zErr);
1909 }
@@ -2616,60 +2357,5 @@
2357 zPrefix[0] = 0;
2358 }
2359 fossil_print("%21s %4d: %.*s\n", zPrefix, i+1, n, z);
2360 }
2361 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2362
+306 -40
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -597,53 +597,319 @@
597597
return db_get(zName, zDefault);
598598
}
599599
600600
/* A Tcl/Tk script used to render diff output.
601601
*/
602
-static const char zDiffScript[] =
602
+static const char zDiffScript[] =
603603
@ package require Tk
604
-@ wm withdraw .
605
-@ wm title . {Fossil Diff}
606
-@ wm iconname . {Fossil Diff}
607
-@ bind . <q> exit
608
-@ set body {}
609
-@ set mx 80 ;# Length of the longest line of text
610
-@ set nLine 0 ;# Number of lines of text
611
-@ text .t -width 180 -yscroll {.sb set}
612
-@ if {$tcl_platform(platform)=="windows"} {.t config -font {courier 9}}
613
-@ .t tag config ln -foreground gray
614
-@ .t tag config chng -background {#d0d0ff}
615
-@ .t tag config add -background {#c0ffc0}
616
-@ .t tag config rm -background {#ffc0c0}
604
+@
605
+@ array set CFG {
606
+@ TITLE {Fossil Diff}
607
+@ LN_COL_BG #dddddd
608
+@ LN_COL_FG #444444
609
+@ TXT_COL_BG #ffffff
610
+@ TXT_COL_FG #000000
611
+@ MKR_COL_BG #444444
612
+@ MKR_COL_FG #dddddd
613
+@ CHNG_BG #d0d0ff
614
+@ ADD_BG #c0ffc0
615
+@ RM_BG #ffc0c0
616
+@ HR_FG #888888
617
+@ HR_PAD_TOP 4
618
+@ HR_PAD_BTM 8
619
+@ FN_BG #444444
620
+@ FN_FG #ffffff
621
+@ FN_PAD 5
622
+@ FONTS {{DejaVu Sans Mono} Consolas Monaco fixed}
623
+@ FONT_SIZE 9
624
+@ PADX 5
625
+@ WIDTH 80
626
+@ HEIGHT 45
627
+@ LB_HEIGHT 25
628
+@ }
629
+@
630
+@ if {![namespace exists ttk]} {
631
+@ interp alias {} ::ttk::scrollbar {} ::scrollbar
632
+@ interp alias {} ::ttk::menubutton {} ::menubutton
633
+@ }
634
+@
617635
@ proc dehtml {x} {
636
+@ set x [regsub -all {<[^>]*>} $x {}]
618637
@ return [string map {&amp; & &lt; < &gt; > &#39; ' &quot; \"} $x]
619638
@ }
620
-@ # puts $cmd
621
-@ set in [open $cmd r]
622
-@ while {![eof $in]} {
623
-@ set line [gets $in]
624
-@ if {[regexp {^<a name="chunk.*"></a>} $line]} continue
625
-@ if {[regexp {^===} $line]} {
626
-@ set n [string length $line]
627
-@ if {$n>$mx} {set mx $n}
628
-@ }
629
-@ incr nLine
630
-@ while {[regexp {^(.*?)<span class="diff([a-z]+)">(.*?)</span>(.*)$} $line \
631
-@ all pre class mid tail]} {
632
-@ .t insert end [dehtml $pre] {} [dehtml $mid] $class
633
-@ set line $tail
634
-@ }
635
-@ .t insert end [dehtml $line]\n {}
636
-@ }
637
-@ close $in
638
-@ if {$mx>250} {set mx 250} ;# Limit window width to 200 characters
639
-@ if {$nLine>55} {set nLine 55} ;# Limit window height to 55 lines
640
-@ .t config -height $nLine -width $mx
641
-@ pack .t -side left -fill both -expand 1
642
-@ scrollbar .sb -command {.t yview} -orient vertical
643
-@ pack .sb -side left -fill y
644
-@ wm deiconify .
639
+@
640
+@ proc cols {} {
641
+@ return [list .lnA .txtA .mkr .lnB .txtB]
642
+@ }
643
+@
644
+@ proc colType {c} {
645
+@ regexp {[a-z]+} $c type
646
+@ return $type
647
+@ }
648
+@
649
+@ proc readDiffs {cmd} {
650
+@ set in [open $cmd r]
651
+@ set nDiffs 0
652
+@ array set widths {txt 0 ln 0 mkr 0}
653
+@ while {[gets $in line] != -1} {
654
+@ if {![regexp {^=+\s+(.*?)\s+=+$} $line all fn]} {
655
+@ continue
656
+@ }
657
+@ if {[string compare -length 6 [gets $in] "<table"]} {
658
+@ continue
659
+@ }
660
+@ incr nDiffs
661
+@ set idx [expr {$nDiffs > 1 ? [.txtA index end] : "1.0"}]
662
+@ .wfiles.lb insert end $fn
663
+@
664
+@ foreach c [cols] {
665
+@ while {[gets $in] ne "<pre>"} continue
666
+@
667
+@ if {$nDiffs > 1} {
668
+@ $c insert end \n -
669
+@ }
670
+@ if {[colType $c] eq "txt"} {
671
+@ $c insert end $fn\n fn
672
+@ } else {
673
+@ $c insert end \n fn
674
+@ }
675
+@ $c insert end \n -
676
+@
677
+@ set type [colType $c]
678
+@ set str {}
679
+@ while {[set line [gets $in]] ne "</pre>"} {
680
+@ set len [string length [dehtml $line]]
681
+@ if {$len > $widths($type)} {
682
+@ set widths($type) $len
683
+@ }
684
+@ append str $line\n
685
+@ }
686
+@
687
+@ set re {<span class="diff([a-z]+)">([^<]*)</span>}
688
+@ # Use \r as separator since it can't appear in the diff output (it gets
689
+@ # converted to a space).
690
+@ set str [regsub -all $re $str "\r\\1\r\\2\r"]
691
+@ foreach {pre class mid} [split $str \r] {
692
+@ if {$class ne ""} {
693
+@ $c insert end [dehtml $pre] - [dehtml $mid] [list $class -]
694
+@ } else {
695
+@ $c insert end [dehtml $pre] -
696
+@ }
697
+@ }
698
+@ }
699
+@ }
700
+@ close $in
701
+@
702
+@ foreach c [cols] {
703
+@ set type [colType $c]
704
+@ if {$type ne "txt"} {
705
+@ $c config -width $widths($type)
706
+@ }
707
+@ $c config -state disabled
708
+@ }
709
+@ if {$nDiffs <= [.wfiles.lb cget -height]} {
710
+@ .wfiles.lb config -height $nDiffs
711
+@ grid remove .wfiles.sb
712
+@ }
713
+@
714
+@ return $nDiffs
715
+@ }
716
+@
717
+@ proc viewDiff {idx} {
718
+@ .txtA yview $idx
719
+@ .txtA xview moveto 0
720
+@ }
721
+@
722
+@ proc cycleDiffs {{reverse 0}} {
723
+@ if {$reverse} {
724
+@ set range [.txtA tag prevrange fn @0,0 1.0]
725
+@ if {$range eq ""} {
726
+@ viewDiff {fn.last -1c}
727
+@ } else {
728
+@ viewDiff [lindex $range 0]
729
+@ }
730
+@ } else {
731
+@ set range [.txtA tag nextrange fn {@0,0 +1c} end]
732
+@ if {$range eq "" || [lindex [.txtA yview] 1] == 1} {
733
+@ viewDiff fn.first
734
+@ } else {
735
+@ viewDiff [lindex $range 0]
736
+@ }
737
+@ }
738
+@ }
739
+@
740
+@ proc xvis {col} {
741
+@ set view [$col xview]
742
+@ return [expr {[lindex $view 1]-[lindex $view 0]}]
743
+@ }
744
+@
745
+@ proc scroll-x {args} {
746
+@ set c .txt[expr {[xvis .txtA] < [xvis .txtB] ? "A" : "B"}]
747
+@ eval $c xview $args
748
+@ }
749
+@
750
+@ interp alias {} scroll-y {} .txtA yview
751
+@
752
+@ proc noop {args} {}
753
+@
754
+@ proc enableSync {axis} {
755
+@ update idletasks
756
+@ interp alias {} sync-$axis {}
757
+@ rename _sync-$axis sync-$axis
758
+@ }
759
+@
760
+@ proc disableSync {axis} {
761
+@ rename sync-$axis _sync-$axis
762
+@ interp alias {} sync-$axis {} noop
763
+@ }
764
+@
765
+@ proc sync-x {col first last} {
766
+@ disableSync x
767
+@ $col xview moveto [expr {$first*[xvis $col]/($last-$first)}]
768
+@ foreach side {A B} {
769
+@ set sb .sbx$side
770
+@ set xview [.txt$side xview]
771
+@ if {$xview ne "0.0 1.0"} {
772
+@ grid $sb
773
+@ eval $sb set $xview
774
+@ } else {
775
+@ grid remove $sb
776
+@ }
777
+@ }
778
+@ enableSync x
779
+@ }
780
+@
781
+@ proc sync-y {first last} {
782
+@ disableSync y
783
+@ foreach c [cols] {
784
+@ $c yview moveto $first
785
+@ }
786
+@ if {$first > 0 || $last < 1} {
787
+@ grid .sby
788
+@ .sby set $first $last
789
+@ } else {
790
+@ grid remove .sby
791
+@ }
792
+@ enableSync y
793
+@ }
794
+@
795
+@ wm withdraw .
796
+@ wm title . $CFG(TITLE)
797
+@ wm iconname . $CFG(TITLE)
798
+@ bind . <q> exit
799
+@ bind . <Tab> {cycleDiffs; break}
800
+@ bind . <<PrevWindow>> {cycleDiffs 1; break}
801
+@ bind . <Return> {
802
+@ event generate .files <1>
803
+@ event generate .files <ButtonRelease-1>
804
+@ break
805
+@ }
806
+@ foreach {key axis args} {
807
+@ Up y {scroll -5 units}
808
+@ Down y {scroll 5 units}
809
+@ Left x {scroll -5 units}
810
+@ Right x {scroll 5 units}
811
+@ Prior y {scroll -1 page}
812
+@ Next y {scroll 1 page}
813
+@ Home y {moveto 0}
814
+@ End y {moveto 1}
815
+@ } {
816
+@ bind . <$key> "scroll-$axis $args; break"
817
+@ bind . <Shift-$key> continue
818
+@ }
819
+@
820
+@ ::ttk::menubutton .files -text "Files"
821
+@ toplevel .wfiles
822
+@ wm withdraw .wfiles
823
+@ update idletasks
824
+@ wm transient .wfiles .
825
+@ wm overrideredirect .wfiles 1
826
+@ listbox .wfiles.lb -width 0 -height $CFG(LB_HEIGHT) -activestyle none \
827
+@ -yscroll {.wfiles.sb set}
828
+@ ::ttk::scrollbar .wfiles.sb -command {.wfiles.lb yview}
829
+@ grid .wfiles.lb .wfiles.sb -sticky ns
830
+@ bind .files <1> {
831
+@ set x [winfo rootx %W]
832
+@ set y [expr {[winfo rooty %W]+[winfo height %W]}]
833
+@ wm geometry .wfiles +$x+$y
834
+@ wm deiconify .wfiles
835
+@ focus .wfiles.lb
836
+@ }
837
+@ bind .wfiles <FocusOut> {wm withdraw .wfiles}
838
+@ bind .wfiles <Escape> {focus .}
839
+@ foreach evt {1 Return} {
840
+@ bind .wfiles.lb <$evt> {
841
+@ catch {
842
+@ set idx [lindex [.txtA tag ranges fn] [expr {[%W curselection]*2}]]
843
+@ viewDiff $idx
844
+@ }
845
+@ focus .
846
+@ break
847
+@ }
848
+@ }
849
+@ bind .wfiles.lb <Motion> {
850
+@ %W selection clear 0 end
851
+@ %W selection set @%x,%y
852
+@ }
853
+@
854
+@ foreach {side syncCol} {A .txtB B .txtA} {
855
+@ set ln .ln$side
856
+@ text $ln
857
+@ $ln tag config - -justify right
858
+@
859
+@ set txt .txt$side
860
+@ text $txt -width $CFG(WIDTH) -height $CFG(HEIGHT) -wrap none \
861
+@ -xscroll "sync-x $syncCol"
862
+@ foreach tag {add rm chng} {
863
+@ $txt tag config $tag -background $CFG([string toupper $tag]_BG)
864
+@ $txt tag lower $tag
865
+@ }
866
+@ $txt tag config fn -background $CFG(FN_BG) -foreground $CFG(FN_FG) \
867
+@ -justify center
868
+@ }
869
+@ text .mkr
870
+@
871
+@ font create mono -family courier -size $CFG(FONT_SIZE)
872
+@ foreach font $CFG(FONTS) {
873
+@ if {[lsearch -exact [font families] $font] != -1} {
874
+@ font config mono -family $font
875
+@ break
876
+@ }
877
+@ }
878
+@ foreach c [cols] {
879
+@ set keyPrefix [string toupper [colType $c]]_COL_
880
+@ $c config -bg $CFG(${keyPrefix}BG) -fg $CFG(${keyPrefix}FG) -borderwidth 0 \
881
+@ -font mono -padx $CFG(PADX) -yscroll sync-y
882
+@ $c tag config hr -spacing1 $CFG(HR_PAD_TOP) -spacing3 $CFG(HR_PAD_BTM) \
883
+@ -foreground $CFG(HR_FG)
884
+@ $c tag config fn -spacing1 $CFG(FN_PAD) -spacing3 $CFG(FN_PAD)
885
+@ bindtags $c ". $c Text all"
886
+@ bind $c <1> {focus %W}
887
+@ }
888
+@
889
+@ ::ttk::scrollbar .sby -command {.txtA yview} -orient vertical
890
+@ ::ttk::scrollbar .sbxA -command {.txtA xview} -orient horizontal
891
+@ ::ttk::scrollbar .sbxB -command {.txtB xview} -orient horizontal
892
+@ frame .spacer
893
+@
894
+@ if {[readDiffs $cmd] == 0} {
895
+@ tk_messageBox -type ok -title $CFG(TITLE) -message "No changes"
896
+@ exit
897
+@ }
898
+@
899
+@ grid rowconfigure . 1 -weight 1
900
+@ grid columnconfigure . 1 -weight 1
901
+@ grid columnconfigure . 4 -weight 1
902
+@ grid .files -columnspan 6
903
+@ eval grid [cols] .sby -sticky nsew
904
+@ grid .sbxA -row 2 -column 0 -columnspan 2 -sticky ew
905
+@ grid .spacer -row 2 -column 2
906
+@ grid .sbxB -row 2 -column 3 -columnspan 2 -sticky ew
907
+@
908
+@ wm deiconify .
909
+@ update idletasks
910
+@ .spacer config -height [winfo height .sbxA]
645911
;
646912
647913
/*
648914
** Show diff output in a Tcl/Tk window, in response to the --tk option
649915
** to the diff command.
@@ -657,11 +923,11 @@
657923
int i;
658924
Blob script;
659925
char *zTempFile;
660926
char *zCmd;
661927
blob_zero(&script);
662
- blob_appendf(&script, "set cmd {| \"%/\" %s --html -y -i",
928
+ blob_appendf(&script, "set cmd {| \"%/\" %s --html -y -i -v",
663929
g.nameOfExe, zSubCmd);
664930
for(i=firstArg; i<g.argc; i++){
665931
const char *z = g.argv[i];
666932
if( z[0]=='-' ){
667933
if( strglob("*-html",z) ) continue;
668934
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -597,53 +597,319 @@
597 return db_get(zName, zDefault);
598 }
599
600 /* A Tcl/Tk script used to render diff output.
601 */
602 static const char zDiffScript[] =
603 @ package require Tk
604 @ wm withdraw .
605 @ wm title . {Fossil Diff}
606 @ wm iconname . {Fossil Diff}
607 @ bind . <q> exit
608 @ set body {}
609 @ set mx 80 ;# Length of the longest line of text
610 @ set nLine 0 ;# Number of lines of text
611 @ text .t -width 180 -yscroll {.sb set}
612 @ if {$tcl_platform(platform)=="windows"} {.t config -font {courier 9}}
613 @ .t tag config ln -foreground gray
614 @ .t tag config chng -background {#d0d0ff}
615 @ .t tag config add -background {#c0ffc0}
616 @ .t tag config rm -background {#ffc0c0}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
617 @ proc dehtml {x} {
 
618 @ return [string map {&amp; & &lt; < &gt; > &#39; ' &quot; \"} $x]
619 @ }
620 @ # puts $cmd
621 @ set in [open $cmd r]
622 @ while {![eof $in]} {
623 @ set line [gets $in]
624 @ if {[regexp {^<a name="chunk.*"></a>} $line]} continue
625 @ if {[regexp {^===} $line]} {
626 @ set n [string length $line]
627 @ if {$n>$mx} {set mx $n}
628 @ }
629 @ incr nLine
630 @ while {[regexp {^(.*?)<span class="diff([a-z]+)">(.*?)</span>(.*)$} $line \
631 @ all pre class mid tail]} {
632 @ .t insert end [dehtml $pre] {} [dehtml $mid] $class
633 @ set line $tail
634 @ }
635 @ .t insert end [dehtml $line]\n {}
636 @ }
637 @ close $in
638 @ if {$mx>250} {set mx 250} ;# Limit window width to 200 characters
639 @ if {$nLine>55} {set nLine 55} ;# Limit window height to 55 lines
640 @ .t config -height $nLine -width $mx
641 @ pack .t -side left -fill both -expand 1
642 @ scrollbar .sb -command {.t yview} -orient vertical
643 @ pack .sb -side left -fill y
644 @ wm deiconify .
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
645 ;
646
647 /*
648 ** Show diff output in a Tcl/Tk window, in response to the --tk option
649 ** to the diff command.
@@ -657,11 +923,11 @@
657 int i;
658 Blob script;
659 char *zTempFile;
660 char *zCmd;
661 blob_zero(&script);
662 blob_appendf(&script, "set cmd {| \"%/\" %s --html -y -i",
663 g.nameOfExe, zSubCmd);
664 for(i=firstArg; i<g.argc; i++){
665 const char *z = g.argv[i];
666 if( z[0]=='-' ){
667 if( strglob("*-html",z) ) continue;
668
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -597,53 +597,319 @@
597 return db_get(zName, zDefault);
598 }
599
600 /* A Tcl/Tk script used to render diff output.
601 */
602 static const char zDiffScript[] =
603 @ package require Tk
604 @
605 @ array set CFG {
606 @ TITLE {Fossil Diff}
607 @ LN_COL_BG #dddddd
608 @ LN_COL_FG #444444
609 @ TXT_COL_BG #ffffff
610 @ TXT_COL_FG #000000
611 @ MKR_COL_BG #444444
612 @ MKR_COL_FG #dddddd
613 @ CHNG_BG #d0d0ff
614 @ ADD_BG #c0ffc0
615 @ RM_BG #ffc0c0
616 @ HR_FG #888888
617 @ HR_PAD_TOP 4
618 @ HR_PAD_BTM 8
619 @ FN_BG #444444
620 @ FN_FG #ffffff
621 @ FN_PAD 5
622 @ FONTS {{DejaVu Sans Mono} Consolas Monaco fixed}
623 @ FONT_SIZE 9
624 @ PADX 5
625 @ WIDTH 80
626 @ HEIGHT 45
627 @ LB_HEIGHT 25
628 @ }
629 @
630 @ if {![namespace exists ttk]} {
631 @ interp alias {} ::ttk::scrollbar {} ::scrollbar
632 @ interp alias {} ::ttk::menubutton {} ::menubutton
633 @ }
634 @
635 @ proc dehtml {x} {
636 @ set x [regsub -all {<[^>]*>} $x {}]
637 @ return [string map {&amp; & &lt; < &gt; > &#39; ' &quot; \"} $x]
638 @ }
639 @
640 @ proc cols {} {
641 @ return [list .lnA .txtA .mkr .lnB .txtB]
642 @ }
643 @
644 @ proc colType {c} {
645 @ regexp {[a-z]+} $c type
646 @ return $type
647 @ }
648 @
649 @ proc readDiffs {cmd} {
650 @ set in [open $cmd r]
651 @ set nDiffs 0
652 @ array set widths {txt 0 ln 0 mkr 0}
653 @ while {[gets $in line] != -1} {
654 @ if {![regexp {^=+\s+(.*?)\s+=+$} $line all fn]} {
655 @ continue
656 @ }
657 @ if {[string compare -length 6 [gets $in] "<table"]} {
658 @ continue
659 @ }
660 @ incr nDiffs
661 @ set idx [expr {$nDiffs > 1 ? [.txtA index end] : "1.0"}]
662 @ .wfiles.lb insert end $fn
663 @
664 @ foreach c [cols] {
665 @ while {[gets $in] ne "<pre>"} continue
666 @
667 @ if {$nDiffs > 1} {
668 @ $c insert end \n -
669 @ }
670 @ if {[colType $c] eq "txt"} {
671 @ $c insert end $fn\n fn
672 @ } else {
673 @ $c insert end \n fn
674 @ }
675 @ $c insert end \n -
676 @
677 @ set type [colType $c]
678 @ set str {}
679 @ while {[set line [gets $in]] ne "</pre>"} {
680 @ set len [string length [dehtml $line]]
681 @ if {$len > $widths($type)} {
682 @ set widths($type) $len
683 @ }
684 @ append str $line\n
685 @ }
686 @
687 @ set re {<span class="diff([a-z]+)">([^<]*)</span>}
688 @ # Use \r as separator since it can't appear in the diff output (it gets
689 @ # converted to a space).
690 @ set str [regsub -all $re $str "\r\\1\r\\2\r"]
691 @ foreach {pre class mid} [split $str \r] {
692 @ if {$class ne ""} {
693 @ $c insert end [dehtml $pre] - [dehtml $mid] [list $class -]
694 @ } else {
695 @ $c insert end [dehtml $pre] -
696 @ }
697 @ }
698 @ }
699 @ }
700 @ close $in
701 @
702 @ foreach c [cols] {
703 @ set type [colType $c]
704 @ if {$type ne "txt"} {
705 @ $c config -width $widths($type)
706 @ }
707 @ $c config -state disabled
708 @ }
709 @ if {$nDiffs <= [.wfiles.lb cget -height]} {
710 @ .wfiles.lb config -height $nDiffs
711 @ grid remove .wfiles.sb
712 @ }
713 @
714 @ return $nDiffs
715 @ }
716 @
717 @ proc viewDiff {idx} {
718 @ .txtA yview $idx
719 @ .txtA xview moveto 0
720 @ }
721 @
722 @ proc cycleDiffs {{reverse 0}} {
723 @ if {$reverse} {
724 @ set range [.txtA tag prevrange fn @0,0 1.0]
725 @ if {$range eq ""} {
726 @ viewDiff {fn.last -1c}
727 @ } else {
728 @ viewDiff [lindex $range 0]
729 @ }
730 @ } else {
731 @ set range [.txtA tag nextrange fn {@0,0 +1c} end]
732 @ if {$range eq "" || [lindex [.txtA yview] 1] == 1} {
733 @ viewDiff fn.first
734 @ } else {
735 @ viewDiff [lindex $range 0]
736 @ }
737 @ }
738 @ }
739 @
740 @ proc xvis {col} {
741 @ set view [$col xview]
742 @ return [expr {[lindex $view 1]-[lindex $view 0]}]
743 @ }
744 @
745 @ proc scroll-x {args} {
746 @ set c .txt[expr {[xvis .txtA] < [xvis .txtB] ? "A" : "B"}]
747 @ eval $c xview $args
748 @ }
749 @
750 @ interp alias {} scroll-y {} .txtA yview
751 @
752 @ proc noop {args} {}
753 @
754 @ proc enableSync {axis} {
755 @ update idletasks
756 @ interp alias {} sync-$axis {}
757 @ rename _sync-$axis sync-$axis
758 @ }
759 @
760 @ proc disableSync {axis} {
761 @ rename sync-$axis _sync-$axis
762 @ interp alias {} sync-$axis {} noop
763 @ }
764 @
765 @ proc sync-x {col first last} {
766 @ disableSync x
767 @ $col xview moveto [expr {$first*[xvis $col]/($last-$first)}]
768 @ foreach side {A B} {
769 @ set sb .sbx$side
770 @ set xview [.txt$side xview]
771 @ if {$xview ne "0.0 1.0"} {
772 @ grid $sb
773 @ eval $sb set $xview
774 @ } else {
775 @ grid remove $sb
776 @ }
777 @ }
778 @ enableSync x
779 @ }
780 @
781 @ proc sync-y {first last} {
782 @ disableSync y
783 @ foreach c [cols] {
784 @ $c yview moveto $first
785 @ }
786 @ if {$first > 0 || $last < 1} {
787 @ grid .sby
788 @ .sby set $first $last
789 @ } else {
790 @ grid remove .sby
791 @ }
792 @ enableSync y
793 @ }
794 @
795 @ wm withdraw .
796 @ wm title . $CFG(TITLE)
797 @ wm iconname . $CFG(TITLE)
798 @ bind . <q> exit
799 @ bind . <Tab> {cycleDiffs; break}
800 @ bind . <<PrevWindow>> {cycleDiffs 1; break}
801 @ bind . <Return> {
802 @ event generate .files <1>
803 @ event generate .files <ButtonRelease-1>
804 @ break
805 @ }
806 @ foreach {key axis args} {
807 @ Up y {scroll -5 units}
808 @ Down y {scroll 5 units}
809 @ Left x {scroll -5 units}
810 @ Right x {scroll 5 units}
811 @ Prior y {scroll -1 page}
812 @ Next y {scroll 1 page}
813 @ Home y {moveto 0}
814 @ End y {moveto 1}
815 @ } {
816 @ bind . <$key> "scroll-$axis $args; break"
817 @ bind . <Shift-$key> continue
818 @ }
819 @
820 @ ::ttk::menubutton .files -text "Files"
821 @ toplevel .wfiles
822 @ wm withdraw .wfiles
823 @ update idletasks
824 @ wm transient .wfiles .
825 @ wm overrideredirect .wfiles 1
826 @ listbox .wfiles.lb -width 0 -height $CFG(LB_HEIGHT) -activestyle none \
827 @ -yscroll {.wfiles.sb set}
828 @ ::ttk::scrollbar .wfiles.sb -command {.wfiles.lb yview}
829 @ grid .wfiles.lb .wfiles.sb -sticky ns
830 @ bind .files <1> {
831 @ set x [winfo rootx %W]
832 @ set y [expr {[winfo rooty %W]+[winfo height %W]}]
833 @ wm geometry .wfiles +$x+$y
834 @ wm deiconify .wfiles
835 @ focus .wfiles.lb
836 @ }
837 @ bind .wfiles <FocusOut> {wm withdraw .wfiles}
838 @ bind .wfiles <Escape> {focus .}
839 @ foreach evt {1 Return} {
840 @ bind .wfiles.lb <$evt> {
841 @ catch {
842 @ set idx [lindex [.txtA tag ranges fn] [expr {[%W curselection]*2}]]
843 @ viewDiff $idx
844 @ }
845 @ focus .
846 @ break
847 @ }
848 @ }
849 @ bind .wfiles.lb <Motion> {
850 @ %W selection clear 0 end
851 @ %W selection set @%x,%y
852 @ }
853 @
854 @ foreach {side syncCol} {A .txtB B .txtA} {
855 @ set ln .ln$side
856 @ text $ln
857 @ $ln tag config - -justify right
858 @
859 @ set txt .txt$side
860 @ text $txt -width $CFG(WIDTH) -height $CFG(HEIGHT) -wrap none \
861 @ -xscroll "sync-x $syncCol"
862 @ foreach tag {add rm chng} {
863 @ $txt tag config $tag -background $CFG([string toupper $tag]_BG)
864 @ $txt tag lower $tag
865 @ }
866 @ $txt tag config fn -background $CFG(FN_BG) -foreground $CFG(FN_FG) \
867 @ -justify center
868 @ }
869 @ text .mkr
870 @
871 @ font create mono -family courier -size $CFG(FONT_SIZE)
872 @ foreach font $CFG(FONTS) {
873 @ if {[lsearch -exact [font families] $font] != -1} {
874 @ font config mono -family $font
875 @ break
876 @ }
877 @ }
878 @ foreach c [cols] {
879 @ set keyPrefix [string toupper [colType $c]]_COL_
880 @ $c config -bg $CFG(${keyPrefix}BG) -fg $CFG(${keyPrefix}FG) -borderwidth 0 \
881 @ -font mono -padx $CFG(PADX) -yscroll sync-y
882 @ $c tag config hr -spacing1 $CFG(HR_PAD_TOP) -spacing3 $CFG(HR_PAD_BTM) \
883 @ -foreground $CFG(HR_FG)
884 @ $c tag config fn -spacing1 $CFG(FN_PAD) -spacing3 $CFG(FN_PAD)
885 @ bindtags $c ". $c Text all"
886 @ bind $c <1> {focus %W}
887 @ }
888 @
889 @ ::ttk::scrollbar .sby -command {.txtA yview} -orient vertical
890 @ ::ttk::scrollbar .sbxA -command {.txtA xview} -orient horizontal
891 @ ::ttk::scrollbar .sbxB -command {.txtB xview} -orient horizontal
892 @ frame .spacer
893 @
894 @ if {[readDiffs $cmd] == 0} {
895 @ tk_messageBox -type ok -title $CFG(TITLE) -message "No changes"
896 @ exit
897 @ }
898 @
899 @ grid rowconfigure . 1 -weight 1
900 @ grid columnconfigure . 1 -weight 1
901 @ grid columnconfigure . 4 -weight 1
902 @ grid .files -columnspan 6
903 @ eval grid [cols] .sby -sticky nsew
904 @ grid .sbxA -row 2 -column 0 -columnspan 2 -sticky ew
905 @ grid .spacer -row 2 -column 2
906 @ grid .sbxB -row 2 -column 3 -columnspan 2 -sticky ew
907 @
908 @ wm deiconify .
909 @ update idletasks
910 @ .spacer config -height [winfo height .sbxA]
911 ;
912
913 /*
914 ** Show diff output in a Tcl/Tk window, in response to the --tk option
915 ** to the diff command.
@@ -657,11 +923,11 @@
923 int i;
924 Blob script;
925 char *zTempFile;
926 char *zCmd;
927 blob_zero(&script);
928 blob_appendf(&script, "set cmd {| \"%/\" %s --html -y -i -v",
929 g.nameOfExe, zSubCmd);
930 for(i=firstArg; i<g.argc; i++){
931 const char *z = g.argv[i];
932 if( z[0]=='-' ){
933 if( strglob("*-html",z) ) continue;
934
+86 -70
--- src/info.c
+++ src/info.c
@@ -316,25 +316,22 @@
316316
blob_zero(&to);
317317
}
318318
blob_zero(&out);
319319
if( diffFlags & DIFF_SIDEBYSIDE ){
320320
text_diff(&from, &to, &out, pRe, diffFlags | DIFF_HTML | DIFF_NOTTOOBIG);
321
- @ <div class="sbsdiff">
322321
@ %s(blob_str(&out))
323
- @ </div>
324322
}else{
325323
text_diff(&from, &to, &out, pRe,
326324
diffFlags | DIFF_LINENO | DIFF_HTML | DIFF_NOTTOOBIG);
327
- @ <div class="udiff">
325
+ @ <pre class="udiff">
328326
@ %s(blob_str(&out))
329
- @ </div>
327
+ @ </pre>
330328
}
331329
blob_reset(&from);
332330
blob_reset(&to);
333331
blob_reset(&out);
334332
}
335
-
336333
337334
/*
338335
** Write a line of web-page output that shows changes that have occurred
339336
** to a file between two check-ins.
340337
*/
@@ -359,13 +356,11 @@
359356
@ for %h(zName)</p>
360357
}else{
361358
@ <p>Changes to %h(zName)</p>
362359
}
363360
if( diffFlags ){
364
- @ <pre style="white-space:pre;">
365361
append_diff(zOld, zNew, diffFlags, pRe);
366
- @ </pre>
367362
}
368363
}else{
369364
if( zOld && zNew ){
370365
if( fossil_strcmp(zOld, zNew)!=0 ){
371366
@ <p>Modified %z(href("%R/finfo?name=%T",zName))%h(zName)</a>
@@ -385,20 +380,51 @@
385380
}else{
386381
@ <p>Added %z(href("%R/finfo?name=%T",zName))%h(zName)</a>
387382
@ version %z(href("%R/artifact/%s",zNew))[%S(zNew)]</a>
388383
}
389384
if( diffFlags ){
390
- @ <pre style="white-space:pre;">
391385
append_diff(zOld, zNew, diffFlags, pRe);
392
- @ </pre>
393386
}else if( zOld && zNew && fossil_strcmp(zOld,zNew)!=0 ){
394387
@ &nbsp;&nbsp;
395388
@ %z(href("%R/fdiff?v1=%S&v2=%S&sbs=1",zOld,zNew))[diff]</a>
396389
}
397
- @ </p>
398390
}
399391
}
392
+
393
+/*
394
+** Generate javascript to enhance HTML diffs.
395
+*/
396
+void append_diff_javascript(int sideBySide){
397
+ if( !sideBySide ) return;
398
+ @ <script>(function(){
399
+ @ var SCROLL_LEN = 25;
400
+ @ function initSbsDiff(diff){
401
+ @ var txtCols = diff.querySelectorAll('.difftxtcol');
402
+ @ var txtPres = diff.querySelectorAll('.difftxtcol pre');
403
+ @ var width = Math.max(txtPres[0].scrollWidth, txtPres[1].scrollWidth);
404
+ @ for(var i=0; i<2; i++){
405
+ @ txtPres[i].style.width = width + 'px';
406
+ @ txtCols[i].onscroll = function(e){
407
+ @ txtCols[0].scrollLeft = txtCols[1].scrollLeft = this.scrollLeft;
408
+ @ };
409
+ @ }
410
+ @ diff.tabIndex = 0;
411
+ @ diff.onkeydown = function(e){
412
+ @ e = e || event;
413
+ @ var len = {37: -SCROLL_LEN, 39: SCROLL_LEN}[e.keyCode];
414
+ @ if( !len ) return;
415
+ @ txtCols[0].scrollLeft += len;
416
+ @ return false;
417
+ @ };
418
+ @ }
419
+ @
420
+ @ var diffs = document.querySelectorAll('.sbsdiffcols');
421
+ @ for(var i=0; i<diffs.length; i++){
422
+ @ initSbsDiff(diffs[i]);
423
+ @ }
424
+ @ }())</script>
425
+}
400426
401427
/*
402428
** Construct an appropriate diffFlag for text_diff() based on query
403429
** parameters and the to boolean arguments.
404430
*/
@@ -675,10 +701,11 @@
675701
const char *zOldName = db_column_text(&q, 4);
676702
append_file_change_line(zName, zOld, zNew, zOldName, diffFlags,pRe,mperm);
677703
}
678704
db_finalize(&q);
679705
}
706
+ append_diff_javascript(sideBySide);
680707
style_footer();
681708
}
682709
683710
/*
684711
** WEBPAGE: winfo
@@ -988,11 +1015,11 @@
9881015
pFileTo = manifest_file_next(pTo, 0);
9891016
}
9901017
}
9911018
manifest_destroy(pFrom);
9921019
manifest_destroy(pTo);
993
-
1020
+ append_diff_javascript(sideBySide);
9941021
style_footer();
9951022
}
9961023
9971024
#if INTERFACE
9981025
/*
@@ -1244,85 +1271,74 @@
12441271
*/
12451272
void diff_page(void){
12461273
int v1, v2;
12471274
int isPatch;
12481275
int sideBySide;
1249
- Blob c1, c2, diff, *pOut;
12501276
char *zV1;
12511277
char *zV2;
12521278
const char *zRe;
12531279
ReCompiled *pRe = 0;
12541280
u64 diffFlags;
1255
- const char *zStyle = "sbsdiff";
12561281
12571282
login_check_credentials();
12581283
if( !g.perm.Read ){ login_needed(); return; }
12591284
v1 = name_to_rid_www("v1");
12601285
v2 = name_to_rid_www("v2");
12611286
if( v1==0 || v2==0 ) fossil_redirect_home();
1262
- sideBySide = !is_false(PD("sbs","1"));
1263
- zV1 = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", v1);
1264
- zV2 = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", v2);
1287
+ zRe = P("regex");
1288
+ if( zRe ) re_compile(&pRe, zRe, 0);
12651289
isPatch = P("patch")!=0;
12661290
if( isPatch ){
1291
+ Blob c1, c2, *pOut;
12671292
pOut = cgi_output_blob();
12681293
cgi_set_content_type("text/plain");
12691294
diffFlags = 4;
1270
- }else{
1271
- blob_zero(&diff);
1272
- pOut = &diff;
1273
- diffFlags = construct_diff_flags(1, sideBySide) | DIFF_HTML;
1274
- if( sideBySide ){
1275
- zStyle = "sbsdiff";
1276
- }else{
1277
- diffFlags |= DIFF_LINENO;
1278
- zStyle = "udiff";
1279
- }
1280
- }
1281
- zRe = P("regex");
1282
- if( zRe ) re_compile(&pRe, zRe, 0);
1283
- content_get(v1, &c1);
1284
- content_get(v2, &c2);
1285
- text_diff(&c1, &c2, pOut, pRe, diffFlags);
1286
- blob_reset(&c1);
1287
- blob_reset(&c2);
1288
- if( !isPatch ){
1289
- style_header("Diff");
1290
- style_submenu_element("Patch", "Patch", "%s/fdiff?v1=%T&v2=%T&patch",
1291
- g.zTop, P("v1"), P("v2"));
1292
- if( !sideBySide ){
1293
- style_submenu_element("Side-by-side Diff", "sbsdiff",
1294
- "%s/fdiff?v1=%T&v2=%T&sbs=1",
1295
- g.zTop, P("v1"), P("v2"));
1296
- }else{
1297
- style_submenu_element("Unified Diff", "udiff",
1298
- "%s/fdiff?v1=%T&v2=%T&sbs=0",
1299
- g.zTop, P("v1"), P("v2"));
1300
- }
1301
-
1302
- if( P("smhdr")!=0 ){
1303
- @ <h2>Differences From Artifact
1304
- @ %z(href("%R/artifact/%S",zV1))[%S(zV1)]</a> To
1305
- @ %z(href("%R/artifact/%S",zV2))[%S(zV2)]</a>.</h2>
1306
- }else{
1307
- @ <h2>Differences From
1308
- @ Artifact %z(href("%R/artifact/%S",zV1))[%S(zV1)]</a>:</h2>
1309
- object_description(v1, 0, 0);
1310
- @ <h2>To Artifact %z(href("%R/artifact/%S",zV2))[%S(zV2)]</a>:</h2>
1311
- object_description(v2, 0, 0);
1312
- }
1313
- if( pRe ){
1314
- @ <b>Only differences that match regular expression "%h(zRe)"
1315
- @ are shown.</b>
1316
- }
1317
- @ <hr />
1318
- @ <div class="%s(zStyle)">
1319
- @ %s(blob_str(&diff))
1320
- @ </div>
1321
- blob_reset(&diff);
1322
- style_footer();
1323
- }
1295
+ content_get(v1, &c1);
1296
+ content_get(v2, &c2);
1297
+ text_diff(&c1, &c2, pOut, pRe, diffFlags);
1298
+ blob_reset(&c1);
1299
+ blob_reset(&c2);
1300
+ return;
1301
+ }
1302
+
1303
+ sideBySide = !is_false(PD("sbs","1"));
1304
+ zV1 = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", v1);
1305
+ zV2 = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", v2);
1306
+ diffFlags = construct_diff_flags(1, sideBySide) | DIFF_HTML;
1307
+
1308
+ style_header("Diff");
1309
+ style_submenu_element("Patch", "Patch", "%s/fdiff?v1=%T&v2=%T&patch",
1310
+ g.zTop, P("v1"), P("v2"));
1311
+ if( !sideBySide ){
1312
+ style_submenu_element("Side-by-side Diff", "sbsdiff",
1313
+ "%s/fdiff?v1=%T&v2=%T&sbs=1",
1314
+ g.zTop, P("v1"), P("v2"));
1315
+ }else{
1316
+ style_submenu_element("Unified Diff", "udiff",
1317
+ "%s/fdiff?v1=%T&v2=%T&sbs=0",
1318
+ g.zTop, P("v1"), P("v2"));
1319
+ }
1320
+
1321
+ if( P("smhdr")!=0 ){
1322
+ @ <h2>Differences From Artifact
1323
+ @ %z(href("%R/artifact/%S",zV1))[%S(zV1)]</a> To
1324
+ @ %z(href("%R/artifact/%S",zV2))[%S(zV2)]</a>.</h2>
1325
+ }else{
1326
+ @ <h2>Differences From
1327
+ @ Artifact %z(href("%R/artifact/%S",zV1))[%S(zV1)]</a>:</h2>
1328
+ object_description(v1, 0, 0);
1329
+ @ <h2>To Artifact %z(href("%R/artifact/%S",zV2))[%S(zV2)]</a>:</h2>
1330
+ object_description(v2, 0, 0);
1331
+ }
1332
+ if( pRe ){
1333
+ @ <b>Only differences that match regular expression "%h(zRe)"
1334
+ @ are shown.</b>
1335
+ }
1336
+ @ <hr />
1337
+ append_diff(zV1, zV2, diffFlags, pRe);
1338
+ append_diff_javascript(sideBySide);
1339
+ style_footer();
13241340
}
13251341
13261342
/*
13271343
** WEBPAGE: raw
13281344
** URL: /raw?name=ARTIFACTID&m=TYPE
13291345
13301346
ADDED src/lookslike.c
--- src/info.c
+++ src/info.c
@@ -316,25 +316,22 @@
316 blob_zero(&to);
317 }
318 blob_zero(&out);
319 if( diffFlags & DIFF_SIDEBYSIDE ){
320 text_diff(&from, &to, &out, pRe, diffFlags | DIFF_HTML | DIFF_NOTTOOBIG);
321 @ <div class="sbsdiff">
322 @ %s(blob_str(&out))
323 @ </div>
324 }else{
325 text_diff(&from, &to, &out, pRe,
326 diffFlags | DIFF_LINENO | DIFF_HTML | DIFF_NOTTOOBIG);
327 @ <div class="udiff">
328 @ %s(blob_str(&out))
329 @ </div>
330 }
331 blob_reset(&from);
332 blob_reset(&to);
333 blob_reset(&out);
334 }
335
336
337 /*
338 ** Write a line of web-page output that shows changes that have occurred
339 ** to a file between two check-ins.
340 */
@@ -359,13 +356,11 @@
359 @ for %h(zName)</p>
360 }else{
361 @ <p>Changes to %h(zName)</p>
362 }
363 if( diffFlags ){
364 @ <pre style="white-space:pre;">
365 append_diff(zOld, zNew, diffFlags, pRe);
366 @ </pre>
367 }
368 }else{
369 if( zOld && zNew ){
370 if( fossil_strcmp(zOld, zNew)!=0 ){
371 @ <p>Modified %z(href("%R/finfo?name=%T",zName))%h(zName)</a>
@@ -385,20 +380,51 @@
385 }else{
386 @ <p>Added %z(href("%R/finfo?name=%T",zName))%h(zName)</a>
387 @ version %z(href("%R/artifact/%s",zNew))[%S(zNew)]</a>
388 }
389 if( diffFlags ){
390 @ <pre style="white-space:pre;">
391 append_diff(zOld, zNew, diffFlags, pRe);
392 @ </pre>
393 }else if( zOld && zNew && fossil_strcmp(zOld,zNew)!=0 ){
394 @ &nbsp;&nbsp;
395 @ %z(href("%R/fdiff?v1=%S&v2=%S&sbs=1",zOld,zNew))[diff]</a>
396 }
397 @ </p>
398 }
399 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
400
401 /*
402 ** Construct an appropriate diffFlag for text_diff() based on query
403 ** parameters and the to boolean arguments.
404 */
@@ -675,10 +701,11 @@
675 const char *zOldName = db_column_text(&q, 4);
676 append_file_change_line(zName, zOld, zNew, zOldName, diffFlags,pRe,mperm);
677 }
678 db_finalize(&q);
679 }
 
680 style_footer();
681 }
682
683 /*
684 ** WEBPAGE: winfo
@@ -988,11 +1015,11 @@
988 pFileTo = manifest_file_next(pTo, 0);
989 }
990 }
991 manifest_destroy(pFrom);
992 manifest_destroy(pTo);
993
994 style_footer();
995 }
996
997 #if INTERFACE
998 /*
@@ -1244,85 +1271,74 @@
1244 */
1245 void diff_page(void){
1246 int v1, v2;
1247 int isPatch;
1248 int sideBySide;
1249 Blob c1, c2, diff, *pOut;
1250 char *zV1;
1251 char *zV2;
1252 const char *zRe;
1253 ReCompiled *pRe = 0;
1254 u64 diffFlags;
1255 const char *zStyle = "sbsdiff";
1256
1257 login_check_credentials();
1258 if( !g.perm.Read ){ login_needed(); return; }
1259 v1 = name_to_rid_www("v1");
1260 v2 = name_to_rid_www("v2");
1261 if( v1==0 || v2==0 ) fossil_redirect_home();
1262 sideBySide = !is_false(PD("sbs","1"));
1263 zV1 = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", v1);
1264 zV2 = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", v2);
1265 isPatch = P("patch")!=0;
1266 if( isPatch ){
 
1267 pOut = cgi_output_blob();
1268 cgi_set_content_type("text/plain");
1269 diffFlags = 4;
1270 }else{
1271 blob_zero(&diff);
1272 pOut = &diff;
1273 diffFlags = construct_diff_flags(1, sideBySide) | DIFF_HTML;
1274 if( sideBySide ){
1275 zStyle = "sbsdiff";
1276 }else{
1277 diffFlags |= DIFF_LINENO;
1278 zStyle = "udiff";
1279 }
1280 }
1281 zRe = P("regex");
1282 if( zRe ) re_compile(&pRe, zRe, 0);
1283 content_get(v1, &c1);
1284 content_get(v2, &c2);
1285 text_diff(&c1, &c2, pOut, pRe, diffFlags);
1286 blob_reset(&c1);
1287 blob_reset(&c2);
1288 if( !isPatch ){
1289 style_header("Diff");
1290 style_submenu_element("Patch", "Patch", "%s/fdiff?v1=%T&v2=%T&patch",
1291 g.zTop, P("v1"), P("v2"));
1292 if( !sideBySide ){
1293 style_submenu_element("Side-by-side Diff", "sbsdiff",
1294 "%s/fdiff?v1=%T&v2=%T&sbs=1",
1295 g.zTop, P("v1"), P("v2"));
1296 }else{
1297 style_submenu_element("Unified Diff", "udiff",
1298 "%s/fdiff?v1=%T&v2=%T&sbs=0",
1299 g.zTop, P("v1"), P("v2"));
1300 }
1301
1302 if( P("smhdr")!=0 ){
1303 @ <h2>Differences From Artifact
1304 @ %z(href("%R/artifact/%S",zV1))[%S(zV1)]</a> To
1305 @ %z(href("%R/artifact/%S",zV2))[%S(zV2)]</a>.</h2>
1306 }else{
1307 @ <h2>Differences From
1308 @ Artifact %z(href("%R/artifact/%S",zV1))[%S(zV1)]</a>:</h2>
1309 object_description(v1, 0, 0);
1310 @ <h2>To Artifact %z(href("%R/artifact/%S",zV2))[%S(zV2)]</a>:</h2>
1311 object_description(v2, 0, 0);
1312 }
1313 if( pRe ){
1314 @ <b>Only differences that match regular expression "%h(zRe)"
1315 @ are shown.</b>
1316 }
1317 @ <hr />
1318 @ <div class="%s(zStyle)">
1319 @ %s(blob_str(&diff))
1320 @ </div>
1321 blob_reset(&diff);
1322 style_footer();
1323 }
1324 }
1325
1326 /*
1327 ** WEBPAGE: raw
1328 ** URL: /raw?name=ARTIFACTID&m=TYPE
1329
1330 DDED src/lookslike.c
--- src/info.c
+++ src/info.c
@@ -316,25 +316,22 @@
316 blob_zero(&to);
317 }
318 blob_zero(&out);
319 if( diffFlags & DIFF_SIDEBYSIDE ){
320 text_diff(&from, &to, &out, pRe, diffFlags | DIFF_HTML | DIFF_NOTTOOBIG);
 
321 @ %s(blob_str(&out))
 
322 }else{
323 text_diff(&from, &to, &out, pRe,
324 diffFlags | DIFF_LINENO | DIFF_HTML | DIFF_NOTTOOBIG);
325 @ <pre class="udiff">
326 @ %s(blob_str(&out))
327 @ </pre>
328 }
329 blob_reset(&from);
330 blob_reset(&to);
331 blob_reset(&out);
332 }
 
333
334 /*
335 ** Write a line of web-page output that shows changes that have occurred
336 ** to a file between two check-ins.
337 */
@@ -359,13 +356,11 @@
356 @ for %h(zName)</p>
357 }else{
358 @ <p>Changes to %h(zName)</p>
359 }
360 if( diffFlags ){
 
361 append_diff(zOld, zNew, diffFlags, pRe);
 
362 }
363 }else{
364 if( zOld && zNew ){
365 if( fossil_strcmp(zOld, zNew)!=0 ){
366 @ <p>Modified %z(href("%R/finfo?name=%T",zName))%h(zName)</a>
@@ -385,20 +380,51 @@
380 }else{
381 @ <p>Added %z(href("%R/finfo?name=%T",zName))%h(zName)</a>
382 @ version %z(href("%R/artifact/%s",zNew))[%S(zNew)]</a>
383 }
384 if( diffFlags ){
 
385 append_diff(zOld, zNew, diffFlags, pRe);
 
386 }else if( zOld && zNew && fossil_strcmp(zOld,zNew)!=0 ){
387 @ &nbsp;&nbsp;
388 @ %z(href("%R/fdiff?v1=%S&v2=%S&sbs=1",zOld,zNew))[diff]</a>
389 }
 
390 }
391 }
392
393 /*
394 ** Generate javascript to enhance HTML diffs.
395 */
396 void append_diff_javascript(int sideBySide){
397 if( !sideBySide ) return;
398 @ <script>(function(){
399 @ var SCROLL_LEN = 25;
400 @ function initSbsDiff(diff){
401 @ var txtCols = diff.querySelectorAll('.difftxtcol');
402 @ var txtPres = diff.querySelectorAll('.difftxtcol pre');
403 @ var width = Math.max(txtPres[0].scrollWidth, txtPres[1].scrollWidth);
404 @ for(var i=0; i<2; i++){
405 @ txtPres[i].style.width = width + 'px';
406 @ txtCols[i].onscroll = function(e){
407 @ txtCols[0].scrollLeft = txtCols[1].scrollLeft = this.scrollLeft;
408 @ };
409 @ }
410 @ diff.tabIndex = 0;
411 @ diff.onkeydown = function(e){
412 @ e = e || event;
413 @ var len = {37: -SCROLL_LEN, 39: SCROLL_LEN}[e.keyCode];
414 @ if( !len ) return;
415 @ txtCols[0].scrollLeft += len;
416 @ return false;
417 @ };
418 @ }
419 @
420 @ var diffs = document.querySelectorAll('.sbsdiffcols');
421 @ for(var i=0; i<diffs.length; i++){
422 @ initSbsDiff(diffs[i]);
423 @ }
424 @ }())</script>
425 }
426
427 /*
428 ** Construct an appropriate diffFlag for text_diff() based on query
429 ** parameters and the to boolean arguments.
430 */
@@ -675,10 +701,11 @@
701 const char *zOldName = db_column_text(&q, 4);
702 append_file_change_line(zName, zOld, zNew, zOldName, diffFlags,pRe,mperm);
703 }
704 db_finalize(&q);
705 }
706 append_diff_javascript(sideBySide);
707 style_footer();
708 }
709
710 /*
711 ** WEBPAGE: winfo
@@ -988,11 +1015,11 @@
1015 pFileTo = manifest_file_next(pTo, 0);
1016 }
1017 }
1018 manifest_destroy(pFrom);
1019 manifest_destroy(pTo);
1020 append_diff_javascript(sideBySide);
1021 style_footer();
1022 }
1023
1024 #if INTERFACE
1025 /*
@@ -1244,85 +1271,74 @@
1271 */
1272 void diff_page(void){
1273 int v1, v2;
1274 int isPatch;
1275 int sideBySide;
 
1276 char *zV1;
1277 char *zV2;
1278 const char *zRe;
1279 ReCompiled *pRe = 0;
1280 u64 diffFlags;
 
1281
1282 login_check_credentials();
1283 if( !g.perm.Read ){ login_needed(); return; }
1284 v1 = name_to_rid_www("v1");
1285 v2 = name_to_rid_www("v2");
1286 if( v1==0 || v2==0 ) fossil_redirect_home();
1287 zRe = P("regex");
1288 if( zRe ) re_compile(&pRe, zRe, 0);
 
1289 isPatch = P("patch")!=0;
1290 if( isPatch ){
1291 Blob c1, c2, *pOut;
1292 pOut = cgi_output_blob();
1293 cgi_set_content_type("text/plain");
1294 diffFlags = 4;
1295 content_get(v1, &c1);
1296 content_get(v2, &c2);
1297 text_diff(&c1, &c2, pOut, pRe, diffFlags);
1298 blob_reset(&c1);
1299 blob_reset(&c2);
1300 return;
1301 }
1302
1303 sideBySide = !is_false(PD("sbs","1"));
1304 zV1 = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", v1);
1305 zV2 = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", v2);
1306 diffFlags = construct_diff_flags(1, sideBySide) | DIFF_HTML;
1307
1308 style_header("Diff");
1309 style_submenu_element("Patch", "Patch", "%s/fdiff?v1=%T&v2=%T&patch",
1310 g.zTop, P("v1"), P("v2"));
1311 if( !sideBySide ){
1312 style_submenu_element("Side-by-side Diff", "sbsdiff",
1313 "%s/fdiff?v1=%T&v2=%T&sbs=1",
1314 g.zTop, P("v1"), P("v2"));
1315 }else{
1316 style_submenu_element("Unified Diff", "udiff",
1317 "%s/fdiff?v1=%T&v2=%T&sbs=0",
1318 g.zTop, P("v1"), P("v2"));
1319 }
1320
1321 if( P("smhdr")!=0 ){
1322 @ <h2>Differences From Artifact
1323 @ %z(href("%R/artifact/%S",zV1))[%S(zV1)]</a> To
1324 @ %z(href("%R/artifact/%S",zV2))[%S(zV2)]</a>.</h2>
1325 }else{
1326 @ <h2>Differences From
1327 @ Artifact %z(href("%R/artifact/%S",zV1))[%S(zV1)]</a>:</h2>
1328 object_description(v1, 0, 0);
1329 @ <h2>To Artifact %z(href("%R/artifact/%S",zV2))[%S(zV2)]</a>:</h2>
1330 object_description(v2, 0, 0);
1331 }
1332 if( pRe ){
1333 @ <b>Only differences that match regular expression "%h(zRe)"
1334 @ are shown.</b>
1335 }
1336 @ <hr />
1337 append_diff(zV1, zV2, diffFlags, pRe);
1338 append_diff_javascript(sideBySide);
1339 style_footer();
 
 
 
 
 
 
 
 
 
1340 }
1341
1342 /*
1343 ** WEBPAGE: raw
1344 ** URL: /raw?name=ARTIFACTID&m=TYPE
1345
1346 DDED src/lookslike.c
--- a/src/lookslike.c
+++ b/src/lookslike.c
@@ -0,0 +1,119 @@
1
+utf8((blob), LOOK_BINARY, 0) & LOOK_BINARY) != LOOK_NONE)
2
+
3
+/*
4
+** Output flags for the looks_like_utf8() and looks_like_utf16() routines used
5
+** to convey status information about the blob content.
6
+*/
7
+#define LOOK_NONE ((int)0x00000000) /* Nothing special was found. */
8
+#define LOOK_NUL ((int)0x00000001) /* One or more Nfossil_isalnumne LOOK_NUL ((int)0x00000001) /* One or more Nutf8((blob), Lz[i+n]!=0&&SQL. This is only a
9
+** high-level check, not intended to be used for any application-level
10
+** logic other than in defense against spiders in limited context((blob), LOOK_BINARY, 0) & LOOK_BINARY) != LOOK_NONE)
11
+
12
+/*
13
+** Output flags for the looks_like_utf8() and looks_like_utf16() routines used
14
+** to convey status information about the blob content.
15
+*/
16
+#define LOOK_NONE ((int)0x00000000) /* Nothing special was found. */
17
+#define LOOK_NUL ((int)0x00000001) /* One or more Nfossil_isalnumne LOOK_NUL ((int)0x00000001) /* One or more Nutf8((blob), LRY, 0) & LOOK_BINARY) != LOOK_NONE)
18
+
19
+/*
20
+** Output flags for the looks_like_utf8() and looks_like_utf16() routines used
21
+** to convey status information about the blob content.
22
+*/
23
+#define LOOK_NONE ((int)0x00000000) /* Nothing special was found. */
24
+#define LOOK_NUL ((int)0x00000001) /* One or more Nfossil_isalnumne LOOK_NUL ((int)0x00000001) /* One or more Nutf8((blob), Lmight_be_sql(cCR tatus i10ormation a02LOOK_BINARY, 0) & LOOK_BI were LOOK_NUL ((int)0x00LONE_CR 20d ") || L(" or ")
25
+ /* ^^^^^ F tatus i10ormation a08/* One or more Nfossil_is were LOOK_NUL ((int)0x00LONE_LF ((int)0x00000010 ")
26
+ /* ^^^^^ no=08ere LOOK_NUL ((/LF paiLF ((int)0x00000010") || L20F ((int)0x00000010") || L("updaten 0;
27
+#define L(GLOB1" andf8() an88((blob), LOO4f8() and looks_like_utf16() routines used
28
+** to 2onvey status i10ormation a8efine LOOK_NONE ((in04#define LOOK_NONE ((int)0x0000000020/* Nothing sp10ial was found. */
29
+#08fine LOOK_NUL ((int)0x00000001) /* One or more N20ssil_isalnumne LOOK_NUL ((int)0x00000001) /* One or more Nutf8((blob), Lz[i+n]!=0&&SQL. This is only aited context((blob), LOOK_BINARY, 0)define LOOK_CR [i+n]!=0&&SQL. This is onlCRLFere LOOK_ne or more Nfossil_isalnumne LOOK_NUL ((int)0x00000001) /* One or more Nutf8((blob), Lz[i+n]!=0&&SQL. This is only aited context((blob), LOOK_BINARY, 0) & LOOK_BINARY) != LOOK_NONE)
30
+
31
+/*
32
+** Output flags for the looks_like_utf8() and looks_like_utf16() routines used
33
+** to convey status information about the blob content.
34
+*/
35
+#define LOOK_NONE ((int)0x00000000) /* Nothing special was found. */
36
+#define LOOK_NUL ((int)0x00000001) /* One or more Nfossil_isalnumne LOOK_NUL ((int)0x00000001) /* One or more Nutf8((blob), LRY, 0) & LOOK_BINARY) != LOOK_NONE)
37
+
38
+/*
39
+** Output flags for the looks_like_utf8() and looks_like_utf16() routines used
40
+** to convey status information about the blob content.
41
+*/
42
+#define LOOK_NONE ((int)0x00000000) /* Nothing special was found. */
43
+#define LOOK_NUL ((int)0x00000001) /* One or more Nfossil_isalnumne LOOK_NUL ((int)0x00000001) /* One or more Nutf8((blob), Lmight_be_sql(const char *zTxt){
44
+ if( zTxt==0 || zTxt[0]==0 ) return 0;
45
+#define L(GLOB) 0==sqlite3_strlike("%" GLOB "%",zTxt, '%')
46
+ return L(";") || L("'")
47
+ || L("select") || L("order") || L("drop")
48
+ || L(" and ") || L(" or ")
49
+ /* ^^^^^ noting that \n and \t should also be checked */
50
+ || L("null") || L("delete") || L("update")
51
+ |;<num> Repeatest_looks_like_utflooks_like_utf_testshort *z = (unsigned short1]==0possible UTF-32. */
52
+ if( z[0]z[0]==0xfffeutf8((blob), LOOK_BINARY, 0) & LOOK_BINARY) != LOOK_NONE)
53
+
54
+/*
55
+** Output flflags |= LOOK_CR;
56
+F | flags |= LOOK_LF; | flags |= LOOK_CR;flags |= LOOK_CR;
57
+F | flags |= LOOK_LF; | flags |= LOOK_CR;f8() and looks_like_utf16() roututf8((blob), LOOKf8() and looks_like_utf16() routines used
58
+** to convey status information about the blob content.
59
+*/
60
+#define LOOK_NONE ((int)0x00000000) /* Nothing special was found. */
61
+#define LOOK_NUL ((int)0x00000001) /* One or more Nfossil_isalnumne LOOK_NUL ((int)0x00000001) /* One or more Nutf8((blobflags |= LOOK_CR;(blob), Lz[i+n]!=0&&SQL. This is only a
62
+** high-level check, not intended to be used for any application-level
63
+** logic other tMore chars, next char is--n>0() and flags |= LOOK_LF; | * to convey status informatiBF LOOK_BINARY) != nformationBF LOOK_BINARY) != LOO((int)0x00000000) /* NothingBF LOOK_BINARY) != int)0x0000BF LOOK_BINARY) != LOOK ((int)0x00000001) /* One BF LOOK_BINARY) != ),flags |= LOOK_CR;
64
+ K_CR CRLFurn 0;
65
+#define L(GLOB) 0=LF (rop")
66
+ || L(" andf8() an88((blob), LOOKf8() and looks_like_utf16() routines used
67
+** to convey status i10ormation about the blob content.
68
+*/
69
+#define LOOK_NONE ((int)0x0000000020More chars, next char is0/* Nothing special was found. */
70
+#define LOOK_NUL , c2;
71
+ if( c2>=0xC0 ){
72
+ *def = &lb_tab[(2*c2)-0x180];
73
+ if( c2>=0xe80 ){
74
+ if( ((c2<0xc2) || (c2>=0xf4) || ((c&0xc0)!=0x80)) &&
75
+ (((c2!=0xf4) || (c>=0x90)) &c = (c2 >= 0xe0) ? (c2<<1)+1 : ' '|flags |= LOOK_CR;
76
+ intended to be used for any application-level
77
+** logic other than in defense against spiders F | flags |= LOOK_LF; | * to convey status informat** to convey status information about the blob content.
78
+*/
79
+#define LOOK_NONE ((int)0x00000000) /* Nothing special was found. */
80
+#define LOOK_NUL ((int)0x00000001) /* One or more Nfossil_isalnumne LOOK_NUL ((int)0x00000001) /* One or more Nutf8((blob), Lz[i+n]!=0&&SQL. This is only a
81
+** high-level check, not intended to be used for any application-level
82
+** logic other than in defense against spiders in limited context((blob), LOOK_BINARY, 0) & LOOK_BINARY) != LOOK_NONE)
83
+
84
+/*
85
+** Output flags for the looks_like_utf8() and looks_like_utf16() routines used
86
+** to convey status information about the blob content.
87
+*/
88
+#define LOOK_NONE ((int)0((blob), LOOK_BINARY, 0) & LO{
89
+ *def || (c> ){
90
+ return 1 }c>=0x8tf8((blob), LOOK_BINARY, 0) & LOOK_BINARY) != LOOK_NONE)
91
+
92
+/*
93
+** Output flags for the looks_like_utf8() and looks_like_utf16() routines used
94
+** to convey status information about the blob content.
95
+*/
96
+#define LOOK_NONE ((int)0x00000000) /* Nothing special was found. */
97
+#define LOOK_NUL ((int)0x00000001) /* One or more Nfossil_isalnumne LOOK_NUL ((int)0x00000001) /* One or more Nutf8((blob), Lz[i+n]!=0&&SQL. This is only a
98
+** high-level check, not intended to be used for any application-level
99
+** logic other than in defense against spiders in limited context((blob), LOOK_BINARY, 0) & LOOK_BINARY) != LOOK_NONE)
100
+
101
+/*
102
+** Output flags for the looks_like_utf8() and looks_like_utf16() routines used
103
+** to convey status information about the blob content.
104
+*/
105
+#define LOOK_NONE ((int)0x00000000) /* Nothing special was found. */
106
+#define LOOK_NUL ((int)0x00000001) /* One or more Nfossil_isalnumne LOOKY, 0) & LOOK_BINARY) }utf8((blob), LOOKK_BINARY, 0) & LOOK_BINARY) != LOOK_NONE)
107
+
108
+/*
109
+** Output flags for the looks_like_utf8() and looks_like_utf16() routines used
110
+** to convey status information about the blob content.
111
+*/
112
+#define LOOK_NONE ((int)0x00000000) /* Nothing special was found. */
113
+#define LOOK_NUL ((int)0x00000001) /* One or more Nfossil_isalnumne LOOK_NUL ((int)0x00000001) /* One or more Nutf8((blob), Lz[i+n]!=0&&SQL. This is o1if( flags&stopFlags ) break;
114
+ n -= sizeof(WCHAR_T);
115
+ if( n< break/*bRevUnicodefUtf16((int)0x00000000) utf8((blob), LOOK_BINARY, 0) & LfUnicode = 0;
116
+ }else{
117
+&bRevUnicode) || fForceUtEF, 0xBB, 0xBFlookFlags = fUnicode ? :
118
+und. */
119
+#define
--- a/src/lookslike.c
+++ b/src/lookslike.c
@@ -0,0 +1,119 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
--- a/src/lookslike.c
+++ b/src/lookslike.c
@@ -0,0 +1,119 @@
1 utf8((blob), LOOK_BINARY, 0) & LOOK_BINARY) != LOOK_NONE)
2
3 /*
4 ** Output flags for the looks_like_utf8() and looks_like_utf16() routines used
5 ** to convey status information about the blob content.
6 */
7 #define LOOK_NONE ((int)0x00000000) /* Nothing special was found. */
8 #define LOOK_NUL ((int)0x00000001) /* One or more Nfossil_isalnumne LOOK_NUL ((int)0x00000001) /* One or more Nutf8((blob), Lz[i+n]!=0&&SQL. This is only a
9 ** high-level check, not intended to be used for any application-level
10 ** logic other than in defense against spiders in limited context((blob), LOOK_BINARY, 0) & LOOK_BINARY) != LOOK_NONE)
11
12 /*
13 ** Output flags for the looks_like_utf8() and looks_like_utf16() routines used
14 ** to convey status information about the blob content.
15 */
16 #define LOOK_NONE ((int)0x00000000) /* Nothing special was found. */
17 #define LOOK_NUL ((int)0x00000001) /* One or more Nfossil_isalnumne LOOK_NUL ((int)0x00000001) /* One or more Nutf8((blob), LRY, 0) & LOOK_BINARY) != LOOK_NONE)
18
19 /*
20 ** Output flags for the looks_like_utf8() and looks_like_utf16() routines used
21 ** to convey status information about the blob content.
22 */
23 #define LOOK_NONE ((int)0x00000000) /* Nothing special was found. */
24 #define LOOK_NUL ((int)0x00000001) /* One or more Nfossil_isalnumne LOOK_NUL ((int)0x00000001) /* One or more Nutf8((blob), Lmight_be_sql(cCR tatus i10ormation a02LOOK_BINARY, 0) & LOOK_BI were LOOK_NUL ((int)0x00LONE_CR 20d ") || L(" or ")
25 /* ^^^^^ F tatus i10ormation a08/* One or more Nfossil_is were LOOK_NUL ((int)0x00LONE_LF ((int)0x00000010 ")
26 /* ^^^^^ no=08ere LOOK_NUL ((/LF paiLF ((int)0x00000010") || L20F ((int)0x00000010") || L("updaten 0;
27 #define L(GLOB1" andf8() an88((blob), LOO4f8() and looks_like_utf16() routines used
28 ** to 2onvey status i10ormation a8efine LOOK_NONE ((in04#define LOOK_NONE ((int)0x0000000020/* Nothing sp10ial was found. */
29 #08fine LOOK_NUL ((int)0x00000001) /* One or more N20ssil_isalnumne LOOK_NUL ((int)0x00000001) /* One or more Nutf8((blob), Lz[i+n]!=0&&SQL. This is only aited context((blob), LOOK_BINARY, 0)define LOOK_CR [i+n]!=0&&SQL. This is onlCRLFere LOOK_ne or more Nfossil_isalnumne LOOK_NUL ((int)0x00000001) /* One or more Nutf8((blob), Lz[i+n]!=0&&SQL. This is only aited context((blob), LOOK_BINARY, 0) & LOOK_BINARY) != LOOK_NONE)
30
31 /*
32 ** Output flags for the looks_like_utf8() and looks_like_utf16() routines used
33 ** to convey status information about the blob content.
34 */
35 #define LOOK_NONE ((int)0x00000000) /* Nothing special was found. */
36 #define LOOK_NUL ((int)0x00000001) /* One or more Nfossil_isalnumne LOOK_NUL ((int)0x00000001) /* One or more Nutf8((blob), LRY, 0) & LOOK_BINARY) != LOOK_NONE)
37
38 /*
39 ** Output flags for the looks_like_utf8() and looks_like_utf16() routines used
40 ** to convey status information about the blob content.
41 */
42 #define LOOK_NONE ((int)0x00000000) /* Nothing special was found. */
43 #define LOOK_NUL ((int)0x00000001) /* One or more Nfossil_isalnumne LOOK_NUL ((int)0x00000001) /* One or more Nutf8((blob), Lmight_be_sql(const char *zTxt){
44 if( zTxt==0 || zTxt[0]==0 ) return 0;
45 #define L(GLOB) 0==sqlite3_strlike("%" GLOB "%",zTxt, '%')
46 return L(";") || L("'")
47 || L("select") || L("order") || L("drop")
48 || L(" and ") || L(" or ")
49 /* ^^^^^ noting that \n and \t should also be checked */
50 || L("null") || L("delete") || L("update")
51 |;<num> Repeatest_looks_like_utflooks_like_utf_testshort *z = (unsigned short1]==0possible UTF-32. */
52 if( z[0]z[0]==0xfffeutf8((blob), LOOK_BINARY, 0) & LOOK_BINARY) != LOOK_NONE)
53
54 /*
55 ** Output flflags |= LOOK_CR;
56 F | flags |= LOOK_LF; | flags |= LOOK_CR;flags |= LOOK_CR;
57 F | flags |= LOOK_LF; | flags |= LOOK_CR;f8() and looks_like_utf16() roututf8((blob), LOOKf8() and looks_like_utf16() routines used
58 ** to convey status information about the blob content.
59 */
60 #define LOOK_NONE ((int)0x00000000) /* Nothing special was found. */
61 #define LOOK_NUL ((int)0x00000001) /* One or more Nfossil_isalnumne LOOK_NUL ((int)0x00000001) /* One or more Nutf8((blobflags |= LOOK_CR;(blob), Lz[i+n]!=0&&SQL. This is only a
62 ** high-level check, not intended to be used for any application-level
63 ** logic other tMore chars, next char is--n>0() and flags |= LOOK_LF; | * to convey status informatiBF LOOK_BINARY) != nformationBF LOOK_BINARY) != LOO((int)0x00000000) /* NothingBF LOOK_BINARY) != int)0x0000BF LOOK_BINARY) != LOOK ((int)0x00000001) /* One BF LOOK_BINARY) != ),flags |= LOOK_CR;
64 K_CR CRLFurn 0;
65 #define L(GLOB) 0=LF (rop")
66 || L(" andf8() an88((blob), LOOKf8() and looks_like_utf16() routines used
67 ** to convey status i10ormation about the blob content.
68 */
69 #define LOOK_NONE ((int)0x0000000020More chars, next char is0/* Nothing special was found. */
70 #define LOOK_NUL , c2;
71 if( c2>=0xC0 ){
72 *def = &lb_tab[(2*c2)-0x180];
73 if( c2>=0xe80 ){
74 if( ((c2<0xc2) || (c2>=0xf4) || ((c&0xc0)!=0x80)) &&
75 (((c2!=0xf4) || (c>=0x90)) &c = (c2 >= 0xe0) ? (c2<<1)+1 : ' '|flags |= LOOK_CR;
76 intended to be used for any application-level
77 ** logic other than in defense against spiders F | flags |= LOOK_LF; | * to convey status informat** to convey status information about the blob content.
78 */
79 #define LOOK_NONE ((int)0x00000000) /* Nothing special was found. */
80 #define LOOK_NUL ((int)0x00000001) /* One or more Nfossil_isalnumne LOOK_NUL ((int)0x00000001) /* One or more Nutf8((blob), Lz[i+n]!=0&&SQL. This is only a
81 ** high-level check, not intended to be used for any application-level
82 ** logic other than in defense against spiders in limited context((blob), LOOK_BINARY, 0) & LOOK_BINARY) != LOOK_NONE)
83
84 /*
85 ** Output flags for the looks_like_utf8() and looks_like_utf16() routines used
86 ** to convey status information about the blob content.
87 */
88 #define LOOK_NONE ((int)0((blob), LOOK_BINARY, 0) & LO{
89 *def || (c> ){
90 return 1 }c>=0x8tf8((blob), LOOK_BINARY, 0) & LOOK_BINARY) != LOOK_NONE)
91
92 /*
93 ** Output flags for the looks_like_utf8() and looks_like_utf16() routines used
94 ** to convey status information about the blob content.
95 */
96 #define LOOK_NONE ((int)0x00000000) /* Nothing special was found. */
97 #define LOOK_NUL ((int)0x00000001) /* One or more Nfossil_isalnumne LOOK_NUL ((int)0x00000001) /* One or more Nutf8((blob), Lz[i+n]!=0&&SQL. This is only a
98 ** high-level check, not intended to be used for any application-level
99 ** logic other than in defense against spiders in limited context((blob), LOOK_BINARY, 0) & LOOK_BINARY) != LOOK_NONE)
100
101 /*
102 ** Output flags for the looks_like_utf8() and looks_like_utf16() routines used
103 ** to convey status information about the blob content.
104 */
105 #define LOOK_NONE ((int)0x00000000) /* Nothing special was found. */
106 #define LOOK_NUL ((int)0x00000001) /* One or more Nfossil_isalnumne LOOKY, 0) & LOOK_BINARY) }utf8((blob), LOOKK_BINARY, 0) & LOOK_BINARY) != LOOK_NONE)
107
108 /*
109 ** Output flags for the looks_like_utf8() and looks_like_utf16() routines used
110 ** to convey status information about the blob content.
111 */
112 #define LOOK_NONE ((int)0x00000000) /* Nothing special was found. */
113 #define LOOK_NUL ((int)0x00000001) /* One or more Nfossil_isalnumne LOOK_NUL ((int)0x00000001) /* One or more Nutf8((blob), Lz[i+n]!=0&&SQL. This is o1if( flags&stopFlags ) break;
114 n -= sizeof(WCHAR_T);
115 if( n< break/*bRevUnicodefUtf16((int)0x00000000) utf8((blob), LOOK_BINARY, 0) & LfUnicode = 0;
116 }else{
117 &bRevUnicode) || fForceUtEF, 0xBB, 0xBFlookFlags = fUnicode ? :
118 und. */
119 #define
+11 -1
--- src/main.mk
+++ src/main.mk
@@ -67,10 +67,11 @@
6767
$(SRCDIR)/json_timeline.c \
6868
$(SRCDIR)/json_user.c \
6969
$(SRCDIR)/json_wiki.c \
7070
$(SRCDIR)/leaf.c \
7171
$(SRCDIR)/login.c \
72
+ $(SRCDIR)/lookslike.c \
7273
$(SRCDIR)/main.c \
7374
$(SRCDIR)/manifest.c \
7475
$(SRCDIR)/markdown.c \
7576
$(SRCDIR)/markdown_html.c \
7677
$(SRCDIR)/md5.c \
@@ -175,10 +176,11 @@
175176
$(OBJDIR)/json_timeline_.c \
176177
$(OBJDIR)/json_user_.c \
177178
$(OBJDIR)/json_wiki_.c \
178179
$(OBJDIR)/leaf_.c \
179180
$(OBJDIR)/login_.c \
181
+ $(OBJDIR)/lookslike_.c \
180182
$(OBJDIR)/main_.c \
181183
$(OBJDIR)/manifest_.c \
182184
$(OBJDIR)/markdown_.c \
183185
$(OBJDIR)/markdown_html_.c \
184186
$(OBJDIR)/md5_.c \
@@ -283,10 +285,11 @@
283285
$(OBJDIR)/json_timeline.o \
284286
$(OBJDIR)/json_user.o \
285287
$(OBJDIR)/json_wiki.o \
286288
$(OBJDIR)/leaf.o \
287289
$(OBJDIR)/login.o \
290
+ $(OBJDIR)/lookslike.o \
288291
$(OBJDIR)/main.o \
289292
$(OBJDIR)/manifest.o \
290293
$(OBJDIR)/markdown.o \
291294
$(OBJDIR)/markdown_html.o \
292295
$(OBJDIR)/md5.o \
@@ -402,11 +405,11 @@
402405
403406
404407
$(OBJDIR)/page_index.h: $(TRANS_SRC) $(OBJDIR)/mkindex
405408
$(OBJDIR)/mkindex $(TRANS_SRC) >$@
406409
$(OBJDIR)/headers: $(OBJDIR)/page_index.h $(OBJDIR)/makeheaders $(OBJDIR)/VERSION.h
407
- $(OBJDIR)/makeheaders $(OBJDIR)/add_.c:$(OBJDIR)/add.h $(OBJDIR)/allrepo_.c:$(OBJDIR)/allrepo.h $(OBJDIR)/attach_.c:$(OBJDIR)/attach.h $(OBJDIR)/bag_.c:$(OBJDIR)/bag.h $(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h $(OBJDIR)/blob_.c:$(OBJDIR)/blob.h $(OBJDIR)/branch_.c:$(OBJDIR)/branch.h $(OBJDIR)/browse_.c:$(OBJDIR)/browse.h $(OBJDIR)/captcha_.c:$(OBJDIR)/captcha.h $(OBJDIR)/cgi_.c:$(OBJDIR)/cgi.h $(OBJDIR)/checkin_.c:$(OBJDIR)/checkin.h $(OBJDIR)/checkout_.c:$(OBJDIR)/checkout.h $(OBJDIR)/clearsign_.c:$(OBJDIR)/clearsign.h $(OBJDIR)/clone_.c:$(OBJDIR)/clone.h $(OBJDIR)/comformat_.c:$(OBJDIR)/comformat.h $(OBJDIR)/configure_.c:$(OBJDIR)/configure.h $(OBJDIR)/content_.c:$(OBJDIR)/content.h $(OBJDIR)/db_.c:$(OBJDIR)/db.h $(OBJDIR)/delta_.c:$(OBJDIR)/delta.h $(OBJDIR)/deltacmd_.c:$(OBJDIR)/deltacmd.h $(OBJDIR)/descendants_.c:$(OBJDIR)/descendants.h $(OBJDIR)/diff_.c:$(OBJDIR)/diff.h $(OBJDIR)/diffcmd_.c:$(OBJDIR)/diffcmd.h $(OBJDIR)/doc_.c:$(OBJDIR)/doc.h $(OBJDIR)/encode_.c:$(OBJDIR)/encode.h $(OBJDIR)/event_.c:$(OBJDIR)/event.h $(OBJDIR)/export_.c:$(OBJDIR)/export.h $(OBJDIR)/file_.c:$(OBJDIR)/file.h $(OBJDIR)/finfo_.c:$(OBJDIR)/finfo.h $(OBJDIR)/glob_.c:$(OBJDIR)/glob.h $(OBJDIR)/graph_.c:$(OBJDIR)/graph.h $(OBJDIR)/gzip_.c:$(OBJDIR)/gzip.h $(OBJDIR)/http_.c:$(OBJDIR)/http.h $(OBJDIR)/http_socket_.c:$(OBJDIR)/http_socket.h $(OBJDIR)/http_ssl_.c:$(OBJDIR)/http_ssl.h $(OBJDIR)/http_transport_.c:$(OBJDIR)/http_transport.h $(OBJDIR)/import_.c:$(OBJDIR)/import.h $(OBJDIR)/info_.c:$(OBJDIR)/info.h $(OBJDIR)/json_.c:$(OBJDIR)/json.h $(OBJDIR)/json_artifact_.c:$(OBJDIR)/json_artifact.h $(OBJDIR)/json_branch_.c:$(OBJDIR)/json_branch.h $(OBJDIR)/json_config_.c:$(OBJDIR)/json_config.h $(OBJDIR)/json_diff_.c:$(OBJDIR)/json_diff.h $(OBJDIR)/json_dir_.c:$(OBJDIR)/json_dir.h $(OBJDIR)/json_finfo_.c:$(OBJDIR)/json_finfo.h $(OBJDIR)/json_login_.c:$(OBJDIR)/json_login.h $(OBJDIR)/json_query_.c:$(OBJDIR)/json_query.h $(OBJDIR)/json_report_.c:$(OBJDIR)/json_report.h $(OBJDIR)/json_status_.c:$(OBJDIR)/json_status.h $(OBJDIR)/json_tag_.c:$(OBJDIR)/json_tag.h $(OBJDIR)/json_timeline_.c:$(OBJDIR)/json_timeline.h $(OBJDIR)/json_user_.c:$(OBJDIR)/json_user.h $(OBJDIR)/json_wiki_.c:$(OBJDIR)/json_wiki.h $(OBJDIR)/leaf_.c:$(OBJDIR)/leaf.h $(OBJDIR)/login_.c:$(OBJDIR)/login.h $(OBJDIR)/main_.c:$(OBJDIR)/main.h $(OBJDIR)/manifest_.c:$(OBJDIR)/manifest.h $(OBJDIR)/markdown_.c:$(OBJDIR)/markdown.h $(OBJDIR)/markdown_html_.c:$(OBJDIR)/markdown_html.h $(OBJDIR)/md5_.c:$(OBJDIR)/md5.h $(OBJDIR)/merge_.c:$(OBJDIR)/merge.h $(OBJDIR)/merge3_.c:$(OBJDIR)/merge3.h $(OBJDIR)/moderate_.c:$(OBJDIR)/moderate.h $(OBJDIR)/name_.c:$(OBJDIR)/name.h $(OBJDIR)/path_.c:$(OBJDIR)/path.h $(OBJDIR)/pivot_.c:$(OBJDIR)/pivot.h $(OBJDIR)/popen_.c:$(OBJDIR)/popen.h $(OBJDIR)/pqueue_.c:$(OBJDIR)/pqueue.h $(OBJDIR)/printf_.c:$(OBJDIR)/printf.h $(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h $(OBJDIR)/regexp_.c:$(OBJDIR)/regexp.h $(OBJDIR)/report_.c:$(OBJDIR)/report.h $(OBJDIR)/rss_.c:$(OBJDIR)/rss.h $(OBJDIR)/schema_.c:$(OBJDIR)/schema.h $(OBJDIR)/search_.c:$(OBJDIR)/search.h $(OBJDIR)/setup_.c:$(OBJDIR)/setup.h $(OBJDIR)/sha1_.c:$(OBJDIR)/sha1.h $(OBJDIR)/shun_.c:$(OBJDIR)/shun.h $(OBJDIR)/skins_.c:$(OBJDIR)/skins.h $(OBJDIR)/sqlcmd_.c:$(OBJDIR)/sqlcmd.h $(OBJDIR)/stash_.c:$(OBJDIR)/stash.h $(OBJDIR)/stat_.c:$(OBJDIR)/stat.h $(OBJDIR)/style_.c:$(OBJDIR)/style.h $(OBJDIR)/sync_.c:$(OBJDIR)/sync.h $(OBJDIR)/tag_.c:$(OBJDIR)/tag.h $(OBJDIR)/tar_.c:$(OBJDIR)/tar.h $(OBJDIR)/th_main_.c:$(OBJDIR)/th_main.h $(OBJDIR)/timeline_.c:$(OBJDIR)/timeline.h $(OBJDIR)/tkt_.c:$(OBJDIR)/tkt.h $(OBJDIR)/tktsetup_.c:$(OBJDIR)/tktsetup.h $(OBJDIR)/undo_.c:$(OBJDIR)/undo.h $(OBJDIR)/unicode_.c:$(OBJDIR)/unicode.h $(OBJDIR)/update_.c:$(OBJDIR)/update.h $(OBJDIR)/url_.c:$(OBJDIR)/url.h $(OBJDIR)/user_.c:$(OBJDIR)/user.h $(OBJDIR)/utf8_.c:$(OBJDIR)/utf8.h $(OBJDIR)/util_.c:$(OBJDIR)/util.h $(OBJDIR)/verify_.c:$(OBJDIR)/verify.h $(OBJDIR)/vfile_.c:$(OBJDIR)/vfile.h $(OBJDIR)/wiki_.c:$(OBJDIR)/wiki.h $(OBJDIR)/wikiformat_.c:$(OBJDIR)/wikiformat.h $(OBJDIR)/winhttp_.c:$(OBJDIR)/winhttp.h $(OBJDIR)/wysiwyg_.c:$(OBJDIR)/wysiwyg.h $(OBJDIR)/xfer_.c:$(OBJDIR)/xfer.h $(OBJDIR)/xfersetup_.c:$(OBJDIR)/xfersetup.h $(OBJDIR)/zip_.c:$(OBJDIR)/zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h $(OBJDIR)/VERSION.h
410
+ $(OBJDIR)/makeheaders $(OBJDIR)/add_.c:$(OBJDIR)/add.h $(OBJDIR)/allrepo_.c:$(OBJDIR)/allrepo.h $(OBJDIR)/attach_.c:$(OBJDIR)/attach.h $(OBJDIR)/bag_.c:$(OBJDIR)/bag.h $(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h $(OBJDIR)/blob_.c:$(OBJDIR)/blob.h $(OBJDIR)/branch_.c:$(OBJDIR)/branch.h $(OBJDIR)/browse_.c:$(OBJDIR)/browse.h $(OBJDIR)/captcha_.c:$(OBJDIR)/captcha.h $(OBJDIR)/cgi_.c:$(OBJDIR)/cgi.h $(OBJDIR)/checkin_.c:$(OBJDIR)/checkin.h $(OBJDIR)/checkout_.c:$(OBJDIR)/checkout.h $(OBJDIR)/clearsign_.c:$(OBJDIR)/clearsign.h $(OBJDIR)/clone_.c:$(OBJDIR)/clone.h $(OBJDIR)/comformat_.c:$(OBJDIR)/comformat.h $(OBJDIR)/configure_.c:$(OBJDIR)/configure.h $(OBJDIR)/content_.c:$(OBJDIR)/content.h $(OBJDIR)/db_.c:$(OBJDIR)/db.h $(OBJDIR)/delta_.c:$(OBJDIR)/delta.h $(OBJDIR)/deltacmd_.c:$(OBJDIR)/deltacmd.h $(OBJDIR)/descendants_.c:$(OBJDIR)/descendants.h $(OBJDIR)/diff_.c:$(OBJDIR)/diff.h $(OBJDIR)/diffcmd_.c:$(OBJDIR)/diffcmd.h $(OBJDIR)/doc_.c:$(OBJDIR)/doc.h $(OBJDIR)/encode_.c:$(OBJDIR)/encode.h $(OBJDIR)/event_.c:$(OBJDIR)/event.h $(OBJDIR)/export_.c:$(OBJDIR)/export.h $(OBJDIR)/file_.c:$(OBJDIR)/file.h $(OBJDIR)/finfo_.c:$(OBJDIR)/finfo.h $(OBJDIR)/glob_.c:$(OBJDIR)/glob.h $(OBJDIR)/graph_.c:$(OBJDIR)/graph.h $(OBJDIR)/gzip_.c:$(OBJDIR)/gzip.h $(OBJDIR)/http_.c:$(OBJDIR)/http.h $(OBJDIR)/http_socket_.c:$(OBJDIR)/http_socket.h $(OBJDIR)/http_ssl_.c:$(OBJDIR)/http_ssl.h $(OBJDIR)/http_transport_.c:$(OBJDIR)/http_transport.h $(OBJDIR)/import_.c:$(OBJDIR)/import.h $(OBJDIR)/info_.c:$(OBJDIR)/info.h $(OBJDIR)/json_.c:$(OBJDIR)/json.h $(OBJDIR)/json_artifact_.c:$(OBJDIR)/json_artifact.h $(OBJDIR)/json_branch_.c:$(OBJDIR)/json_branch.h $(OBJDIR)/json_config_.c:$(OBJDIR)/json_config.h $(OBJDIR)/json_diff_.c:$(OBJDIR)/json_diff.h $(OBJDIR)/json_dir_.c:$(OBJDIR)/json_dir.h $(OBJDIR)/json_finfo_.c:$(OBJDIR)/json_finfo.h $(OBJDIR)/json_login_.c:$(OBJDIR)/json_login.h $(OBJDIR)/json_query_.c:$(OBJDIR)/json_query.h $(OBJDIR)/json_report_.c:$(OBJDIR)/json_report.h $(OBJDIR)/json_status_.c:$(OBJDIR)/json_status.h $(OBJDIR)/json_tag_.c:$(OBJDIR)/json_tag.h $(OBJDIR)/json_timeline_.c:$(OBJDIR)/json_timeline.h $(OBJDIR)/json_user_.c:$(OBJDIR)/json_user.h $(OBJDIR)/json_wiki_.c:$(OBJDIR)/json_wiki.h $(OBJDIR)/leaf_.c:$(OBJDIR)/leaf.h $(OBJDIR)/login_.c:$(OBJDIR)/login.h $(OBJDIR)/lookslike_.c:$(OBJDIR)/lookslike.h $(OBJDIR)/main_.c:$(OBJDIR)/main.h $(OBJDIR)/manifest_.c:$(OBJDIR)/manifest.h $(OBJDIR)/markdown_.c:$(OBJDIR)/markdown.h $(OBJDIR)/markdown_html_.c:$(OBJDIR)/markdown_html.h $(OBJDIR)/md5_.c:$(OBJDIR)/md5.h $(OBJDIR)/merge_.c:$(OBJDIR)/merge.h $(OBJDIR)/merge3_.c:$(OBJDIR)/merge3.h $(OBJDIR)/moderate_.c:$(OBJDIR)/moderate.h $(OBJDIR)/name_.c:$(OBJDIR)/name.h $(OBJDIR)/path_.c:$(OBJDIR)/path.h $(OBJDIR)/pivot_.c:$(OBJDIR)/pivot.h $(OBJDIR)/popen_.c:$(OBJDIR)/popen.h $(OBJDIR)/pqueue_.c:$(OBJDIR)/pqueue.h $(OBJDIR)/printf_.c:$(OBJDIR)/printf.h $(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h $(OBJDIR)/regexp_.c:$(OBJDIR)/regexp.h $(OBJDIR)/report_.c:$(OBJDIR)/report.h $(OBJDIR)/rss_.c:$(OBJDIR)/rss.h $(OBJDIR)/schema_.c:$(OBJDIR)/schema.h $(OBJDIR)/search_.c:$(OBJDIR)/search.h $(OBJDIR)/setup_.c:$(OBJDIR)/setup.h $(OBJDIR)/sha1_.c:$(OBJDIR)/sha1.h $(OBJDIR)/shun_.c:$(OBJDIR)/shun.h $(OBJDIR)/skins_.c:$(OBJDIR)/skins.h $(OBJDIR)/sqlcmd_.c:$(OBJDIR)/sqlcmd.h $(OBJDIR)/stash_.c:$(OBJDIR)/stash.h $(OBJDIR)/stat_.c:$(OBJDIR)/stat.h $(OBJDIR)/style_.c:$(OBJDIR)/style.h $(OBJDIR)/sync_.c:$(OBJDIR)/sync.h $(OBJDIR)/tag_.c:$(OBJDIR)/tag.h $(OBJDIR)/tar_.c:$(OBJDIR)/tar.h $(OBJDIR)/th_main_.c:$(OBJDIR)/th_main.h $(OBJDIR)/timeline_.c:$(OBJDIR)/timeline.h $(OBJDIR)/tkt_.c:$(OBJDIR)/tkt.h $(OBJDIR)/tktsetup_.c:$(OBJDIR)/tktsetup.h $(OBJDIR)/undo_.c:$(OBJDIR)/undo.h $(OBJDIR)/unicode_.c:$(OBJDIR)/unicode.h $(OBJDIR)/update_.c:$(OBJDIR)/update.h $(OBJDIR)/url_.c:$(OBJDIR)/url.h $(OBJDIR)/user_.c:$(OBJDIR)/user.h $(OBJDIR)/utf8_.c:$(OBJDIR)/utf8.h $(OBJDIR)/util_.c:$(OBJDIR)/util.h $(OBJDIR)/verify_.c:$(OBJDIR)/verify.h $(OBJDIR)/vfile_.c:$(OBJDIR)/vfile.h $(OBJDIR)/wiki_.c:$(OBJDIR)/wiki.h $(OBJDIR)/wikiformat_.c:$(OBJDIR)/wikiformat.h $(OBJDIR)/winhttp_.c:$(OBJDIR)/winhttp.h $(OBJDIR)/wysiwyg_.c:$(OBJDIR)/wysiwyg.h $(OBJDIR)/xfer_.c:$(OBJDIR)/xfer.h $(OBJDIR)/xfersetup_.c:$(OBJDIR)/xfersetup.h $(OBJDIR)/zip_.c:$(OBJDIR)/zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h $(OBJDIR)/VERSION.h
408411
touch $(OBJDIR)/headers
409412
$(OBJDIR)/headers: Makefile
410413
$(OBJDIR)/json.o $(OBJDIR)/json_artifact.o $(OBJDIR)/json_branch.o $(OBJDIR)/json_config.o $(OBJDIR)/json_diff.o $(OBJDIR)/json_dir.o $(OBJDIR)/json_finfo.o $(OBJDIR)/json_login.o $(OBJDIR)/json_query.o $(OBJDIR)/json_report.o $(OBJDIR)/json_status.o $(OBJDIR)/json_tag.o $(OBJDIR)/json_timeline.o $(OBJDIR)/json_user.o $(OBJDIR)/json_wiki.o : $(SRCDIR)/json_detail.h
411414
Makefile:
412415
$(OBJDIR)/add_.c: $(SRCDIR)/add.c $(OBJDIR)/translate
@@ -792,10 +795,17 @@
792795
793796
$(OBJDIR)/login.o: $(OBJDIR)/login_.c $(OBJDIR)/login.h $(SRCDIR)/config.h
794797
$(XTCC) -o $(OBJDIR)/login.o -c $(OBJDIR)/login_.c
795798
796799
$(OBJDIR)/login.h: $(OBJDIR)/headers
800
+$(OBJDIR)/lookslike_.c: $(SRCDIR)/lookslike.c $(OBJDIR)/translate
801
+ $(OBJDIR)/translate $(SRCDIR)/lookslike.c >$(OBJDIR)/lookslike_.c
802
+
803
+$(OBJDIR)/lookslike.o: $(OBJDIR)/lookslike_.c $(OBJDIR)/lookslike.h $(SRCDIR)/config.h
804
+ $(XTCC) -o $(OBJDIR)/lookslike.o -c $(OBJDIR)/lookslike_.c
805
+
806
+$(OBJDIR)/lookslike.h: $(OBJDIR)/headers
797807
$(OBJDIR)/main_.c: $(SRCDIR)/main.c $(OBJDIR)/translate
798808
$(OBJDIR)/translate $(SRCDIR)/main.c >$(OBJDIR)/main_.c
799809
800810
$(OBJDIR)/main.o: $(OBJDIR)/main_.c $(OBJDIR)/main.h $(OBJDIR)/page_index.h $(SRCDIR)/config.h
801811
$(XTCC) -o $(OBJDIR)/main.o -c $(OBJDIR)/main_.c
802812
--- src/main.mk
+++ src/main.mk
@@ -67,10 +67,11 @@
67 $(SRCDIR)/json_timeline.c \
68 $(SRCDIR)/json_user.c \
69 $(SRCDIR)/json_wiki.c \
70 $(SRCDIR)/leaf.c \
71 $(SRCDIR)/login.c \
 
72 $(SRCDIR)/main.c \
73 $(SRCDIR)/manifest.c \
74 $(SRCDIR)/markdown.c \
75 $(SRCDIR)/markdown_html.c \
76 $(SRCDIR)/md5.c \
@@ -175,10 +176,11 @@
175 $(OBJDIR)/json_timeline_.c \
176 $(OBJDIR)/json_user_.c \
177 $(OBJDIR)/json_wiki_.c \
178 $(OBJDIR)/leaf_.c \
179 $(OBJDIR)/login_.c \
 
180 $(OBJDIR)/main_.c \
181 $(OBJDIR)/manifest_.c \
182 $(OBJDIR)/markdown_.c \
183 $(OBJDIR)/markdown_html_.c \
184 $(OBJDIR)/md5_.c \
@@ -283,10 +285,11 @@
283 $(OBJDIR)/json_timeline.o \
284 $(OBJDIR)/json_user.o \
285 $(OBJDIR)/json_wiki.o \
286 $(OBJDIR)/leaf.o \
287 $(OBJDIR)/login.o \
 
288 $(OBJDIR)/main.o \
289 $(OBJDIR)/manifest.o \
290 $(OBJDIR)/markdown.o \
291 $(OBJDIR)/markdown_html.o \
292 $(OBJDIR)/md5.o \
@@ -402,11 +405,11 @@
402
403
404 $(OBJDIR)/page_index.h: $(TRANS_SRC) $(OBJDIR)/mkindex
405 $(OBJDIR)/mkindex $(TRANS_SRC) >$@
406 $(OBJDIR)/headers: $(OBJDIR)/page_index.h $(OBJDIR)/makeheaders $(OBJDIR)/VERSION.h
407 $(OBJDIR)/makeheaders $(OBJDIR)/add_.c:$(OBJDIR)/add.h $(OBJDIR)/allrepo_.c:$(OBJDIR)/allrepo.h $(OBJDIR)/attach_.c:$(OBJDIR)/attach.h $(OBJDIR)/bag_.c:$(OBJDIR)/bag.h $(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h $(OBJDIR)/blob_.c:$(OBJDIR)/blob.h $(OBJDIR)/branch_.c:$(OBJDIR)/branch.h $(OBJDIR)/browse_.c:$(OBJDIR)/browse.h $(OBJDIR)/captcha_.c:$(OBJDIR)/captcha.h $(OBJDIR)/cgi_.c:$(OBJDIR)/cgi.h $(OBJDIR)/checkin_.c:$(OBJDIR)/checkin.h $(OBJDIR)/checkout_.c:$(OBJDIR)/checkout.h $(OBJDIR)/clearsign_.c:$(OBJDIR)/clearsign.h $(OBJDIR)/clone_.c:$(OBJDIR)/clone.h $(OBJDIR)/comformat_.c:$(OBJDIR)/comformat.h $(OBJDIR)/configure_.c:$(OBJDIR)/configure.h $(OBJDIR)/content_.c:$(OBJDIR)/content.h $(OBJDIR)/db_.c:$(OBJDIR)/db.h $(OBJDIR)/delta_.c:$(OBJDIR)/delta.h $(OBJDIR)/deltacmd_.c:$(OBJDIR)/deltacmd.h $(OBJDIR)/descendants_.c:$(OBJDIR)/descendants.h $(OBJDIR)/diff_.c:$(OBJDIR)/diff.h $(OBJDIR)/diffcmd_.c:$(OBJDIR)/diffcmd.h $(OBJDIR)/doc_.c:$(OBJDIR)/doc.h $(OBJDIR)/encode_.c:$(OBJDIR)/encode.h $(OBJDIR)/event_.c:$(OBJDIR)/event.h $(OBJDIR)/export_.c:$(OBJDIR)/export.h $(OBJDIR)/file_.c:$(OBJDIR)/file.h $(OBJDIR)/finfo_.c:$(OBJDIR)/finfo.h $(OBJDIR)/glob_.c:$(OBJDIR)/glob.h $(OBJDIR)/graph_.c:$(OBJDIR)/graph.h $(OBJDIR)/gzip_.c:$(OBJDIR)/gzip.h $(OBJDIR)/http_.c:$(OBJDIR)/http.h $(OBJDIR)/http_socket_.c:$(OBJDIR)/http_socket.h $(OBJDIR)/http_ssl_.c:$(OBJDIR)/http_ssl.h $(OBJDIR)/http_transport_.c:$(OBJDIR)/http_transport.h $(OBJDIR)/import_.c:$(OBJDIR)/import.h $(OBJDIR)/info_.c:$(OBJDIR)/info.h $(OBJDIR)/json_.c:$(OBJDIR)/json.h $(OBJDIR)/json_artifact_.c:$(OBJDIR)/json_artifact.h $(OBJDIR)/json_branch_.c:$(OBJDIR)/json_branch.h $(OBJDIR)/json_config_.c:$(OBJDIR)/json_config.h $(OBJDIR)/json_diff_.c:$(OBJDIR)/json_diff.h $(OBJDIR)/json_dir_.c:$(OBJDIR)/json_dir.h $(OBJDIR)/json_finfo_.c:$(OBJDIR)/json_finfo.h $(OBJDIR)/json_login_.c:$(OBJDIR)/json_login.h $(OBJDIR)/json_query_.c:$(OBJDIR)/json_query.h $(OBJDIR)/json_report_.c:$(OBJDIR)/json_report.h $(OBJDIR)/json_status_.c:$(OBJDIR)/json_status.h $(OBJDIR)/json_tag_.c:$(OBJDIR)/json_tag.h $(OBJDIR)/json_timeline_.c:$(OBJDIR)/json_timeline.h $(OBJDIR)/json_user_.c:$(OBJDIR)/json_user.h $(OBJDIR)/json_wiki_.c:$(OBJDIR)/json_wiki.h $(OBJDIR)/leaf_.c:$(OBJDIR)/leaf.h $(OBJDIR)/login_.c:$(OBJDIR)/login.h $(OBJDIR)/main_.c:$(OBJDIR)/main.h $(OBJDIR)/manifest_.c:$(OBJDIR)/manifest.h $(OBJDIR)/markdown_.c:$(OBJDIR)/markdown.h $(OBJDIR)/markdown_html_.c:$(OBJDIR)/markdown_html.h $(OBJDIR)/md5_.c:$(OBJDIR)/md5.h $(OBJDIR)/merge_.c:$(OBJDIR)/merge.h $(OBJDIR)/merge3_.c:$(OBJDIR)/merge3.h $(OBJDIR)/moderate_.c:$(OBJDIR)/moderate.h $(OBJDIR)/name_.c:$(OBJDIR)/name.h $(OBJDIR)/path_.c:$(OBJDIR)/path.h $(OBJDIR)/pivot_.c:$(OBJDIR)/pivot.h $(OBJDIR)/popen_.c:$(OBJDIR)/popen.h $(OBJDIR)/pqueue_.c:$(OBJDIR)/pqueue.h $(OBJDIR)/printf_.c:$(OBJDIR)/printf.h $(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h $(OBJDIR)/regexp_.c:$(OBJDIR)/regexp.h $(OBJDIR)/report_.c:$(OBJDIR)/report.h $(OBJDIR)/rss_.c:$(OBJDIR)/rss.h $(OBJDIR)/schema_.c:$(OBJDIR)/schema.h $(OBJDIR)/search_.c:$(OBJDIR)/search.h $(OBJDIR)/setup_.c:$(OBJDIR)/setup.h $(OBJDIR)/sha1_.c:$(OBJDIR)/sha1.h $(OBJDIR)/shun_.c:$(OBJDIR)/shun.h $(OBJDIR)/skins_.c:$(OBJDIR)/skins.h $(OBJDIR)/sqlcmd_.c:$(OBJDIR)/sqlcmd.h $(OBJDIR)/stash_.c:$(OBJDIR)/stash.h $(OBJDIR)/stat_.c:$(OBJDIR)/stat.h $(OBJDIR)/style_.c:$(OBJDIR)/style.h $(OBJDIR)/sync_.c:$(OBJDIR)/sync.h $(OBJDIR)/tag_.c:$(OBJDIR)/tag.h $(OBJDIR)/tar_.c:$(OBJDIR)/tar.h $(OBJDIR)/th_main_.c:$(OBJDIR)/th_main.h $(OBJDIR)/timeline_.c:$(OBJDIR)/timeline.h $(OBJDIR)/tkt_.c:$(OBJDIR)/tkt.h $(OBJDIR)/tktsetup_.c:$(OBJDIR)/tktsetup.h $(OBJDIR)/undo_.c:$(OBJDIR)/undo.h $(OBJDIR)/unicode_.c:$(OBJDIR)/unicode.h $(OBJDIR)/update_.c:$(OBJDIR)/update.h $(OBJDIR)/url_.c:$(OBJDIR)/url.h $(OBJDIR)/user_.c:$(OBJDIR)/user.h $(OBJDIR)/utf8_.c:$(OBJDIR)/utf8.h $(OBJDIR)/util_.c:$(OBJDIR)/util.h $(OBJDIR)/verify_.c:$(OBJDIR)/verify.h $(OBJDIR)/vfile_.c:$(OBJDIR)/vfile.h $(OBJDIR)/wiki_.c:$(OBJDIR)/wiki.h $(OBJDIR)/wikiformat_.c:$(OBJDIR)/wikiformat.h $(OBJDIR)/winhttp_.c:$(OBJDIR)/winhttp.h $(OBJDIR)/wysiwyg_.c:$(OBJDIR)/wysiwyg.h $(OBJDIR)/xfer_.c:$(OBJDIR)/xfer.h $(OBJDIR)/xfersetup_.c:$(OBJDIR)/xfersetup.h $(OBJDIR)/zip_.c:$(OBJDIR)/zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h $(OBJDIR)/VERSION.h
408 touch $(OBJDIR)/headers
409 $(OBJDIR)/headers: Makefile
410 $(OBJDIR)/json.o $(OBJDIR)/json_artifact.o $(OBJDIR)/json_branch.o $(OBJDIR)/json_config.o $(OBJDIR)/json_diff.o $(OBJDIR)/json_dir.o $(OBJDIR)/json_finfo.o $(OBJDIR)/json_login.o $(OBJDIR)/json_query.o $(OBJDIR)/json_report.o $(OBJDIR)/json_status.o $(OBJDIR)/json_tag.o $(OBJDIR)/json_timeline.o $(OBJDIR)/json_user.o $(OBJDIR)/json_wiki.o : $(SRCDIR)/json_detail.h
411 Makefile:
412 $(OBJDIR)/add_.c: $(SRCDIR)/add.c $(OBJDIR)/translate
@@ -792,10 +795,17 @@
792
793 $(OBJDIR)/login.o: $(OBJDIR)/login_.c $(OBJDIR)/login.h $(SRCDIR)/config.h
794 $(XTCC) -o $(OBJDIR)/login.o -c $(OBJDIR)/login_.c
795
796 $(OBJDIR)/login.h: $(OBJDIR)/headers
 
 
 
 
 
 
 
797 $(OBJDIR)/main_.c: $(SRCDIR)/main.c $(OBJDIR)/translate
798 $(OBJDIR)/translate $(SRCDIR)/main.c >$(OBJDIR)/main_.c
799
800 $(OBJDIR)/main.o: $(OBJDIR)/main_.c $(OBJDIR)/main.h $(OBJDIR)/page_index.h $(SRCDIR)/config.h
801 $(XTCC) -o $(OBJDIR)/main.o -c $(OBJDIR)/main_.c
802
--- src/main.mk
+++ src/main.mk
@@ -67,10 +67,11 @@
67 $(SRCDIR)/json_timeline.c \
68 $(SRCDIR)/json_user.c \
69 $(SRCDIR)/json_wiki.c \
70 $(SRCDIR)/leaf.c \
71 $(SRCDIR)/login.c \
72 $(SRCDIR)/lookslike.c \
73 $(SRCDIR)/main.c \
74 $(SRCDIR)/manifest.c \
75 $(SRCDIR)/markdown.c \
76 $(SRCDIR)/markdown_html.c \
77 $(SRCDIR)/md5.c \
@@ -175,10 +176,11 @@
176 $(OBJDIR)/json_timeline_.c \
177 $(OBJDIR)/json_user_.c \
178 $(OBJDIR)/json_wiki_.c \
179 $(OBJDIR)/leaf_.c \
180 $(OBJDIR)/login_.c \
181 $(OBJDIR)/lookslike_.c \
182 $(OBJDIR)/main_.c \
183 $(OBJDIR)/manifest_.c \
184 $(OBJDIR)/markdown_.c \
185 $(OBJDIR)/markdown_html_.c \
186 $(OBJDIR)/md5_.c \
@@ -283,10 +285,11 @@
285 $(OBJDIR)/json_timeline.o \
286 $(OBJDIR)/json_user.o \
287 $(OBJDIR)/json_wiki.o \
288 $(OBJDIR)/leaf.o \
289 $(OBJDIR)/login.o \
290 $(OBJDIR)/lookslike.o \
291 $(OBJDIR)/main.o \
292 $(OBJDIR)/manifest.o \
293 $(OBJDIR)/markdown.o \
294 $(OBJDIR)/markdown_html.o \
295 $(OBJDIR)/md5.o \
@@ -402,11 +405,11 @@
405
406
407 $(OBJDIR)/page_index.h: $(TRANS_SRC) $(OBJDIR)/mkindex
408 $(OBJDIR)/mkindex $(TRANS_SRC) >$@
409 $(OBJDIR)/headers: $(OBJDIR)/page_index.h $(OBJDIR)/makeheaders $(OBJDIR)/VERSION.h
410 $(OBJDIR)/makeheaders $(OBJDIR)/add_.c:$(OBJDIR)/add.h $(OBJDIR)/allrepo_.c:$(OBJDIR)/allrepo.h $(OBJDIR)/attach_.c:$(OBJDIR)/attach.h $(OBJDIR)/bag_.c:$(OBJDIR)/bag.h $(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h $(OBJDIR)/blob_.c:$(OBJDIR)/blob.h $(OBJDIR)/branch_.c:$(OBJDIR)/branch.h $(OBJDIR)/browse_.c:$(OBJDIR)/browse.h $(OBJDIR)/captcha_.c:$(OBJDIR)/captcha.h $(OBJDIR)/cgi_.c:$(OBJDIR)/cgi.h $(OBJDIR)/checkin_.c:$(OBJDIR)/checkin.h $(OBJDIR)/checkout_.c:$(OBJDIR)/checkout.h $(OBJDIR)/clearsign_.c:$(OBJDIR)/clearsign.h $(OBJDIR)/clone_.c:$(OBJDIR)/clone.h $(OBJDIR)/comformat_.c:$(OBJDIR)/comformat.h $(OBJDIR)/configure_.c:$(OBJDIR)/configure.h $(OBJDIR)/content_.c:$(OBJDIR)/content.h $(OBJDIR)/db_.c:$(OBJDIR)/db.h $(OBJDIR)/delta_.c:$(OBJDIR)/delta.h $(OBJDIR)/deltacmd_.c:$(OBJDIR)/deltacmd.h $(OBJDIR)/descendants_.c:$(OBJDIR)/descendants.h $(OBJDIR)/diff_.c:$(OBJDIR)/diff.h $(OBJDIR)/diffcmd_.c:$(OBJDIR)/diffcmd.h $(OBJDIR)/doc_.c:$(OBJDIR)/doc.h $(OBJDIR)/encode_.c:$(OBJDIR)/encode.h $(OBJDIR)/event_.c:$(OBJDIR)/event.h $(OBJDIR)/export_.c:$(OBJDIR)/export.h $(OBJDIR)/file_.c:$(OBJDIR)/file.h $(OBJDIR)/finfo_.c:$(OBJDIR)/finfo.h $(OBJDIR)/glob_.c:$(OBJDIR)/glob.h $(OBJDIR)/graph_.c:$(OBJDIR)/graph.h $(OBJDIR)/gzip_.c:$(OBJDIR)/gzip.h $(OBJDIR)/http_.c:$(OBJDIR)/http.h $(OBJDIR)/http_socket_.c:$(OBJDIR)/http_socket.h $(OBJDIR)/http_ssl_.c:$(OBJDIR)/http_ssl.h $(OBJDIR)/http_transport_.c:$(OBJDIR)/http_transport.h $(OBJDIR)/import_.c:$(OBJDIR)/import.h $(OBJDIR)/info_.c:$(OBJDIR)/info.h $(OBJDIR)/json_.c:$(OBJDIR)/json.h $(OBJDIR)/json_artifact_.c:$(OBJDIR)/json_artifact.h $(OBJDIR)/json_branch_.c:$(OBJDIR)/json_branch.h $(OBJDIR)/json_config_.c:$(OBJDIR)/json_config.h $(OBJDIR)/json_diff_.c:$(OBJDIR)/json_diff.h $(OBJDIR)/json_dir_.c:$(OBJDIR)/json_dir.h $(OBJDIR)/json_finfo_.c:$(OBJDIR)/json_finfo.h $(OBJDIR)/json_login_.c:$(OBJDIR)/json_login.h $(OBJDIR)/json_query_.c:$(OBJDIR)/json_query.h $(OBJDIR)/json_report_.c:$(OBJDIR)/json_report.h $(OBJDIR)/json_status_.c:$(OBJDIR)/json_status.h $(OBJDIR)/json_tag_.c:$(OBJDIR)/json_tag.h $(OBJDIR)/json_timeline_.c:$(OBJDIR)/json_timeline.h $(OBJDIR)/json_user_.c:$(OBJDIR)/json_user.h $(OBJDIR)/json_wiki_.c:$(OBJDIR)/json_wiki.h $(OBJDIR)/leaf_.c:$(OBJDIR)/leaf.h $(OBJDIR)/login_.c:$(OBJDIR)/login.h $(OBJDIR)/lookslike_.c:$(OBJDIR)/lookslike.h $(OBJDIR)/main_.c:$(OBJDIR)/main.h $(OBJDIR)/manifest_.c:$(OBJDIR)/manifest.h $(OBJDIR)/markdown_.c:$(OBJDIR)/markdown.h $(OBJDIR)/markdown_html_.c:$(OBJDIR)/markdown_html.h $(OBJDIR)/md5_.c:$(OBJDIR)/md5.h $(OBJDIR)/merge_.c:$(OBJDIR)/merge.h $(OBJDIR)/merge3_.c:$(OBJDIR)/merge3.h $(OBJDIR)/moderate_.c:$(OBJDIR)/moderate.h $(OBJDIR)/name_.c:$(OBJDIR)/name.h $(OBJDIR)/path_.c:$(OBJDIR)/path.h $(OBJDIR)/pivot_.c:$(OBJDIR)/pivot.h $(OBJDIR)/popen_.c:$(OBJDIR)/popen.h $(OBJDIR)/pqueue_.c:$(OBJDIR)/pqueue.h $(OBJDIR)/printf_.c:$(OBJDIR)/printf.h $(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h $(OBJDIR)/regexp_.c:$(OBJDIR)/regexp.h $(OBJDIR)/report_.c:$(OBJDIR)/report.h $(OBJDIR)/rss_.c:$(OBJDIR)/rss.h $(OBJDIR)/schema_.c:$(OBJDIR)/schema.h $(OBJDIR)/search_.c:$(OBJDIR)/search.h $(OBJDIR)/setup_.c:$(OBJDIR)/setup.h $(OBJDIR)/sha1_.c:$(OBJDIR)/sha1.h $(OBJDIR)/shun_.c:$(OBJDIR)/shun.h $(OBJDIR)/skins_.c:$(OBJDIR)/skins.h $(OBJDIR)/sqlcmd_.c:$(OBJDIR)/sqlcmd.h $(OBJDIR)/stash_.c:$(OBJDIR)/stash.h $(OBJDIR)/stat_.c:$(OBJDIR)/stat.h $(OBJDIR)/style_.c:$(OBJDIR)/style.h $(OBJDIR)/sync_.c:$(OBJDIR)/sync.h $(OBJDIR)/tag_.c:$(OBJDIR)/tag.h $(OBJDIR)/tar_.c:$(OBJDIR)/tar.h $(OBJDIR)/th_main_.c:$(OBJDIR)/th_main.h $(OBJDIR)/timeline_.c:$(OBJDIR)/timeline.h $(OBJDIR)/tkt_.c:$(OBJDIR)/tkt.h $(OBJDIR)/tktsetup_.c:$(OBJDIR)/tktsetup.h $(OBJDIR)/undo_.c:$(OBJDIR)/undo.h $(OBJDIR)/unicode_.c:$(OBJDIR)/unicode.h $(OBJDIR)/update_.c:$(OBJDIR)/update.h $(OBJDIR)/url_.c:$(OBJDIR)/url.h $(OBJDIR)/user_.c:$(OBJDIR)/user.h $(OBJDIR)/utf8_.c:$(OBJDIR)/utf8.h $(OBJDIR)/util_.c:$(OBJDIR)/util.h $(OBJDIR)/verify_.c:$(OBJDIR)/verify.h $(OBJDIR)/vfile_.c:$(OBJDIR)/vfile.h $(OBJDIR)/wiki_.c:$(OBJDIR)/wiki.h $(OBJDIR)/wikiformat_.c:$(OBJDIR)/wikiformat.h $(OBJDIR)/winhttp_.c:$(OBJDIR)/winhttp.h $(OBJDIR)/wysiwyg_.c:$(OBJDIR)/wysiwyg.h $(OBJDIR)/xfer_.c:$(OBJDIR)/xfer.h $(OBJDIR)/xfersetup_.c:$(OBJDIR)/xfersetup.h $(OBJDIR)/zip_.c:$(OBJDIR)/zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h $(OBJDIR)/VERSION.h
411 touch $(OBJDIR)/headers
412 $(OBJDIR)/headers: Makefile
413 $(OBJDIR)/json.o $(OBJDIR)/json_artifact.o $(OBJDIR)/json_branch.o $(OBJDIR)/json_config.o $(OBJDIR)/json_diff.o $(OBJDIR)/json_dir.o $(OBJDIR)/json_finfo.o $(OBJDIR)/json_login.o $(OBJDIR)/json_query.o $(OBJDIR)/json_report.o $(OBJDIR)/json_status.o $(OBJDIR)/json_tag.o $(OBJDIR)/json_timeline.o $(OBJDIR)/json_user.o $(OBJDIR)/json_wiki.o : $(SRCDIR)/json_detail.h
414 Makefile:
415 $(OBJDIR)/add_.c: $(SRCDIR)/add.c $(OBJDIR)/translate
@@ -792,10 +795,17 @@
795
796 $(OBJDIR)/login.o: $(OBJDIR)/login_.c $(OBJDIR)/login.h $(SRCDIR)/config.h
797 $(XTCC) -o $(OBJDIR)/login.o -c $(OBJDIR)/login_.c
798
799 $(OBJDIR)/login.h: $(OBJDIR)/headers
800 $(OBJDIR)/lookslike_.c: $(SRCDIR)/lookslike.c $(OBJDIR)/translate
801 $(OBJDIR)/translate $(SRCDIR)/lookslike.c >$(OBJDIR)/lookslike_.c
802
803 $(OBJDIR)/lookslike.o: $(OBJDIR)/lookslike_.c $(OBJDIR)/lookslike.h $(SRCDIR)/config.h
804 $(XTCC) -o $(OBJDIR)/lookslike.o -c $(OBJDIR)/lookslike_.c
805
806 $(OBJDIR)/lookslike.h: $(OBJDIR)/headers
807 $(OBJDIR)/main_.c: $(SRCDIR)/main.c $(OBJDIR)/translate
808 $(OBJDIR)/translate $(SRCDIR)/main.c >$(OBJDIR)/main_.c
809
810 $(OBJDIR)/main.o: $(OBJDIR)/main_.c $(OBJDIR)/main.h $(OBJDIR)/page_index.h $(SRCDIR)/config.h
811 $(XTCC) -o $(OBJDIR)/main.o -c $(OBJDIR)/main_.c
812
--- src/makemake.tcl
+++ src/makemake.tcl
@@ -70,10 +70,11 @@
7070
json_timeline
7171
json_user
7272
json_wiki
7373
leaf
7474
login
75
+ lookslike
7576
main
7677
manifest
7778
markdown
7879
markdown_html
7980
md5
8081
--- src/makemake.tcl
+++ src/makemake.tcl
@@ -70,10 +70,11 @@
70 json_timeline
71 json_user
72 json_wiki
73 leaf
74 login
 
75 main
76 manifest
77 markdown
78 markdown_html
79 md5
80
--- src/makemake.tcl
+++ src/makemake.tcl
@@ -70,10 +70,11 @@
70 json_timeline
71 json_user
72 json_wiki
73 leaf
74 login
75 lookslike
76 main
77 manifest
78 markdown
79 markdown_html
80 md5
81
+34 -9
--- src/style.c
+++ src/style.c
@@ -462,11 +462,11 @@
462462
;
463463
464464
/*
465465
** The default Cascading Style Sheet.
466466
** It's assembled by different strings for each class.
467
-** The default css conatains all definitions.
467
+** The default css contains all definitions.
468468
** The style sheet, send to the client only contains the ones,
469469
** not defined in the user defined css.
470470
*/
471471
const char zDefaultCSS[] =
472472
@ /* General settings for the entire page */
@@ -965,20 +965,43 @@
965965
{ "ul.filelist",
966966
"List of files in a timeline",
967967
@ margin-top: 3px;
968968
@ line-height: 100%;
969969
},
970
- { "div.sbsdiff",
971
- "side-by-side diff display",
972
- @ font-family: monospace;
970
+ { "table.sbsdiffcols",
971
+ "side-by-side diff display (column-based)",
972
+ @ border-spacing: 0;
973973
@ font-size: xx-small;
974
- @ white-space: pre;
974
+ },
975
+ { "table.sbsdiffcols td",
976
+ "sbs diff table cell",
977
+ @ padding: 0;
978
+ @ vertical-align: top;
979
+ },
980
+ { "table.sbsdiffcols pre",
981
+ "sbs diff pre block",
982
+ @ margin: 0;
983
+ @ padding: 0;
984
+ @ border: 0;
985
+ @ font-size: inherit;
986
+ @ background: inherit;
987
+ @ color: inherit;
988
+ },
989
+ { "div.difflncol",
990
+ "diff line number column",
991
+ @ padding-right: 1em;
992
+ @ text-align: right;
993
+ @ color: #a0a0a0;
994
+ },
995
+ { "div.difftxtcol",
996
+ "diff text column",
997
+ @ width: 45em;
998
+ @ overflow-x: auto;
975999
},
976
- { "div.udiff",
977
- "context diff display",
978
- @ font-family: monospace;
979
- @ white-space: pre;
1000
+ { "div.diffmkrcol",
1001
+ "diff marker column",
1002
+ @ padding: 0 1em;
9801003
},
9811004
{ "span.diffchng",
9821005
"changes in a diff",
9831006
@ background-color: #c0c0ff;
9841007
},
@@ -990,10 +1013,12 @@
9901013
"deleted in a diff",
9911014
@ background-color: #ffc8c8;
9921015
},
9931016
{ "span.diffhr",
9941017
"suppressed lines in a diff",
1018
+ @ display: inline-block;
1019
+ @ margin: .5em 0 1em;
9951020
@ color: #0000ff;
9961021
},
9971022
{ "span.diffln",
9981023
"line numbers in a diff",
9991024
@ color: #a0a0a0;
10001025
--- src/style.c
+++ src/style.c
@@ -462,11 +462,11 @@
462 ;
463
464 /*
465 ** The default Cascading Style Sheet.
466 ** It's assembled by different strings for each class.
467 ** The default css conatains all definitions.
468 ** The style sheet, send to the client only contains the ones,
469 ** not defined in the user defined css.
470 */
471 const char zDefaultCSS[] =
472 @ /* General settings for the entire page */
@@ -965,20 +965,43 @@
965 { "ul.filelist",
966 "List of files in a timeline",
967 @ margin-top: 3px;
968 @ line-height: 100%;
969 },
970 { "div.sbsdiff",
971 "side-by-side diff display",
972 @ font-family: monospace;
973 @ font-size: xx-small;
974 @ white-space: pre;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
975 },
976 { "div.udiff",
977 "context diff display",
978 @ font-family: monospace;
979 @ white-space: pre;
980 },
981 { "span.diffchng",
982 "changes in a diff",
983 @ background-color: #c0c0ff;
984 },
@@ -990,10 +1013,12 @@
990 "deleted in a diff",
991 @ background-color: #ffc8c8;
992 },
993 { "span.diffhr",
994 "suppressed lines in a diff",
 
 
995 @ color: #0000ff;
996 },
997 { "span.diffln",
998 "line numbers in a diff",
999 @ color: #a0a0a0;
1000
--- src/style.c
+++ src/style.c
@@ -462,11 +462,11 @@
462 ;
463
464 /*
465 ** The default Cascading Style Sheet.
466 ** It's assembled by different strings for each class.
467 ** The default css contains all definitions.
468 ** The style sheet, send to the client only contains the ones,
469 ** not defined in the user defined css.
470 */
471 const char zDefaultCSS[] =
472 @ /* General settings for the entire page */
@@ -965,20 +965,43 @@
965 { "ul.filelist",
966 "List of files in a timeline",
967 @ margin-top: 3px;
968 @ line-height: 100%;
969 },
970 { "table.sbsdiffcols",
971 "side-by-side diff display (column-based)",
972 @ border-spacing: 0;
973 @ font-size: xx-small;
974 },
975 { "table.sbsdiffcols td",
976 "sbs diff table cell",
977 @ padding: 0;
978 @ vertical-align: top;
979 },
980 { "table.sbsdiffcols pre",
981 "sbs diff pre block",
982 @ margin: 0;
983 @ padding: 0;
984 @ border: 0;
985 @ font-size: inherit;
986 @ background: inherit;
987 @ color: inherit;
988 },
989 { "div.difflncol",
990 "diff line number column",
991 @ padding-right: 1em;
992 @ text-align: right;
993 @ color: #a0a0a0;
994 },
995 { "div.difftxtcol",
996 "diff text column",
997 @ width: 45em;
998 @ overflow-x: auto;
999 },
1000 { "div.diffmkrcol",
1001 "diff marker column",
1002 @ padding: 0 1em;
 
1003 },
1004 { "span.diffchng",
1005 "changes in a diff",
1006 @ background-color: #c0c0ff;
1007 },
@@ -990,10 +1013,12 @@
1013 "deleted in a diff",
1014 @ background-color: #ffc8c8;
1015 },
1016 { "span.diffhr",
1017 "suppressed lines in a diff",
1018 @ display: inline-block;
1019 @ margin: .5em 0 1em;
1020 @ color: #0000ff;
1021 },
1022 { "span.diffln",
1023 "line numbers in a diff",
1024 @ color: #a0a0a0;
1025
--- src/translate.c
+++ src/translate.c
@@ -30,10 +30,25 @@
3030
**
3131
** This tool allows us to put raw HTML, without the special codes, in
3232
** the middle of a C program. This program then translates the text
3333
** into standard C by inserting all necessary backslashes and other
3434
** punctuation.
35
+**
36
+** Enhancement #1:
37
+**
38
+** If the last non-whitespace character prior to the first "@" of a
39
+** @-block is "=" or "," then the @-block is a string literal initializer
40
+** rather than text that is to be output via cgi_printf(). Render it
41
+** as such.
42
+**
43
+** Enhancement #2:
44
+**
45
+** Comments of the form: "/* @-comment: CC" cause CC to become a
46
+** comment character for the @-substitution. Typical values for CC are
47
+** "--" (for SQL text) or "#" (for TCL script) or "//" (for C++ code).
48
+** Lines of subsequent @-blocks that begin with CC are omitted from the
49
+** output.
3550
**
3651
*/
3752
#include <stdio.h>
3853
#include <ctype.h>
3954
#include <stdlib.h>
4055
--- src/translate.c
+++ src/translate.c
@@ -30,10 +30,25 @@
30 **
31 ** This tool allows us to put raw HTML, without the special codes, in
32 ** the middle of a C program. This program then translates the text
33 ** into standard C by inserting all necessary backslashes and other
34 ** punctuation.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35 **
36 */
37 #include <stdio.h>
38 #include <ctype.h>
39 #include <stdlib.h>
40
--- src/translate.c
+++ src/translate.c
@@ -30,10 +30,25 @@
30 **
31 ** This tool allows us to put raw HTML, without the special codes, in
32 ** the middle of a C program. This program then translates the text
33 ** into standard C by inserting all necessary backslashes and other
34 ** punctuation.
35 **
36 ** Enhancement #1:
37 **
38 ** If the last non-whitespace character prior to the first "@" of a
39 ** @-block is "=" or "," then the @-block is a string literal initializer
40 ** rather than text that is to be output via cgi_printf(). Render it
41 ** as such.
42 **
43 ** Enhancement #2:
44 **
45 ** Comments of the form: "/* @-comment: CC" cause CC to become a
46 ** comment character for the @-substitution. Typical values for CC are
47 ** "--" (for SQL text) or "#" (for TCL script) or "//" (for C++ code).
48 ** Lines of subsequent @-blocks that begin with CC are omitted from the
49 ** output.
50 **
51 */
52 #include <stdio.h>
53 #include <ctype.h>
54 #include <stdlib.h>
55
+2 -2
--- src/wiki.c
+++ src/wiki.c
@@ -786,13 +786,13 @@
786786
blob_init(&w2, pW2->zWiki, -1);
787787
}
788788
blob_zero(&d);
789789
diffFlags = construct_diff_flags(1,0);
790790
text_diff(&w2, &w1, &d, 0, diffFlags | DIFF_HTML | DIFF_LINENO);
791
- @ <div class="udiff">
791
+ @ <pre class="udiff">
792792
@ %s(blob_str(&d))
793
- @ </div>
793
+ @ <pre>
794794
manifest_destroy(pW1);
795795
manifest_destroy(pW2);
796796
style_footer();
797797
}
798798
799799
--- src/wiki.c
+++ src/wiki.c
@@ -786,13 +786,13 @@
786 blob_init(&w2, pW2->zWiki, -1);
787 }
788 blob_zero(&d);
789 diffFlags = construct_diff_flags(1,0);
790 text_diff(&w2, &w1, &d, 0, diffFlags | DIFF_HTML | DIFF_LINENO);
791 @ <div class="udiff">
792 @ %s(blob_str(&d))
793 @ </div>
794 manifest_destroy(pW1);
795 manifest_destroy(pW2);
796 style_footer();
797 }
798
799
--- src/wiki.c
+++ src/wiki.c
@@ -786,13 +786,13 @@
786 blob_init(&w2, pW2->zWiki, -1);
787 }
788 blob_zero(&d);
789 diffFlags = construct_diff_flags(1,0);
790 text_diff(&w2, &w1, &d, 0, diffFlags | DIFF_HTML | DIFF_LINENO);
791 @ <pre class="udiff">
792 @ %s(blob_str(&d))
793 @ <pre>
794 manifest_destroy(pW1);
795 manifest_destroy(pW2);
796 style_footer();
797 }
798
799
--- test/diff-test-1.wiki
+++ test/diff-test-1.wiki
@@ -2,11 +2,11 @@
22
33
This page contains list of URLs of interesting diffs.
44
Click on all URLs, one by one, to verify
55
the correct operation of the diff logic.
66
7
- * <a href="../../../info/030035345c#chunk59" target="testwindow">
7
+ * <a href="../../../info/030035345c#chunk73" target="testwindow">
88
Multiple edits on a single line.</a> This is an SQLite version
99
update diff. It is a large diff and contains many other interesting
1010
features. Scan the whole diff.
1111
* <a href="../../../fdiff?v1=6da016415dc52d61&v2=af6df3466e3c4a88"
1212
target="testwindow">Tricky alignment and multiple edits per line</a>.
@@ -15,12 +15,12 @@
1515
* <a href="../../../fdiff?v1=d1c60722e0b9d775&v2=58d1a8991bacb113"
1616
target="testwindow">Column alignment with multibyte characters.</a>
1717
The edit of a line with multibyte characters is the first chunk.
1818
* <a href="../../../fdiff?v1=57b0d8183cab0e3d&v2=37b3ef49d73cdfe6"
1919
target="testwindow">Large diff of sqlite3.c</a>. This diff was very
20
- slow prior to the preformance enhancement change [9e15437e97].
21
- * <a href="../../../info/bda00cbada#chunk42" target="testwindow">
20
+ slow prior to the performance enhancement change [9e15437e97].
21
+ * <a href="../../../info/bda00cbada#chunk49" target="testwindow">
2222
A difficult indentation change.
2323
* <a href="../../../fdiff?v1=955cc67ace8fb622&v2=e2e1c87b86664b45#chunk13"
2424
target="testwindow">Another tricky indentation.</a> Notice especially
2525
lines 59398 and 59407 on the left.
2626
* <a href="../../../fdiff?v2=955cc67ace8fb622&v1=e2e1c87b86664b45#chunk13"
2727
--- test/diff-test-1.wiki
+++ test/diff-test-1.wiki
@@ -2,11 +2,11 @@
2
3 This page contains list of URLs of interesting diffs.
4 Click on all URLs, one by one, to verify
5 the correct operation of the diff logic.
6
7 * <a href="../../../info/030035345c#chunk59" target="testwindow">
8 Multiple edits on a single line.</a> This is an SQLite version
9 update diff. It is a large diff and contains many other interesting
10 features. Scan the whole diff.
11 * <a href="../../../fdiff?v1=6da016415dc52d61&v2=af6df3466e3c4a88"
12 target="testwindow">Tricky alignment and multiple edits per line</a>.
@@ -15,12 +15,12 @@
15 * <a href="../../../fdiff?v1=d1c60722e0b9d775&v2=58d1a8991bacb113"
16 target="testwindow">Column alignment with multibyte characters.</a>
17 The edit of a line with multibyte characters is the first chunk.
18 * <a href="../../../fdiff?v1=57b0d8183cab0e3d&v2=37b3ef49d73cdfe6"
19 target="testwindow">Large diff of sqlite3.c</a>. This diff was very
20 slow prior to the preformance enhancement change [9e15437e97].
21 * <a href="../../../info/bda00cbada#chunk42" target="testwindow">
22 A difficult indentation change.
23 * <a href="../../../fdiff?v1=955cc67ace8fb622&v2=e2e1c87b86664b45#chunk13"
24 target="testwindow">Another tricky indentation.</a> Notice especially
25 lines 59398 and 59407 on the left.
26 * <a href="../../../fdiff?v2=955cc67ace8fb622&v1=e2e1c87b86664b45#chunk13"
27
--- test/diff-test-1.wiki
+++ test/diff-test-1.wiki
@@ -2,11 +2,11 @@
2
3 This page contains list of URLs of interesting diffs.
4 Click on all URLs, one by one, to verify
5 the correct operation of the diff logic.
6
7 * <a href="../../../info/030035345c#chunk73" target="testwindow">
8 Multiple edits on a single line.</a> This is an SQLite version
9 update diff. It is a large diff and contains many other interesting
10 features. Scan the whole diff.
11 * <a href="../../../fdiff?v1=6da016415dc52d61&v2=af6df3466e3c4a88"
12 target="testwindow">Tricky alignment and multiple edits per line</a>.
@@ -15,12 +15,12 @@
15 * <a href="../../../fdiff?v1=d1c60722e0b9d775&v2=58d1a8991bacb113"
16 target="testwindow">Column alignment with multibyte characters.</a>
17 The edit of a line with multibyte characters is the first chunk.
18 * <a href="../../../fdiff?v1=57b0d8183cab0e3d&v2=37b3ef49d73cdfe6"
19 target="testwindow">Large diff of sqlite3.c</a>. This diff was very
20 slow prior to the performance enhancement change [9e15437e97].
21 * <a href="../../../info/bda00cbada#chunk49" target="testwindow">
22 A difficult indentation change.
23 * <a href="../../../fdiff?v1=955cc67ace8fb622&v2=e2e1c87b86664b45#chunk13"
24 target="testwindow">Another tricky indentation.</a> Notice especially
25 lines 59398 and 59407 on the left.
26 * <a href="../../../fdiff?v2=955cc67ace8fb622&v1=e2e1c87b86664b45#chunk13"
27
+10 -4
--- win/Makefile.dmc
+++ win/Makefile.dmc
@@ -26,13 +26,13 @@
2626
TCC = $(DMDIR)\bin\dmc $(CFLAGS) $(DMCDEF) $(SSL) $(INCL)
2727
LIBS = $(DMDIR)\extra\lib\ zlib wsock32 advapi32
2828
2929
SQLITE_OPTIONS = -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_STAT3 -Dlocaltime=fossil_localtime -DSQLITE_ENABLE_LOCKING_STYLE=0
3030
31
-SRC = add_.c allrepo_.c attach_.c bag_.c bisect_.c blob_.c branch_.c browse_.c captcha_.c cgi_.c checkin_.c checkout_.c clearsign_.c clone_.c comformat_.c configure_.c content_.c db_.c delta_.c deltacmd_.c descendants_.c diff_.c diffcmd_.c doc_.c encode_.c event_.c export_.c file_.c finfo_.c glob_.c graph_.c gzip_.c http_.c http_socket_.c http_ssl_.c http_transport_.c import_.c info_.c json_.c json_artifact_.c json_branch_.c json_config_.c json_diff_.c json_dir_.c json_finfo_.c json_login_.c json_query_.c json_report_.c json_status_.c json_tag_.c json_timeline_.c json_user_.c json_wiki_.c leaf_.c login_.c main_.c manifest_.c markdown_.c markdown_html_.c md5_.c merge_.c merge3_.c moderate_.c name_.c path_.c pivot_.c popen_.c pqueue_.c printf_.c rebuild_.c regexp_.c report_.c rss_.c schema_.c search_.c setup_.c sha1_.c shun_.c skins_.c sqlcmd_.c stash_.c stat_.c style_.c sync_.c tag_.c tar_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c unicode_.c update_.c url_.c user_.c utf8_.c util_.c verify_.c vfile_.c wiki_.c wikiformat_.c winhttp_.c wysiwyg_.c xfer_.c xfersetup_.c zip_.c
31
+SRC = add_.c allrepo_.c attach_.c bag_.c bisect_.c blob_.c branch_.c browse_.c captcha_.c cgi_.c checkin_.c checkout_.c clearsign_.c clone_.c comformat_.c configure_.c content_.c db_.c delta_.c deltacmd_.c descendants_.c diff_.c diffcmd_.c doc_.c encode_.c event_.c export_.c file_.c finfo_.c glob_.c graph_.c gzip_.c http_.c http_socket_.c http_ssl_.c http_transport_.c import_.c info_.c json_.c json_artifact_.c json_branch_.c json_config_.c json_diff_.c json_dir_.c json_finfo_.c json_login_.c json_query_.c json_report_.c json_status_.c json_tag_.c json_timeline_.c json_user_.c json_wiki_.c leaf_.c login_.c lookslike_.c main_.c manifest_.c markdown_.c markdown_html_.c md5_.c merge_.c merge3_.c moderate_.c name_.c path_.c pivot_.c popen_.c pqueue_.c printf_.c rebuild_.c regexp_.c report_.c rss_.c schema_.c search_.c setup_.c sha1_.c shun_.c skins_.c sqlcmd_.c stash_.c stat_.c style_.c sync_.c tag_.c tar_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c unicode_.c update_.c url_.c user_.c utf8_.c util_.c verify_.c vfile_.c wiki_.c wikiformat_.c winhttp_.c wysiwyg_.c xfer_.c xfersetup_.c zip_.c
3232
33
-OBJ = $(OBJDIR)\add$O $(OBJDIR)\allrepo$O $(OBJDIR)\attach$O $(OBJDIR)\bag$O $(OBJDIR)\bisect$O $(OBJDIR)\blob$O $(OBJDIR)\branch$O $(OBJDIR)\browse$O $(OBJDIR)\captcha$O $(OBJDIR)\cgi$O $(OBJDIR)\checkin$O $(OBJDIR)\checkout$O $(OBJDIR)\clearsign$O $(OBJDIR)\clone$O $(OBJDIR)\comformat$O $(OBJDIR)\configure$O $(OBJDIR)\content$O $(OBJDIR)\db$O $(OBJDIR)\delta$O $(OBJDIR)\deltacmd$O $(OBJDIR)\descendants$O $(OBJDIR)\diff$O $(OBJDIR)\diffcmd$O $(OBJDIR)\doc$O $(OBJDIR)\encode$O $(OBJDIR)\event$O $(OBJDIR)\export$O $(OBJDIR)\file$O $(OBJDIR)\finfo$O $(OBJDIR)\glob$O $(OBJDIR)\graph$O $(OBJDIR)\gzip$O $(OBJDIR)\http$O $(OBJDIR)\http_socket$O $(OBJDIR)\http_ssl$O $(OBJDIR)\http_transport$O $(OBJDIR)\import$O $(OBJDIR)\info$O $(OBJDIR)\json$O $(OBJDIR)\json_artifact$O $(OBJDIR)\json_branch$O $(OBJDIR)\json_config$O $(OBJDIR)\json_diff$O $(OBJDIR)\json_dir$O $(OBJDIR)\json_finfo$O $(OBJDIR)\json_login$O $(OBJDIR)\json_query$O $(OBJDIR)\json_report$O $(OBJDIR)\json_status$O $(OBJDIR)\json_tag$O $(OBJDIR)\json_timeline$O $(OBJDIR)\json_user$O $(OBJDIR)\json_wiki$O $(OBJDIR)\leaf$O $(OBJDIR)\login$O $(OBJDIR)\main$O $(OBJDIR)\manifest$O $(OBJDIR)\markdown$O $(OBJDIR)\markdown_html$O $(OBJDIR)\md5$O $(OBJDIR)\merge$O $(OBJDIR)\merge3$O $(OBJDIR)\moderate$O $(OBJDIR)\name$O $(OBJDIR)\path$O $(OBJDIR)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$O $(OBJDIR)\rebuild$O $(OBJDIR)\regexp$O $(OBJDIR)\report$O $(OBJDIR)\rss$O $(OBJDIR)\schema$O $(OBJDIR)\search$O $(OBJDIR)\setup$O $(OBJDIR)\sha1$O $(OBJDIR)\shun$O $(OBJDIR)\skins$O $(OBJDIR)\sqlcmd$O $(OBJDIR)\stash$O $(OBJDIR)\stat$O $(OBJDIR)\style$O $(OBJDIR)\sync$O $(OBJDIR)\tag$O $(OBJDIR)\tar$O $(OBJDIR)\th_main$O $(OBJDIR)\timeline$O $(OBJDIR)\tkt$O $(OBJDIR)\tktsetup$O $(OBJDIR)\undo$O $(OBJDIR)\unicode$O $(OBJDIR)\update$O $(OBJDIR)\url$O $(OBJDIR)\user$O $(OBJDIR)\utf8$O $(OBJDIR)\util$O $(OBJDIR)\verify$O $(OBJDIR)\vfile$O $(OBJDIR)\wiki$O $(OBJDIR)\wikiformat$O $(OBJDIR)\winhttp$O $(OBJDIR)\wysiwyg$O $(OBJDIR)\xfer$O $(OBJDIR)\xfersetup$O $(OBJDIR)\zip$O $(OBJDIR)\shell$O $(OBJDIR)\sqlite3$O $(OBJDIR)\th$O $(OBJDIR)\th_lang$O
33
+OBJ = $(OBJDIR)\add$O $(OBJDIR)\allrepo$O $(OBJDIR)\attach$O $(OBJDIR)\bag$O $(OBJDIR)\bisect$O $(OBJDIR)\blob$O $(OBJDIR)\branch$O $(OBJDIR)\browse$O $(OBJDIR)\captcha$O $(OBJDIR)\cgi$O $(OBJDIR)\checkin$O $(OBJDIR)\checkout$O $(OBJDIR)\clearsign$O $(OBJDIR)\clone$O $(OBJDIR)\comformat$O $(OBJDIR)\configure$O $(OBJDIR)\content$O $(OBJDIR)\db$O $(OBJDIR)\delta$O $(OBJDIR)\deltacmd$O $(OBJDIR)\descendants$O $(OBJDIR)\diff$O $(OBJDIR)\diffcmd$O $(OBJDIR)\doc$O $(OBJDIR)\encode$O $(OBJDIR)\event$O $(OBJDIR)\export$O $(OBJDIR)\file$O $(OBJDIR)\finfo$O $(OBJDIR)\glob$O $(OBJDIR)\graph$O $(OBJDIR)\gzip$O $(OBJDIR)\http$O $(OBJDIR)\http_socket$O $(OBJDIR)\http_ssl$O $(OBJDIR)\http_transport$O $(OBJDIR)\import$O $(OBJDIR)\info$O $(OBJDIR)\json$O $(OBJDIR)\json_artifact$O $(OBJDIR)\json_branch$O $(OBJDIR)\json_config$O $(OBJDIR)\json_diff$O $(OBJDIR)\json_dir$O $(OBJDIR)\json_finfo$O $(OBJDIR)\json_login$O $(OBJDIR)\json_query$O $(OBJDIR)\json_report$O $(OBJDIR)\json_status$O $(OBJDIR)\json_tag$O $(OBJDIR)\json_timeline$O $(OBJDIR)\json_user$O $(OBJDIR)\json_wiki$O $(OBJDIR)\leaf$O $(OBJDIR)\login$O $(OBJDIR)\lookslike$O $(OBJDIR)\main$O $(OBJDIR)\manifest$O $(OBJDIR)\markdown$O $(OBJDIR)\markdown_html$O $(OBJDIR)\md5$O $(OBJDIR)\merge$O $(OBJDIR)\merge3$O $(OBJDIR)\moderate$O $(OBJDIR)\name$O $(OBJDIR)\path$O $(OBJDIR)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$O $(OBJDIR)\rebuild$O $(OBJDIR)\regexp$O $(OBJDIR)\report$O $(OBJDIR)\rss$O $(OBJDIR)\schema$O $(OBJDIR)\search$O $(OBJDIR)\setup$O $(OBJDIR)\sha1$O $(OBJDIR)\shun$O $(OBJDIR)\skins$O $(OBJDIR)\sqlcmd$O $(OBJDIR)\stash$O $(OBJDIR)\stat$O $(OBJDIR)\style$O $(OBJDIR)\sync$O $(OBJDIR)\tag$O $(OBJDIR)\tar$O $(OBJDIR)\th_main$O $(OBJDIR)\timeline$O $(OBJDIR)\tkt$O $(OBJDIR)\tktsetup$O $(OBJDIR)\undo$O $(OBJDIR)\unicode$O $(OBJDIR)\update$O $(OBJDIR)\url$O $(OBJDIR)\user$O $(OBJDIR)\utf8$O $(OBJDIR)\util$O $(OBJDIR)\verify$O $(OBJDIR)\vfile$O $(OBJDIR)\wiki$O $(OBJDIR)\wikiformat$O $(OBJDIR)\winhttp$O $(OBJDIR)\wysiwyg$O $(OBJDIR)\xfer$O $(OBJDIR)\xfersetup$O $(OBJDIR)\zip$O $(OBJDIR)\shell$O $(OBJDIR)\sqlite3$O $(OBJDIR)\th$O $(OBJDIR)\th_lang$O
3434
3535
3636
RC=$(DMDIR)\bin\rcc
3737
RCFLAGS=-32 -w1 -I$(SRCDIR) /D__DMC__
3838
@@ -46,11 +46,11 @@
4646
4747
$(OBJDIR)\fossil.res: $B\win\fossil.rc
4848
$(RC) $(RCFLAGS) -o$@ $**
4949
5050
$(OBJDIR)\link: $B\win\Makefile.dmc $(OBJDIR)\fossil.res
51
- +echo add allrepo attach bag bisect blob branch browse captcha cgi checkin checkout clearsign clone comformat configure content db delta deltacmd descendants diff diffcmd doc encode event export file finfo glob graph gzip http http_socket http_ssl http_transport import info json json_artifact json_branch json_config json_diff json_dir json_finfo json_login json_query json_report json_status json_tag json_timeline json_user json_wiki leaf login main manifest markdown markdown_html md5 merge merge3 moderate name path pivot popen pqueue printf rebuild regexp report rss schema search setup sha1 shun skins sqlcmd stash stat style sync tag tar th_main timeline tkt tktsetup undo unicode update url user utf8 util verify vfile wiki wikiformat winhttp wysiwyg xfer xfersetup zip shell sqlite3 th th_lang > $@
51
+ +echo add allrepo attach bag bisect blob branch browse captcha cgi checkin checkout clearsign clone comformat configure content db delta deltacmd descendants diff diffcmd doc encode event export file finfo glob graph gzip http http_socket http_ssl http_transport import info json json_artifact json_branch json_config json_diff json_dir json_finfo json_login json_query json_report json_status json_tag json_timeline json_user json_wiki leaf login lookslike main manifest markdown markdown_html md5 merge merge3 moderate name path pivot popen pqueue printf rebuild regexp report rss schema search setup sha1 shun skins sqlcmd stash stat style sync tag tar th_main timeline tkt tktsetup undo unicode update url user utf8 util verify vfile wiki wikiformat winhttp wysiwyg xfer xfersetup zip shell sqlite3 th th_lang > $@
5252
+echo fossil >> $@
5353
+echo fossil >> $@
5454
+echo $(LIBS) >> $@
5555
+echo. >> $@
5656
+echo fossil >> $@
@@ -440,10 +440,16 @@
440440
$(OBJDIR)\login$O : login_.c login.h
441441
$(TCC) -o$@ -c login_.c
442442
443443
login_.c : $(SRCDIR)\login.c
444444
+translate$E $** > $@
445
+
446
+$(OBJDIR)\lookslike$O : lookslike_.c lookslike.h
447
+ $(TCC) -o$@ -c lookslike_.c
448
+
449
+lookslike_.c : $(SRCDIR)\lookslike.c
450
+ +translate$E $** > $@
445451
446452
$(OBJDIR)\main$O : main_.c main.h
447453
$(TCC) -o$@ -c main_.c
448454
449455
main_.c : $(SRCDIR)\main.c
@@ -748,7 +754,7 @@
748754
749755
zip_.c : $(SRCDIR)\zip.c
750756
+translate$E $** > $@
751757
752758
headers: makeheaders$E page_index.h VERSION.h
753
- +makeheaders$E add_.c:add.h allrepo_.c:allrepo.h attach_.c:attach.h bag_.c:bag.h bisect_.c:bisect.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h captcha_.c:captcha.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h configure_.c:configure.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendants_.c:descendants.h diff_.c:diff.h diffcmd_.c:diffcmd.h doc_.c:doc.h encode_.c:encode.h event_.c:event.h export_.c:export.h file_.c:file.h finfo_.c:finfo.h glob_.c:glob.h graph_.c:graph.h gzip_.c:gzip.h http_.c:http.h http_socket_.c:http_socket.h http_ssl_.c:http_ssl.h http_transport_.c:http_transport.h import_.c:import.h info_.c:info.h json_.c:json.h json_artifact_.c:json_artifact.h json_branch_.c:json_branch.h json_config_.c:json_config.h json_diff_.c:json_diff.h json_dir_.c:json_dir.h json_finfo_.c:json_finfo.h json_login_.c:json_login.h json_query_.c:json_query.h json_report_.c:json_report.h json_status_.c:json_status.h json_tag_.c:json_tag.h json_timeline_.c:json_timeline.h json_user_.c:json_user.h json_wiki_.c:json_wiki.h leaf_.c:leaf.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h markdown_.c:markdown.h markdown_html_.c:markdown_html.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h moderate_.c:moderate.h name_.c:name.h path_.c:path.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h regexp_.c:regexp.h report_.c:report.h rss_.c:rss.h schema_.c:schema.h search_.c:search.h setup_.c:setup.h sha1_.c:sha1.h shun_.c:shun.h skins_.c:skins.h sqlcmd_.c:sqlcmd.h stash_.c:stash.h stat_.c:stat.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tar_.c:tar.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktsetup_.c:tktsetup.h undo_.c:undo.h unicode_.c:unicode.h update_.c:update.h url_.c:url.h user_.c:user.h utf8_.c:utf8.h util_.c:util.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winhttp_.c:winhttp.h wysiwyg_.c:wysiwyg.h xfer_.c:xfer.h xfersetup_.c:xfersetup.h zip_.c:zip.h $(SRCDIR)\sqlite3.h $(SRCDIR)\th.h VERSION.h $(SRCDIR)\cson_amalgamation.h
759
+ +makeheaders$E add_.c:add.h allrepo_.c:allrepo.h attach_.c:attach.h bag_.c:bag.h bisect_.c:bisect.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h captcha_.c:captcha.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h configure_.c:configure.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendants_.c:descendants.h diff_.c:diff.h diffcmd_.c:diffcmd.h doc_.c:doc.h encode_.c:encode.h event_.c:event.h export_.c:export.h file_.c:file.h finfo_.c:finfo.h glob_.c:glob.h graph_.c:graph.h gzip_.c:gzip.h http_.c:http.h http_socket_.c:http_socket.h http_ssl_.c:http_ssl.h http_transport_.c:http_transport.h import_.c:import.h info_.c:info.h json_.c:json.h json_artifact_.c:json_artifact.h json_branch_.c:json_branch.h json_config_.c:json_config.h json_diff_.c:json_diff.h json_dir_.c:json_dir.h json_finfo_.c:json_finfo.h json_login_.c:json_login.h json_query_.c:json_query.h json_report_.c:json_report.h json_status_.c:json_status.h json_tag_.c:json_tag.h json_timeline_.c:json_timeline.h json_user_.c:json_user.h json_wiki_.c:json_wiki.h leaf_.c:leaf.h login_.c:login.h lookslike_.c:lookslike.h main_.c:main.h manifest_.c:manifest.h markdown_.c:markdown.h markdown_html_.c:markdown_html.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h moderate_.c:moderate.h name_.c:name.h path_.c:path.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h regexp_.c:regexp.h report_.c:report.h rss_.c:rss.h schema_.c:schema.h search_.c:search.h setup_.c:setup.h sha1_.c:sha1.h shun_.c:shun.h skins_.c:skins.h sqlcmd_.c:sqlcmd.h stash_.c:stash.h stat_.c:stat.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tar_.c:tar.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktsetup_.c:tktsetup.h undo_.c:undo.h unicode_.c:unicode.h update_.c:update.h url_.c:url.h user_.c:user.h utf8_.c:utf8.h util_.c:util.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winhttp_.c:winhttp.h wysiwyg_.c:wysiwyg.h xfer_.c:xfer.h xfersetup_.c:xfersetup.h zip_.c:zip.h $(SRCDIR)\sqlite3.h $(SRCDIR)\th.h VERSION.h $(SRCDIR)\cson_amalgamation.h
754760
@copy /Y nul: headers
755761
--- win/Makefile.dmc
+++ win/Makefile.dmc
@@ -26,13 +26,13 @@
26 TCC = $(DMDIR)\bin\dmc $(CFLAGS) $(DMCDEF) $(SSL) $(INCL)
27 LIBS = $(DMDIR)\extra\lib\ zlib wsock32 advapi32
28
29 SQLITE_OPTIONS = -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_STAT3 -Dlocaltime=fossil_localtime -DSQLITE_ENABLE_LOCKING_STYLE=0
30
31 SRC = add_.c allrepo_.c attach_.c bag_.c bisect_.c blob_.c branch_.c browse_.c captcha_.c cgi_.c checkin_.c checkout_.c clearsign_.c clone_.c comformat_.c configure_.c content_.c db_.c delta_.c deltacmd_.c descendants_.c diff_.c diffcmd_.c doc_.c encode_.c event_.c export_.c file_.c finfo_.c glob_.c graph_.c gzip_.c http_.c http_socket_.c http_ssl_.c http_transport_.c import_.c info_.c json_.c json_artifact_.c json_branch_.c json_config_.c json_diff_.c json_dir_.c json_finfo_.c json_login_.c json_query_.c json_report_.c json_status_.c json_tag_.c json_timeline_.c json_user_.c json_wiki_.c leaf_.c login_.c main_.c manifest_.c markdown_.c markdown_html_.c md5_.c merge_.c merge3_.c moderate_.c name_.c path_.c pivot_.c popen_.c pqueue_.c printf_.c rebuild_.c regexp_.c report_.c rss_.c schema_.c search_.c setup_.c sha1_.c shun_.c skins_.c sqlcmd_.c stash_.c stat_.c style_.c sync_.c tag_.c tar_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c unicode_.c update_.c url_.c user_.c utf8_.c util_.c verify_.c vfile_.c wiki_.c wikiformat_.c winhttp_.c wysiwyg_.c xfer_.c xfersetup_.c zip_.c
32
33 OBJ = $(OBJDIR)\add$O $(OBJDIR)\allrepo$O $(OBJDIR)\attach$O $(OBJDIR)\bag$O $(OBJDIR)\bisect$O $(OBJDIR)\blob$O $(OBJDIR)\branch$O $(OBJDIR)\browse$O $(OBJDIR)\captcha$O $(OBJDIR)\cgi$O $(OBJDIR)\checkin$O $(OBJDIR)\checkout$O $(OBJDIR)\clearsign$O $(OBJDIR)\clone$O $(OBJDIR)\comformat$O $(OBJDIR)\configure$O $(OBJDIR)\content$O $(OBJDIR)\db$O $(OBJDIR)\delta$O $(OBJDIR)\deltacmd$O $(OBJDIR)\descendants$O $(OBJDIR)\diff$O $(OBJDIR)\diffcmd$O $(OBJDIR)\doc$O $(OBJDIR)\encode$O $(OBJDIR)\event$O $(OBJDIR)\export$O $(OBJDIR)\file$O $(OBJDIR)\finfo$O $(OBJDIR)\glob$O $(OBJDIR)\graph$O $(OBJDIR)\gzip$O $(OBJDIR)\http$O $(OBJDIR)\http_socket$O $(OBJDIR)\http_ssl$O $(OBJDIR)\http_transport$O $(OBJDIR)\import$O $(OBJDIR)\info$O $(OBJDIR)\json$O $(OBJDIR)\json_artifact$O $(OBJDIR)\json_branch$O $(OBJDIR)\json_config$O $(OBJDIR)\json_diff$O $(OBJDIR)\json_dir$O $(OBJDIR)\json_finfo$O $(OBJDIR)\json_login$O $(OBJDIR)\json_query$O $(OBJDIR)\json_report$O $(OBJDIR)\json_status$O $(OBJDIR)\json_tag$O $(OBJDIR)\json_timeline$O $(OBJDIR)\json_user$O $(OBJDIR)\json_wiki$O $(OBJDIR)\leaf$O $(OBJDIR)\login$O $(OBJDIR)\main$O $(OBJDIR)\manifest$O $(OBJDIR)\markdown$O $(OBJDIR)\markdown_html$O $(OBJDIR)\md5$O $(OBJDIR)\merge$O $(OBJDIR)\merge3$O $(OBJDIR)\moderate$O $(OBJDIR)\name$O $(OBJDIR)\path$O $(OBJDIR)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$O $(OBJDIR)\rebuild$O $(OBJDIR)\regexp$O $(OBJDIR)\report$O $(OBJDIR)\rss$O $(OBJDIR)\schema$O $(OBJDIR)\search$O $(OBJDIR)\setup$O $(OBJDIR)\sha1$O $(OBJDIR)\shun$O $(OBJDIR)\skins$O $(OBJDIR)\sqlcmd$O $(OBJDIR)\stash$O $(OBJDIR)\stat$O $(OBJDIR)\style$O $(OBJDIR)\sync$O $(OBJDIR)\tag$O $(OBJDIR)\tar$O $(OBJDIR)\th_main$O $(OBJDIR)\timeline$O $(OBJDIR)\tkt$O $(OBJDIR)\tktsetup$O $(OBJDIR)\undo$O $(OBJDIR)\unicode$O $(OBJDIR)\update$O $(OBJDIR)\url$O $(OBJDIR)\user$O $(OBJDIR)\utf8$O $(OBJDIR)\util$O $(OBJDIR)\verify$O $(OBJDIR)\vfile$O $(OBJDIR)\wiki$O $(OBJDIR)\wikiformat$O $(OBJDIR)\winhttp$O $(OBJDIR)\wysiwyg$O $(OBJDIR)\xfer$O $(OBJDIR)\xfersetup$O $(OBJDIR)\zip$O $(OBJDIR)\shell$O $(OBJDIR)\sqlite3$O $(OBJDIR)\th$O $(OBJDIR)\th_lang$O
34
35
36 RC=$(DMDIR)\bin\rcc
37 RCFLAGS=-32 -w1 -I$(SRCDIR) /D__DMC__
38
@@ -46,11 +46,11 @@
46
47 $(OBJDIR)\fossil.res: $B\win\fossil.rc
48 $(RC) $(RCFLAGS) -o$@ $**
49
50 $(OBJDIR)\link: $B\win\Makefile.dmc $(OBJDIR)\fossil.res
51 +echo add allrepo attach bag bisect blob branch browse captcha cgi checkin checkout clearsign clone comformat configure content db delta deltacmd descendants diff diffcmd doc encode event export file finfo glob graph gzip http http_socket http_ssl http_transport import info json json_artifact json_branch json_config json_diff json_dir json_finfo json_login json_query json_report json_status json_tag json_timeline json_user json_wiki leaf login main manifest markdown markdown_html md5 merge merge3 moderate name path pivot popen pqueue printf rebuild regexp report rss schema search setup sha1 shun skins sqlcmd stash stat style sync tag tar th_main timeline tkt tktsetup undo unicode update url user utf8 util verify vfile wiki wikiformat winhttp wysiwyg xfer xfersetup zip shell sqlite3 th th_lang > $@
52 +echo fossil >> $@
53 +echo fossil >> $@
54 +echo $(LIBS) >> $@
55 +echo. >> $@
56 +echo fossil >> $@
@@ -440,10 +440,16 @@
440 $(OBJDIR)\login$O : login_.c login.h
441 $(TCC) -o$@ -c login_.c
442
443 login_.c : $(SRCDIR)\login.c
444 +translate$E $** > $@
 
 
 
 
 
 
445
446 $(OBJDIR)\main$O : main_.c main.h
447 $(TCC) -o$@ -c main_.c
448
449 main_.c : $(SRCDIR)\main.c
@@ -748,7 +754,7 @@
748
749 zip_.c : $(SRCDIR)\zip.c
750 +translate$E $** > $@
751
752 headers: makeheaders$E page_index.h VERSION.h
753 +makeheaders$E add_.c:add.h allrepo_.c:allrepo.h attach_.c:attach.h bag_.c:bag.h bisect_.c:bisect.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h captcha_.c:captcha.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h configure_.c:configure.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendants_.c:descendants.h diff_.c:diff.h diffcmd_.c:diffcmd.h doc_.c:doc.h encode_.c:encode.h event_.c:event.h export_.c:export.h file_.c:file.h finfo_.c:finfo.h glob_.c:glob.h graph_.c:graph.h gzip_.c:gzip.h http_.c:http.h http_socket_.c:http_socket.h http_ssl_.c:http_ssl.h http_transport_.c:http_transport.h import_.c:import.h info_.c:info.h json_.c:json.h json_artifact_.c:json_artifact.h json_branch_.c:json_branch.h json_config_.c:json_config.h json_diff_.c:json_diff.h json_dir_.c:json_dir.h json_finfo_.c:json_finfo.h json_login_.c:json_login.h json_query_.c:json_query.h json_report_.c:json_report.h json_status_.c:json_status.h json_tag_.c:json_tag.h json_timeline_.c:json_timeline.h json_user_.c:json_user.h json_wiki_.c:json_wiki.h leaf_.c:leaf.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h markdown_.c:markdown.h markdown_html_.c:markdown_html.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h moderate_.c:moderate.h name_.c:name.h path_.c:path.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h regexp_.c:regexp.h report_.c:report.h rss_.c:rss.h schema_.c:schema.h search_.c:search.h setup_.c:setup.h sha1_.c:sha1.h shun_.c:shun.h skins_.c:skins.h sqlcmd_.c:sqlcmd.h stash_.c:stash.h stat_.c:stat.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tar_.c:tar.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktsetup_.c:tktsetup.h undo_.c:undo.h unicode_.c:unicode.h update_.c:update.h url_.c:url.h user_.c:user.h utf8_.c:utf8.h util_.c:util.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winhttp_.c:winhttp.h wysiwyg_.c:wysiwyg.h xfer_.c:xfer.h xfersetup_.c:xfersetup.h zip_.c:zip.h $(SRCDIR)\sqlite3.h $(SRCDIR)\th.h VERSION.h $(SRCDIR)\cson_amalgamation.h
754 @copy /Y nul: headers
755
--- win/Makefile.dmc
+++ win/Makefile.dmc
@@ -26,13 +26,13 @@
26 TCC = $(DMDIR)\bin\dmc $(CFLAGS) $(DMCDEF) $(SSL) $(INCL)
27 LIBS = $(DMDIR)\extra\lib\ zlib wsock32 advapi32
28
29 SQLITE_OPTIONS = -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_STAT3 -Dlocaltime=fossil_localtime -DSQLITE_ENABLE_LOCKING_STYLE=0
30
31 SRC = add_.c allrepo_.c attach_.c bag_.c bisect_.c blob_.c branch_.c browse_.c captcha_.c cgi_.c checkin_.c checkout_.c clearsign_.c clone_.c comformat_.c configure_.c content_.c db_.c delta_.c deltacmd_.c descendants_.c diff_.c diffcmd_.c doc_.c encode_.c event_.c export_.c file_.c finfo_.c glob_.c graph_.c gzip_.c http_.c http_socket_.c http_ssl_.c http_transport_.c import_.c info_.c json_.c json_artifact_.c json_branch_.c json_config_.c json_diff_.c json_dir_.c json_finfo_.c json_login_.c json_query_.c json_report_.c json_status_.c json_tag_.c json_timeline_.c json_user_.c json_wiki_.c leaf_.c login_.c lookslike_.c main_.c manifest_.c markdown_.c markdown_html_.c md5_.c merge_.c merge3_.c moderate_.c name_.c path_.c pivot_.c popen_.c pqueue_.c printf_.c rebuild_.c regexp_.c report_.c rss_.c schema_.c search_.c setup_.c sha1_.c shun_.c skins_.c sqlcmd_.c stash_.c stat_.c style_.c sync_.c tag_.c tar_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c unicode_.c update_.c url_.c user_.c utf8_.c util_.c verify_.c vfile_.c wiki_.c wikiformat_.c winhttp_.c wysiwyg_.c xfer_.c xfersetup_.c zip_.c
32
33 OBJ = $(OBJDIR)\add$O $(OBJDIR)\allrepo$O $(OBJDIR)\attach$O $(OBJDIR)\bag$O $(OBJDIR)\bisect$O $(OBJDIR)\blob$O $(OBJDIR)\branch$O $(OBJDIR)\browse$O $(OBJDIR)\captcha$O $(OBJDIR)\cgi$O $(OBJDIR)\checkin$O $(OBJDIR)\checkout$O $(OBJDIR)\clearsign$O $(OBJDIR)\clone$O $(OBJDIR)\comformat$O $(OBJDIR)\configure$O $(OBJDIR)\content$O $(OBJDIR)\db$O $(OBJDIR)\delta$O $(OBJDIR)\deltacmd$O $(OBJDIR)\descendants$O $(OBJDIR)\diff$O $(OBJDIR)\diffcmd$O $(OBJDIR)\doc$O $(OBJDIR)\encode$O $(OBJDIR)\event$O $(OBJDIR)\export$O $(OBJDIR)\file$O $(OBJDIR)\finfo$O $(OBJDIR)\glob$O $(OBJDIR)\graph$O $(OBJDIR)\gzip$O $(OBJDIR)\http$O $(OBJDIR)\http_socket$O $(OBJDIR)\http_ssl$O $(OBJDIR)\http_transport$O $(OBJDIR)\import$O $(OBJDIR)\info$O $(OBJDIR)\json$O $(OBJDIR)\json_artifact$O $(OBJDIR)\json_branch$O $(OBJDIR)\json_config$O $(OBJDIR)\json_diff$O $(OBJDIR)\json_dir$O $(OBJDIR)\json_finfo$O $(OBJDIR)\json_login$O $(OBJDIR)\json_query$O $(OBJDIR)\json_report$O $(OBJDIR)\json_status$O $(OBJDIR)\json_tag$O $(OBJDIR)\json_timeline$O $(OBJDIR)\json_user$O $(OBJDIR)\json_wiki$O $(OBJDIR)\leaf$O $(OBJDIR)\login$O $(OBJDIR)\lookslike$O $(OBJDIR)\main$O $(OBJDIR)\manifest$O $(OBJDIR)\markdown$O $(OBJDIR)\markdown_html$O $(OBJDIR)\md5$O $(OBJDIR)\merge$O $(OBJDIR)\merge3$O $(OBJDIR)\moderate$O $(OBJDIR)\name$O $(OBJDIR)\path$O $(OBJDIR)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$O $(OBJDIR)\rebuild$O $(OBJDIR)\regexp$O $(OBJDIR)\report$O $(OBJDIR)\rss$O $(OBJDIR)\schema$O $(OBJDIR)\search$O $(OBJDIR)\setup$O $(OBJDIR)\sha1$O $(OBJDIR)\shun$O $(OBJDIR)\skins$O $(OBJDIR)\sqlcmd$O $(OBJDIR)\stash$O $(OBJDIR)\stat$O $(OBJDIR)\style$O $(OBJDIR)\sync$O $(OBJDIR)\tag$O $(OBJDIR)\tar$O $(OBJDIR)\th_main$O $(OBJDIR)\timeline$O $(OBJDIR)\tkt$O $(OBJDIR)\tktsetup$O $(OBJDIR)\undo$O $(OBJDIR)\unicode$O $(OBJDIR)\update$O $(OBJDIR)\url$O $(OBJDIR)\user$O $(OBJDIR)\utf8$O $(OBJDIR)\util$O $(OBJDIR)\verify$O $(OBJDIR)\vfile$O $(OBJDIR)\wiki$O $(OBJDIR)\wikiformat$O $(OBJDIR)\winhttp$O $(OBJDIR)\wysiwyg$O $(OBJDIR)\xfer$O $(OBJDIR)\xfersetup$O $(OBJDIR)\zip$O $(OBJDIR)\shell$O $(OBJDIR)\sqlite3$O $(OBJDIR)\th$O $(OBJDIR)\th_lang$O
34
35
36 RC=$(DMDIR)\bin\rcc
37 RCFLAGS=-32 -w1 -I$(SRCDIR) /D__DMC__
38
@@ -46,11 +46,11 @@
46
47 $(OBJDIR)\fossil.res: $B\win\fossil.rc
48 $(RC) $(RCFLAGS) -o$@ $**
49
50 $(OBJDIR)\link: $B\win\Makefile.dmc $(OBJDIR)\fossil.res
51 +echo add allrepo attach bag bisect blob branch browse captcha cgi checkin checkout clearsign clone comformat configure content db delta deltacmd descendants diff diffcmd doc encode event export file finfo glob graph gzip http http_socket http_ssl http_transport import info json json_artifact json_branch json_config json_diff json_dir json_finfo json_login json_query json_report json_status json_tag json_timeline json_user json_wiki leaf login lookslike main manifest markdown markdown_html md5 merge merge3 moderate name path pivot popen pqueue printf rebuild regexp report rss schema search setup sha1 shun skins sqlcmd stash stat style sync tag tar th_main timeline tkt tktsetup undo unicode update url user utf8 util verify vfile wiki wikiformat winhttp wysiwyg xfer xfersetup zip shell sqlite3 th th_lang > $@
52 +echo fossil >> $@
53 +echo fossil >> $@
54 +echo $(LIBS) >> $@
55 +echo. >> $@
56 +echo fossil >> $@
@@ -440,10 +440,16 @@
440 $(OBJDIR)\login$O : login_.c login.h
441 $(TCC) -o$@ -c login_.c
442
443 login_.c : $(SRCDIR)\login.c
444 +translate$E $** > $@
445
446 $(OBJDIR)\lookslike$O : lookslike_.c lookslike.h
447 $(TCC) -o$@ -c lookslike_.c
448
449 lookslike_.c : $(SRCDIR)\lookslike.c
450 +translate$E $** > $@
451
452 $(OBJDIR)\main$O : main_.c main.h
453 $(TCC) -o$@ -c main_.c
454
455 main_.c : $(SRCDIR)\main.c
@@ -748,7 +754,7 @@
754
755 zip_.c : $(SRCDIR)\zip.c
756 +translate$E $** > $@
757
758 headers: makeheaders$E page_index.h VERSION.h
759 +makeheaders$E add_.c:add.h allrepo_.c:allrepo.h attach_.c:attach.h bag_.c:bag.h bisect_.c:bisect.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h captcha_.c:captcha.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h configure_.c:configure.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendants_.c:descendants.h diff_.c:diff.h diffcmd_.c:diffcmd.h doc_.c:doc.h encode_.c:encode.h event_.c:event.h export_.c:export.h file_.c:file.h finfo_.c:finfo.h glob_.c:glob.h graph_.c:graph.h gzip_.c:gzip.h http_.c:http.h http_socket_.c:http_socket.h http_ssl_.c:http_ssl.h http_transport_.c:http_transport.h import_.c:import.h info_.c:info.h json_.c:json.h json_artifact_.c:json_artifact.h json_branch_.c:json_branch.h json_config_.c:json_config.h json_diff_.c:json_diff.h json_dir_.c:json_dir.h json_finfo_.c:json_finfo.h json_login_.c:json_login.h json_query_.c:json_query.h json_report_.c:json_report.h json_status_.c:json_status.h json_tag_.c:json_tag.h json_timeline_.c:json_timeline.h json_user_.c:json_user.h json_wiki_.c:json_wiki.h leaf_.c:leaf.h login_.c:login.h lookslike_.c:lookslike.h main_.c:main.h manifest_.c:manifest.h markdown_.c:markdown.h markdown_html_.c:markdown_html.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h moderate_.c:moderate.h name_.c:name.h path_.c:path.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h regexp_.c:regexp.h report_.c:report.h rss_.c:rss.h schema_.c:schema.h search_.c:search.h setup_.c:setup.h sha1_.c:sha1.h shun_.c:shun.h skins_.c:skins.h sqlcmd_.c:sqlcmd.h stash_.c:stash.h stat_.c:stat.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tar_.c:tar.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktsetup_.c:tktsetup.h undo_.c:undo.h unicode_.c:unicode.h update_.c:update.h url_.c:url.h user_.c:user.h utf8_.c:utf8.h util_.c:util.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winhttp_.c:winhttp.h wysiwyg_.c:wysiwyg.h xfer_.c:xfer.h xfersetup_.c:xfersetup.h zip_.c:zip.h $(SRCDIR)\sqlite3.h $(SRCDIR)\th.h VERSION.h $(SRCDIR)\cson_amalgamation.h
760 @copy /Y nul: headers
761
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -298,10 +298,11 @@
298298
$(SRCDIR)/json_timeline.c \
299299
$(SRCDIR)/json_user.c \
300300
$(SRCDIR)/json_wiki.c \
301301
$(SRCDIR)/leaf.c \
302302
$(SRCDIR)/login.c \
303
+ $(SRCDIR)/lookslike.c \
303304
$(SRCDIR)/main.c \
304305
$(SRCDIR)/manifest.c \
305306
$(SRCDIR)/markdown.c \
306307
$(SRCDIR)/markdown_html.c \
307308
$(SRCDIR)/md5.c \
@@ -406,10 +407,11 @@
406407
$(OBJDIR)/json_timeline_.c \
407408
$(OBJDIR)/json_user_.c \
408409
$(OBJDIR)/json_wiki_.c \
409410
$(OBJDIR)/leaf_.c \
410411
$(OBJDIR)/login_.c \
412
+ $(OBJDIR)/lookslike_.c \
411413
$(OBJDIR)/main_.c \
412414
$(OBJDIR)/manifest_.c \
413415
$(OBJDIR)/markdown_.c \
414416
$(OBJDIR)/markdown_html_.c \
415417
$(OBJDIR)/md5_.c \
@@ -514,10 +516,11 @@
514516
$(OBJDIR)/json_timeline.o \
515517
$(OBJDIR)/json_user.o \
516518
$(OBJDIR)/json_wiki.o \
517519
$(OBJDIR)/leaf.o \
518520
$(OBJDIR)/login.o \
521
+ $(OBJDIR)/lookslike.o \
519522
$(OBJDIR)/main.o \
520523
$(OBJDIR)/manifest.o \
521524
$(OBJDIR)/markdown.o \
522525
$(OBJDIR)/markdown_html.o \
523526
$(OBJDIR)/md5.o \
@@ -735,10 +738,11 @@
735738
$(OBJDIR)/json_timeline_.c:$(OBJDIR)/json_timeline.h \
736739
$(OBJDIR)/json_user_.c:$(OBJDIR)/json_user.h \
737740
$(OBJDIR)/json_wiki_.c:$(OBJDIR)/json_wiki.h \
738741
$(OBJDIR)/leaf_.c:$(OBJDIR)/leaf.h \
739742
$(OBJDIR)/login_.c:$(OBJDIR)/login.h \
743
+ $(OBJDIR)/lookslike_.c:$(OBJDIR)/lookslike.h \
740744
$(OBJDIR)/main_.c:$(OBJDIR)/main.h \
741745
$(OBJDIR)/manifest_.c:$(OBJDIR)/manifest.h \
742746
$(OBJDIR)/markdown_.c:$(OBJDIR)/markdown.h \
743747
$(OBJDIR)/markdown_html_.c:$(OBJDIR)/markdown_html.h \
744748
$(OBJDIR)/md5_.c:$(OBJDIR)/md5.h \
@@ -1234,10 +1238,18 @@
12341238
12351239
$(OBJDIR)/login.o: $(OBJDIR)/login_.c $(OBJDIR)/login.h $(SRCDIR)/config.h
12361240
$(XTCC) -o $(OBJDIR)/login.o -c $(OBJDIR)/login_.c
12371241
12381242
$(OBJDIR)/login.h: $(OBJDIR)/headers
1243
+
1244
+$(OBJDIR)/lookslike_.c: $(SRCDIR)/lookslike.c $(OBJDIR)/translate
1245
+ $(TRANSLATE) $(SRCDIR)/lookslike.c >$(OBJDIR)/lookslike_.c
1246
+
1247
+$(OBJDIR)/lookslike.o: $(OBJDIR)/lookslike_.c $(OBJDIR)/lookslike.h $(SRCDIR)/config.h
1248
+ $(XTCC) -o $(OBJDIR)/lookslike.o -c $(OBJDIR)/lookslike_.c
1249
+
1250
+$(OBJDIR)/lookslike.h: $(OBJDIR)/headers
12391251
12401252
$(OBJDIR)/main_.c: $(SRCDIR)/main.c $(OBJDIR)/translate
12411253
$(TRANSLATE) $(SRCDIR)/main.c >$(OBJDIR)/main_.c
12421254
12431255
$(OBJDIR)/main.o: $(OBJDIR)/main_.c $(OBJDIR)/main.h $(OBJDIR)/page_index.h $(SRCDIR)/config.h
12441256
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -298,10 +298,11 @@
298 $(SRCDIR)/json_timeline.c \
299 $(SRCDIR)/json_user.c \
300 $(SRCDIR)/json_wiki.c \
301 $(SRCDIR)/leaf.c \
302 $(SRCDIR)/login.c \
 
303 $(SRCDIR)/main.c \
304 $(SRCDIR)/manifest.c \
305 $(SRCDIR)/markdown.c \
306 $(SRCDIR)/markdown_html.c \
307 $(SRCDIR)/md5.c \
@@ -406,10 +407,11 @@
406 $(OBJDIR)/json_timeline_.c \
407 $(OBJDIR)/json_user_.c \
408 $(OBJDIR)/json_wiki_.c \
409 $(OBJDIR)/leaf_.c \
410 $(OBJDIR)/login_.c \
 
411 $(OBJDIR)/main_.c \
412 $(OBJDIR)/manifest_.c \
413 $(OBJDIR)/markdown_.c \
414 $(OBJDIR)/markdown_html_.c \
415 $(OBJDIR)/md5_.c \
@@ -514,10 +516,11 @@
514 $(OBJDIR)/json_timeline.o \
515 $(OBJDIR)/json_user.o \
516 $(OBJDIR)/json_wiki.o \
517 $(OBJDIR)/leaf.o \
518 $(OBJDIR)/login.o \
 
519 $(OBJDIR)/main.o \
520 $(OBJDIR)/manifest.o \
521 $(OBJDIR)/markdown.o \
522 $(OBJDIR)/markdown_html.o \
523 $(OBJDIR)/md5.o \
@@ -735,10 +738,11 @@
735 $(OBJDIR)/json_timeline_.c:$(OBJDIR)/json_timeline.h \
736 $(OBJDIR)/json_user_.c:$(OBJDIR)/json_user.h \
737 $(OBJDIR)/json_wiki_.c:$(OBJDIR)/json_wiki.h \
738 $(OBJDIR)/leaf_.c:$(OBJDIR)/leaf.h \
739 $(OBJDIR)/login_.c:$(OBJDIR)/login.h \
 
740 $(OBJDIR)/main_.c:$(OBJDIR)/main.h \
741 $(OBJDIR)/manifest_.c:$(OBJDIR)/manifest.h \
742 $(OBJDIR)/markdown_.c:$(OBJDIR)/markdown.h \
743 $(OBJDIR)/markdown_html_.c:$(OBJDIR)/markdown_html.h \
744 $(OBJDIR)/md5_.c:$(OBJDIR)/md5.h \
@@ -1234,10 +1238,18 @@
1234
1235 $(OBJDIR)/login.o: $(OBJDIR)/login_.c $(OBJDIR)/login.h $(SRCDIR)/config.h
1236 $(XTCC) -o $(OBJDIR)/login.o -c $(OBJDIR)/login_.c
1237
1238 $(OBJDIR)/login.h: $(OBJDIR)/headers
 
 
 
 
 
 
 
 
1239
1240 $(OBJDIR)/main_.c: $(SRCDIR)/main.c $(OBJDIR)/translate
1241 $(TRANSLATE) $(SRCDIR)/main.c >$(OBJDIR)/main_.c
1242
1243 $(OBJDIR)/main.o: $(OBJDIR)/main_.c $(OBJDIR)/main.h $(OBJDIR)/page_index.h $(SRCDIR)/config.h
1244
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -298,10 +298,11 @@
298 $(SRCDIR)/json_timeline.c \
299 $(SRCDIR)/json_user.c \
300 $(SRCDIR)/json_wiki.c \
301 $(SRCDIR)/leaf.c \
302 $(SRCDIR)/login.c \
303 $(SRCDIR)/lookslike.c \
304 $(SRCDIR)/main.c \
305 $(SRCDIR)/manifest.c \
306 $(SRCDIR)/markdown.c \
307 $(SRCDIR)/markdown_html.c \
308 $(SRCDIR)/md5.c \
@@ -406,10 +407,11 @@
407 $(OBJDIR)/json_timeline_.c \
408 $(OBJDIR)/json_user_.c \
409 $(OBJDIR)/json_wiki_.c \
410 $(OBJDIR)/leaf_.c \
411 $(OBJDIR)/login_.c \
412 $(OBJDIR)/lookslike_.c \
413 $(OBJDIR)/main_.c \
414 $(OBJDIR)/manifest_.c \
415 $(OBJDIR)/markdown_.c \
416 $(OBJDIR)/markdown_html_.c \
417 $(OBJDIR)/md5_.c \
@@ -514,10 +516,11 @@
516 $(OBJDIR)/json_timeline.o \
517 $(OBJDIR)/json_user.o \
518 $(OBJDIR)/json_wiki.o \
519 $(OBJDIR)/leaf.o \
520 $(OBJDIR)/login.o \
521 $(OBJDIR)/lookslike.o \
522 $(OBJDIR)/main.o \
523 $(OBJDIR)/manifest.o \
524 $(OBJDIR)/markdown.o \
525 $(OBJDIR)/markdown_html.o \
526 $(OBJDIR)/md5.o \
@@ -735,10 +738,11 @@
738 $(OBJDIR)/json_timeline_.c:$(OBJDIR)/json_timeline.h \
739 $(OBJDIR)/json_user_.c:$(OBJDIR)/json_user.h \
740 $(OBJDIR)/json_wiki_.c:$(OBJDIR)/json_wiki.h \
741 $(OBJDIR)/leaf_.c:$(OBJDIR)/leaf.h \
742 $(OBJDIR)/login_.c:$(OBJDIR)/login.h \
743 $(OBJDIR)/lookslike_.c:$(OBJDIR)/lookslike.h \
744 $(OBJDIR)/main_.c:$(OBJDIR)/main.h \
745 $(OBJDIR)/manifest_.c:$(OBJDIR)/manifest.h \
746 $(OBJDIR)/markdown_.c:$(OBJDIR)/markdown.h \
747 $(OBJDIR)/markdown_html_.c:$(OBJDIR)/markdown_html.h \
748 $(OBJDIR)/md5_.c:$(OBJDIR)/md5.h \
@@ -1234,10 +1238,18 @@
1238
1239 $(OBJDIR)/login.o: $(OBJDIR)/login_.c $(OBJDIR)/login.h $(SRCDIR)/config.h
1240 $(XTCC) -o $(OBJDIR)/login.o -c $(OBJDIR)/login_.c
1241
1242 $(OBJDIR)/login.h: $(OBJDIR)/headers
1243
1244 $(OBJDIR)/lookslike_.c: $(SRCDIR)/lookslike.c $(OBJDIR)/translate
1245 $(TRANSLATE) $(SRCDIR)/lookslike.c >$(OBJDIR)/lookslike_.c
1246
1247 $(OBJDIR)/lookslike.o: $(OBJDIR)/lookslike_.c $(OBJDIR)/lookslike.h $(SRCDIR)/config.h
1248 $(XTCC) -o $(OBJDIR)/lookslike.o -c $(OBJDIR)/lookslike_.c
1249
1250 $(OBJDIR)/lookslike.h: $(OBJDIR)/headers
1251
1252 $(OBJDIR)/main_.c: $(SRCDIR)/main.c $(OBJDIR)/translate
1253 $(TRANSLATE) $(SRCDIR)/main.c >$(OBJDIR)/main_.c
1254
1255 $(OBJDIR)/main.o: $(OBJDIR)/main_.c $(OBJDIR)/main.h $(OBJDIR)/page_index.h $(SRCDIR)/config.h
1256
--- win/Makefile.msc
+++ win/Makefile.msc
@@ -116,10 +116,11 @@
116116
json_timeline_.c \
117117
json_user_.c \
118118
json_wiki_.c \
119119
leaf_.c \
120120
login_.c \
121
+ lookslike_.c \
121122
main_.c \
122123
manifest_.c \
123124
markdown_.c \
124125
markdown_html_.c \
125126
md5_.c \
@@ -224,10 +225,11 @@
224225
$(OX)\json_timeline$O \
225226
$(OX)\json_user$O \
226227
$(OX)\json_wiki$O \
227228
$(OX)\leaf$O \
228229
$(OX)\login$O \
230
+ $(OX)\lookslike$O \
229231
$(OX)\main$O \
230232
$(OX)\manifest$O \
231233
$(OX)\markdown$O \
232234
$(OX)\markdown_html$O \
233235
$(OX)\md5$O \
@@ -350,10 +352,11 @@
350352
echo $(OX)\json_timeline.obj >> $@
351353
echo $(OX)\json_user.obj >> $@
352354
echo $(OX)\json_wiki.obj >> $@
353355
echo $(OX)\leaf.obj >> $@
354356
echo $(OX)\login.obj >> $@
357
+ echo $(OX)\lookslike.obj >> $@
355358
echo $(OX)\main.obj >> $@
356359
echo $(OX)\manifest.obj >> $@
357360
echo $(OX)\markdown.obj >> $@
358361
echo $(OX)\markdown_html.obj >> $@
359362
echo $(OX)\md5.obj >> $@
@@ -809,10 +812,16 @@
809812
$(OX)\login$O : login_.c login.h
810813
$(TCC) /Fo$@ -c login_.c
811814
812815
login_.c : $(SRCDIR)\login.c
813816
translate$E $** > $@
817
+
818
+$(OX)\lookslike$O : lookslike_.c lookslike.h
819
+ $(TCC) /Fo$@ -c lookslike_.c
820
+
821
+lookslike_.c : $(SRCDIR)\lookslike.c
822
+ translate$E $** > $@
814823
815824
$(OX)\main$O : main_.c main.h
816825
$(TCC) /Fo$@ -c main_.c
817826
818827
main_.c : $(SRCDIR)\main.c
@@ -1174,10 +1183,11 @@
11741183
json_timeline_.c:json_timeline.h \
11751184
json_user_.c:json_user.h \
11761185
json_wiki_.c:json_wiki.h \
11771186
leaf_.c:leaf.h \
11781187
login_.c:login.h \
1188
+ lookslike_.c:lookslike.h \
11791189
main_.c:main.h \
11801190
manifest_.c:manifest.h \
11811191
markdown_.c:markdown.h \
11821192
markdown_html_.c:markdown_html.h \
11831193
md5_.c:md5.h \
11841194
--- win/Makefile.msc
+++ win/Makefile.msc
@@ -116,10 +116,11 @@
116 json_timeline_.c \
117 json_user_.c \
118 json_wiki_.c \
119 leaf_.c \
120 login_.c \
 
121 main_.c \
122 manifest_.c \
123 markdown_.c \
124 markdown_html_.c \
125 md5_.c \
@@ -224,10 +225,11 @@
224 $(OX)\json_timeline$O \
225 $(OX)\json_user$O \
226 $(OX)\json_wiki$O \
227 $(OX)\leaf$O \
228 $(OX)\login$O \
 
229 $(OX)\main$O \
230 $(OX)\manifest$O \
231 $(OX)\markdown$O \
232 $(OX)\markdown_html$O \
233 $(OX)\md5$O \
@@ -350,10 +352,11 @@
350 echo $(OX)\json_timeline.obj >> $@
351 echo $(OX)\json_user.obj >> $@
352 echo $(OX)\json_wiki.obj >> $@
353 echo $(OX)\leaf.obj >> $@
354 echo $(OX)\login.obj >> $@
 
355 echo $(OX)\main.obj >> $@
356 echo $(OX)\manifest.obj >> $@
357 echo $(OX)\markdown.obj >> $@
358 echo $(OX)\markdown_html.obj >> $@
359 echo $(OX)\md5.obj >> $@
@@ -809,10 +812,16 @@
809 $(OX)\login$O : login_.c login.h
810 $(TCC) /Fo$@ -c login_.c
811
812 login_.c : $(SRCDIR)\login.c
813 translate$E $** > $@
 
 
 
 
 
 
814
815 $(OX)\main$O : main_.c main.h
816 $(TCC) /Fo$@ -c main_.c
817
818 main_.c : $(SRCDIR)\main.c
@@ -1174,10 +1183,11 @@
1174 json_timeline_.c:json_timeline.h \
1175 json_user_.c:json_user.h \
1176 json_wiki_.c:json_wiki.h \
1177 leaf_.c:leaf.h \
1178 login_.c:login.h \
 
1179 main_.c:main.h \
1180 manifest_.c:manifest.h \
1181 markdown_.c:markdown.h \
1182 markdown_html_.c:markdown_html.h \
1183 md5_.c:md5.h \
1184
--- win/Makefile.msc
+++ win/Makefile.msc
@@ -116,10 +116,11 @@
116 json_timeline_.c \
117 json_user_.c \
118 json_wiki_.c \
119 leaf_.c \
120 login_.c \
121 lookslike_.c \
122 main_.c \
123 manifest_.c \
124 markdown_.c \
125 markdown_html_.c \
126 md5_.c \
@@ -224,10 +225,11 @@
225 $(OX)\json_timeline$O \
226 $(OX)\json_user$O \
227 $(OX)\json_wiki$O \
228 $(OX)\leaf$O \
229 $(OX)\login$O \
230 $(OX)\lookslike$O \
231 $(OX)\main$O \
232 $(OX)\manifest$O \
233 $(OX)\markdown$O \
234 $(OX)\markdown_html$O \
235 $(OX)\md5$O \
@@ -350,10 +352,11 @@
352 echo $(OX)\json_timeline.obj >> $@
353 echo $(OX)\json_user.obj >> $@
354 echo $(OX)\json_wiki.obj >> $@
355 echo $(OX)\leaf.obj >> $@
356 echo $(OX)\login.obj >> $@
357 echo $(OX)\lookslike.obj >> $@
358 echo $(OX)\main.obj >> $@
359 echo $(OX)\manifest.obj >> $@
360 echo $(OX)\markdown.obj >> $@
361 echo $(OX)\markdown_html.obj >> $@
362 echo $(OX)\md5.obj >> $@
@@ -809,10 +812,16 @@
812 $(OX)\login$O : login_.c login.h
813 $(TCC) /Fo$@ -c login_.c
814
815 login_.c : $(SRCDIR)\login.c
816 translate$E $** > $@
817
818 $(OX)\lookslike$O : lookslike_.c lookslike.h
819 $(TCC) /Fo$@ -c lookslike_.c
820
821 lookslike_.c : $(SRCDIR)\lookslike.c
822 translate$E $** > $@
823
824 $(OX)\main$O : main_.c main.h
825 $(TCC) /Fo$@ -c main_.c
826
827 main_.c : $(SRCDIR)\main.c
@@ -1174,10 +1183,11 @@
1183 json_timeline_.c:json_timeline.h \
1184 json_user_.c:json_user.h \
1185 json_wiki_.c:json_wiki.h \
1186 leaf_.c:leaf.h \
1187 login_.c:login.h \
1188 lookslike_.c:lookslike.h \
1189 main_.c:main.h \
1190 manifest_.c:manifest.h \
1191 markdown_.c:markdown.h \
1192 markdown_html_.c:markdown_html.h \
1193 md5_.c:md5.h \
1194

Keyboard Shortcuts

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