Fossil SCM

Allow unicode files for Wiki-rendering on Windows. <p>Trying to commit a file with an UTF-16 BOM will now give a warning, just as a file containing crlf

jan.nijtmans 2012-10-29 14:45 trunk merge
Commit 70b4f105ebaab44c807092d06c74943768c00391
+19 -8
--- src/checkin.c
+++ src/checkin.c
@@ -882,35 +882,46 @@
882882
if( pnFBcard ) *pnFBcard = nFBcard;
883883
}
884884
885885
/*
886886
** Issue a warning and give the user an opportunity to abandon out
887
-** if a \r\n line ending is seen in a text file.
887
+** if unicode or a \r\n line ending is seen in a text file.
888888
*/
889
-static void cr_warning(const Blob *p, const char *zFilename){
889
+static void encoding_warning(const Blob *p, int crnlOk, const char *zFilename){
890
+ int looksLike; /* return value of looks_like_text() */
890891
char *zMsg; /* Warning message */
891892
Blob fname; /* Relative pathname of the file */
892893
static int allOk = 0; /* Set to true to disable this routine */
893894
894895
if( allOk ) return;
895
- if( looks_like_text(p)<0 ){
896
+ looksLike = looks_like_text(p);
897
+ if( looksLike<0 ){
898
+ const char *type;
896899
Blob ans;
897900
char cReply;
898901
902
+ if( looksLike&1 ){
903
+ if( crnlOk ){
904
+ return; /* We don't want CrLf warnings for this file. */
905
+ }
906
+ type = "CR/NL line endings";
907
+ }else{
908
+ type = "unicode";
909
+ }
899910
file_relative_name(zFilename, &fname, 0);
900911
blob_zero(&ans);
901912
zMsg = mprintf(
902
- "%s contains CR/NL line endings; commit anyhow (a=all/y/N)?",
903
- blob_str(&fname));
913
+ "%s contains %s; commit anyhow (a=all/y/N)?",
914
+ blob_str(&fname), type);
904915
prompt_user(zMsg, &ans);
905916
fossil_free(zMsg);
906917
cReply = blob_str(&ans)[0];
907918
if( cReply=='a' || cReply=='A' ){
908919
allOk = 1;
909920
}else if( cReply!='y' && cReply!='Y' ){
910
- fossil_fatal("Abandoning commit due to CR/NL line endings in %s",
911
- blob_str(&fname));
921
+ fossil_fatal("Abandoning commit due to %s in %s",
922
+ type, blob_str(&fname));
912923
}
913924
blob_reset(&ans);
914925
blob_reset(&fname);
915926
}
916927
}
@@ -1221,11 +1232,11 @@
12211232
/* Instead of file content, put link destination path */
12221233
blob_read_link(&content, zFullname);
12231234
}else{
12241235
blob_read_from_file(&content, zFullname);
12251236
}
1226
- if( !crnlOk ) cr_warning(&content, zFullname);
1237
+ encoding_warning(&content, crnlOk, zFullname);
12271238
if( chnged==1 && contains_merge_marker(&content) ){
12281239
Blob fname; /* Relative pathname of the file */
12291240
12301241
nConflict++;
12311242
file_relative_name(zFullname, &fname, 0);
12321243
--- src/checkin.c
+++ src/checkin.c
@@ -882,35 +882,46 @@
882 if( pnFBcard ) *pnFBcard = nFBcard;
883 }
884
885 /*
886 ** Issue a warning and give the user an opportunity to abandon out
887 ** if a \r\n line ending is seen in a text file.
888 */
889 static void cr_warning(const Blob *p, const char *zFilename){
 
890 char *zMsg; /* Warning message */
891 Blob fname; /* Relative pathname of the file */
892 static int allOk = 0; /* Set to true to disable this routine */
893
894 if( allOk ) return;
895 if( looks_like_text(p)<0 ){
 
 
896 Blob ans;
897 char cReply;
898
 
 
 
 
 
 
 
 
899 file_relative_name(zFilename, &fname, 0);
900 blob_zero(&ans);
901 zMsg = mprintf(
902 "%s contains CR/NL line endings; commit anyhow (a=all/y/N)?",
903 blob_str(&fname));
904 prompt_user(zMsg, &ans);
905 fossil_free(zMsg);
906 cReply = blob_str(&ans)[0];
907 if( cReply=='a' || cReply=='A' ){
908 allOk = 1;
909 }else if( cReply!='y' && cReply!='Y' ){
910 fossil_fatal("Abandoning commit due to CR/NL line endings in %s",
911 blob_str(&fname));
912 }
913 blob_reset(&ans);
914 blob_reset(&fname);
915 }
916 }
@@ -1221,11 +1232,11 @@
1221 /* Instead of file content, put link destination path */
1222 blob_read_link(&content, zFullname);
1223 }else{
1224 blob_read_from_file(&content, zFullname);
1225 }
1226 if( !crnlOk ) cr_warning(&content, zFullname);
1227 if( chnged==1 && contains_merge_marker(&content) ){
1228 Blob fname; /* Relative pathname of the file */
1229
1230 nConflict++;
1231 file_relative_name(zFullname, &fname, 0);
1232
--- src/checkin.c
+++ src/checkin.c
@@ -882,35 +882,46 @@
882 if( pnFBcard ) *pnFBcard = nFBcard;
883 }
884
885 /*
886 ** Issue a warning and give the user an opportunity to abandon out
887 ** if unicode or a \r\n line ending is seen in a text file.
888 */
889 static void encoding_warning(const Blob *p, int crnlOk, const char *zFilename){
890 int looksLike; /* return value of looks_like_text() */
891 char *zMsg; /* Warning message */
892 Blob fname; /* Relative pathname of the file */
893 static int allOk = 0; /* Set to true to disable this routine */
894
895 if( allOk ) return;
896 looksLike = looks_like_text(p);
897 if( looksLike<0 ){
898 const char *type;
899 Blob ans;
900 char cReply;
901
902 if( looksLike&1 ){
903 if( crnlOk ){
904 return; /* We don't want CrLf warnings for this file. */
905 }
906 type = "CR/NL line endings";
907 }else{
908 type = "unicode";
909 }
910 file_relative_name(zFilename, &fname, 0);
911 blob_zero(&ans);
912 zMsg = mprintf(
913 "%s contains %s; commit anyhow (a=all/y/N)?",
914 blob_str(&fname), type);
915 prompt_user(zMsg, &ans);
916 fossil_free(zMsg);
917 cReply = blob_str(&ans)[0];
918 if( cReply=='a' || cReply=='A' ){
919 allOk = 1;
920 }else if( cReply!='y' && cReply!='Y' ){
921 fossil_fatal("Abandoning commit due to %s in %s",
922 type, blob_str(&fname));
923 }
924 blob_reset(&ans);
925 blob_reset(&fname);
926 }
927 }
@@ -1221,11 +1232,11 @@
1232 /* Instead of file content, put link destination path */
1233 blob_read_link(&content, zFullname);
1234 }else{
1235 blob_read_from_file(&content, zFullname);
1236 }
1237 encoding_warning(&content, crnlOk, zFullname);
1238 if( chnged==1 && contains_merge_marker(&content) ){
1239 Blob fname; /* Relative pathname of the file */
1240
1241 nConflict++;
1242 file_relative_name(zFullname, &fname, 0);
1243
+19 -8
--- src/checkin.c
+++ src/checkin.c
@@ -882,35 +882,46 @@
882882
if( pnFBcard ) *pnFBcard = nFBcard;
883883
}
884884
885885
/*
886886
** Issue a warning and give the user an opportunity to abandon out
887
-** if a \r\n line ending is seen in a text file.
887
+** if unicode or a \r\n line ending is seen in a text file.
888888
*/
889
-static void cr_warning(const Blob *p, const char *zFilename){
889
+static void encoding_warning(const Blob *p, int crnlOk, const char *zFilename){
890
+ int looksLike; /* return value of looks_like_text() */
890891
char *zMsg; /* Warning message */
891892
Blob fname; /* Relative pathname of the file */
892893
static int allOk = 0; /* Set to true to disable this routine */
893894
894895
if( allOk ) return;
895
- if( looks_like_text(p)<0 ){
896
+ looksLike = looks_like_text(p);
897
+ if( looksLike<0 ){
898
+ const char *type;
896899
Blob ans;
897900
char cReply;
898901
902
+ if( looksLike&1 ){
903
+ if( crnlOk ){
904
+ return; /* We don't want CrLf warnings for this file. */
905
+ }
906
+ type = "CR/NL line endings";
907
+ }else{
908
+ type = "unicode";
909
+ }
899910
file_relative_name(zFilename, &fname, 0);
900911
blob_zero(&ans);
901912
zMsg = mprintf(
902
- "%s contains CR/NL line endings; commit anyhow (a=all/y/N)?",
903
- blob_str(&fname));
913
+ "%s contains %s; commit anyhow (a=all/y/N)?",
914
+ blob_str(&fname), type);
904915
prompt_user(zMsg, &ans);
905916
fossil_free(zMsg);
906917
cReply = blob_str(&ans)[0];
907918
if( cReply=='a' || cReply=='A' ){
908919
allOk = 1;
909920
}else if( cReply!='y' && cReply!='Y' ){
910
- fossil_fatal("Abandoning commit due to CR/NL line endings in %s",
911
- blob_str(&fname));
921
+ fossil_fatal("Abandoning commit due to %s in %s",
922
+ type, blob_str(&fname));
912923
}
913924
blob_reset(&ans);
914925
blob_reset(&fname);
915926
}
916927
}
@@ -1221,11 +1232,11 @@
12211232
/* Instead of file content, put link destination path */
12221233
blob_read_link(&content, zFullname);
12231234
}else{
12241235
blob_read_from_file(&content, zFullname);
12251236
}
1226
- if( !crnlOk ) cr_warning(&content, zFullname);
1237
+ encoding_warning(&content, crnlOk, zFullname);
12271238
if( chnged==1 && contains_merge_marker(&content) ){
12281239
Blob fname; /* Relative pathname of the file */
12291240
12301241
nConflict++;
12311242
file_relative_name(zFullname, &fname, 0);
12321243
--- src/checkin.c
+++ src/checkin.c
@@ -882,35 +882,46 @@
882 if( pnFBcard ) *pnFBcard = nFBcard;
883 }
884
885 /*
886 ** Issue a warning and give the user an opportunity to abandon out
887 ** if a \r\n line ending is seen in a text file.
888 */
889 static void cr_warning(const Blob *p, const char *zFilename){
 
890 char *zMsg; /* Warning message */
891 Blob fname; /* Relative pathname of the file */
892 static int allOk = 0; /* Set to true to disable this routine */
893
894 if( allOk ) return;
895 if( looks_like_text(p)<0 ){
 
 
896 Blob ans;
897 char cReply;
898
 
 
 
 
 
 
 
 
899 file_relative_name(zFilename, &fname, 0);
900 blob_zero(&ans);
901 zMsg = mprintf(
902 "%s contains CR/NL line endings; commit anyhow (a=all/y/N)?",
903 blob_str(&fname));
904 prompt_user(zMsg, &ans);
905 fossil_free(zMsg);
906 cReply = blob_str(&ans)[0];
907 if( cReply=='a' || cReply=='A' ){
908 allOk = 1;
909 }else if( cReply!='y' && cReply!='Y' ){
910 fossil_fatal("Abandoning commit due to CR/NL line endings in %s",
911 blob_str(&fname));
912 }
913 blob_reset(&ans);
914 blob_reset(&fname);
915 }
916 }
@@ -1221,11 +1232,11 @@
1221 /* Instead of file content, put link destination path */
1222 blob_read_link(&content, zFullname);
1223 }else{
1224 blob_read_from_file(&content, zFullname);
1225 }
1226 if( !crnlOk ) cr_warning(&content, zFullname);
1227 if( chnged==1 && contains_merge_marker(&content) ){
1228 Blob fname; /* Relative pathname of the file */
1229
1230 nConflict++;
1231 file_relative_name(zFullname, &fname, 0);
1232
--- src/checkin.c
+++ src/checkin.c
@@ -882,35 +882,46 @@
882 if( pnFBcard ) *pnFBcard = nFBcard;
883 }
884
885 /*
886 ** Issue a warning and give the user an opportunity to abandon out
887 ** if unicode or a \r\n line ending is seen in a text file.
888 */
889 static void encoding_warning(const Blob *p, int crnlOk, const char *zFilename){
890 int looksLike; /* return value of looks_like_text() */
891 char *zMsg; /* Warning message */
892 Blob fname; /* Relative pathname of the file */
893 static int allOk = 0; /* Set to true to disable this routine */
894
895 if( allOk ) return;
896 looksLike = looks_like_text(p);
897 if( looksLike<0 ){
898 const char *type;
899 Blob ans;
900 char cReply;
901
902 if( looksLike&1 ){
903 if( crnlOk ){
904 return; /* We don't want CrLf warnings for this file. */
905 }
906 type = "CR/NL line endings";
907 }else{
908 type = "unicode";
909 }
910 file_relative_name(zFilename, &fname, 0);
911 blob_zero(&ans);
912 zMsg = mprintf(
913 "%s contains %s; commit anyhow (a=all/y/N)?",
914 blob_str(&fname), type);
915 prompt_user(zMsg, &ans);
916 fossil_free(zMsg);
917 cReply = blob_str(&ans)[0];
918 if( cReply=='a' || cReply=='A' ){
919 allOk = 1;
920 }else if( cReply!='y' && cReply!='Y' ){
921 fossil_fatal("Abandoning commit due to %s in %s",
922 type, blob_str(&fname));
923 }
924 blob_reset(&ans);
925 blob_reset(&fname);
926 }
927 }
@@ -1221,11 +1232,11 @@
1232 /* Instead of file content, put link destination path */
1233 blob_read_link(&content, zFullname);
1234 }else{
1235 blob_read_from_file(&content, zFullname);
1236 }
1237 encoding_warning(&content, crnlOk, zFullname);
1238 if( chnged==1 && contains_merge_marker(&content) ){
1239 Blob fname; /* Relative pathname of the file */
1240
1241 nConflict++;
1242 file_relative_name(zFullname, &fname, 0);
1243
+10 -2
--- src/diff.c
+++ src/diff.c
@@ -48,11 +48,11 @@
4848
"cannot compute difference between binary files\n"
4949
5050
#define DIFF_CANNOT_COMPUTE_SYMLINK \
5151
"cannot compute difference between symlink and regular file\n"
5252
53
-#define looks_like_binary(blob) (looks_like_text((blob)) == 0)
53
+#define looks_like_binary(blob) ((looks_like_text(blob)&1) == 0)
5454
#endif /* INTERFACE */
5555
5656
/*
5757
** Maximum length of a line in a text file. (8192)
5858
*/
@@ -170,14 +170,15 @@
170170
*pnLine = nLine;
171171
return a;
172172
}
173173
174174
/*
175
-** Returns 1, if the file appears text, and does not contain CrLf
175
+** Returns 1, if everything OK
176176
** Returns 0 if the specified content appears to be binary or
177177
** contains a line that is too long
178178
** Returns -1, if the file appears text, but it contains CrLf
179
+** Returns -2, if the file starts with an UTF-16 BOM (le or be)
179180
*/
180181
int looks_like_text(const Blob *pContent){
181182
const char *z = blob_buffer(pContent);
182183
unsigned int n = blob_size(pContent);
183184
int j, c;
@@ -186,10 +187,17 @@
186187
/* Check individual lines.
187188
*/
188189
if( n==0 ) return result; /* Empty file -> text */
189190
c = *z;
190191
if( c==0 ) return 0; /* \000 byte in a file -> binary */
192
+ if ( n > 1 ){
193
+ if ( (c==(char)0xff) && (z[1]==(char)0xfe) ){
194
+ return -2;
195
+ } else if ( (c==(char)0xfe) && (z[1]==(char)0xff) ){
196
+ return -2;
197
+ }
198
+ }
191199
j = (c!='\n');
192200
while( --n>0 ){
193201
c = *++z; ++j;
194202
if( c==0 ) return 0; /* \000 byte in a file -> binary */
195203
if( c=='\n' ){
196204
--- src/diff.c
+++ src/diff.c
@@ -48,11 +48,11 @@
48 "cannot compute difference between binary files\n"
49
50 #define DIFF_CANNOT_COMPUTE_SYMLINK \
51 "cannot compute difference between symlink and regular file\n"
52
53 #define looks_like_binary(blob) (looks_like_text((blob)) == 0)
54 #endif /* INTERFACE */
55
56 /*
57 ** Maximum length of a line in a text file. (8192)
58 */
@@ -170,14 +170,15 @@
170 *pnLine = nLine;
171 return a;
172 }
173
174 /*
175 ** Returns 1, if the file appears text, and does not contain CrLf
176 ** Returns 0 if the specified content appears to be binary or
177 ** contains a line that is too long
178 ** Returns -1, if the file appears text, but it contains CrLf
 
179 */
180 int looks_like_text(const Blob *pContent){
181 const char *z = blob_buffer(pContent);
182 unsigned int n = blob_size(pContent);
183 int j, c;
@@ -186,10 +187,17 @@
186 /* Check individual lines.
187 */
188 if( n==0 ) return result; /* Empty file -> text */
189 c = *z;
190 if( c==0 ) return 0; /* \000 byte in a file -> binary */
 
 
 
 
 
 
 
191 j = (c!='\n');
192 while( --n>0 ){
193 c = *++z; ++j;
194 if( c==0 ) return 0; /* \000 byte in a file -> binary */
195 if( c=='\n' ){
196
--- src/diff.c
+++ src/diff.c
@@ -48,11 +48,11 @@
48 "cannot compute difference between binary files\n"
49
50 #define DIFF_CANNOT_COMPUTE_SYMLINK \
51 "cannot compute difference between symlink and regular file\n"
52
53 #define looks_like_binary(blob) ((looks_like_text(blob)&1) == 0)
54 #endif /* INTERFACE */
55
56 /*
57 ** Maximum length of a line in a text file. (8192)
58 */
@@ -170,14 +170,15 @@
170 *pnLine = nLine;
171 return a;
172 }
173
174 /*
175 ** Returns 1, if everything OK
176 ** Returns 0 if the specified content appears to be binary or
177 ** contains a line that is too long
178 ** Returns -1, if the file appears text, but it contains CrLf
179 ** Returns -2, if the file starts with an UTF-16 BOM (le or be)
180 */
181 int looks_like_text(const Blob *pContent){
182 const char *z = blob_buffer(pContent);
183 unsigned int n = blob_size(pContent);
184 int j, c;
@@ -186,10 +187,17 @@
187 /* Check individual lines.
188 */
189 if( n==0 ) return result; /* Empty file -> text */
190 c = *z;
191 if( c==0 ) return 0; /* \000 byte in a file -> binary */
192 if ( n > 1 ){
193 if ( (c==(char)0xff) && (z[1]==(char)0xfe) ){
194 return -2;
195 } else if ( (c==(char)0xfe) && (z[1]==(char)0xff) ){
196 return -2;
197 }
198 }
199 j = (c!='\n');
200 while( --n>0 ){
201 c = *++z; ++j;
202 if( c==0 ) return 0; /* \000 byte in a file -> binary */
203 if( c=='\n' ){
204
+3 -13
--- src/main.c
+++ src/main.c
@@ -476,13 +476,12 @@
476476
int n; /* Number of bytes in one line */
477477
char *z; /* General use string pointer */
478478
char **newArgv; /* New expanded g.argv under construction */
479479
char const * zFileName; /* input file name */
480480
FILE * zInFile; /* input FILE */
481
- int foundBom = -1; /* -1= not searched yet, 0 = no; 1=yes */
482481
#ifdef _WIN32
483
- wchar_t buf[MAX_PATH];
482
+ WCHAR buf[MAX_PATH];
484483
#endif
485484
486485
g.argc = argc;
487486
g.argv = argv;
488487
#ifdef _WIN32
@@ -514,10 +513,11 @@
514513
if(stdin != zInFile){
515514
fclose(zInFile);
516515
}
517516
zInFile = NULL;
518517
}
518
+ blob_strip_bom(&file, 1);
519519
z = blob_str(&file);
520520
for(k=0, nLine=1; z[k]; k++) if( z[k]=='\n' ) nLine++;
521521
newArgv = fossil_malloc( sizeof(char*)*(g.argc + nLine*2) );
522522
for(j=0; j<i; j++) newArgv[j] = g.argv[j];
523523
@@ -524,24 +524,14 @@
524524
blob_rewind(&file);
525525
while( (n = blob_line(&file, &line))>0 ){
526526
if( n<=1 ) continue;
527527
z = blob_buffer(&line);
528528
z[n-1] = 0;
529
- if (foundBom == -1) {
530
- static const unsigned char bom[] = { 0xEF, 0xBB, 0xBF };
531
- foundBom = memcmp(z, bom, 3)==0;
532
- if( foundBom ) {
533
- z += 3; n -= 3;
534
- }
535
- }
536529
if((n>1) && ('\r'==z[n-2])){
537530
if(n==2) continue /*empty line*/;
538531
z[n-2] = 0;
539532
}
540
- if (!foundBom) {
541
- z = fossil_mbcs_to_utf8(z);
542
- }
543533
newArgv[j++] = z;
544534
if( z[0]=='-' ){
545535
for(k=1; z[k] && !fossil_isspace(z[k]); k++){}
546536
if( z[k] ){
547537
z[k] = 0;
@@ -850,11 +840,11 @@
850840
#if defined(_WIN32)
851841
/* On windows, we have to put double-quotes around the entire command.
852842
** Who knows why - this is just the way windows works.
853843
*/
854844
char *zNewCmd = mprintf("\"%s\"", zOrigCmd);
855
- wchar_t *zUnicode = fossil_utf8_to_unicode(zNewCmd);
845
+ WCHAR *zUnicode = fossil_utf8_to_unicode(zNewCmd);
856846
if( g.fSystemTrace ) {
857847
char *zOut = mprintf("SYSTEM: %s\n", zNewCmd);
858848
fossil_puts(zOut, 1);
859849
fossil_free(zOut);
860850
}
861851
--- src/main.c
+++ src/main.c
@@ -476,13 +476,12 @@
476 int n; /* Number of bytes in one line */
477 char *z; /* General use string pointer */
478 char **newArgv; /* New expanded g.argv under construction */
479 char const * zFileName; /* input file name */
480 FILE * zInFile; /* input FILE */
481 int foundBom = -1; /* -1= not searched yet, 0 = no; 1=yes */
482 #ifdef _WIN32
483 wchar_t buf[MAX_PATH];
484 #endif
485
486 g.argc = argc;
487 g.argv = argv;
488 #ifdef _WIN32
@@ -514,10 +513,11 @@
514 if(stdin != zInFile){
515 fclose(zInFile);
516 }
517 zInFile = NULL;
518 }
 
519 z = blob_str(&file);
520 for(k=0, nLine=1; z[k]; k++) if( z[k]=='\n' ) nLine++;
521 newArgv = fossil_malloc( sizeof(char*)*(g.argc + nLine*2) );
522 for(j=0; j<i; j++) newArgv[j] = g.argv[j];
523
@@ -524,24 +524,14 @@
524 blob_rewind(&file);
525 while( (n = blob_line(&file, &line))>0 ){
526 if( n<=1 ) continue;
527 z = blob_buffer(&line);
528 z[n-1] = 0;
529 if (foundBom == -1) {
530 static const unsigned char bom[] = { 0xEF, 0xBB, 0xBF };
531 foundBom = memcmp(z, bom, 3)==0;
532 if( foundBom ) {
533 z += 3; n -= 3;
534 }
535 }
536 if((n>1) && ('\r'==z[n-2])){
537 if(n==2) continue /*empty line*/;
538 z[n-2] = 0;
539 }
540 if (!foundBom) {
541 z = fossil_mbcs_to_utf8(z);
542 }
543 newArgv[j++] = z;
544 if( z[0]=='-' ){
545 for(k=1; z[k] && !fossil_isspace(z[k]); k++){}
546 if( z[k] ){
547 z[k] = 0;
@@ -850,11 +840,11 @@
850 #if defined(_WIN32)
851 /* On windows, we have to put double-quotes around the entire command.
852 ** Who knows why - this is just the way windows works.
853 */
854 char *zNewCmd = mprintf("\"%s\"", zOrigCmd);
855 wchar_t *zUnicode = fossil_utf8_to_unicode(zNewCmd);
856 if( g.fSystemTrace ) {
857 char *zOut = mprintf("SYSTEM: %s\n", zNewCmd);
858 fossil_puts(zOut, 1);
859 fossil_free(zOut);
860 }
861
--- src/main.c
+++ src/main.c
@@ -476,13 +476,12 @@
476 int n; /* Number of bytes in one line */
477 char *z; /* General use string pointer */
478 char **newArgv; /* New expanded g.argv under construction */
479 char const * zFileName; /* input file name */
480 FILE * zInFile; /* input FILE */
 
481 #ifdef _WIN32
482 WCHAR buf[MAX_PATH];
483 #endif
484
485 g.argc = argc;
486 g.argv = argv;
487 #ifdef _WIN32
@@ -514,10 +513,11 @@
513 if(stdin != zInFile){
514 fclose(zInFile);
515 }
516 zInFile = NULL;
517 }
518 blob_strip_bom(&file, 1);
519 z = blob_str(&file);
520 for(k=0, nLine=1; z[k]; k++) if( z[k]=='\n' ) nLine++;
521 newArgv = fossil_malloc( sizeof(char*)*(g.argc + nLine*2) );
522 for(j=0; j<i; j++) newArgv[j] = g.argv[j];
523
@@ -524,24 +524,14 @@
524 blob_rewind(&file);
525 while( (n = blob_line(&file, &line))>0 ){
526 if( n<=1 ) continue;
527 z = blob_buffer(&line);
528 z[n-1] = 0;
 
 
 
 
 
 
 
529 if((n>1) && ('\r'==z[n-2])){
530 if(n==2) continue /*empty line*/;
531 z[n-2] = 0;
532 }
 
 
 
533 newArgv[j++] = z;
534 if( z[0]=='-' ){
535 for(k=1; z[k] && !fossil_isspace(z[k]); k++){}
536 if( z[k] ){
537 z[k] = 0;
@@ -850,11 +840,11 @@
840 #if defined(_WIN32)
841 /* On windows, we have to put double-quotes around the entire command.
842 ** Who knows why - this is just the way windows works.
843 */
844 char *zNewCmd = mprintf("\"%s\"", zOrigCmd);
845 WCHAR *zUnicode = fossil_utf8_to_unicode(zNewCmd);
846 if( g.fSystemTrace ) {
847 char *zOut = mprintf("SYSTEM: %s\n", zNewCmd);
848 fossil_puts(zOut, 1);
849 fossil_free(zOut);
850 }
851
+8 -18
--- src/wikiformat.c
+++ src/wikiformat.c
@@ -315,11 +315,11 @@
315315
{ "tbody", MARKUP_TBODY, MUTYPE_BLOCK,
316316
AMSK_ALIGN|AMSK_CLASS|AMSK_STYLE },
317317
{ "td", MARKUP_TD, MUTYPE_TD,
318318
AMSK_ALIGN|AMSK_BGCOLOR|AMSK_COLSPAN|
319319
AMSK_ROWSPAN|AMSK_VALIGN|AMSK_CLASS|AMSK_STYLE },
320
- { "tfoot", MARKUP_TFOOT, MUTYPE_BLOCK,
320
+ { "tfoot", MARKUP_TFOOT, MUTYPE_BLOCK,
321321
AMSK_ALIGN|AMSK_CLASS|AMSK_STYLE },
322322
{ "th", MARKUP_TH, MUTYPE_TD,
323323
AMSK_ALIGN|AMSK_BGCOLOR|AMSK_COLSPAN|
324324
AMSK_ROWSPAN|AMSK_VALIGN|AMSK_CLASS|AMSK_STYLE },
325325
{ "thead", MARKUP_THEAD, MUTYPE_BLOCK,
@@ -856,11 +856,11 @@
856856
** <a class="button" href="../index.wiki">Index</a>
857857
**
858858
** If the markup matches this pattern, and if the WIKI_BUTTONS flag was
859859
** passed to wiki_convert(), then transform this link into a submenu
860860
** button, skip the text, and set *pN equal to the total length of the
861
-** text through the end of </a> and return true. If the markup does
861
+** text through the end of </a> and return true. If the markup does
862862
** not match or if WIKI_BUTTONS is not set, then make no changes to *pN
863863
** and return false.
864864
*/
865865
static int isButtonHyperlink(
866866
Renderer *p, /* Renderer state */
@@ -1019,11 +1019,11 @@
10191019
static int in_this_repo(const char *zUuid){
10201020
static Stmt q;
10211021
int rc;
10221022
int n;
10231023
char zU2[UUID_SIZE+1];
1024
- db_static_prepare(&q,
1024
+ db_static_prepare(&q,
10251025
"SELECT 1 FROM blob WHERE uuid>=:u AND uuid<:u2"
10261026
);
10271027
db_bind_text(&q, ":u", zUuid);
10281028
n = (int)strlen(zUuid);
10291029
if( n>=sizeof(zU2) ) n = sizeof(zU2)-1;
@@ -1165,11 +1165,11 @@
11651165
zTerm = "]</a>";
11661166
}
11671167
}else if( strlen(zTarget)>=10 && fossil_isdigit(zTarget[0]) && zTarget[4]=='-'
11681168
&& db_int(0, "SELECT datetime(%Q) NOT NULL", zTarget) ){
11691169
blob_appendf(p->pOut, "<a href=\"%R/timeline?c=%T\">", zTarget);
1170
- }else if( strncmp(zTarget, "wiki:", 5)==0
1170
+ }else if( strncmp(zTarget, "wiki:", 5)==0
11711171
&& wiki_name_is_wellformed((const unsigned char*)zTarget) ){
11721172
zTarget += 5;
11731173
blob_appendf(p->pOut, "<a href=\"%R/wiki?name=%T\">", zTarget);
11741174
}else if( wiki_name_is_wellformed((const unsigned char *)zTarget) ){
11751175
blob_appendf(p->pOut, "<a href=\"%R/wiki?name=%T\">", zTarget);
@@ -1547,29 +1547,18 @@
15471547
}
15481548
z += n;
15491549
}
15501550
}
15511551
1552
-/*
1553
-** Skip over the UTF-8 Byte-Order-Mark that some broken Windows
1554
-** tools add to the beginning of text files.
1555
-*/
1556
-char *skip_bom(char *z){
1557
- static const unsigned char bom[] = { 0xEF, 0xBB, 0xBF };
1558
- if( z && memcmp(z, bom, 3)==0 ) z += 3;
1559
- return z;
1560
-}
1561
-
15621552
/*
15631553
** Transform the text in the pIn blob. Write the results
15641554
** into the pOut blob. The pOut blob should already be
15651555
** initialized. The output is merely appended to pOut.
15661556
** If pOut is NULL, then the output is appended to the CGI
15671557
** reply.
15681558
*/
15691559
void wiki_convert(Blob *pIn, Blob *pOut, int flags){
1570
- char *z;
15711560
Renderer renderer;
15721561
15731562
memset(&renderer, 0, sizeof(renderer));
15741563
renderer.state = ALLOW_WIKI|AT_NEWLINE|AT_PARAGRAPH|flags;
15751564
if( flags & WIKI_NOBLOCK ){
@@ -1587,12 +1576,12 @@
15871576
renderer.pOut = pOut;
15881577
}else{
15891578
renderer.pOut = cgi_output_blob();
15901579
}
15911580
1592
- z = skip_bom(blob_str(pIn));
1593
- wiki_render(&renderer, z);
1581
+ blob_strip_bom(pIn, 0);
1582
+ wiki_render(&renderer, blob_str(pIn));
15941583
endAutoParagraph(&renderer);
15951584
while( renderer.nStack ){
15961585
popStack(&renderer);
15971586
}
15981587
blob_append(renderer.pOut, "\n", 1);
@@ -1630,11 +1619,12 @@
16301619
*/
16311620
int wiki_find_title(Blob *pIn, Blob *pTitle, Blob *pTail){
16321621
char *z;
16331622
int i;
16341623
int iStart;
1635
- z = skip_bom(blob_str(pIn));
1624
+ blob_strip_bom(pIn, 0);
1625
+ z = blob_str(pIn);
16361626
for(i=0; fossil_isspace(z[i]); i++){}
16371627
if( z[i]!='<' ) return 0;
16381628
i++;
16391629
if( strncmp(&z[i],"title>", 6)!=0 ) return 0;
16401630
iStart = i+6;
16411631
--- src/wikiformat.c
+++ src/wikiformat.c
@@ -315,11 +315,11 @@
315 { "tbody", MARKUP_TBODY, MUTYPE_BLOCK,
316 AMSK_ALIGN|AMSK_CLASS|AMSK_STYLE },
317 { "td", MARKUP_TD, MUTYPE_TD,
318 AMSK_ALIGN|AMSK_BGCOLOR|AMSK_COLSPAN|
319 AMSK_ROWSPAN|AMSK_VALIGN|AMSK_CLASS|AMSK_STYLE },
320 { "tfoot", MARKUP_TFOOT, MUTYPE_BLOCK,
321 AMSK_ALIGN|AMSK_CLASS|AMSK_STYLE },
322 { "th", MARKUP_TH, MUTYPE_TD,
323 AMSK_ALIGN|AMSK_BGCOLOR|AMSK_COLSPAN|
324 AMSK_ROWSPAN|AMSK_VALIGN|AMSK_CLASS|AMSK_STYLE },
325 { "thead", MARKUP_THEAD, MUTYPE_BLOCK,
@@ -856,11 +856,11 @@
856 ** <a class="button" href="../index.wiki">Index</a>
857 **
858 ** If the markup matches this pattern, and if the WIKI_BUTTONS flag was
859 ** passed to wiki_convert(), then transform this link into a submenu
860 ** button, skip the text, and set *pN equal to the total length of the
861 ** text through the end of </a> and return true. If the markup does
862 ** not match or if WIKI_BUTTONS is not set, then make no changes to *pN
863 ** and return false.
864 */
865 static int isButtonHyperlink(
866 Renderer *p, /* Renderer state */
@@ -1019,11 +1019,11 @@
1019 static int in_this_repo(const char *zUuid){
1020 static Stmt q;
1021 int rc;
1022 int n;
1023 char zU2[UUID_SIZE+1];
1024 db_static_prepare(&q,
1025 "SELECT 1 FROM blob WHERE uuid>=:u AND uuid<:u2"
1026 );
1027 db_bind_text(&q, ":u", zUuid);
1028 n = (int)strlen(zUuid);
1029 if( n>=sizeof(zU2) ) n = sizeof(zU2)-1;
@@ -1165,11 +1165,11 @@
1165 zTerm = "]</a>";
1166 }
1167 }else if( strlen(zTarget)>=10 && fossil_isdigit(zTarget[0]) && zTarget[4]=='-'
1168 && db_int(0, "SELECT datetime(%Q) NOT NULL", zTarget) ){
1169 blob_appendf(p->pOut, "<a href=\"%R/timeline?c=%T\">", zTarget);
1170 }else if( strncmp(zTarget, "wiki:", 5)==0
1171 && wiki_name_is_wellformed((const unsigned char*)zTarget) ){
1172 zTarget += 5;
1173 blob_appendf(p->pOut, "<a href=\"%R/wiki?name=%T\">", zTarget);
1174 }else if( wiki_name_is_wellformed((const unsigned char *)zTarget) ){
1175 blob_appendf(p->pOut, "<a href=\"%R/wiki?name=%T\">", zTarget);
@@ -1547,29 +1547,18 @@
1547 }
1548 z += n;
1549 }
1550 }
1551
1552 /*
1553 ** Skip over the UTF-8 Byte-Order-Mark that some broken Windows
1554 ** tools add to the beginning of text files.
1555 */
1556 char *skip_bom(char *z){
1557 static const unsigned char bom[] = { 0xEF, 0xBB, 0xBF };
1558 if( z && memcmp(z, bom, 3)==0 ) z += 3;
1559 return z;
1560 }
1561
1562 /*
1563 ** Transform the text in the pIn blob. Write the results
1564 ** into the pOut blob. The pOut blob should already be
1565 ** initialized. The output is merely appended to pOut.
1566 ** If pOut is NULL, then the output is appended to the CGI
1567 ** reply.
1568 */
1569 void wiki_convert(Blob *pIn, Blob *pOut, int flags){
1570 char *z;
1571 Renderer renderer;
1572
1573 memset(&renderer, 0, sizeof(renderer));
1574 renderer.state = ALLOW_WIKI|AT_NEWLINE|AT_PARAGRAPH|flags;
1575 if( flags & WIKI_NOBLOCK ){
@@ -1587,12 +1576,12 @@
1587 renderer.pOut = pOut;
1588 }else{
1589 renderer.pOut = cgi_output_blob();
1590 }
1591
1592 z = skip_bom(blob_str(pIn));
1593 wiki_render(&renderer, z);
1594 endAutoParagraph(&renderer);
1595 while( renderer.nStack ){
1596 popStack(&renderer);
1597 }
1598 blob_append(renderer.pOut, "\n", 1);
@@ -1630,11 +1619,12 @@
1630 */
1631 int wiki_find_title(Blob *pIn, Blob *pTitle, Blob *pTail){
1632 char *z;
1633 int i;
1634 int iStart;
1635 z = skip_bom(blob_str(pIn));
 
1636 for(i=0; fossil_isspace(z[i]); i++){}
1637 if( z[i]!='<' ) return 0;
1638 i++;
1639 if( strncmp(&z[i],"title>", 6)!=0 ) return 0;
1640 iStart = i+6;
1641
--- src/wikiformat.c
+++ src/wikiformat.c
@@ -315,11 +315,11 @@
315 { "tbody", MARKUP_TBODY, MUTYPE_BLOCK,
316 AMSK_ALIGN|AMSK_CLASS|AMSK_STYLE },
317 { "td", MARKUP_TD, MUTYPE_TD,
318 AMSK_ALIGN|AMSK_BGCOLOR|AMSK_COLSPAN|
319 AMSK_ROWSPAN|AMSK_VALIGN|AMSK_CLASS|AMSK_STYLE },
320 { "tfoot", MARKUP_TFOOT, MUTYPE_BLOCK,
321 AMSK_ALIGN|AMSK_CLASS|AMSK_STYLE },
322 { "th", MARKUP_TH, MUTYPE_TD,
323 AMSK_ALIGN|AMSK_BGCOLOR|AMSK_COLSPAN|
324 AMSK_ROWSPAN|AMSK_VALIGN|AMSK_CLASS|AMSK_STYLE },
325 { "thead", MARKUP_THEAD, MUTYPE_BLOCK,
@@ -856,11 +856,11 @@
856 ** <a class="button" href="../index.wiki">Index</a>
857 **
858 ** If the markup matches this pattern, and if the WIKI_BUTTONS flag was
859 ** passed to wiki_convert(), then transform this link into a submenu
860 ** button, skip the text, and set *pN equal to the total length of the
861 ** text through the end of </a> and return true. If the markup does
862 ** not match or if WIKI_BUTTONS is not set, then make no changes to *pN
863 ** and return false.
864 */
865 static int isButtonHyperlink(
866 Renderer *p, /* Renderer state */
@@ -1019,11 +1019,11 @@
1019 static int in_this_repo(const char *zUuid){
1020 static Stmt q;
1021 int rc;
1022 int n;
1023 char zU2[UUID_SIZE+1];
1024 db_static_prepare(&q,
1025 "SELECT 1 FROM blob WHERE uuid>=:u AND uuid<:u2"
1026 );
1027 db_bind_text(&q, ":u", zUuid);
1028 n = (int)strlen(zUuid);
1029 if( n>=sizeof(zU2) ) n = sizeof(zU2)-1;
@@ -1165,11 +1165,11 @@
1165 zTerm = "]</a>";
1166 }
1167 }else if( strlen(zTarget)>=10 && fossil_isdigit(zTarget[0]) && zTarget[4]=='-'
1168 && db_int(0, "SELECT datetime(%Q) NOT NULL", zTarget) ){
1169 blob_appendf(p->pOut, "<a href=\"%R/timeline?c=%T\">", zTarget);
1170 }else if( strncmp(zTarget, "wiki:", 5)==0
1171 && wiki_name_is_wellformed((const unsigned char*)zTarget) ){
1172 zTarget += 5;
1173 blob_appendf(p->pOut, "<a href=\"%R/wiki?name=%T\">", zTarget);
1174 }else if( wiki_name_is_wellformed((const unsigned char *)zTarget) ){
1175 blob_appendf(p->pOut, "<a href=\"%R/wiki?name=%T\">", zTarget);
@@ -1547,29 +1547,18 @@
1547 }
1548 z += n;
1549 }
1550 }
1551
 
 
 
 
 
 
 
 
 
 
1552 /*
1553 ** Transform the text in the pIn blob. Write the results
1554 ** into the pOut blob. The pOut blob should already be
1555 ** initialized. The output is merely appended to pOut.
1556 ** If pOut is NULL, then the output is appended to the CGI
1557 ** reply.
1558 */
1559 void wiki_convert(Blob *pIn, Blob *pOut, int flags){
 
1560 Renderer renderer;
1561
1562 memset(&renderer, 0, sizeof(renderer));
1563 renderer.state = ALLOW_WIKI|AT_NEWLINE|AT_PARAGRAPH|flags;
1564 if( flags & WIKI_NOBLOCK ){
@@ -1587,12 +1576,12 @@
1576 renderer.pOut = pOut;
1577 }else{
1578 renderer.pOut = cgi_output_blob();
1579 }
1580
1581 blob_strip_bom(pIn, 0);
1582 wiki_render(&renderer, blob_str(pIn));
1583 endAutoParagraph(&renderer);
1584 while( renderer.nStack ){
1585 popStack(&renderer);
1586 }
1587 blob_append(renderer.pOut, "\n", 1);
@@ -1630,11 +1619,12 @@
1619 */
1620 int wiki_find_title(Blob *pIn, Blob *pTitle, Blob *pTail){
1621 char *z;
1622 int i;
1623 int iStart;
1624 blob_strip_bom(pIn, 0);
1625 z = blob_str(pIn);
1626 for(i=0; fossil_isspace(z[i]); i++){}
1627 if( z[i]!='<' ) return 0;
1628 i++;
1629 if( strncmp(&z[i],"title>", 6)!=0 ) return 0;
1630 iStart = i+6;
1631
+8 -18
--- src/wikiformat.c
+++ src/wikiformat.c
@@ -315,11 +315,11 @@
315315
{ "tbody", MARKUP_TBODY, MUTYPE_BLOCK,
316316
AMSK_ALIGN|AMSK_CLASS|AMSK_STYLE },
317317
{ "td", MARKUP_TD, MUTYPE_TD,
318318
AMSK_ALIGN|AMSK_BGCOLOR|AMSK_COLSPAN|
319319
AMSK_ROWSPAN|AMSK_VALIGN|AMSK_CLASS|AMSK_STYLE },
320
- { "tfoot", MARKUP_TFOOT, MUTYPE_BLOCK,
320
+ { "tfoot", MARKUP_TFOOT, MUTYPE_BLOCK,
321321
AMSK_ALIGN|AMSK_CLASS|AMSK_STYLE },
322322
{ "th", MARKUP_TH, MUTYPE_TD,
323323
AMSK_ALIGN|AMSK_BGCOLOR|AMSK_COLSPAN|
324324
AMSK_ROWSPAN|AMSK_VALIGN|AMSK_CLASS|AMSK_STYLE },
325325
{ "thead", MARKUP_THEAD, MUTYPE_BLOCK,
@@ -856,11 +856,11 @@
856856
** <a class="button" href="../index.wiki">Index</a>
857857
**
858858
** If the markup matches this pattern, and if the WIKI_BUTTONS flag was
859859
** passed to wiki_convert(), then transform this link into a submenu
860860
** button, skip the text, and set *pN equal to the total length of the
861
-** text through the end of </a> and return true. If the markup does
861
+** text through the end of </a> and return true. If the markup does
862862
** not match or if WIKI_BUTTONS is not set, then make no changes to *pN
863863
** and return false.
864864
*/
865865
static int isButtonHyperlink(
866866
Renderer *p, /* Renderer state */
@@ -1019,11 +1019,11 @@
10191019
static int in_this_repo(const char *zUuid){
10201020
static Stmt q;
10211021
int rc;
10221022
int n;
10231023
char zU2[UUID_SIZE+1];
1024
- db_static_prepare(&q,
1024
+ db_static_prepare(&q,
10251025
"SELECT 1 FROM blob WHERE uuid>=:u AND uuid<:u2"
10261026
);
10271027
db_bind_text(&q, ":u", zUuid);
10281028
n = (int)strlen(zUuid);
10291029
if( n>=sizeof(zU2) ) n = sizeof(zU2)-1;
@@ -1165,11 +1165,11 @@
11651165
zTerm = "]</a>";
11661166
}
11671167
}else if( strlen(zTarget)>=10 && fossil_isdigit(zTarget[0]) && zTarget[4]=='-'
11681168
&& db_int(0, "SELECT datetime(%Q) NOT NULL", zTarget) ){
11691169
blob_appendf(p->pOut, "<a href=\"%R/timeline?c=%T\">", zTarget);
1170
- }else if( strncmp(zTarget, "wiki:", 5)==0
1170
+ }else if( strncmp(zTarget, "wiki:", 5)==0
11711171
&& wiki_name_is_wellformed((const unsigned char*)zTarget) ){
11721172
zTarget += 5;
11731173
blob_appendf(p->pOut, "<a href=\"%R/wiki?name=%T\">", zTarget);
11741174
}else if( wiki_name_is_wellformed((const unsigned char *)zTarget) ){
11751175
blob_appendf(p->pOut, "<a href=\"%R/wiki?name=%T\">", zTarget);
@@ -1547,29 +1547,18 @@
15471547
}
15481548
z += n;
15491549
}
15501550
}
15511551
1552
-/*
1553
-** Skip over the UTF-8 Byte-Order-Mark that some broken Windows
1554
-** tools add to the beginning of text files.
1555
-*/
1556
-char *skip_bom(char *z){
1557
- static const unsigned char bom[] = { 0xEF, 0xBB, 0xBF };
1558
- if( z && memcmp(z, bom, 3)==0 ) z += 3;
1559
- return z;
1560
-}
1561
-
15621552
/*
15631553
** Transform the text in the pIn blob. Write the results
15641554
** into the pOut blob. The pOut blob should already be
15651555
** initialized. The output is merely appended to pOut.
15661556
** If pOut is NULL, then the output is appended to the CGI
15671557
** reply.
15681558
*/
15691559
void wiki_convert(Blob *pIn, Blob *pOut, int flags){
1570
- char *z;
15711560
Renderer renderer;
15721561
15731562
memset(&renderer, 0, sizeof(renderer));
15741563
renderer.state = ALLOW_WIKI|AT_NEWLINE|AT_PARAGRAPH|flags;
15751564
if( flags & WIKI_NOBLOCK ){
@@ -1587,12 +1576,12 @@
15871576
renderer.pOut = pOut;
15881577
}else{
15891578
renderer.pOut = cgi_output_blob();
15901579
}
15911580
1592
- z = skip_bom(blob_str(pIn));
1593
- wiki_render(&renderer, z);
1581
+ blob_strip_bom(pIn, 0);
1582
+ wiki_render(&renderer, blob_str(pIn));
15941583
endAutoParagraph(&renderer);
15951584
while( renderer.nStack ){
15961585
popStack(&renderer);
15971586
}
15981587
blob_append(renderer.pOut, "\n", 1);
@@ -1630,11 +1619,12 @@
16301619
*/
16311620
int wiki_find_title(Blob *pIn, Blob *pTitle, Blob *pTail){
16321621
char *z;
16331622
int i;
16341623
int iStart;
1635
- z = skip_bom(blob_str(pIn));
1624
+ blob_strip_bom(pIn, 0);
1625
+ z = blob_str(pIn);
16361626
for(i=0; fossil_isspace(z[i]); i++){}
16371627
if( z[i]!='<' ) return 0;
16381628
i++;
16391629
if( strncmp(&z[i],"title>", 6)!=0 ) return 0;
16401630
iStart = i+6;
16411631
--- src/wikiformat.c
+++ src/wikiformat.c
@@ -315,11 +315,11 @@
315 { "tbody", MARKUP_TBODY, MUTYPE_BLOCK,
316 AMSK_ALIGN|AMSK_CLASS|AMSK_STYLE },
317 { "td", MARKUP_TD, MUTYPE_TD,
318 AMSK_ALIGN|AMSK_BGCOLOR|AMSK_COLSPAN|
319 AMSK_ROWSPAN|AMSK_VALIGN|AMSK_CLASS|AMSK_STYLE },
320 { "tfoot", MARKUP_TFOOT, MUTYPE_BLOCK,
321 AMSK_ALIGN|AMSK_CLASS|AMSK_STYLE },
322 { "th", MARKUP_TH, MUTYPE_TD,
323 AMSK_ALIGN|AMSK_BGCOLOR|AMSK_COLSPAN|
324 AMSK_ROWSPAN|AMSK_VALIGN|AMSK_CLASS|AMSK_STYLE },
325 { "thead", MARKUP_THEAD, MUTYPE_BLOCK,
@@ -856,11 +856,11 @@
856 ** <a class="button" href="../index.wiki">Index</a>
857 **
858 ** If the markup matches this pattern, and if the WIKI_BUTTONS flag was
859 ** passed to wiki_convert(), then transform this link into a submenu
860 ** button, skip the text, and set *pN equal to the total length of the
861 ** text through the end of </a> and return true. If the markup does
862 ** not match or if WIKI_BUTTONS is not set, then make no changes to *pN
863 ** and return false.
864 */
865 static int isButtonHyperlink(
866 Renderer *p, /* Renderer state */
@@ -1019,11 +1019,11 @@
1019 static int in_this_repo(const char *zUuid){
1020 static Stmt q;
1021 int rc;
1022 int n;
1023 char zU2[UUID_SIZE+1];
1024 db_static_prepare(&q,
1025 "SELECT 1 FROM blob WHERE uuid>=:u AND uuid<:u2"
1026 );
1027 db_bind_text(&q, ":u", zUuid);
1028 n = (int)strlen(zUuid);
1029 if( n>=sizeof(zU2) ) n = sizeof(zU2)-1;
@@ -1165,11 +1165,11 @@
1165 zTerm = "]</a>";
1166 }
1167 }else if( strlen(zTarget)>=10 && fossil_isdigit(zTarget[0]) && zTarget[4]=='-'
1168 && db_int(0, "SELECT datetime(%Q) NOT NULL", zTarget) ){
1169 blob_appendf(p->pOut, "<a href=\"%R/timeline?c=%T\">", zTarget);
1170 }else if( strncmp(zTarget, "wiki:", 5)==0
1171 && wiki_name_is_wellformed((const unsigned char*)zTarget) ){
1172 zTarget += 5;
1173 blob_appendf(p->pOut, "<a href=\"%R/wiki?name=%T\">", zTarget);
1174 }else if( wiki_name_is_wellformed((const unsigned char *)zTarget) ){
1175 blob_appendf(p->pOut, "<a href=\"%R/wiki?name=%T\">", zTarget);
@@ -1547,29 +1547,18 @@
1547 }
1548 z += n;
1549 }
1550 }
1551
1552 /*
1553 ** Skip over the UTF-8 Byte-Order-Mark that some broken Windows
1554 ** tools add to the beginning of text files.
1555 */
1556 char *skip_bom(char *z){
1557 static const unsigned char bom[] = { 0xEF, 0xBB, 0xBF };
1558 if( z && memcmp(z, bom, 3)==0 ) z += 3;
1559 return z;
1560 }
1561
1562 /*
1563 ** Transform the text in the pIn blob. Write the results
1564 ** into the pOut blob. The pOut blob should already be
1565 ** initialized. The output is merely appended to pOut.
1566 ** If pOut is NULL, then the output is appended to the CGI
1567 ** reply.
1568 */
1569 void wiki_convert(Blob *pIn, Blob *pOut, int flags){
1570 char *z;
1571 Renderer renderer;
1572
1573 memset(&renderer, 0, sizeof(renderer));
1574 renderer.state = ALLOW_WIKI|AT_NEWLINE|AT_PARAGRAPH|flags;
1575 if( flags & WIKI_NOBLOCK ){
@@ -1587,12 +1576,12 @@
1587 renderer.pOut = pOut;
1588 }else{
1589 renderer.pOut = cgi_output_blob();
1590 }
1591
1592 z = skip_bom(blob_str(pIn));
1593 wiki_render(&renderer, z);
1594 endAutoParagraph(&renderer);
1595 while( renderer.nStack ){
1596 popStack(&renderer);
1597 }
1598 blob_append(renderer.pOut, "\n", 1);
@@ -1630,11 +1619,12 @@
1630 */
1631 int wiki_find_title(Blob *pIn, Blob *pTitle, Blob *pTail){
1632 char *z;
1633 int i;
1634 int iStart;
1635 z = skip_bom(blob_str(pIn));
 
1636 for(i=0; fossil_isspace(z[i]); i++){}
1637 if( z[i]!='<' ) return 0;
1638 i++;
1639 if( strncmp(&z[i],"title>", 6)!=0 ) return 0;
1640 iStart = i+6;
1641
--- src/wikiformat.c
+++ src/wikiformat.c
@@ -315,11 +315,11 @@
315 { "tbody", MARKUP_TBODY, MUTYPE_BLOCK,
316 AMSK_ALIGN|AMSK_CLASS|AMSK_STYLE },
317 { "td", MARKUP_TD, MUTYPE_TD,
318 AMSK_ALIGN|AMSK_BGCOLOR|AMSK_COLSPAN|
319 AMSK_ROWSPAN|AMSK_VALIGN|AMSK_CLASS|AMSK_STYLE },
320 { "tfoot", MARKUP_TFOOT, MUTYPE_BLOCK,
321 AMSK_ALIGN|AMSK_CLASS|AMSK_STYLE },
322 { "th", MARKUP_TH, MUTYPE_TD,
323 AMSK_ALIGN|AMSK_BGCOLOR|AMSK_COLSPAN|
324 AMSK_ROWSPAN|AMSK_VALIGN|AMSK_CLASS|AMSK_STYLE },
325 { "thead", MARKUP_THEAD, MUTYPE_BLOCK,
@@ -856,11 +856,11 @@
856 ** <a class="button" href="../index.wiki">Index</a>
857 **
858 ** If the markup matches this pattern, and if the WIKI_BUTTONS flag was
859 ** passed to wiki_convert(), then transform this link into a submenu
860 ** button, skip the text, and set *pN equal to the total length of the
861 ** text through the end of </a> and return true. If the markup does
862 ** not match or if WIKI_BUTTONS is not set, then make no changes to *pN
863 ** and return false.
864 */
865 static int isButtonHyperlink(
866 Renderer *p, /* Renderer state */
@@ -1019,11 +1019,11 @@
1019 static int in_this_repo(const char *zUuid){
1020 static Stmt q;
1021 int rc;
1022 int n;
1023 char zU2[UUID_SIZE+1];
1024 db_static_prepare(&q,
1025 "SELECT 1 FROM blob WHERE uuid>=:u AND uuid<:u2"
1026 );
1027 db_bind_text(&q, ":u", zUuid);
1028 n = (int)strlen(zUuid);
1029 if( n>=sizeof(zU2) ) n = sizeof(zU2)-1;
@@ -1165,11 +1165,11 @@
1165 zTerm = "]</a>";
1166 }
1167 }else if( strlen(zTarget)>=10 && fossil_isdigit(zTarget[0]) && zTarget[4]=='-'
1168 && db_int(0, "SELECT datetime(%Q) NOT NULL", zTarget) ){
1169 blob_appendf(p->pOut, "<a href=\"%R/timeline?c=%T\">", zTarget);
1170 }else if( strncmp(zTarget, "wiki:", 5)==0
1171 && wiki_name_is_wellformed((const unsigned char*)zTarget) ){
1172 zTarget += 5;
1173 blob_appendf(p->pOut, "<a href=\"%R/wiki?name=%T\">", zTarget);
1174 }else if( wiki_name_is_wellformed((const unsigned char *)zTarget) ){
1175 blob_appendf(p->pOut, "<a href=\"%R/wiki?name=%T\">", zTarget);
@@ -1547,29 +1547,18 @@
1547 }
1548 z += n;
1549 }
1550 }
1551
 
 
 
 
 
 
 
 
 
 
1552 /*
1553 ** Transform the text in the pIn blob. Write the results
1554 ** into the pOut blob. The pOut blob should already be
1555 ** initialized. The output is merely appended to pOut.
1556 ** If pOut is NULL, then the output is appended to the CGI
1557 ** reply.
1558 */
1559 void wiki_convert(Blob *pIn, Blob *pOut, int flags){
 
1560 Renderer renderer;
1561
1562 memset(&renderer, 0, sizeof(renderer));
1563 renderer.state = ALLOW_WIKI|AT_NEWLINE|AT_PARAGRAPH|flags;
1564 if( flags & WIKI_NOBLOCK ){
@@ -1587,12 +1576,12 @@
1576 renderer.pOut = pOut;
1577 }else{
1578 renderer.pOut = cgi_output_blob();
1579 }
1580
1581 blob_strip_bom(pIn, 0);
1582 wiki_render(&renderer, blob_str(pIn));
1583 endAutoParagraph(&renderer);
1584 while( renderer.nStack ){
1585 popStack(&renderer);
1586 }
1587 blob_append(renderer.pOut, "\n", 1);
@@ -1630,11 +1619,12 @@
1619 */
1620 int wiki_find_title(Blob *pIn, Blob *pTitle, Blob *pTail){
1621 char *z;
1622 int i;
1623 int iStart;
1624 blob_strip_bom(pIn, 0);
1625 z = blob_str(pIn);
1626 for(i=0; fossil_isspace(z[i]); i++){}
1627 if( z[i]!='<' ) return 0;
1628 i++;
1629 if( strncmp(&z[i],"title>", 6)!=0 ) return 0;
1630 iStart = i+6;
1631

Keyboard Shortcuts

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