Fossil SCM

Improve comments

jan.nijtmans 2016-06-26 17:04 invalid_utf8_improvements merge
Commit 8bdd0abc7a4e95728c12103e3bbec38c911157af
+1 -1
--- src/allrepo.c
+++ src/allrepo.c
@@ -138,11 +138,11 @@
138138
**
139139
** In addition, the following maintenance operations are supported:
140140
**
141141
** add Add all the repositories named to the set of repositories
142142
** tracked by Fossil. Normally Fossil is able to keep up with
143
-** this list by itself, but sometime it can benefit from this
143
+** this list by itself, but sometimes it can benefit from this
144144
** hint if you rename repositories.
145145
**
146146
** ignore Arguments are repositories that should be ignored by
147147
** subsequent clean, extras, list, pull, push, rebuild, and
148148
** sync operations. The -c|--ckout option causes the listed
149149
--- src/allrepo.c
+++ src/allrepo.c
@@ -138,11 +138,11 @@
138 **
139 ** In addition, the following maintenance operations are supported:
140 **
141 ** add Add all the repositories named to the set of repositories
142 ** tracked by Fossil. Normally Fossil is able to keep up with
143 ** this list by itself, but sometime it can benefit from this
144 ** hint if you rename repositories.
145 **
146 ** ignore Arguments are repositories that should be ignored by
147 ** subsequent clean, extras, list, pull, push, rebuild, and
148 ** sync operations. The -c|--ckout option causes the listed
149
--- src/allrepo.c
+++ src/allrepo.c
@@ -138,11 +138,11 @@
138 **
139 ** In addition, the following maintenance operations are supported:
140 **
141 ** add Add all the repositories named to the set of repositories
142 ** tracked by Fossil. Normally Fossil is able to keep up with
143 ** this list by itself, but sometimes it can benefit from this
144 ** hint if you rename repositories.
145 **
146 ** ignore Arguments are repositories that should be ignored by
147 ** subsequent clean, extras, list, pull, push, rebuild, and
148 ** sync operations. The -c|--ckout option causes the listed
149
+2 -2
--- src/bundle.c
+++ src/bundle.c
@@ -26,11 +26,11 @@
2626
**
2727
** The bblob.delta field can be an integer, a text string, or NULL.
2828
** If an integer, then the corresponding blobid is the delta basis.
2929
** If a text string, then that string is a SHA1 hash for the delta
3030
** basis, which is presumably in the master repository. If NULL, then
31
-** data contains contain without delta compression.
31
+** data contains content without delta compression.
3232
*/
3333
static const char zBundleInit[] =
3434
@ CREATE TABLE IF NOT EXISTS "%w".bconfig(
3535
@ bcname TEXT,
3636
@ bcvalue ANY
@@ -370,11 +370,11 @@
370370
" WHERE fnid=(SELECT fnid FROM mlink WHERE fid=%d)"
371371
" AND fid<%d", rid, mnToBundle);
372372
}
373373
}
374374
375
- /* Try to insert the insert the artifact as a delta
375
+ /* Try to insert the artifact as a delta
376376
*/
377377
if( deltaFrom ){
378378
Blob basis, delta;
379379
content_get(deltaFrom, &basis);
380380
blob_delta_create(&basis, &content, &delta);
381381
--- src/bundle.c
+++ src/bundle.c
@@ -26,11 +26,11 @@
26 **
27 ** The bblob.delta field can be an integer, a text string, or NULL.
28 ** If an integer, then the corresponding blobid is the delta basis.
29 ** If a text string, then that string is a SHA1 hash for the delta
30 ** basis, which is presumably in the master repository. If NULL, then
31 ** data contains contain without delta compression.
32 */
33 static const char zBundleInit[] =
34 @ CREATE TABLE IF NOT EXISTS "%w".bconfig(
35 @ bcname TEXT,
36 @ bcvalue ANY
@@ -370,11 +370,11 @@
370 " WHERE fnid=(SELECT fnid FROM mlink WHERE fid=%d)"
371 " AND fid<%d", rid, mnToBundle);
372 }
373 }
374
375 /* Try to insert the insert the artifact as a delta
376 */
377 if( deltaFrom ){
378 Blob basis, delta;
379 content_get(deltaFrom, &basis);
380 blob_delta_create(&basis, &content, &delta);
381
--- src/bundle.c
+++ src/bundle.c
@@ -26,11 +26,11 @@
26 **
27 ** The bblob.delta field can be an integer, a text string, or NULL.
28 ** If an integer, then the corresponding blobid is the delta basis.
29 ** If a text string, then that string is a SHA1 hash for the delta
30 ** basis, which is presumably in the master repository. If NULL, then
31 ** data contains content without delta compression.
32 */
33 static const char zBundleInit[] =
34 @ CREATE TABLE IF NOT EXISTS "%w".bconfig(
35 @ bcname TEXT,
36 @ bcvalue ANY
@@ -370,11 +370,11 @@
370 " WHERE fnid=(SELECT fnid FROM mlink WHERE fid=%d)"
371 " AND fid<%d", rid, mnToBundle);
372 }
373 }
374
375 /* Try to insert the artifact as a delta
376 */
377 if( deltaFrom ){
378 Blob basis, delta;
379 content_get(deltaFrom, &basis);
380 blob_delta_create(&basis, &content, &delta);
381
+1 -1
--- src/fusefs.c
+++ src/fusefs.c
@@ -51,11 +51,11 @@
5151
/* Parsed path */
5252
char *az[3]; /* 0=type, 1=id, 2=path */
5353
} fusefs;
5454
5555
/*
56
-** Clear the fusefs.sz[] array.
56
+** Clear the fusefs.az[] array.
5757
*/
5858
static void fusefs_clear_path(void){
5959
int i;
6060
for(i=0; i<count(fusefs.az); i++){
6161
fossil_free(fusefs.az[i]);
6262
--- src/fusefs.c
+++ src/fusefs.c
@@ -51,11 +51,11 @@
51 /* Parsed path */
52 char *az[3]; /* 0=type, 1=id, 2=path */
53 } fusefs;
54
55 /*
56 ** Clear the fusefs.sz[] array.
57 */
58 static void fusefs_clear_path(void){
59 int i;
60 for(i=0; i<count(fusefs.az); i++){
61 fossil_free(fusefs.az[i]);
62
--- src/fusefs.c
+++ src/fusefs.c
@@ -51,11 +51,11 @@
51 /* Parsed path */
52 char *az[3]; /* 0=type, 1=id, 2=path */
53 } fusefs;
54
55 /*
56 ** Clear the fusefs.az[] array.
57 */
58 static void fusefs_clear_path(void){
59 int i;
60 for(i=0; i<count(fusefs.az); i++){
61 fossil_free(fusefs.az[i]);
62
+41 -42
--- src/lookslike.c
+++ src/lookslike.c
@@ -50,10 +50,41 @@
5050
#define LOOK_INVALID ((int)0x00000200) /* Invalid sequence was found. */
5151
#define LOOK_BINARY (LOOK_NUL | LOOK_LONG | LOOK_SHORT) /* May be binary. */
5252
#define LOOK_EOL (LOOK_LONE_CR | LOOK_LONE_LF | LOOK_CRLF) /* Line seps. */
5353
#endif /* INTERFACE */
5454
55
+/* definitions for various UTF-8 sequence lengths, encoded as start value
56
+ * and size of each valid range belonging to some lead byte*/
57
+#define US2A 0x80, 0x01 /* for lead byte 0xC0 */
58
+#define US2B 0x80, 0x40 /* for lead bytes 0xC2-0xDF */
59
+#define US3A 0xA0, 0x20 /* for lead byte 0xE0 */
60
+#define US3B 0x80, 0x40 /* for lead bytes 0xE1-0xEF */
61
+#define US4A 0x90, 0x30 /* for lead byte 0xF0 */
62
+#define US4B 0x80, 0x40 /* for lead bytes 0xF1-0xF3 */
63
+#define US4C 0x80, 0x10 /* for lead byte 0xF4 */
64
+#define US0A 0x00, 0x00 /* for any other lead byte */
65
+
66
+/* a table used for quick lookup of the definition that goes with a
67
+ * particular lead byte */
68
+static const unsigned char lb_tab[] = {
69
+ US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A,
70
+ US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A,
71
+ US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A,
72
+ US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A,
73
+ US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A,
74
+ US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A,
75
+ US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A,
76
+ US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A,
77
+ US2A, US0A, US2B, US2B, US2B, US2B, US2B, US2B,
78
+ US2B, US2B, US2B, US2B, US2B, US2B, US2B, US2B,
79
+ US2B, US2B, US2B, US2B, US2B, US2B, US2B, US2B,
80
+ US2B, US2B, US2B, US2B, US2B, US2B, US2B, US2B,
81
+ US3A, US3B, US3B, US3B, US3B, US3B, US3B, US3B,
82
+ US3B, US3B, US3B, US3B, US3B, US3B, US3B, US3B,
83
+ US4A, US4B, US4B, US4B, US4C, US0A, US0A, US0A,
84
+ US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A
85
+};
5586
5687
/*
5788
** This function attempts to scan each logical line within the blob to
5889
** determine the type of content it appears to contain. The return value
5990
** is a combination of one or more of the LOOK_XXX flags (see above):
@@ -135,54 +166,22 @@
135166
}
136167
137168
/*
138169
** Checks for proper UTF-8. It uses the method described in:
139170
** http://en.wikipedia.org/wiki/UTF-8#Invalid_byte_sequences
140
-** except for the "overlong form" of \u0000 which is not considered invalid
141
-** here: Some languages like Java and Tcl use it. This function also
142
-** considers valid the derivatives CESU-8 & WTF-8 (as described in the
143
-** same wikipedia article referenced previously). For UTF-8 characters
144
-** > 7f, the variable 'c2' not necessary means the previous character.
145
-** It's number of higher 1-bits indicate the number of continuation bytes
146
-** that are expected to be followed. E.g. when 'c2' has a value in the range
147
-** 0xc0..0xdf it means that 'c' is expected to contain the last continuation
148
-** byte of a UTF-8 character. A value 0xe0..0xef means that after 'c' one
149
-** more continuation byte is expected.
171
+** except for the "overlong form" of \u0000 which is not considered
172
+** invalid here: Some languages like Java and Tcl use it. This function
173
+** also considers valid the derivatives CESU-8 & WTF-8 (as described in
174
+** the same wikipedia article referenced previously). For UTF-8 characters
175
+** > 0x7f, the variable 'c' not necessary means the real lead byte.
176
+** It's number of higher 1-bits indicate the number of continuation
177
+** bytes that are expected to be followed. E.g. when 'c' has a value
178
+** in the range 0xc0..0xdf it means that after 'c' a single continuation
179
+** byte is expected. A value 0xe0..0xef means that after 'c' two more
180
+** continuation bytes are expected.
150181
*/
151182
152
-/* definitions for various UTF-8 sequence lengths, encoded as start value
153
- * and size of each valid range belonging to some lead byte*/
154
-#define US2A 0x80, 0x01 /* for lead byte 0xC0 */
155
-#define US2B 0x80, 0x40 /* for lead bytes 0xC2-0xDF */
156
-#define US3A 0xA0, 0x20 /* for lead byte 0xE0 */
157
-#define US3B 0x80, 0x40 /* for lead bytes 0xE1-0xEF */
158
-#define US4A 0x90, 0x30 /* for lead byte 0xF0 */
159
-#define US4B 0x80, 0x40 /* for lead bytes 0xF1-0xF3 */
160
-#define US4C 0x80, 0x10 /* for lead byte 0xF4 */
161
-#define US0A 0xFF, 0x00 /* for any other lead byte */
162
-
163
-/* a table used for quick lookup of the definition that goes with a
164
- * particular lead byte */
165
-static const unsigned char lb_tab[] = {
166
- US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A,
167
- US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A,
168
- US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A,
169
- US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A,
170
- US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A,
171
- US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A,
172
- US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A,
173
- US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A,
174
- US2A, US0A, US2B, US2B, US2B, US2B, US2B, US2B,
175
- US2B, US2B, US2B, US2B, US2B, US2B, US2B, US2B,
176
- US2B, US2B, US2B, US2B, US2B, US2B, US2B, US2B,
177
- US2B, US2B, US2B, US2B, US2B, US2B, US2B, US2B,
178
- US3A, US3B, US3B, US3B, US3B, US3B, US3B, US3B,
179
- US3B, US3B, US3B, US3B, US3B, US3B, US3B, US3B,
180
- US4A, US4B, US4B, US4B, US4C, US0A, US0A, US0A,
181
- US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A
182
-};
183
-
184183
int invalid_utf8(
185184
const Blob *pContent
186185
){
187186
const unsigned char *z = (unsigned char *) blob_buffer(pContent);
188187
unsigned int n = blob_size(pContent);
189188
--- src/lookslike.c
+++ src/lookslike.c
@@ -50,10 +50,41 @@
50 #define LOOK_INVALID ((int)0x00000200) /* Invalid sequence was found. */
51 #define LOOK_BINARY (LOOK_NUL | LOOK_LONG | LOOK_SHORT) /* May be binary. */
52 #define LOOK_EOL (LOOK_LONE_CR | LOOK_LONE_LF | LOOK_CRLF) /* Line seps. */
53 #endif /* INTERFACE */
54
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55
56 /*
57 ** This function attempts to scan each logical line within the blob to
58 ** determine the type of content it appears to contain. The return value
59 ** is a combination of one or more of the LOOK_XXX flags (see above):
@@ -135,54 +166,22 @@
135 }
136
137 /*
138 ** Checks for proper UTF-8. It uses the method described in:
139 ** http://en.wikipedia.org/wiki/UTF-8#Invalid_byte_sequences
140 ** except for the "overlong form" of \u0000 which is not considered invalid
141 ** here: Some languages like Java and Tcl use it. This function also
142 ** considers valid the derivatives CESU-8 & WTF-8 (as described in the
143 ** same wikipedia article referenced previously). For UTF-8 characters
144 ** > 7f, the variable 'c2' not necessary means the previous character.
145 ** It's number of higher 1-bits indicate the number of continuation bytes
146 ** that are expected to be followed. E.g. when 'c2' has a value in the range
147 ** 0xc0..0xdf it means that 'c' is expected to contain the last continuation
148 ** byte of a UTF-8 character. A value 0xe0..0xef means that after 'c' one
149 ** more continuation byte is expected.
150 */
151
152 /* definitions for various UTF-8 sequence lengths, encoded as start value
153 * and size of each valid range belonging to some lead byte*/
154 #define US2A 0x80, 0x01 /* for lead byte 0xC0 */
155 #define US2B 0x80, 0x40 /* for lead bytes 0xC2-0xDF */
156 #define US3A 0xA0, 0x20 /* for lead byte 0xE0 */
157 #define US3B 0x80, 0x40 /* for lead bytes 0xE1-0xEF */
158 #define US4A 0x90, 0x30 /* for lead byte 0xF0 */
159 #define US4B 0x80, 0x40 /* for lead bytes 0xF1-0xF3 */
160 #define US4C 0x80, 0x10 /* for lead byte 0xF4 */
161 #define US0A 0xFF, 0x00 /* for any other lead byte */
162
163 /* a table used for quick lookup of the definition that goes with a
164 * particular lead byte */
165 static const unsigned char lb_tab[] = {
166 US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A,
167 US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A,
168 US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A,
169 US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A,
170 US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A,
171 US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A,
172 US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A,
173 US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A,
174 US2A, US0A, US2B, US2B, US2B, US2B, US2B, US2B,
175 US2B, US2B, US2B, US2B, US2B, US2B, US2B, US2B,
176 US2B, US2B, US2B, US2B, US2B, US2B, US2B, US2B,
177 US2B, US2B, US2B, US2B, US2B, US2B, US2B, US2B,
178 US3A, US3B, US3B, US3B, US3B, US3B, US3B, US3B,
179 US3B, US3B, US3B, US3B, US3B, US3B, US3B, US3B,
180 US4A, US4B, US4B, US4B, US4C, US0A, US0A, US0A,
181 US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A
182 };
183
184 int invalid_utf8(
185 const Blob *pContent
186 ){
187 const unsigned char *z = (unsigned char *) blob_buffer(pContent);
188 unsigned int n = blob_size(pContent);
189
--- src/lookslike.c
+++ src/lookslike.c
@@ -50,10 +50,41 @@
50 #define LOOK_INVALID ((int)0x00000200) /* Invalid sequence was found. */
51 #define LOOK_BINARY (LOOK_NUL | LOOK_LONG | LOOK_SHORT) /* May be binary. */
52 #define LOOK_EOL (LOOK_LONE_CR | LOOK_LONE_LF | LOOK_CRLF) /* Line seps. */
53 #endif /* INTERFACE */
54
55 /* definitions for various UTF-8 sequence lengths, encoded as start value
56 * and size of each valid range belonging to some lead byte*/
57 #define US2A 0x80, 0x01 /* for lead byte 0xC0 */
58 #define US2B 0x80, 0x40 /* for lead bytes 0xC2-0xDF */
59 #define US3A 0xA0, 0x20 /* for lead byte 0xE0 */
60 #define US3B 0x80, 0x40 /* for lead bytes 0xE1-0xEF */
61 #define US4A 0x90, 0x30 /* for lead byte 0xF0 */
62 #define US4B 0x80, 0x40 /* for lead bytes 0xF1-0xF3 */
63 #define US4C 0x80, 0x10 /* for lead byte 0xF4 */
64 #define US0A 0x00, 0x00 /* for any other lead byte */
65
66 /* a table used for quick lookup of the definition that goes with a
67 * particular lead byte */
68 static const unsigned char lb_tab[] = {
69 US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A,
70 US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A,
71 US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A,
72 US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A,
73 US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A,
74 US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A,
75 US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A,
76 US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A,
77 US2A, US0A, US2B, US2B, US2B, US2B, US2B, US2B,
78 US2B, US2B, US2B, US2B, US2B, US2B, US2B, US2B,
79 US2B, US2B, US2B, US2B, US2B, US2B, US2B, US2B,
80 US2B, US2B, US2B, US2B, US2B, US2B, US2B, US2B,
81 US3A, US3B, US3B, US3B, US3B, US3B, US3B, US3B,
82 US3B, US3B, US3B, US3B, US3B, US3B, US3B, US3B,
83 US4A, US4B, US4B, US4B, US4C, US0A, US0A, US0A,
84 US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A
85 };
86
87 /*
88 ** This function attempts to scan each logical line within the blob to
89 ** determine the type of content it appears to contain. The return value
90 ** is a combination of one or more of the LOOK_XXX flags (see above):
@@ -135,54 +166,22 @@
166 }
167
168 /*
169 ** Checks for proper UTF-8. It uses the method described in:
170 ** http://en.wikipedia.org/wiki/UTF-8#Invalid_byte_sequences
171 ** except for the "overlong form" of \u0000 which is not considered
172 ** invalid here: Some languages like Java and Tcl use it. This function
173 ** also considers valid the derivatives CESU-8 & WTF-8 (as described in
174 ** the same wikipedia article referenced previously). For UTF-8 characters
175 ** > 0x7f, the variable 'c' not necessary means the real lead byte.
176 ** It's number of higher 1-bits indicate the number of continuation
177 ** bytes that are expected to be followed. E.g. when 'c' has a value
178 ** in the range 0xc0..0xdf it means that after 'c' a single continuation
179 ** byte is expected. A value 0xe0..0xef means that after 'c' two more
180 ** continuation bytes are expected.
181 */
182
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
183 int invalid_utf8(
184 const Blob *pContent
185 ){
186 const unsigned char *z = (unsigned char *) blob_buffer(pContent);
187 unsigned int n = blob_size(pContent);
188
+41 -42
--- src/lookslike.c
+++ src/lookslike.c
@@ -50,10 +50,41 @@
5050
#define LOOK_INVALID ((int)0x00000200) /* Invalid sequence was found. */
5151
#define LOOK_BINARY (LOOK_NUL | LOOK_LONG | LOOK_SHORT) /* May be binary. */
5252
#define LOOK_EOL (LOOK_LONE_CR | LOOK_LONE_LF | LOOK_CRLF) /* Line seps. */
5353
#endif /* INTERFACE */
5454
55
+/* definitions for various UTF-8 sequence lengths, encoded as start value
56
+ * and size of each valid range belonging to some lead byte*/
57
+#define US2A 0x80, 0x01 /* for lead byte 0xC0 */
58
+#define US2B 0x80, 0x40 /* for lead bytes 0xC2-0xDF */
59
+#define US3A 0xA0, 0x20 /* for lead byte 0xE0 */
60
+#define US3B 0x80, 0x40 /* for lead bytes 0xE1-0xEF */
61
+#define US4A 0x90, 0x30 /* for lead byte 0xF0 */
62
+#define US4B 0x80, 0x40 /* for lead bytes 0xF1-0xF3 */
63
+#define US4C 0x80, 0x10 /* for lead byte 0xF4 */
64
+#define US0A 0x00, 0x00 /* for any other lead byte */
65
+
66
+/* a table used for quick lookup of the definition that goes with a
67
+ * particular lead byte */
68
+static const unsigned char lb_tab[] = {
69
+ US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A,
70
+ US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A,
71
+ US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A,
72
+ US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A,
73
+ US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A,
74
+ US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A,
75
+ US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A,
76
+ US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A,
77
+ US2A, US0A, US2B, US2B, US2B, US2B, US2B, US2B,
78
+ US2B, US2B, US2B, US2B, US2B, US2B, US2B, US2B,
79
+ US2B, US2B, US2B, US2B, US2B, US2B, US2B, US2B,
80
+ US2B, US2B, US2B, US2B, US2B, US2B, US2B, US2B,
81
+ US3A, US3B, US3B, US3B, US3B, US3B, US3B, US3B,
82
+ US3B, US3B, US3B, US3B, US3B, US3B, US3B, US3B,
83
+ US4A, US4B, US4B, US4B, US4C, US0A, US0A, US0A,
84
+ US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A
85
+};
5586
5687
/*
5788
** This function attempts to scan each logical line within the blob to
5889
** determine the type of content it appears to contain. The return value
5990
** is a combination of one or more of the LOOK_XXX flags (see above):
@@ -135,54 +166,22 @@
135166
}
136167
137168
/*
138169
** Checks for proper UTF-8. It uses the method described in:
139170
** http://en.wikipedia.org/wiki/UTF-8#Invalid_byte_sequences
140
-** except for the "overlong form" of \u0000 which is not considered invalid
141
-** here: Some languages like Java and Tcl use it. This function also
142
-** considers valid the derivatives CESU-8 & WTF-8 (as described in the
143
-** same wikipedia article referenced previously). For UTF-8 characters
144
-** > 7f, the variable 'c2' not necessary means the previous character.
145
-** It's number of higher 1-bits indicate the number of continuation bytes
146
-** that are expected to be followed. E.g. when 'c2' has a value in the range
147
-** 0xc0..0xdf it means that 'c' is expected to contain the last continuation
148
-** byte of a UTF-8 character. A value 0xe0..0xef means that after 'c' one
149
-** more continuation byte is expected.
171
+** except for the "overlong form" of \u0000 which is not considered
172
+** invalid here: Some languages like Java and Tcl use it. This function
173
+** also considers valid the derivatives CESU-8 & WTF-8 (as described in
174
+** the same wikipedia article referenced previously). For UTF-8 characters
175
+** > 0x7f, the variable 'c' not necessary means the real lead byte.
176
+** It's number of higher 1-bits indicate the number of continuation
177
+** bytes that are expected to be followed. E.g. when 'c' has a value
178
+** in the range 0xc0..0xdf it means that after 'c' a single continuation
179
+** byte is expected. A value 0xe0..0xef means that after 'c' two more
180
+** continuation bytes are expected.
150181
*/
151182
152
-/* definitions for various UTF-8 sequence lengths, encoded as start value
153
- * and size of each valid range belonging to some lead byte*/
154
-#define US2A 0x80, 0x01 /* for lead byte 0xC0 */
155
-#define US2B 0x80, 0x40 /* for lead bytes 0xC2-0xDF */
156
-#define US3A 0xA0, 0x20 /* for lead byte 0xE0 */
157
-#define US3B 0x80, 0x40 /* for lead bytes 0xE1-0xEF */
158
-#define US4A 0x90, 0x30 /* for lead byte 0xF0 */
159
-#define US4B 0x80, 0x40 /* for lead bytes 0xF1-0xF3 */
160
-#define US4C 0x80, 0x10 /* for lead byte 0xF4 */
161
-#define US0A 0xFF, 0x00 /* for any other lead byte */
162
-
163
-/* a table used for quick lookup of the definition that goes with a
164
- * particular lead byte */
165
-static const unsigned char lb_tab[] = {
166
- US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A,
167
- US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A,
168
- US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A,
169
- US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A,
170
- US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A,
171
- US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A,
172
- US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A,
173
- US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A,
174
- US2A, US0A, US2B, US2B, US2B, US2B, US2B, US2B,
175
- US2B, US2B, US2B, US2B, US2B, US2B, US2B, US2B,
176
- US2B, US2B, US2B, US2B, US2B, US2B, US2B, US2B,
177
- US2B, US2B, US2B, US2B, US2B, US2B, US2B, US2B,
178
- US3A, US3B, US3B, US3B, US3B, US3B, US3B, US3B,
179
- US3B, US3B, US3B, US3B, US3B, US3B, US3B, US3B,
180
- US4A, US4B, US4B, US4B, US4C, US0A, US0A, US0A,
181
- US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A
182
-};
183
-
184183
int invalid_utf8(
185184
const Blob *pContent
186185
){
187186
const unsigned char *z = (unsigned char *) blob_buffer(pContent);
188187
unsigned int n = blob_size(pContent);
189188
--- src/lookslike.c
+++ src/lookslike.c
@@ -50,10 +50,41 @@
50 #define LOOK_INVALID ((int)0x00000200) /* Invalid sequence was found. */
51 #define LOOK_BINARY (LOOK_NUL | LOOK_LONG | LOOK_SHORT) /* May be binary. */
52 #define LOOK_EOL (LOOK_LONE_CR | LOOK_LONE_LF | LOOK_CRLF) /* Line seps. */
53 #endif /* INTERFACE */
54
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55
56 /*
57 ** This function attempts to scan each logical line within the blob to
58 ** determine the type of content it appears to contain. The return value
59 ** is a combination of one or more of the LOOK_XXX flags (see above):
@@ -135,54 +166,22 @@
135 }
136
137 /*
138 ** Checks for proper UTF-8. It uses the method described in:
139 ** http://en.wikipedia.org/wiki/UTF-8#Invalid_byte_sequences
140 ** except for the "overlong form" of \u0000 which is not considered invalid
141 ** here: Some languages like Java and Tcl use it. This function also
142 ** considers valid the derivatives CESU-8 & WTF-8 (as described in the
143 ** same wikipedia article referenced previously). For UTF-8 characters
144 ** > 7f, the variable 'c2' not necessary means the previous character.
145 ** It's number of higher 1-bits indicate the number of continuation bytes
146 ** that are expected to be followed. E.g. when 'c2' has a value in the range
147 ** 0xc0..0xdf it means that 'c' is expected to contain the last continuation
148 ** byte of a UTF-8 character. A value 0xe0..0xef means that after 'c' one
149 ** more continuation byte is expected.
150 */
151
152 /* definitions for various UTF-8 sequence lengths, encoded as start value
153 * and size of each valid range belonging to some lead byte*/
154 #define US2A 0x80, 0x01 /* for lead byte 0xC0 */
155 #define US2B 0x80, 0x40 /* for lead bytes 0xC2-0xDF */
156 #define US3A 0xA0, 0x20 /* for lead byte 0xE0 */
157 #define US3B 0x80, 0x40 /* for lead bytes 0xE1-0xEF */
158 #define US4A 0x90, 0x30 /* for lead byte 0xF0 */
159 #define US4B 0x80, 0x40 /* for lead bytes 0xF1-0xF3 */
160 #define US4C 0x80, 0x10 /* for lead byte 0xF4 */
161 #define US0A 0xFF, 0x00 /* for any other lead byte */
162
163 /* a table used for quick lookup of the definition that goes with a
164 * particular lead byte */
165 static const unsigned char lb_tab[] = {
166 US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A,
167 US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A,
168 US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A,
169 US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A,
170 US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A,
171 US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A,
172 US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A,
173 US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A,
174 US2A, US0A, US2B, US2B, US2B, US2B, US2B, US2B,
175 US2B, US2B, US2B, US2B, US2B, US2B, US2B, US2B,
176 US2B, US2B, US2B, US2B, US2B, US2B, US2B, US2B,
177 US2B, US2B, US2B, US2B, US2B, US2B, US2B, US2B,
178 US3A, US3B, US3B, US3B, US3B, US3B, US3B, US3B,
179 US3B, US3B, US3B, US3B, US3B, US3B, US3B, US3B,
180 US4A, US4B, US4B, US4B, US4C, US0A, US0A, US0A,
181 US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A
182 };
183
184 int invalid_utf8(
185 const Blob *pContent
186 ){
187 const unsigned char *z = (unsigned char *) blob_buffer(pContent);
188 unsigned int n = blob_size(pContent);
189
--- src/lookslike.c
+++ src/lookslike.c
@@ -50,10 +50,41 @@
50 #define LOOK_INVALID ((int)0x00000200) /* Invalid sequence was found. */
51 #define LOOK_BINARY (LOOK_NUL | LOOK_LONG | LOOK_SHORT) /* May be binary. */
52 #define LOOK_EOL (LOOK_LONE_CR | LOOK_LONE_LF | LOOK_CRLF) /* Line seps. */
53 #endif /* INTERFACE */
54
55 /* definitions for various UTF-8 sequence lengths, encoded as start value
56 * and size of each valid range belonging to some lead byte*/
57 #define US2A 0x80, 0x01 /* for lead byte 0xC0 */
58 #define US2B 0x80, 0x40 /* for lead bytes 0xC2-0xDF */
59 #define US3A 0xA0, 0x20 /* for lead byte 0xE0 */
60 #define US3B 0x80, 0x40 /* for lead bytes 0xE1-0xEF */
61 #define US4A 0x90, 0x30 /* for lead byte 0xF0 */
62 #define US4B 0x80, 0x40 /* for lead bytes 0xF1-0xF3 */
63 #define US4C 0x80, 0x10 /* for lead byte 0xF4 */
64 #define US0A 0x00, 0x00 /* for any other lead byte */
65
66 /* a table used for quick lookup of the definition that goes with a
67 * particular lead byte */
68 static const unsigned char lb_tab[] = {
69 US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A,
70 US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A,
71 US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A,
72 US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A,
73 US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A,
74 US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A,
75 US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A,
76 US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A,
77 US2A, US0A, US2B, US2B, US2B, US2B, US2B, US2B,
78 US2B, US2B, US2B, US2B, US2B, US2B, US2B, US2B,
79 US2B, US2B, US2B, US2B, US2B, US2B, US2B, US2B,
80 US2B, US2B, US2B, US2B, US2B, US2B, US2B, US2B,
81 US3A, US3B, US3B, US3B, US3B, US3B, US3B, US3B,
82 US3B, US3B, US3B, US3B, US3B, US3B, US3B, US3B,
83 US4A, US4B, US4B, US4B, US4C, US0A, US0A, US0A,
84 US0A, US0A, US0A, US0A, US0A, US0A, US0A, US0A
85 };
86
87 /*
88 ** This function attempts to scan each logical line within the blob to
89 ** determine the type of content it appears to contain. The return value
90 ** is a combination of one or more of the LOOK_XXX flags (see above):
@@ -135,54 +166,22 @@
166 }
167
168 /*
169 ** Checks for proper UTF-8. It uses the method described in:
170 ** http://en.wikipedia.org/wiki/UTF-8#Invalid_byte_sequences
171 ** except for the "overlong form" of \u0000 which is not considered
172 ** invalid here: Some languages like Java and Tcl use it. This function
173 ** also considers valid the derivatives CESU-8 & WTF-8 (as described in
174 ** the same wikipedia article referenced previously). For UTF-8 characters
175 ** > 0x7f, the variable 'c' not necessary means the real lead byte.
176 ** It's number of higher 1-bits indicate the number of continuation
177 ** bytes that are expected to be followed. E.g. when 'c' has a value
178 ** in the range 0xc0..0xdf it means that after 'c' a single continuation
179 ** byte is expected. A value 0xe0..0xef means that after 'c' two more
180 ** continuation bytes are expected.
181 */
182
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
183 int invalid_utf8(
184 const Blob *pContent
185 ){
186 const unsigned char *z = (unsigned char *) blob_buffer(pContent);
187 unsigned int n = blob_size(pContent);
188
+16 -16
--- src/markdown.c
+++ src/markdown.c
@@ -35,12 +35,12 @@
3535
#if INTERFACE
3636
3737
/* mkd_autolink -- type of autolink */
3838
enum mkd_autolink {
3939
MKDA_NOT_AUTOLINK, /* used internally when it is not an autolink*/
40
- MKDA_NORMAL, /* normal http/http/ftp/etc link */
41
- MKDA_EXPLICIT_EMAIL, /* e-mail link with explit mailto: */
40
+ MKDA_NORMAL, /* normal http/http/ftp link */
41
+ MKDA_EXPLICIT_EMAIL, /* e-mail link with explicit mailto: */
4242
MKDA_IMPLICIT_EMAIL /* e-mail link without mailto: */
4343
};
4444
4545
/* mkd_renderer -- functions for rendering parsed data */
4646
struct mkd_renderer {
@@ -348,11 +348,11 @@
348348
if( i>=size || data[i]!='>' || nb!=1 ) return 0;
349349
return i+1;
350350
}
351351
352352
353
-/* tag_length -- returns the length of the given tag, or 0 is it's not valid */
353
+/* tag_length -- returns the length of the given tag, or 0 if it's not valid */
354354
static size_t tag_length(char *data, size_t size, enum mkd_autolink *autolink){
355355
size_t i, j;
356356
357357
/* a valid tag can't be shorter than 3 chars */
358358
if( size<3 ) return 0;
@@ -403,11 +403,11 @@
403403
}else if( (j = is_mail_autolink(data+i, size-i))!=0 ){
404404
*autolink = (i==8) ? MKDA_EXPLICIT_EMAIL : MKDA_IMPLICIT_EMAIL;
405405
return i+j;
406406
}
407407
408
- /* looking for sometinhg looking like a tag end */
408
+ /* looking for something looking like a tag end */
409409
while( i<size && data[i]!='>' ){ i++; }
410410
if( i>=size ) return 0;
411411
return i+1;
412412
}
413413
@@ -520,11 +520,11 @@
520520
}
521521
return 0;
522522
}
523523
524524
525
-/* parse_emph1 -- parsing single emphase */
525
+/* parse_emph1 -- parsing single emphasis */
526526
/* closed by a symbol not preceded by whitespace and not followed by symbol */
527527
static size_t parse_emph1(
528528
struct Blob *ob,
529529
struct render *rndr,
530530
char *data,
@@ -565,11 +565,11 @@
565565
}
566566
return 0;
567567
}
568568
569569
570
-/* parse_emph2 -- parsing single emphase */
570
+/* parse_emph2 -- parsing single emphasis */
571571
static size_t parse_emph2(
572572
struct Blob *ob,
573573
struct render *rndr,
574574
char *data,
575575
size_t size,
@@ -604,11 +604,11 @@
604604
}
605605
return 0;
606606
}
607607
608608
609
-/* parse_emph3 -- parsing single emphase */
609
+/* parse_emph3 -- parsing single emphasis */
610610
/* finds the first closing tag, and delegates to the other emph */
611611
static size_t parse_emph3(
612612
struct Blob *ob,
613613
struct render *rndr,
614614
char *data,
@@ -777,11 +777,11 @@
777777
return 2;
778778
}
779779
780780
781781
/* char_entity -- '&' escaped when it doesn't belong to an entity */
782
-/* valid entities are assumed to be anything mathing &#?[A-Za-z0-9]+; */
782
+/* valid entities are assumed to be anything matching &#?[A-Za-z0-9]+; */
783783
static size_t char_entity(
784784
struct Blob *ob,
785785
struct render *rndr,
786786
char *data,
787787
size_t offset,
@@ -1022,11 +1022,11 @@
10221022
if( i+1==id_end ){
10231023
/* implicit id - use the contents */
10241024
id_data = data+1;
10251025
id_size = txt_e-1;
10261026
}else{
1027
- /* explici id - between brackets */
1027
+ /* explicit id - between brackets */
10281028
id_data = data+i+1;
10291029
id_size = id_end-(i+1);
10301030
}
10311031
10321032
if( get_link_ref(rndr, link, title, id_data, id_size)<0 ){
@@ -1138,11 +1138,11 @@
11381138
11391139
return 0;
11401140
}
11411141
11421142
1143
-/* is_table_sep -- returns wether there is a table separator at the given pos */
1143
+/* is_table_sep -- returns whether there is a table separator at pos */
11441144
static int is_table_sep(char *data, size_t pos){
11451145
return data[pos]=='|' && (pos==0 || data[pos-1]!='\\');
11461146
}
11471147
11481148
@@ -1187,11 +1187,11 @@
11871187
return 0;
11881188
}
11891189
}
11901190
11911191
1192
-/* prefix_code -- returns prefix length for block code*/
1192
+/* prefix_code -- returns prefix length for block code */
11931193
static size_t prefix_code(char *data, size_t size){
11941194
if( size>0 && data[0]=='\t' ) return 1;
11951195
if( size>3 && data[0]==' ' && data[1]==' ' && data[2]==' ' && data[3]==' ' ){
11961196
return 4;
11971197
}
@@ -1244,11 +1244,11 @@
12441244
struct render *rndr,
12451245
char *data,
12461246
size_t size);
12471247
12481248
1249
-/* parse_blockquote -- hanldes parsing of a blockquote fragment */
1249
+/* parse_blockquote -- handles parsing of a blockquote fragment */
12501250
static size_t parse_blockquote(
12511251
struct Blob *ob,
12521252
struct render *rndr,
12531253
char *data,
12541254
size_t size
@@ -1294,11 +1294,11 @@
12941294
release_work_buffer(rndr, out);
12951295
return end;
12961296
}
12971297
12981298
1299
-/* parse_blockquote -- hanldes parsing of a regular paragraph */
1299
+/* parse_paragraph -- handles parsing of a regular paragraph */
13001300
static size_t parse_paragraph(
13011301
struct Blob *ob,
13021302
struct render *rndr,
13031303
char *data,
13041304
size_t size
@@ -1377,11 +1377,11 @@
13771377
}
13781378
return end;
13791379
}
13801380
13811381
1382
-/* parse_blockquote -- hanldes parsing of a block-level code fragment */
1382
+/* parse_blockcode -- handles parsing of a block-level code fragment */
13831383
static size_t parse_blockcode(
13841384
struct Blob *ob,
13851385
struct render *rndr,
13861386
char *data,
13871387
size_t size
@@ -1813,11 +1813,11 @@
18131813
size_t i = 0, col = 0;
18141814
size_t beg, end, total = 0;
18151815
struct Blob *cells = new_work_buffer(rndr);
18161816
int align;
18171817
1818
- /* skip leading blanks and sperator */
1818
+ /* skip leading blanks and separator */
18191819
while( i<size && (data[i]==' ' || data[i]=='\t') ){ i++; }
18201820
if( i<size && data[i]=='|' ) i++;
18211821
18221822
/* go over all the cells */
18231823
while( i<size && total==0 ){
@@ -2030,11 +2030,11 @@
20302030
static int is_ref(
20312031
char *data, /* input text */
20322032
size_t beg, /* offset of the beginning of the line */
20332033
size_t end, /* offset of the end of the text */
20342034
size_t *last, /* last character of the link */
2035
- struct Blob *refs /* arry of link references */
2035
+ struct Blob *refs /* array of link references */
20362036
){
20372037
size_t i = 0;
20382038
size_t id_offset, id_end;
20392039
size_t link_offset, link_end;
20402040
size_t title_offset, title_end;
20412041
--- src/markdown.c
+++ src/markdown.c
@@ -35,12 +35,12 @@
35 #if INTERFACE
36
37 /* mkd_autolink -- type of autolink */
38 enum mkd_autolink {
39 MKDA_NOT_AUTOLINK, /* used internally when it is not an autolink*/
40 MKDA_NORMAL, /* normal http/http/ftp/etc link */
41 MKDA_EXPLICIT_EMAIL, /* e-mail link with explit mailto: */
42 MKDA_IMPLICIT_EMAIL /* e-mail link without mailto: */
43 };
44
45 /* mkd_renderer -- functions for rendering parsed data */
46 struct mkd_renderer {
@@ -348,11 +348,11 @@
348 if( i>=size || data[i]!='>' || nb!=1 ) return 0;
349 return i+1;
350 }
351
352
353 /* tag_length -- returns the length of the given tag, or 0 is it's not valid */
354 static size_t tag_length(char *data, size_t size, enum mkd_autolink *autolink){
355 size_t i, j;
356
357 /* a valid tag can't be shorter than 3 chars */
358 if( size<3 ) return 0;
@@ -403,11 +403,11 @@
403 }else if( (j = is_mail_autolink(data+i, size-i))!=0 ){
404 *autolink = (i==8) ? MKDA_EXPLICIT_EMAIL : MKDA_IMPLICIT_EMAIL;
405 return i+j;
406 }
407
408 /* looking for sometinhg looking like a tag end */
409 while( i<size && data[i]!='>' ){ i++; }
410 if( i>=size ) return 0;
411 return i+1;
412 }
413
@@ -520,11 +520,11 @@
520 }
521 return 0;
522 }
523
524
525 /* parse_emph1 -- parsing single emphase */
526 /* closed by a symbol not preceded by whitespace and not followed by symbol */
527 static size_t parse_emph1(
528 struct Blob *ob,
529 struct render *rndr,
530 char *data,
@@ -565,11 +565,11 @@
565 }
566 return 0;
567 }
568
569
570 /* parse_emph2 -- parsing single emphase */
571 static size_t parse_emph2(
572 struct Blob *ob,
573 struct render *rndr,
574 char *data,
575 size_t size,
@@ -604,11 +604,11 @@
604 }
605 return 0;
606 }
607
608
609 /* parse_emph3 -- parsing single emphase */
610 /* finds the first closing tag, and delegates to the other emph */
611 static size_t parse_emph3(
612 struct Blob *ob,
613 struct render *rndr,
614 char *data,
@@ -777,11 +777,11 @@
777 return 2;
778 }
779
780
781 /* char_entity -- '&' escaped when it doesn't belong to an entity */
782 /* valid entities are assumed to be anything mathing &#?[A-Za-z0-9]+; */
783 static size_t char_entity(
784 struct Blob *ob,
785 struct render *rndr,
786 char *data,
787 size_t offset,
@@ -1022,11 +1022,11 @@
1022 if( i+1==id_end ){
1023 /* implicit id - use the contents */
1024 id_data = data+1;
1025 id_size = txt_e-1;
1026 }else{
1027 /* explici id - between brackets */
1028 id_data = data+i+1;
1029 id_size = id_end-(i+1);
1030 }
1031
1032 if( get_link_ref(rndr, link, title, id_data, id_size)<0 ){
@@ -1138,11 +1138,11 @@
1138
1139 return 0;
1140 }
1141
1142
1143 /* is_table_sep -- returns wether there is a table separator at the given pos */
1144 static int is_table_sep(char *data, size_t pos){
1145 return data[pos]=='|' && (pos==0 || data[pos-1]!='\\');
1146 }
1147
1148
@@ -1187,11 +1187,11 @@
1187 return 0;
1188 }
1189 }
1190
1191
1192 /* prefix_code -- returns prefix length for block code*/
1193 static size_t prefix_code(char *data, size_t size){
1194 if( size>0 && data[0]=='\t' ) return 1;
1195 if( size>3 && data[0]==' ' && data[1]==' ' && data[2]==' ' && data[3]==' ' ){
1196 return 4;
1197 }
@@ -1244,11 +1244,11 @@
1244 struct render *rndr,
1245 char *data,
1246 size_t size);
1247
1248
1249 /* parse_blockquote -- hanldes parsing of a blockquote fragment */
1250 static size_t parse_blockquote(
1251 struct Blob *ob,
1252 struct render *rndr,
1253 char *data,
1254 size_t size
@@ -1294,11 +1294,11 @@
1294 release_work_buffer(rndr, out);
1295 return end;
1296 }
1297
1298
1299 /* parse_blockquote -- hanldes parsing of a regular paragraph */
1300 static size_t parse_paragraph(
1301 struct Blob *ob,
1302 struct render *rndr,
1303 char *data,
1304 size_t size
@@ -1377,11 +1377,11 @@
1377 }
1378 return end;
1379 }
1380
1381
1382 /* parse_blockquote -- hanldes parsing of a block-level code fragment */
1383 static size_t parse_blockcode(
1384 struct Blob *ob,
1385 struct render *rndr,
1386 char *data,
1387 size_t size
@@ -1813,11 +1813,11 @@
1813 size_t i = 0, col = 0;
1814 size_t beg, end, total = 0;
1815 struct Blob *cells = new_work_buffer(rndr);
1816 int align;
1817
1818 /* skip leading blanks and sperator */
1819 while( i<size && (data[i]==' ' || data[i]=='\t') ){ i++; }
1820 if( i<size && data[i]=='|' ) i++;
1821
1822 /* go over all the cells */
1823 while( i<size && total==0 ){
@@ -2030,11 +2030,11 @@
2030 static int is_ref(
2031 char *data, /* input text */
2032 size_t beg, /* offset of the beginning of the line */
2033 size_t end, /* offset of the end of the text */
2034 size_t *last, /* last character of the link */
2035 struct Blob *refs /* arry of link references */
2036 ){
2037 size_t i = 0;
2038 size_t id_offset, id_end;
2039 size_t link_offset, link_end;
2040 size_t title_offset, title_end;
2041
--- src/markdown.c
+++ src/markdown.c
@@ -35,12 +35,12 @@
35 #if INTERFACE
36
37 /* mkd_autolink -- type of autolink */
38 enum mkd_autolink {
39 MKDA_NOT_AUTOLINK, /* used internally when it is not an autolink*/
40 MKDA_NORMAL, /* normal http/http/ftp link */
41 MKDA_EXPLICIT_EMAIL, /* e-mail link with explicit mailto: */
42 MKDA_IMPLICIT_EMAIL /* e-mail link without mailto: */
43 };
44
45 /* mkd_renderer -- functions for rendering parsed data */
46 struct mkd_renderer {
@@ -348,11 +348,11 @@
348 if( i>=size || data[i]!='>' || nb!=1 ) return 0;
349 return i+1;
350 }
351
352
353 /* tag_length -- returns the length of the given tag, or 0 if it's not valid */
354 static size_t tag_length(char *data, size_t size, enum mkd_autolink *autolink){
355 size_t i, j;
356
357 /* a valid tag can't be shorter than 3 chars */
358 if( size<3 ) return 0;
@@ -403,11 +403,11 @@
403 }else if( (j = is_mail_autolink(data+i, size-i))!=0 ){
404 *autolink = (i==8) ? MKDA_EXPLICIT_EMAIL : MKDA_IMPLICIT_EMAIL;
405 return i+j;
406 }
407
408 /* looking for something looking like a tag end */
409 while( i<size && data[i]!='>' ){ i++; }
410 if( i>=size ) return 0;
411 return i+1;
412 }
413
@@ -520,11 +520,11 @@
520 }
521 return 0;
522 }
523
524
525 /* parse_emph1 -- parsing single emphasis */
526 /* closed by a symbol not preceded by whitespace and not followed by symbol */
527 static size_t parse_emph1(
528 struct Blob *ob,
529 struct render *rndr,
530 char *data,
@@ -565,11 +565,11 @@
565 }
566 return 0;
567 }
568
569
570 /* parse_emph2 -- parsing single emphasis */
571 static size_t parse_emph2(
572 struct Blob *ob,
573 struct render *rndr,
574 char *data,
575 size_t size,
@@ -604,11 +604,11 @@
604 }
605 return 0;
606 }
607
608
609 /* parse_emph3 -- parsing single emphasis */
610 /* finds the first closing tag, and delegates to the other emph */
611 static size_t parse_emph3(
612 struct Blob *ob,
613 struct render *rndr,
614 char *data,
@@ -777,11 +777,11 @@
777 return 2;
778 }
779
780
781 /* char_entity -- '&' escaped when it doesn't belong to an entity */
782 /* valid entities are assumed to be anything matching &#?[A-Za-z0-9]+; */
783 static size_t char_entity(
784 struct Blob *ob,
785 struct render *rndr,
786 char *data,
787 size_t offset,
@@ -1022,11 +1022,11 @@
1022 if( i+1==id_end ){
1023 /* implicit id - use the contents */
1024 id_data = data+1;
1025 id_size = txt_e-1;
1026 }else{
1027 /* explicit id - between brackets */
1028 id_data = data+i+1;
1029 id_size = id_end-(i+1);
1030 }
1031
1032 if( get_link_ref(rndr, link, title, id_data, id_size)<0 ){
@@ -1138,11 +1138,11 @@
1138
1139 return 0;
1140 }
1141
1142
1143 /* is_table_sep -- returns whether there is a table separator at pos */
1144 static int is_table_sep(char *data, size_t pos){
1145 return data[pos]=='|' && (pos==0 || data[pos-1]!='\\');
1146 }
1147
1148
@@ -1187,11 +1187,11 @@
1187 return 0;
1188 }
1189 }
1190
1191
1192 /* prefix_code -- returns prefix length for block code */
1193 static size_t prefix_code(char *data, size_t size){
1194 if( size>0 && data[0]=='\t' ) return 1;
1195 if( size>3 && data[0]==' ' && data[1]==' ' && data[2]==' ' && data[3]==' ' ){
1196 return 4;
1197 }
@@ -1244,11 +1244,11 @@
1244 struct render *rndr,
1245 char *data,
1246 size_t size);
1247
1248
1249 /* parse_blockquote -- handles parsing of a blockquote fragment */
1250 static size_t parse_blockquote(
1251 struct Blob *ob,
1252 struct render *rndr,
1253 char *data,
1254 size_t size
@@ -1294,11 +1294,11 @@
1294 release_work_buffer(rndr, out);
1295 return end;
1296 }
1297
1298
1299 /* parse_paragraph -- handles parsing of a regular paragraph */
1300 static size_t parse_paragraph(
1301 struct Blob *ob,
1302 struct render *rndr,
1303 char *data,
1304 size_t size
@@ -1377,11 +1377,11 @@
1377 }
1378 return end;
1379 }
1380
1381
1382 /* parse_blockcode -- handles parsing of a block-level code fragment */
1383 static size_t parse_blockcode(
1384 struct Blob *ob,
1385 struct render *rndr,
1386 char *data,
1387 size_t size
@@ -1813,11 +1813,11 @@
1813 size_t i = 0, col = 0;
1814 size_t beg, end, total = 0;
1815 struct Blob *cells = new_work_buffer(rndr);
1816 int align;
1817
1818 /* skip leading blanks and separator */
1819 while( i<size && (data[i]==' ' || data[i]=='\t') ){ i++; }
1820 if( i<size && data[i]=='|' ) i++;
1821
1822 /* go over all the cells */
1823 while( i<size && total==0 ){
@@ -2030,11 +2030,11 @@
2030 static int is_ref(
2031 char *data, /* input text */
2032 size_t beg, /* offset of the beginning of the line */
2033 size_t end, /* offset of the end of the text */
2034 size_t *last, /* last character of the link */
2035 struct Blob *refs /* array of link references */
2036 ){
2037 size_t i = 0;
2038 size_t id_offset, id_end;
2039 size_t link_offset, link_end;
2040 size_t title_offset, title_end;
2041
--- src/markdown_html.c
+++ src/markdown_html.c
@@ -357,11 +357,11 @@
357357
struct Blob *content,
358358
void *opaque
359359
){
360360
char *zLink = blob_buffer(link);
361361
BLOB_APPEND_LITERAL(ob, "<a href=\"");
362
- if( zLink[0]=='/' ){
362
+ if( zLink && zLink[0]=='/' ){
363363
/* For any hyperlink that begins with "/", make it refer to the root
364364
** of the Fossil repository */
365365
blob_append(ob, g.zTop, -1);
366366
}
367367
html_escape(ob, blob_buffer(link), blob_size(link));
368368
--- src/markdown_html.c
+++ src/markdown_html.c
@@ -357,11 +357,11 @@
357 struct Blob *content,
358 void *opaque
359 ){
360 char *zLink = blob_buffer(link);
361 BLOB_APPEND_LITERAL(ob, "<a href=\"");
362 if( zLink[0]=='/' ){
363 /* For any hyperlink that begins with "/", make it refer to the root
364 ** of the Fossil repository */
365 blob_append(ob, g.zTop, -1);
366 }
367 html_escape(ob, blob_buffer(link), blob_size(link));
368
--- src/markdown_html.c
+++ src/markdown_html.c
@@ -357,11 +357,11 @@
357 struct Blob *content,
358 void *opaque
359 ){
360 char *zLink = blob_buffer(link);
361 BLOB_APPEND_LITERAL(ob, "<a href=\"");
362 if( zLink && zLink[0]=='/' ){
363 /* For any hyperlink that begins with "/", make it refer to the root
364 ** of the Fossil repository */
365 blob_append(ob, g.zTop, -1);
366 }
367 html_escape(ob, blob_buffer(link), blob_size(link));
368
--- src/timeline.c
+++ src/timeline.c
@@ -1183,10 +1183,36 @@
11831183
}
11841184
if( i>2 ){
11851185
style_submenu_multichoice("y", i/2, az, isDisabled);
11861186
}
11871187
}
1188
+
1189
+/*
1190
+** If the zChng string is not NULL, then it should be a comma-separated
1191
+** list of glob patterns for filenames. Add an term to the WHERE clause
1192
+** for the SQL statement under construction that excludes any check-in that
1193
+** does not modify one or more files matching the globs.
1194
+*/
1195
+static void addFileGlobExclusion(
1196
+ const char *zChng, /* The filename GLOB list */
1197
+ Blob *pSql /* The SELECT statement under construction */
1198
+){
1199
+ if( zChng==0 || zChng[0]==0 ) return;
1200
+ blob_append_sql(pSql," AND event.objid IN ("
1201
+ "SELECT mlink.mid FROM mlink, filename"
1202
+ " WHERE mlink.fnid=filename.fnid AND %s)",
1203
+ glob_expr("filename.name", zChng));
1204
+}
1205
+static void addFileGlobDescription(
1206
+ const char *zChng, /* The filename GLOB list */
1207
+ Blob *pDescription /* Result description */
1208
+){
1209
+ if( zChng==0 || zChng[0]==0 ) return;
1210
+ blob_appendf(pDescription, " that include changes to files matching %Q",
1211
+ zChng);
1212
+}
1213
+
11881214
11891215
/*
11901216
** WEBPAGE: timeline
11911217
**
11921218
** Query parameters:
@@ -1209,10 +1235,12 @@
12091235
** f=CHECKIN Show family (immediate parents and children) of CHECKIN
12101236
** from=CHECKIN Path from...
12111237
** to=CHECKIN ... to this
12121238
** shortest ... show only the shortest path
12131239
** uf=FILE_SHA1 Show only check-ins that contain the given file version
1240
+** chng=GLOBLIST Show only check-ins that involve changes to a file whose
1241
+** name matches one of the comma-separate GLOBLIST.
12141242
** brbg Background color from branch name
12151243
** ubg Background color from user
12161244
** namechng Show only check-ins that have filename changes
12171245
** forks Show only forks and their children
12181246
** ym=YYYY-MM Show only events for the given year/month.
@@ -1245,10 +1273,11 @@
12451273
const char *zSearch = P("s"); /* Search string */
12461274
const char *zUses = P("uf"); /* Only show check-ins hold this file */
12471275
const char *zYearMonth = P("ym"); /* Show check-ins for the given YYYY-MM */
12481276
const char *zYearWeek = P("yw"); /* Check-ins for YYYY-WW (week-of-year) */
12491277
const char *zDay = P("ymd"); /* Check-ins for the day YYYY-MM-DD */
1278
+ const char *zChng = P("chng"); /* List of GLOBs for files that changed */
12501279
int useDividers = P("nd")==0; /* Show dividers if "nd" is missing */
12511280
int renameOnly = P("namechng")!=0; /* Show only check-ins that rename files */
12521281
int forkOnly = PB("forks"); /* Show only forks and their children */
12531282
int bisectOnly = PB("bisect"); /* Show the check-ins of the bisect */
12541283
int tagid; /* Tag ID */
@@ -1437,17 +1466,21 @@
14371466
blob_append_sql(&sql, ",%d", p->rid);
14381467
p = p->u.pTo;
14391468
}
14401469
blob_append(&sql, ")", -1);
14411470
path_reset();
1471
+ addFileGlobExclusion(zChng, &sql);
14421472
tmFlags |= TIMELINE_DISJOINT;
14431473
db_multi_exec("%s", blob_sql_text(&sql));
1474
+ style_submenu_binary("v","With Files","Without Files",
1475
+ zType[0]!='a' && zType[0]!='c');
14441476
blob_appendf(&desc, "%d check-ins going from ",
14451477
db_int(0, "SELECT count(*) FROM timeline"));
14461478
blob_appendf(&desc, "%z[%h]</a>", href("%R/info/%h", zFrom), zFrom);
14471479
blob_append(&desc, " to ", -1);
14481480
blob_appendf(&desc, "%z[%h]</a>", href("%R/info/%h",zTo), zTo);
1481
+ addFileGlobDescription(zChng, &desc);
14491482
}else if( (p_rid || d_rid) && g.perm.Read ){
14501483
/* If p= or d= is present, ignore all other parameters other than n= */
14511484
char *zUuid;
14521485
int np, nd;
14531486
@@ -1520,10 +1553,11 @@
15201553
int n;
15211554
const char *zEType = "timeline item";
15221555
char *zDate;
15231556
Blob cond;
15241557
blob_zero(&cond);
1558
+ addFileGlobExclusion(zChng, &cond);
15251559
if( zUses ){
15261560
blob_append_sql(&cond, " AND event.objid IN usesfile ");
15271561
}
15281562
if( renameOnly ){
15291563
blob_append_sql(&cond, " AND event.objid IN rnfile ");
@@ -1730,10 +1764,11 @@
17301764
tmFlags |= TIMELINE_DISJOINT;
17311765
}else if( zBrName ){
17321766
blob_appendf(&desc, " related to \"%h\"", zBrName);
17331767
tmFlags |= TIMELINE_DISJOINT;
17341768
}
1769
+ addFileGlobDescription(zChng, &desc);
17351770
if( rAfter>0.0 ){
17361771
if( rBefore>0.0 ){
17371772
blob_appendf(&desc, " occurring between %h and %h.<br />",
17381773
zAfter, zBefore);
17391774
}else{
17401775
--- src/timeline.c
+++ src/timeline.c
@@ -1183,10 +1183,36 @@
1183 }
1184 if( i>2 ){
1185 style_submenu_multichoice("y", i/2, az, isDisabled);
1186 }
1187 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1188
1189 /*
1190 ** WEBPAGE: timeline
1191 **
1192 ** Query parameters:
@@ -1209,10 +1235,12 @@
1209 ** f=CHECKIN Show family (immediate parents and children) of CHECKIN
1210 ** from=CHECKIN Path from...
1211 ** to=CHECKIN ... to this
1212 ** shortest ... show only the shortest path
1213 ** uf=FILE_SHA1 Show only check-ins that contain the given file version
 
 
1214 ** brbg Background color from branch name
1215 ** ubg Background color from user
1216 ** namechng Show only check-ins that have filename changes
1217 ** forks Show only forks and their children
1218 ** ym=YYYY-MM Show only events for the given year/month.
@@ -1245,10 +1273,11 @@
1245 const char *zSearch = P("s"); /* Search string */
1246 const char *zUses = P("uf"); /* Only show check-ins hold this file */
1247 const char *zYearMonth = P("ym"); /* Show check-ins for the given YYYY-MM */
1248 const char *zYearWeek = P("yw"); /* Check-ins for YYYY-WW (week-of-year) */
1249 const char *zDay = P("ymd"); /* Check-ins for the day YYYY-MM-DD */
 
1250 int useDividers = P("nd")==0; /* Show dividers if "nd" is missing */
1251 int renameOnly = P("namechng")!=0; /* Show only check-ins that rename files */
1252 int forkOnly = PB("forks"); /* Show only forks and their children */
1253 int bisectOnly = PB("bisect"); /* Show the check-ins of the bisect */
1254 int tagid; /* Tag ID */
@@ -1437,17 +1466,21 @@
1437 blob_append_sql(&sql, ",%d", p->rid);
1438 p = p->u.pTo;
1439 }
1440 blob_append(&sql, ")", -1);
1441 path_reset();
 
1442 tmFlags |= TIMELINE_DISJOINT;
1443 db_multi_exec("%s", blob_sql_text(&sql));
 
 
1444 blob_appendf(&desc, "%d check-ins going from ",
1445 db_int(0, "SELECT count(*) FROM timeline"));
1446 blob_appendf(&desc, "%z[%h]</a>", href("%R/info/%h", zFrom), zFrom);
1447 blob_append(&desc, " to ", -1);
1448 blob_appendf(&desc, "%z[%h]</a>", href("%R/info/%h",zTo), zTo);
 
1449 }else if( (p_rid || d_rid) && g.perm.Read ){
1450 /* If p= or d= is present, ignore all other parameters other than n= */
1451 char *zUuid;
1452 int np, nd;
1453
@@ -1520,10 +1553,11 @@
1520 int n;
1521 const char *zEType = "timeline item";
1522 char *zDate;
1523 Blob cond;
1524 blob_zero(&cond);
 
1525 if( zUses ){
1526 blob_append_sql(&cond, " AND event.objid IN usesfile ");
1527 }
1528 if( renameOnly ){
1529 blob_append_sql(&cond, " AND event.objid IN rnfile ");
@@ -1730,10 +1764,11 @@
1730 tmFlags |= TIMELINE_DISJOINT;
1731 }else if( zBrName ){
1732 blob_appendf(&desc, " related to \"%h\"", zBrName);
1733 tmFlags |= TIMELINE_DISJOINT;
1734 }
 
1735 if( rAfter>0.0 ){
1736 if( rBefore>0.0 ){
1737 blob_appendf(&desc, " occurring between %h and %h.<br />",
1738 zAfter, zBefore);
1739 }else{
1740
--- src/timeline.c
+++ src/timeline.c
@@ -1183,10 +1183,36 @@
1183 }
1184 if( i>2 ){
1185 style_submenu_multichoice("y", i/2, az, isDisabled);
1186 }
1187 }
1188
1189 /*
1190 ** If the zChng string is not NULL, then it should be a comma-separated
1191 ** list of glob patterns for filenames. Add an term to the WHERE clause
1192 ** for the SQL statement under construction that excludes any check-in that
1193 ** does not modify one or more files matching the globs.
1194 */
1195 static void addFileGlobExclusion(
1196 const char *zChng, /* The filename GLOB list */
1197 Blob *pSql /* The SELECT statement under construction */
1198 ){
1199 if( zChng==0 || zChng[0]==0 ) return;
1200 blob_append_sql(pSql," AND event.objid IN ("
1201 "SELECT mlink.mid FROM mlink, filename"
1202 " WHERE mlink.fnid=filename.fnid AND %s)",
1203 glob_expr("filename.name", zChng));
1204 }
1205 static void addFileGlobDescription(
1206 const char *zChng, /* The filename GLOB list */
1207 Blob *pDescription /* Result description */
1208 ){
1209 if( zChng==0 || zChng[0]==0 ) return;
1210 blob_appendf(pDescription, " that include changes to files matching %Q",
1211 zChng);
1212 }
1213
1214
1215 /*
1216 ** WEBPAGE: timeline
1217 **
1218 ** Query parameters:
@@ -1209,10 +1235,12 @@
1235 ** f=CHECKIN Show family (immediate parents and children) of CHECKIN
1236 ** from=CHECKIN Path from...
1237 ** to=CHECKIN ... to this
1238 ** shortest ... show only the shortest path
1239 ** uf=FILE_SHA1 Show only check-ins that contain the given file version
1240 ** chng=GLOBLIST Show only check-ins that involve changes to a file whose
1241 ** name matches one of the comma-separate GLOBLIST.
1242 ** brbg Background color from branch name
1243 ** ubg Background color from user
1244 ** namechng Show only check-ins that have filename changes
1245 ** forks Show only forks and their children
1246 ** ym=YYYY-MM Show only events for the given year/month.
@@ -1245,10 +1273,11 @@
1273 const char *zSearch = P("s"); /* Search string */
1274 const char *zUses = P("uf"); /* Only show check-ins hold this file */
1275 const char *zYearMonth = P("ym"); /* Show check-ins for the given YYYY-MM */
1276 const char *zYearWeek = P("yw"); /* Check-ins for YYYY-WW (week-of-year) */
1277 const char *zDay = P("ymd"); /* Check-ins for the day YYYY-MM-DD */
1278 const char *zChng = P("chng"); /* List of GLOBs for files that changed */
1279 int useDividers = P("nd")==0; /* Show dividers if "nd" is missing */
1280 int renameOnly = P("namechng")!=0; /* Show only check-ins that rename files */
1281 int forkOnly = PB("forks"); /* Show only forks and their children */
1282 int bisectOnly = PB("bisect"); /* Show the check-ins of the bisect */
1283 int tagid; /* Tag ID */
@@ -1437,17 +1466,21 @@
1466 blob_append_sql(&sql, ",%d", p->rid);
1467 p = p->u.pTo;
1468 }
1469 blob_append(&sql, ")", -1);
1470 path_reset();
1471 addFileGlobExclusion(zChng, &sql);
1472 tmFlags |= TIMELINE_DISJOINT;
1473 db_multi_exec("%s", blob_sql_text(&sql));
1474 style_submenu_binary("v","With Files","Without Files",
1475 zType[0]!='a' && zType[0]!='c');
1476 blob_appendf(&desc, "%d check-ins going from ",
1477 db_int(0, "SELECT count(*) FROM timeline"));
1478 blob_appendf(&desc, "%z[%h]</a>", href("%R/info/%h", zFrom), zFrom);
1479 blob_append(&desc, " to ", -1);
1480 blob_appendf(&desc, "%z[%h]</a>", href("%R/info/%h",zTo), zTo);
1481 addFileGlobDescription(zChng, &desc);
1482 }else if( (p_rid || d_rid) && g.perm.Read ){
1483 /* If p= or d= is present, ignore all other parameters other than n= */
1484 char *zUuid;
1485 int np, nd;
1486
@@ -1520,10 +1553,11 @@
1553 int n;
1554 const char *zEType = "timeline item";
1555 char *zDate;
1556 Blob cond;
1557 blob_zero(&cond);
1558 addFileGlobExclusion(zChng, &cond);
1559 if( zUses ){
1560 blob_append_sql(&cond, " AND event.objid IN usesfile ");
1561 }
1562 if( renameOnly ){
1563 blob_append_sql(&cond, " AND event.objid IN rnfile ");
@@ -1730,10 +1764,11 @@
1764 tmFlags |= TIMELINE_DISJOINT;
1765 }else if( zBrName ){
1766 blob_appendf(&desc, " related to \"%h\"", zBrName);
1767 tmFlags |= TIMELINE_DISJOINT;
1768 }
1769 addFileGlobDescription(zChng, &desc);
1770 if( rAfter>0.0 ){
1771 if( rBefore>0.0 ){
1772 blob_appendf(&desc, " occurring between %h and %h.<br />",
1773 zAfter, zBefore);
1774 }else{
1775
+80 -4
--- src/user.c
+++ src/user.c
@@ -97,10 +97,79 @@
9797
# undef popen
9898
# define popen _popen
9999
# undef pclose
100100
# define pclose _pclose
101101
#endif
102
+
103
+/*
104
+** Scramble substitution matrix:
105
+*/
106
+static char aSubst[256];
107
+
108
+/*
109
+** Descramble the password
110
+*/
111
+static void userDescramble(char *z){
112
+ int i;
113
+ for(i=0; z[i]; i++) z[i] = aSubst[(unsigned char)z[i]];
114
+}
115
+
116
+/* Print a string in 5-letter groups */
117
+static void printFive(const unsigned char *z){
118
+ int i;
119
+ for(i=0; z[i]; i++){
120
+ if( i>0 && (i%5)==0 ) putchar(' ');
121
+ putchar(z[i]);
122
+ }
123
+ putchar('\n');
124
+}
125
+
126
+/* Return a pseudo-random integer between 0 and N-1 */
127
+static int randint(int N){
128
+ unsigned char x;
129
+ assert( N<256 );
130
+ sqlite3_randomness(1, &x);
131
+ return x % N;
132
+}
133
+
134
+/*
135
+** Generate and print a random scrambling of letters a through z (omitting x)
136
+** and set up the aSubst[] matrix to descramble.
137
+*/
138
+static void userGenerateScrambleCode(void){
139
+ unsigned char zOrig[30];
140
+ unsigned char zA[30];
141
+ unsigned char zB[30];
142
+ int nA = 25;
143
+ int nB = 0;
144
+ int i;
145
+ memcpy(zOrig, "abcdefghijklmnopqrstuvwyz", nA+1);
146
+ memcpy(zA, zOrig, nA+1);
147
+ assert( nA==(int)strlen((char*)zA) );
148
+ for(i=0; i<sizeof(aSubst); i++) aSubst[i] = i;
149
+ printFive(zA);
150
+ while( nA>0 ){
151
+ int x = randint(nA);
152
+ zB[nB++] = zA[x];
153
+ zA[x] = zA[--nA];
154
+ }
155
+ assert( nB==25 );
156
+ zB[nB] = 0;
157
+ printFive(zB);
158
+ for(i=0; i<nB; i++) aSubst[zB[i]] = zOrig[i];
159
+}
160
+
161
+/*
162
+** Return the value of the FOSSIL_SECURITY_LEVEL environment variable.
163
+** Or return 0 if that variable does not exist.
164
+*/
165
+int fossil_security_level(void){
166
+ const char *zLevel = fossil_getenv("FOSSIL_SECURITY_LEVEL");
167
+ if( zLevel==0 ) return 0;
168
+ return atoi(zLevel);
169
+}
170
+
102171
103172
/*
104173
** Do a single prompt for a passphrase. Store the results in the blob.
105174
**
106175
** If the FOSSIL_PWREADER environment variable is set, then it will
@@ -117,10 +186,11 @@
117186
** on subsequent calls to this same routine.
118187
*/
119188
static void prompt_for_passphrase(const char *zPrompt, Blob *pPassphrase){
120189
char *z;
121190
const char *zProg = fossil_getenv("FOSSIL_PWREADER");
191
+ const char *zSecure;
122192
if( zProg && zProg[0] ){
123193
static char zPass[100];
124194
Blob cmd;
125195
FILE *in;
126196
blob_zero(&cmd);
@@ -129,10 +199,16 @@
129199
in = popen(blob_str(&cmd), "r");
130200
fgets(zPass, sizeof(zPass), in);
131201
pclose(in);
132202
blob_reset(&cmd);
133203
z = zPass;
204
+ }else if( fossil_security_level()>=2 ){
205
+ userGenerateScrambleCode();
206
+ z = getpass(zPrompt);
207
+ if( z ) userDescramble(z);
208
+ printf("\033[3A\033[J"); /* Erase previous three lines */
209
+ fflush(stdout);
134210
}else{
135211
z = getpass(zPrompt);
136212
}
137213
strip_string(pPassphrase, z);
138214
}
@@ -180,10 +256,11 @@
180256
char c;
181257
const char *old = db_get("last-sync-pw", 0);
182258
if( (old!=0) && fossil_strcmp(unobscure(old), passwd)==0 ){
183259
return 0;
184260
}
261
+ if( fossil_security_level()>=1 ) return 0;
185262
prompt_user("remember password (Y/n)? ", &x);
186263
c = blob_str(&x)[0];
187264
blob_reset(&x);
188265
return ( c!='n' && c!='N' );
189266
}
@@ -540,15 +617,14 @@
540617
style_submenu_element("Newer", "Newer entries",
541618
"%s/access_log?o=%d&n=%d&y=%d", g.zTop, skip>=n ? skip-n : 0,
542619
n, y);
543620
}
544621
rc = db_prepare_ignore_error(&q, "%s", blob_sql_text(&sql));
545
- @ <center>
546622
fLogEnabled = db_get_boolean("access-log", 0);
547
- @ <div>Access logging is %s(fLogEnabled?"on":"off").
623
+ @ <div align="center">Access logging is %s(fLogEnabled?"on":"off").
548624
@ (Change this on the <a href="setup_settings">settings</a> page.)</div>
549
- @ <table border="1" cellpadding="5" id='logtable'>
625
+ @ <table border="1" cellpadding="5" id="logtable" align="center">
550626
@ <thead><tr><th width="33%%">Date</th><th width="34%%">User</th>
551627
@ <th width="33%%">IP Address</th></tr></thead><tbody>
552628
while( rc==SQLITE_OK && db_step(&q)==SQLITE_ROW ){
553629
const char *zName = db_column_text(&q, 0);
554630
const char *zIP = db_column_text(&q, 1);
@@ -569,11 +645,11 @@
569645
}
570646
if( skip>0 || cnt>n ){
571647
style_submenu_element("All", "All entries",
572648
"%s/access_log?n=10000000", g.zTop);
573649
}
574
- @ </tbody></table></center>
650
+ @ </tbody></table>
575651
db_finalize(&q);
576652
@ <hr />
577653
@ <form method="post" action="%s(g.zTop)/access_log">
578654
@ <label><input type="checkbox" name="delold">
579655
@ Delete all but the most recent 200 entries</input></label>
580656
--- src/user.c
+++ src/user.c
@@ -97,10 +97,79 @@
97 # undef popen
98 # define popen _popen
99 # undef pclose
100 # define pclose _pclose
101 #endif
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
103 /*
104 ** Do a single prompt for a passphrase. Store the results in the blob.
105 **
106 ** If the FOSSIL_PWREADER environment variable is set, then it will
@@ -117,10 +186,11 @@
117 ** on subsequent calls to this same routine.
118 */
119 static void prompt_for_passphrase(const char *zPrompt, Blob *pPassphrase){
120 char *z;
121 const char *zProg = fossil_getenv("FOSSIL_PWREADER");
 
122 if( zProg && zProg[0] ){
123 static char zPass[100];
124 Blob cmd;
125 FILE *in;
126 blob_zero(&cmd);
@@ -129,10 +199,16 @@
129 in = popen(blob_str(&cmd), "r");
130 fgets(zPass, sizeof(zPass), in);
131 pclose(in);
132 blob_reset(&cmd);
133 z = zPass;
 
 
 
 
 
 
134 }else{
135 z = getpass(zPrompt);
136 }
137 strip_string(pPassphrase, z);
138 }
@@ -180,10 +256,11 @@
180 char c;
181 const char *old = db_get("last-sync-pw", 0);
182 if( (old!=0) && fossil_strcmp(unobscure(old), passwd)==0 ){
183 return 0;
184 }
 
185 prompt_user("remember password (Y/n)? ", &x);
186 c = blob_str(&x)[0];
187 blob_reset(&x);
188 return ( c!='n' && c!='N' );
189 }
@@ -540,15 +617,14 @@
540 style_submenu_element("Newer", "Newer entries",
541 "%s/access_log?o=%d&n=%d&y=%d", g.zTop, skip>=n ? skip-n : 0,
542 n, y);
543 }
544 rc = db_prepare_ignore_error(&q, "%s", blob_sql_text(&sql));
545 @ <center>
546 fLogEnabled = db_get_boolean("access-log", 0);
547 @ <div>Access logging is %s(fLogEnabled?"on":"off").
548 @ (Change this on the <a href="setup_settings">settings</a> page.)</div>
549 @ <table border="1" cellpadding="5" id='logtable'>
550 @ <thead><tr><th width="33%%">Date</th><th width="34%%">User</th>
551 @ <th width="33%%">IP Address</th></tr></thead><tbody>
552 while( rc==SQLITE_OK && db_step(&q)==SQLITE_ROW ){
553 const char *zName = db_column_text(&q, 0);
554 const char *zIP = db_column_text(&q, 1);
@@ -569,11 +645,11 @@
569 }
570 if( skip>0 || cnt>n ){
571 style_submenu_element("All", "All entries",
572 "%s/access_log?n=10000000", g.zTop);
573 }
574 @ </tbody></table></center>
575 db_finalize(&q);
576 @ <hr />
577 @ <form method="post" action="%s(g.zTop)/access_log">
578 @ <label><input type="checkbox" name="delold">
579 @ Delete all but the most recent 200 entries</input></label>
580
--- src/user.c
+++ src/user.c
@@ -97,10 +97,79 @@
97 # undef popen
98 # define popen _popen
99 # undef pclose
100 # define pclose _pclose
101 #endif
102
103 /*
104 ** Scramble substitution matrix:
105 */
106 static char aSubst[256];
107
108 /*
109 ** Descramble the password
110 */
111 static void userDescramble(char *z){
112 int i;
113 for(i=0; z[i]; i++) z[i] = aSubst[(unsigned char)z[i]];
114 }
115
116 /* Print a string in 5-letter groups */
117 static void printFive(const unsigned char *z){
118 int i;
119 for(i=0; z[i]; i++){
120 if( i>0 && (i%5)==0 ) putchar(' ');
121 putchar(z[i]);
122 }
123 putchar('\n');
124 }
125
126 /* Return a pseudo-random integer between 0 and N-1 */
127 static int randint(int N){
128 unsigned char x;
129 assert( N<256 );
130 sqlite3_randomness(1, &x);
131 return x % N;
132 }
133
134 /*
135 ** Generate and print a random scrambling of letters a through z (omitting x)
136 ** and set up the aSubst[] matrix to descramble.
137 */
138 static void userGenerateScrambleCode(void){
139 unsigned char zOrig[30];
140 unsigned char zA[30];
141 unsigned char zB[30];
142 int nA = 25;
143 int nB = 0;
144 int i;
145 memcpy(zOrig, "abcdefghijklmnopqrstuvwyz", nA+1);
146 memcpy(zA, zOrig, nA+1);
147 assert( nA==(int)strlen((char*)zA) );
148 for(i=0; i<sizeof(aSubst); i++) aSubst[i] = i;
149 printFive(zA);
150 while( nA>0 ){
151 int x = randint(nA);
152 zB[nB++] = zA[x];
153 zA[x] = zA[--nA];
154 }
155 assert( nB==25 );
156 zB[nB] = 0;
157 printFive(zB);
158 for(i=0; i<nB; i++) aSubst[zB[i]] = zOrig[i];
159 }
160
161 /*
162 ** Return the value of the FOSSIL_SECURITY_LEVEL environment variable.
163 ** Or return 0 if that variable does not exist.
164 */
165 int fossil_security_level(void){
166 const char *zLevel = fossil_getenv("FOSSIL_SECURITY_LEVEL");
167 if( zLevel==0 ) return 0;
168 return atoi(zLevel);
169 }
170
171
172 /*
173 ** Do a single prompt for a passphrase. Store the results in the blob.
174 **
175 ** If the FOSSIL_PWREADER environment variable is set, then it will
@@ -117,10 +186,11 @@
186 ** on subsequent calls to this same routine.
187 */
188 static void prompt_for_passphrase(const char *zPrompt, Blob *pPassphrase){
189 char *z;
190 const char *zProg = fossil_getenv("FOSSIL_PWREADER");
191 const char *zSecure;
192 if( zProg && zProg[0] ){
193 static char zPass[100];
194 Blob cmd;
195 FILE *in;
196 blob_zero(&cmd);
@@ -129,10 +199,16 @@
199 in = popen(blob_str(&cmd), "r");
200 fgets(zPass, sizeof(zPass), in);
201 pclose(in);
202 blob_reset(&cmd);
203 z = zPass;
204 }else if( fossil_security_level()>=2 ){
205 userGenerateScrambleCode();
206 z = getpass(zPrompt);
207 if( z ) userDescramble(z);
208 printf("\033[3A\033[J"); /* Erase previous three lines */
209 fflush(stdout);
210 }else{
211 z = getpass(zPrompt);
212 }
213 strip_string(pPassphrase, z);
214 }
@@ -180,10 +256,11 @@
256 char c;
257 const char *old = db_get("last-sync-pw", 0);
258 if( (old!=0) && fossil_strcmp(unobscure(old), passwd)==0 ){
259 return 0;
260 }
261 if( fossil_security_level()>=1 ) return 0;
262 prompt_user("remember password (Y/n)? ", &x);
263 c = blob_str(&x)[0];
264 blob_reset(&x);
265 return ( c!='n' && c!='N' );
266 }
@@ -540,15 +617,14 @@
617 style_submenu_element("Newer", "Newer entries",
618 "%s/access_log?o=%d&n=%d&y=%d", g.zTop, skip>=n ? skip-n : 0,
619 n, y);
620 }
621 rc = db_prepare_ignore_error(&q, "%s", blob_sql_text(&sql));
 
622 fLogEnabled = db_get_boolean("access-log", 0);
623 @ <div align="center">Access logging is %s(fLogEnabled?"on":"off").
624 @ (Change this on the <a href="setup_settings">settings</a> page.)</div>
625 @ <table border="1" cellpadding="5" id="logtable" align="center">
626 @ <thead><tr><th width="33%%">Date</th><th width="34%%">User</th>
627 @ <th width="33%%">IP Address</th></tr></thead><tbody>
628 while( rc==SQLITE_OK && db_step(&q)==SQLITE_ROW ){
629 const char *zName = db_column_text(&q, 0);
630 const char *zIP = db_column_text(&q, 1);
@@ -569,11 +645,11 @@
645 }
646 if( skip>0 || cnt>n ){
647 style_submenu_element("All", "All entries",
648 "%s/access_log?n=10000000", g.zTop);
649 }
650 @ </tbody></table>
651 db_finalize(&q);
652 @ <hr />
653 @ <form method="post" action="%s(g.zTop)/access_log">
654 @ <label><input type="checkbox" name="delold">
655 @ Delete all but the most recent 200 entries</input></label>
656
+10 -10
--- www/branching.wiki
+++ www/branching.wiki
@@ -2,15 +2,15 @@
22
<h2>Background</h2>
33
44
In a simple and perfect world, the development of a project would proceed
55
linearly, as shown in figure 1.
66
7
-<center><table border=1 cellpadding=10 hspace=10 vspace=10>
7
+<table border=1 cellpadding=10 hspace=10 vspace=10 align="center">
88
<tr><td align="center">
99
<img src="branch01.gif" width=280 height=68><br>
1010
Figure 1
11
-</td></tr></table></center>
11
+</td></tr></table>
1212
1313
Each circle represents a check-in. For the sake of clarity, the check-ins
1414
are given small consecutive numbers. In a real system, of course, the
1515
check-in numbers would be 40-character SHA1 hashes since it is not possible
1616
to allocate collision-free sequential numbers in a distributed system.
@@ -38,15 +38,15 @@
3838
3939
Alas, reality often interferes with the simple linear development of a
4040
project. Suppose two programmers make independent modifications to check-in 2.
4141
After both changes are committed, the check-in graph looks like figure 2:
4242
43
-<center><table border=1 cellpadding=10 hspace=10 vspace=10>
43
+<table border=1 cellpadding=10 hspace=10 vspace=10 align="center">
4444
<tr><td align="center">
4545
<img src="branch02.gif" width=210 height=140><br>
4646
Figure 2
47
-</td></tr></table></center>
47
+</td></tr></table>
4848
4949
The graph in figure 2 has two leaves: check-ins 3 and 4. Check-in 2 has
5050
two children, check-ins 3 and 4. We call this state a <i>fork</i>.
5151
5252
Fossil tries to prevent forks. Suppose two programmers named Alice and
@@ -77,15 +77,15 @@
7777
To resolve this situation, Alice can use the fossil <b>merge</b> command
7878
to merge in Bob's changes in her local copy of check-in 3. Then she
7979
can commit the results as check-in 5. This results in a DAG as shown
8080
in figure 3.
8181
82
-<center><table border=1 cellpadding=10 hspace=10 vspace=10>
82
+<table border=1 cellpadding=10 hspace=10 vspace=10 align="center">
8383
<tr><td align="center">
8484
<img src="branch03.gif" width=282 height=152><br>
8585
Figure 3
86
-</td></tr></table></center>
86
+</td></tr></table>
8787
8888
Check-in 5 is a child of check-in 3 because it was created by editing
8989
check-in 3. But check-in 5 also inherits the changes from check-in 4 by
9090
virtue of the merge. So we say that check-in 5 is a <i>merge child</i>
9191
of check-in 4 and that it is a <i>direct child</i> of check-in 3.
@@ -124,15 +124,15 @@
124124
When multiple leaves are desirable, we call this <i>branching</i>
125125
instead of <i>forking</i>.
126126
Figure 4 shows an example of a project where there are two branches, one
127127
for development work and another for testing.
128128
129
-<center><table border=1 cellpadding=10 hspace=10 vspace=10>
129
+<table border=1 cellpadding=10 hspace=10 vspace=10 align="center">
130130
<tr><td align="center">
131131
<img src="branch04.gif" width=426 height=123><br>
132132
Figure 4
133
-</td></tr></table></center>
133
+</td></tr></table>
134134
135135
The hypothetical scenario of figure 4 is this: The project starts and
136136
progresses to a point where (at check-in 2)
137137
it is ready to enter testing for its first release.
138138
In a real project, of course, there might be hundreds or thousands of
@@ -164,15 +164,15 @@
164164
165165
Tags and properties are used in fossil to help express the intent, and
166166
thus to distinguish between forks and branches. Figure 5 shows the
167167
same scenario as figure 4 but with tags and properties added:
168168
169
-<center><table border=1 cellpadding=10 hspace=10 vspace=10>
169
+<table border=1 cellpadding=10 hspace=10 vspace=10 align="center">
170170
<tr><td align="center">
171171
<img src="branch05.gif" width=485 height=177><br>
172172
Figure 5
173
-</td></tr></table></center>
173
+</td></tr></table>
174174
175175
A <i>tag</i> is a name that is attached to a check-in. A
176176
<i>property</i> is a name/value pair. Internally, fossil implements
177177
tags as properties with a NULL value. So, tags and properties really
178178
are much the same thing, and henceforth we will use the word "tag"
179179
--- www/branching.wiki
+++ www/branching.wiki
@@ -2,15 +2,15 @@
2 <h2>Background</h2>
3
4 In a simple and perfect world, the development of a project would proceed
5 linearly, as shown in figure 1.
6
7 <center><table border=1 cellpadding=10 hspace=10 vspace=10>
8 <tr><td align="center">
9 <img src="branch01.gif" width=280 height=68><br>
10 Figure 1
11 </td></tr></table></center>
12
13 Each circle represents a check-in. For the sake of clarity, the check-ins
14 are given small consecutive numbers. In a real system, of course, the
15 check-in numbers would be 40-character SHA1 hashes since it is not possible
16 to allocate collision-free sequential numbers in a distributed system.
@@ -38,15 +38,15 @@
38
39 Alas, reality often interferes with the simple linear development of a
40 project. Suppose two programmers make independent modifications to check-in 2.
41 After both changes are committed, the check-in graph looks like figure 2:
42
43 <center><table border=1 cellpadding=10 hspace=10 vspace=10>
44 <tr><td align="center">
45 <img src="branch02.gif" width=210 height=140><br>
46 Figure 2
47 </td></tr></table></center>
48
49 The graph in figure 2 has two leaves: check-ins 3 and 4. Check-in 2 has
50 two children, check-ins 3 and 4. We call this state a <i>fork</i>.
51
52 Fossil tries to prevent forks. Suppose two programmers named Alice and
@@ -77,15 +77,15 @@
77 To resolve this situation, Alice can use the fossil <b>merge</b> command
78 to merge in Bob's changes in her local copy of check-in 3. Then she
79 can commit the results as check-in 5. This results in a DAG as shown
80 in figure 3.
81
82 <center><table border=1 cellpadding=10 hspace=10 vspace=10>
83 <tr><td align="center">
84 <img src="branch03.gif" width=282 height=152><br>
85 Figure 3
86 </td></tr></table></center>
87
88 Check-in 5 is a child of check-in 3 because it was created by editing
89 check-in 3. But check-in 5 also inherits the changes from check-in 4 by
90 virtue of the merge. So we say that check-in 5 is a <i>merge child</i>
91 of check-in 4 and that it is a <i>direct child</i> of check-in 3.
@@ -124,15 +124,15 @@
124 When multiple leaves are desirable, we call this <i>branching</i>
125 instead of <i>forking</i>.
126 Figure 4 shows an example of a project where there are two branches, one
127 for development work and another for testing.
128
129 <center><table border=1 cellpadding=10 hspace=10 vspace=10>
130 <tr><td align="center">
131 <img src="branch04.gif" width=426 height=123><br>
132 Figure 4
133 </td></tr></table></center>
134
135 The hypothetical scenario of figure 4 is this: The project starts and
136 progresses to a point where (at check-in 2)
137 it is ready to enter testing for its first release.
138 In a real project, of course, there might be hundreds or thousands of
@@ -164,15 +164,15 @@
164
165 Tags and properties are used in fossil to help express the intent, and
166 thus to distinguish between forks and branches. Figure 5 shows the
167 same scenario as figure 4 but with tags and properties added:
168
169 <center><table border=1 cellpadding=10 hspace=10 vspace=10>
170 <tr><td align="center">
171 <img src="branch05.gif" width=485 height=177><br>
172 Figure 5
173 </td></tr></table></center>
174
175 A <i>tag</i> is a name that is attached to a check-in. A
176 <i>property</i> is a name/value pair. Internally, fossil implements
177 tags as properties with a NULL value. So, tags and properties really
178 are much the same thing, and henceforth we will use the word "tag"
179
--- www/branching.wiki
+++ www/branching.wiki
@@ -2,15 +2,15 @@
2 <h2>Background</h2>
3
4 In a simple and perfect world, the development of a project would proceed
5 linearly, as shown in figure 1.
6
7 <table border=1 cellpadding=10 hspace=10 vspace=10 align="center">
8 <tr><td align="center">
9 <img src="branch01.gif" width=280 height=68><br>
10 Figure 1
11 </td></tr></table>
12
13 Each circle represents a check-in. For the sake of clarity, the check-ins
14 are given small consecutive numbers. In a real system, of course, the
15 check-in numbers would be 40-character SHA1 hashes since it is not possible
16 to allocate collision-free sequential numbers in a distributed system.
@@ -38,15 +38,15 @@
38
39 Alas, reality often interferes with the simple linear development of a
40 project. Suppose two programmers make independent modifications to check-in 2.
41 After both changes are committed, the check-in graph looks like figure 2:
42
43 <table border=1 cellpadding=10 hspace=10 vspace=10 align="center">
44 <tr><td align="center">
45 <img src="branch02.gif" width=210 height=140><br>
46 Figure 2
47 </td></tr></table>
48
49 The graph in figure 2 has two leaves: check-ins 3 and 4. Check-in 2 has
50 two children, check-ins 3 and 4. We call this state a <i>fork</i>.
51
52 Fossil tries to prevent forks. Suppose two programmers named Alice and
@@ -77,15 +77,15 @@
77 To resolve this situation, Alice can use the fossil <b>merge</b> command
78 to merge in Bob's changes in her local copy of check-in 3. Then she
79 can commit the results as check-in 5. This results in a DAG as shown
80 in figure 3.
81
82 <table border=1 cellpadding=10 hspace=10 vspace=10 align="center">
83 <tr><td align="center">
84 <img src="branch03.gif" width=282 height=152><br>
85 Figure 3
86 </td></tr></table>
87
88 Check-in 5 is a child of check-in 3 because it was created by editing
89 check-in 3. But check-in 5 also inherits the changes from check-in 4 by
90 virtue of the merge. So we say that check-in 5 is a <i>merge child</i>
91 of check-in 4 and that it is a <i>direct child</i> of check-in 3.
@@ -124,15 +124,15 @@
124 When multiple leaves are desirable, we call this <i>branching</i>
125 instead of <i>forking</i>.
126 Figure 4 shows an example of a project where there are two branches, one
127 for development work and another for testing.
128
129 <table border=1 cellpadding=10 hspace=10 vspace=10 align="center">
130 <tr><td align="center">
131 <img src="branch04.gif" width=426 height=123><br>
132 Figure 4
133 </td></tr></table>
134
135 The hypothetical scenario of figure 4 is this: The project starts and
136 progresses to a point where (at check-in 2)
137 it is ready to enter testing for its first release.
138 In a real project, of course, there might be hundreds or thousands of
@@ -164,15 +164,15 @@
164
165 Tags and properties are used in fossil to help express the intent, and
166 thus to distinguish between forks and branches. Figure 5 shows the
167 same scenario as figure 4 but with tags and properties added:
168
169 <table border=1 cellpadding=10 hspace=10 vspace=10 align="center">
170 <tr><td align="center">
171 <img src="branch05.gif" width=485 height=177><br>
172 Figure 5
173 </td></tr></table>
174
175 A <i>tag</i> is a name that is attached to a check-in. A
176 <i>property</i> is a name/value pair. Internally, fossil implements
177 tags as properties with a NULL value. So, tags and properties really
178 are much the same thing, and henceforth we will use the word "tag"
179
--- www/copyright-release.html
+++ www/copyright-release.html
@@ -74,12 +74,11 @@
7474
7575
<p>By filling in the following information and signing your name,
7676
you agree to be bound by all of the terms
7777
set forth in this agreement. Please print clearly.</p>
7878
79
-<center>
80
-<p><table width="80%" border="1" cellpadding="0" cellspacing="0">
79
+<p><table width="80%" border="1" cellpadding="0" cellspacing="0" align="center">
8180
<tr><td width="20%" valign="top">Your name &amp email:</td><td width="80%">
8281
8382
<!-- Replace this line with your name and email --> &nbsp;<p>&nbsp;
8483
8584
</td></tr>
@@ -95,14 +94,13 @@
9594
9695
</td></tr>
9796
<tr><td valign="top">Signature:</td><td>&nbsp;<p>&nbsp;</td></tr>
9897
<tr><td valign="top">Date:</td><td>&nbsp;<p>&nbsp;</td></tr>
9998
</table>
100
-</center>
10199
102100
<p>Send completed forms to:
103101
<blockquote>
104102
Hipp, Wyrick &amp; Company, Inc.<br>
105103
6200 Maple Cove Lane<br>
106104
Charlotte, NC 28269-1086<br>
107105
USA
108106
</p>
109107
--- www/copyright-release.html
+++ www/copyright-release.html
@@ -74,12 +74,11 @@
74
75 <p>By filling in the following information and signing your name,
76 you agree to be bound by all of the terms
77 set forth in this agreement. Please print clearly.</p>
78
79 <center>
80 <p><table width="80%" border="1" cellpadding="0" cellspacing="0">
81 <tr><td width="20%" valign="top">Your name &amp email:</td><td width="80%">
82
83 <!-- Replace this line with your name and email --> &nbsp;<p>&nbsp;
84
85 </td></tr>
@@ -95,14 +94,13 @@
95
96 </td></tr>
97 <tr><td valign="top">Signature:</td><td>&nbsp;<p>&nbsp;</td></tr>
98 <tr><td valign="top">Date:</td><td>&nbsp;<p>&nbsp;</td></tr>
99 </table>
100 </center>
101
102 <p>Send completed forms to:
103 <blockquote>
104 Hipp, Wyrick &amp; Company, Inc.<br>
105 6200 Maple Cove Lane<br>
106 Charlotte, NC 28269-1086<br>
107 USA
108 </p>
109
--- www/copyright-release.html
+++ www/copyright-release.html
@@ -74,12 +74,11 @@
74
75 <p>By filling in the following information and signing your name,
76 you agree to be bound by all of the terms
77 set forth in this agreement. Please print clearly.</p>
78
79 <p><table width="80%" border="1" cellpadding="0" cellspacing="0" align="center">
 
80 <tr><td width="20%" valign="top">Your name &amp email:</td><td width="80%">
81
82 <!-- Replace this line with your name and email --> &nbsp;<p>&nbsp;
83
84 </td></tr>
@@ -95,14 +94,13 @@
94
95 </td></tr>
96 <tr><td valign="top">Signature:</td><td>&nbsp;<p>&nbsp;</td></tr>
97 <tr><td valign="top">Date:</td><td>&nbsp;<p>&nbsp;</td></tr>
98 </table>
 
99
100 <p>Send completed forms to:
101 <blockquote>
102 Hipp, Wyrick &amp; Company, Inc.<br>
103 6200 Maple Cove Lane<br>
104 Charlotte, NC 28269-1086<br>
105 USA
106 </p>
107
--- www/fossil-v-git.wiki
+++ www/fossil-v-git.wiki
@@ -19,11 +19,11 @@
1919
wiki, tickets, or tech-notes, so those elements will not transfer when
2020
exporting from Fossil to Git.</i></small>
2121
2222
<h2>2.0 Executive Summary:</h2>
2323
24
-<blockquote><center><table border=1 cellpadding=5>
24
+<blockquote><table border=1 cellpadding=5 align=center>
2525
<tr><th width="50%">GIT</th><th width="50%">FOSSIL</th></tr>
2626
<tr><td>File versioning only</td>
2727
<td>Versioning, Tickets, Wiki, and Technotes</td></tr>
2828
<tr><td>Ad-hoc, pile-of-files key/value database</td>
2929
<td>Relational SQL database</td></tr>
@@ -34,11 +34,11 @@
3434
<tr><td>One check-out per repository</td>
3535
<td>Many check-outs per repository</td></tr>
3636
<tr><td>Remembers what you should have done</td>
3737
<td>Remembers what you actually did</td></tr>
3838
<tr><td>GPL</td><td>BSD</td></tr>
39
-</table></center></blockquote>
39
+</table></blockquote>
4040
4141
<h2>3.0 Discussion</h2>
4242
4343
<h3>3.1 Feature Set</h3>
4444
@@ -58,11 +58,11 @@
5858
5959
For developers who choose to self-host projects (rather than using a
6060
3rd-party service such as GitHub) Fossil is much easier to set up, since
6161
the stand-alone Fossil executable together with a 2-line CGI script
6262
suffice to instantiate a full-featured developer website. To accomplish
63
-the same using Git requires locating, installing, configuring, integrating,
63
+the same using Git requires locating, installing, configuring, integrating,
6464
and managing a wide assortment of separate tools. Standing up a developer
6565
website using Fossil can be done in minutes, whereas doing the same using
6666
Git requires hours or days.
6767
6868
<h3>3.2 Database</h3>
@@ -69,13 +69,13 @@
6969
7070
The baseline data structures for Fossil and Git are the same (modulo
7171
formatting details). Both systems store check-ins as immutable
7272
objects referencing their immediate ancestors and named by their SHA1 hash.
7373
74
-The difference is that Git stores its objects as individual files
74
+The difference is that Git stores its objects as individual files
7575
in the ".git" folder or compressed into
76
-bespoke "pack-files", whereas Fossil stores its objects in a
76
+bespoke "pack-files", whereas Fossil stores its objects in a
7777
relational ([https://www.sqlite.org/|SQLite]) database file. To put it
7878
another way, Git uses an ad-hoc pile-of-files key/value database whereas
7979
Fossil uses a proven, general-purpose SQL database. This
8080
difference is more than an implementation detail. It
8181
has important consequences.
@@ -87,13 +87,13 @@
8787
GitHub provide this capability. With Git, if you are looking at some
8888
historical check-in then you cannot ask
8989
"what came next" or "what are the children of this check-in".
9090
9191
Fossil, on the other hand, parses essential information about check-ins
92
-(parents, children, committers, comments, files changed, etc.)
93
-into a relational database that can be easily
94
-queried using concise SQL statements to find both ancestors and
92
+(parents, children, committers, comments, files changed, etc.)
93
+into a relational database that can be easily
94
+queried using concise SQL statements to find both ancestors and
9595
descendents of a check-in.
9696
9797
Leaf check-ins in Git that lack a "ref" become "detached", making them
9898
difficult to locate and subject to garbage collection. This
9999
"detached head" problem has caused untold grief for countless
@@ -100,11 +100,11 @@
100100
Git users. With Fossil, all check-ins are easily located using
101101
a variety of attributes (parents, children, committer, date, full-text
102102
search of the check-in comment) and so detached heads are simply not possible.
103103
104104
The ease with which check-ins can be located and queried in Fossil
105
-has resulted in a huge variety of reports and status screens
105
+has resulted in a huge variety of reports and status screens
106106
([./webpage-ex.md|examples]) that show project state
107107
in ways that help developers
108108
maintain enhanced awareness and comprehension
109109
and avoid errors.
110110
@@ -112,11 +112,11 @@
112112
113113
Fossil and Git promote different development styles. Git promotes a
114114
"bazaar" development style in which numerous anonymous developers make
115115
small and sometimes haphazard contributions. Fossil
116116
promotes a "cathedral" development model in which the project is
117
-closely supervised by an highly engaged architect and implemented by
117
+closely supervised by an highly engaged architect and implemented by
118118
a clique of developers.
119119
120120
Nota Bene: This is not to say that Git cannot be used for cathedral-style
121121
development or that Fossil cannot be used for bazaar-style development.
122122
They can be. But those modes are not their design intent nor the their
@@ -164,27 +164,27 @@
164164
Git consists of many small tools, each doing one small part of the job,
165165
which can be recombined (by experts) to perform powerful operations.
166166
Git has a lot of complexity and many dependencies and requires an "installer"
167167
script or program to get it running.
168168
169
-Fossil is a single self-contained stand-alone executable with hardly
170
-any dependencies. Fossil can be (and often is) run inside a
169
+Fossil is a single self-contained stand-alone executable with hardly
170
+any dependencies. Fossil can be (and often is) run inside a
171171
minimally configured chroot jail. To install Fossil,
172172
one merely puts the executable on $PATH.
173173
174
-The designer of Git says that the unix philosophy is to have lots of
175
-small tools that collaborate to get the job done. The designer of
176
-Fossil says that the unix philosophy is "it just works". Both
177
-individuals have written their DVCSes to reflect their own view
174
+The designer of Git says that the unix philosophy is to have lots of
175
+small tools that collaborate to get the job done. The designer of
176
+Fossil says that the unix philosophy is "it just works". Both
177
+individuals have written their DVCSes to reflect their own view
178178
of the "unix philosophy".
179179
180180
<h3>3.6 One vs. Many Check-outs per Repository</h3>
181181
182182
A "repository" in Git is a pile-of-files in the ".git" subdirectory
183183
of a single check-out. The check-out and the repository are inseperable.
184184
185
-With Fossil, a "repository" is a single SQLite database file
185
+With Fossil, a "repository" is a single SQLite database file
186186
that can be stored anywhere. There
187187
can be multiple active check-outs from the same repository, perhaps
188188
open on different branches or on different snapshots of the same branch.
189189
Long-running tests or builds can be running in one check-out while
190190
changes are being committed in another.
@@ -201,27 +201,27 @@
201201
202202
Fossil, in contrast, puts more emphasis on recording exactly what happened,
203203
including all of the messy errors, dead-ends, experimental branches, and
204204
so forth. One might argue that this
205205
makes the history of a Fossil project "messy". But another point of view
206
-is that this makes the history "accurate". In actual practice, the
206
+is that this makes the history "accurate". In actual practice, the
207207
superior reporting tools available in Fossil mean that the added "mess"
208208
is not a factor.
209209
210210
One commentator has mused that Git records history according to
211211
the victors, whereas Fossil records history as it actually happened.
212212
213213
<h3>3.8 GPL vs. BSD</h3>
214214
215
-Git is covered by the GPL license whereas Fossil is covered by
215
+Git is covered by the GPL license whereas Fossil is covered by
216216
a two-clause BSD license.
217217
218218
Consider the difference between GPL and BSD licenses: GPL is designed
219219
to make writing easier at the expense of making reading harder. BSD is
220220
designed to make reading easier and the expense of making writing harder.
221221
222
-To a first approximation, the GPL license grants the right to read
222
+To a first approximation, the GPL license grants the right to read
223223
source code to anyone who promises to give back enhancements. In other
224224
words, the act of reading GPL source code (a prerequiste for making changes)
225225
implies acceptance of the license which requires updates to be contributed
226226
back under the same license. (The details are more complex, but the
227227
foregoing captures the essence of the idea.) A big advantage of the GPL
@@ -249,11 +249,11 @@
249249
<h2>4.0 Missing Features</h2>
250250
251251
Most of the capabilities found in Git are also available in Fossil and
252252
the other way around. For example, both systems have local check-outs,
253253
remote repositories, push/pull/sync, bisect capabilities, and a "stash".
254
-Both systems store project history as a directed acyclic graph (DAG)
254
+Both systems store project history as a directed acyclic graph (DAG)
255255
of immutable check-in objects.
256256
257257
But there are a few capabilities in one system that are missing from the
258258
other.
259259
@@ -271,16 +271,16 @@
271271
Git only provides versioning of source code. Fossil strives to provide
272272
other related configuration management services as well.
273273
274274
* <b>Named branches</b>
275275
276
- Branches in Fossil have persistent names that are propagated
276
+ Branches in Fossil have persistent names that are propagated
277277
to collaborators via [/help?cmd=push|push] and [/help?cmd=pull|pull].
278278
All developers see the same name on the same branch. Git, in contrast,
279279
uses only local branch names, so developers working on the
280280
same project can (and frequently do) use a different name for the
281
- same branch.
281
+ same branch.
282282
283283
* <b>The [/help?cmd=all|fossil all] command</b>
284284
285285
Fossil keeps track of all repositories and check-outs and allows
286286
operations over all of them with a single command. For example, in
287287
--- www/fossil-v-git.wiki
+++ www/fossil-v-git.wiki
@@ -19,11 +19,11 @@
19 wiki, tickets, or tech-notes, so those elements will not transfer when
20 exporting from Fossil to Git.</i></small>
21
22 <h2>2.0 Executive Summary:</h2>
23
24 <blockquote><center><table border=1 cellpadding=5>
25 <tr><th width="50%">GIT</th><th width="50%">FOSSIL</th></tr>
26 <tr><td>File versioning only</td>
27 <td>Versioning, Tickets, Wiki, and Technotes</td></tr>
28 <tr><td>Ad-hoc, pile-of-files key/value database</td>
29 <td>Relational SQL database</td></tr>
@@ -34,11 +34,11 @@
34 <tr><td>One check-out per repository</td>
35 <td>Many check-outs per repository</td></tr>
36 <tr><td>Remembers what you should have done</td>
37 <td>Remembers what you actually did</td></tr>
38 <tr><td>GPL</td><td>BSD</td></tr>
39 </table></center></blockquote>
40
41 <h2>3.0 Discussion</h2>
42
43 <h3>3.1 Feature Set</h3>
44
@@ -58,11 +58,11 @@
58
59 For developers who choose to self-host projects (rather than using a
60 3rd-party service such as GitHub) Fossil is much easier to set up, since
61 the stand-alone Fossil executable together with a 2-line CGI script
62 suffice to instantiate a full-featured developer website. To accomplish
63 the same using Git requires locating, installing, configuring, integrating,
64 and managing a wide assortment of separate tools. Standing up a developer
65 website using Fossil can be done in minutes, whereas doing the same using
66 Git requires hours or days.
67
68 <h3>3.2 Database</h3>
@@ -69,13 +69,13 @@
69
70 The baseline data structures for Fossil and Git are the same (modulo
71 formatting details). Both systems store check-ins as immutable
72 objects referencing their immediate ancestors and named by their SHA1 hash.
73
74 The difference is that Git stores its objects as individual files
75 in the ".git" folder or compressed into
76 bespoke "pack-files", whereas Fossil stores its objects in a
77 relational ([https://www.sqlite.org/|SQLite]) database file. To put it
78 another way, Git uses an ad-hoc pile-of-files key/value database whereas
79 Fossil uses a proven, general-purpose SQL database. This
80 difference is more than an implementation detail. It
81 has important consequences.
@@ -87,13 +87,13 @@
87 GitHub provide this capability. With Git, if you are looking at some
88 historical check-in then you cannot ask
89 "what came next" or "what are the children of this check-in".
90
91 Fossil, on the other hand, parses essential information about check-ins
92 (parents, children, committers, comments, files changed, etc.)
93 into a relational database that can be easily
94 queried using concise SQL statements to find both ancestors and
95 descendents of a check-in.
96
97 Leaf check-ins in Git that lack a "ref" become "detached", making them
98 difficult to locate and subject to garbage collection. This
99 "detached head" problem has caused untold grief for countless
@@ -100,11 +100,11 @@
100 Git users. With Fossil, all check-ins are easily located using
101 a variety of attributes (parents, children, committer, date, full-text
102 search of the check-in comment) and so detached heads are simply not possible.
103
104 The ease with which check-ins can be located and queried in Fossil
105 has resulted in a huge variety of reports and status screens
106 ([./webpage-ex.md|examples]) that show project state
107 in ways that help developers
108 maintain enhanced awareness and comprehension
109 and avoid errors.
110
@@ -112,11 +112,11 @@
112
113 Fossil and Git promote different development styles. Git promotes a
114 "bazaar" development style in which numerous anonymous developers make
115 small and sometimes haphazard contributions. Fossil
116 promotes a "cathedral" development model in which the project is
117 closely supervised by an highly engaged architect and implemented by
118 a clique of developers.
119
120 Nota Bene: This is not to say that Git cannot be used for cathedral-style
121 development or that Fossil cannot be used for bazaar-style development.
122 They can be. But those modes are not their design intent nor the their
@@ -164,27 +164,27 @@
164 Git consists of many small tools, each doing one small part of the job,
165 which can be recombined (by experts) to perform powerful operations.
166 Git has a lot of complexity and many dependencies and requires an "installer"
167 script or program to get it running.
168
169 Fossil is a single self-contained stand-alone executable with hardly
170 any dependencies. Fossil can be (and often is) run inside a
171 minimally configured chroot jail. To install Fossil,
172 one merely puts the executable on $PATH.
173
174 The designer of Git says that the unix philosophy is to have lots of
175 small tools that collaborate to get the job done. The designer of
176 Fossil says that the unix philosophy is "it just works". Both
177 individuals have written their DVCSes to reflect their own view
178 of the "unix philosophy".
179
180 <h3>3.6 One vs. Many Check-outs per Repository</h3>
181
182 A "repository" in Git is a pile-of-files in the ".git" subdirectory
183 of a single check-out. The check-out and the repository are inseperable.
184
185 With Fossil, a "repository" is a single SQLite database file
186 that can be stored anywhere. There
187 can be multiple active check-outs from the same repository, perhaps
188 open on different branches or on different snapshots of the same branch.
189 Long-running tests or builds can be running in one check-out while
190 changes are being committed in another.
@@ -201,27 +201,27 @@
201
202 Fossil, in contrast, puts more emphasis on recording exactly what happened,
203 including all of the messy errors, dead-ends, experimental branches, and
204 so forth. One might argue that this
205 makes the history of a Fossil project "messy". But another point of view
206 is that this makes the history "accurate". In actual practice, the
207 superior reporting tools available in Fossil mean that the added "mess"
208 is not a factor.
209
210 One commentator has mused that Git records history according to
211 the victors, whereas Fossil records history as it actually happened.
212
213 <h3>3.8 GPL vs. BSD</h3>
214
215 Git is covered by the GPL license whereas Fossil is covered by
216 a two-clause BSD license.
217
218 Consider the difference between GPL and BSD licenses: GPL is designed
219 to make writing easier at the expense of making reading harder. BSD is
220 designed to make reading easier and the expense of making writing harder.
221
222 To a first approximation, the GPL license grants the right to read
223 source code to anyone who promises to give back enhancements. In other
224 words, the act of reading GPL source code (a prerequiste for making changes)
225 implies acceptance of the license which requires updates to be contributed
226 back under the same license. (The details are more complex, but the
227 foregoing captures the essence of the idea.) A big advantage of the GPL
@@ -249,11 +249,11 @@
249 <h2>4.0 Missing Features</h2>
250
251 Most of the capabilities found in Git are also available in Fossil and
252 the other way around. For example, both systems have local check-outs,
253 remote repositories, push/pull/sync, bisect capabilities, and a "stash".
254 Both systems store project history as a directed acyclic graph (DAG)
255 of immutable check-in objects.
256
257 But there are a few capabilities in one system that are missing from the
258 other.
259
@@ -271,16 +271,16 @@
271 Git only provides versioning of source code. Fossil strives to provide
272 other related configuration management services as well.
273
274 * <b>Named branches</b>
275
276 Branches in Fossil have persistent names that are propagated
277 to collaborators via [/help?cmd=push|push] and [/help?cmd=pull|pull].
278 All developers see the same name on the same branch. Git, in contrast,
279 uses only local branch names, so developers working on the
280 same project can (and frequently do) use a different name for the
281 same branch.
282
283 * <b>The [/help?cmd=all|fossil all] command</b>
284
285 Fossil keeps track of all repositories and check-outs and allows
286 operations over all of them with a single command. For example, in
287
--- www/fossil-v-git.wiki
+++ www/fossil-v-git.wiki
@@ -19,11 +19,11 @@
19 wiki, tickets, or tech-notes, so those elements will not transfer when
20 exporting from Fossil to Git.</i></small>
21
22 <h2>2.0 Executive Summary:</h2>
23
24 <blockquote><table border=1 cellpadding=5 align=center>
25 <tr><th width="50%">GIT</th><th width="50%">FOSSIL</th></tr>
26 <tr><td>File versioning only</td>
27 <td>Versioning, Tickets, Wiki, and Technotes</td></tr>
28 <tr><td>Ad-hoc, pile-of-files key/value database</td>
29 <td>Relational SQL database</td></tr>
@@ -34,11 +34,11 @@
34 <tr><td>One check-out per repository</td>
35 <td>Many check-outs per repository</td></tr>
36 <tr><td>Remembers what you should have done</td>
37 <td>Remembers what you actually did</td></tr>
38 <tr><td>GPL</td><td>BSD</td></tr>
39 </table></blockquote>
40
41 <h2>3.0 Discussion</h2>
42
43 <h3>3.1 Feature Set</h3>
44
@@ -58,11 +58,11 @@
58
59 For developers who choose to self-host projects (rather than using a
60 3rd-party service such as GitHub) Fossil is much easier to set up, since
61 the stand-alone Fossil executable together with a 2-line CGI script
62 suffice to instantiate a full-featured developer website. To accomplish
63 the same using Git requires locating, installing, configuring, integrating,
64 and managing a wide assortment of separate tools. Standing up a developer
65 website using Fossil can be done in minutes, whereas doing the same using
66 Git requires hours or days.
67
68 <h3>3.2 Database</h3>
@@ -69,13 +69,13 @@
69
70 The baseline data structures for Fossil and Git are the same (modulo
71 formatting details). Both systems store check-ins as immutable
72 objects referencing their immediate ancestors and named by their SHA1 hash.
73
74 The difference is that Git stores its objects as individual files
75 in the ".git" folder or compressed into
76 bespoke "pack-files", whereas Fossil stores its objects in a
77 relational ([https://www.sqlite.org/|SQLite]) database file. To put it
78 another way, Git uses an ad-hoc pile-of-files key/value database whereas
79 Fossil uses a proven, general-purpose SQL database. This
80 difference is more than an implementation detail. It
81 has important consequences.
@@ -87,13 +87,13 @@
87 GitHub provide this capability. With Git, if you are looking at some
88 historical check-in then you cannot ask
89 "what came next" or "what are the children of this check-in".
90
91 Fossil, on the other hand, parses essential information about check-ins
92 (parents, children, committers, comments, files changed, etc.)
93 into a relational database that can be easily
94 queried using concise SQL statements to find both ancestors and
95 descendents of a check-in.
96
97 Leaf check-ins in Git that lack a "ref" become "detached", making them
98 difficult to locate and subject to garbage collection. This
99 "detached head" problem has caused untold grief for countless
@@ -100,11 +100,11 @@
100 Git users. With Fossil, all check-ins are easily located using
101 a variety of attributes (parents, children, committer, date, full-text
102 search of the check-in comment) and so detached heads are simply not possible.
103
104 The ease with which check-ins can be located and queried in Fossil
105 has resulted in a huge variety of reports and status screens
106 ([./webpage-ex.md|examples]) that show project state
107 in ways that help developers
108 maintain enhanced awareness and comprehension
109 and avoid errors.
110
@@ -112,11 +112,11 @@
112
113 Fossil and Git promote different development styles. Git promotes a
114 "bazaar" development style in which numerous anonymous developers make
115 small and sometimes haphazard contributions. Fossil
116 promotes a "cathedral" development model in which the project is
117 closely supervised by an highly engaged architect and implemented by
118 a clique of developers.
119
120 Nota Bene: This is not to say that Git cannot be used for cathedral-style
121 development or that Fossil cannot be used for bazaar-style development.
122 They can be. But those modes are not their design intent nor the their
@@ -164,27 +164,27 @@
164 Git consists of many small tools, each doing one small part of the job,
165 which can be recombined (by experts) to perform powerful operations.
166 Git has a lot of complexity and many dependencies and requires an "installer"
167 script or program to get it running.
168
169 Fossil is a single self-contained stand-alone executable with hardly
170 any dependencies. Fossil can be (and often is) run inside a
171 minimally configured chroot jail. To install Fossil,
172 one merely puts the executable on $PATH.
173
174 The designer of Git says that the unix philosophy is to have lots of
175 small tools that collaborate to get the job done. The designer of
176 Fossil says that the unix philosophy is "it just works". Both
177 individuals have written their DVCSes to reflect their own view
178 of the "unix philosophy".
179
180 <h3>3.6 One vs. Many Check-outs per Repository</h3>
181
182 A "repository" in Git is a pile-of-files in the ".git" subdirectory
183 of a single check-out. The check-out and the repository are inseperable.
184
185 With Fossil, a "repository" is a single SQLite database file
186 that can be stored anywhere. There
187 can be multiple active check-outs from the same repository, perhaps
188 open on different branches or on different snapshots of the same branch.
189 Long-running tests or builds can be running in one check-out while
190 changes are being committed in another.
@@ -201,27 +201,27 @@
201
202 Fossil, in contrast, puts more emphasis on recording exactly what happened,
203 including all of the messy errors, dead-ends, experimental branches, and
204 so forth. One might argue that this
205 makes the history of a Fossil project "messy". But another point of view
206 is that this makes the history "accurate". In actual practice, the
207 superior reporting tools available in Fossil mean that the added "mess"
208 is not a factor.
209
210 One commentator has mused that Git records history according to
211 the victors, whereas Fossil records history as it actually happened.
212
213 <h3>3.8 GPL vs. BSD</h3>
214
215 Git is covered by the GPL license whereas Fossil is covered by
216 a two-clause BSD license.
217
218 Consider the difference between GPL and BSD licenses: GPL is designed
219 to make writing easier at the expense of making reading harder. BSD is
220 designed to make reading easier and the expense of making writing harder.
221
222 To a first approximation, the GPL license grants the right to read
223 source code to anyone who promises to give back enhancements. In other
224 words, the act of reading GPL source code (a prerequiste for making changes)
225 implies acceptance of the license which requires updates to be contributed
226 back under the same license. (The details are more complex, but the
227 foregoing captures the essence of the idea.) A big advantage of the GPL
@@ -249,11 +249,11 @@
249 <h2>4.0 Missing Features</h2>
250
251 Most of the capabilities found in Git are also available in Fossil and
252 the other way around. For example, both systems have local check-outs,
253 remote repositories, push/pull/sync, bisect capabilities, and a "stash".
254 Both systems store project history as a directed acyclic graph (DAG)
255 of immutable check-in objects.
256
257 But there are a few capabilities in one system that are missing from the
258 other.
259
@@ -271,16 +271,16 @@
271 Git only provides versioning of source code. Fossil strives to provide
272 other related configuration management services as well.
273
274 * <b>Named branches</b>
275
276 Branches in Fossil have persistent names that are propagated
277 to collaborators via [/help?cmd=push|push] and [/help?cmd=pull|pull].
278 All developers see the same name on the same branch. Git, in contrast,
279 uses only local branch names, so developers working on the
280 same project can (and frequently do) use a different name for the
281 same branch.
282
283 * <b>The [/help?cmd=all|fossil all] command</b>
284
285 Fossil keeps track of all repositories and check-outs and allows
286 operations over all of them with a single command. For example, in
287
+1 -1
--- www/index.wiki
+++ www/index.wiki
@@ -18,11 +18,11 @@
1818
<ul>
1919
<li> [http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/fossil-users | sign-up]
2020
<li> [http://www.mail-archive.com/[email protected] | archives]
2121
</ul>
2222
</ul>
23
-<center><img src="fossil3.gif"></center>
23
+<img src="fossil3.gif" align="center">
2424
</div>
2525
2626
<p>Fossil is a simple, high-reliability, distributed software configuration
2727
management system with these advanced features:
2828
2929
--- www/index.wiki
+++ www/index.wiki
@@ -18,11 +18,11 @@
18 <ul>
19 <li> [http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/fossil-users | sign-up]
20 <li> [http://www.mail-archive.com/[email protected] | archives]
21 </ul>
22 </ul>
23 <center><img src="fossil3.gif"></center>
24 </div>
25
26 <p>Fossil is a simple, high-reliability, distributed software configuration
27 management system with these advanced features:
28
29
--- www/index.wiki
+++ www/index.wiki
@@ -18,11 +18,11 @@
18 <ul>
19 <li> [http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/fossil-users | sign-up]
20 <li> [http://www.mail-archive.com/[email protected] | archives]
21 </ul>
22 </ul>
23 <img src="fossil3.gif" align="center">
24 </div>
25
26 <p>Fossil is a simple, high-reliability, distributed software configuration
27 management system with these advanced features:
28
29
+9 -9
--- www/sync.wiki
+++ www/sync.wiki
@@ -15,11 +15,11 @@
1515
Synchronization is simply the process of sharing artifacts between
1616
servers so that all servers have copies of all artifacts. Because
1717
artifacts are unordered, the order in which artifacts are received
1818
at a server is inconsequential. It is assumed that the SHA1 hashes
1919
of artifacts are unique - that every artifact has a different SHA1 hash.
20
-To a first approximation, synchronization proceeds by sharing lists
20
+To a first approximation, synchronization proceeds by sharing lists
2121
SHA1 hashes of available artifacts, then sharing those artifacts that
2222
are not found on one side or the other of the connection. In practice,
2323
a repository might contain millions of artifacts. The list of
2424
SHA1 hashes for this many artifacts can be large. So optimizations are
2525
employed that usually reduce the number of SHA1 hashes that need to be
@@ -150,11 +150,11 @@
150150
terminates the login card. The signature is the SHA1 hash of
151151
the concatenation of the nonce and the users password.</p>
152152
153153
<p>For each login card, the server looks up the user and verifies
154154
that the nonce matches the SHA1 hash of the remainder of the
155
-message. It then checks the signature hash to make sure the
155
+message. It then checks the signature hash to make sure the
156156
signature matches. If everything
157157
checks out, then the client is granted all privileges of the
158158
specified user.</p>
159159
160160
<p>Privileges are cumulative. There can be multiple successful
@@ -162,11 +162,11 @@
162162
privileges of each individual login.</p>
163163
164164
<h3>3.3 File and Compressed File Cards</h3>
165165
166166
<p>Artifacts are transferred using either "file" cards, or "cfile" cards.
167
-(The name "file" card comes from the fact that most artifacts correspond to
167
+(The name "file" card comes from the fact that most artifacts correspond to
168168
files, and "cfile" is just a compressed file.)
169169
</p>
170170
171171
<h4>3.3.1 File Cards</h4>
172172
@@ -230,11 +230,11 @@
230230
artifact. If the cfile card has four arguments, then the payload is a
231231
delta and the second argument is the ID of another artifact that is the
232232
source of the delta and the third argument is the original size of the
233233
delta artifact.</p>
234234
235
-<p>Unlike file cards, cfile cards are only sent in one direction during a
235
+<p>Unlike file cards, cfile cards are only sent in one direction during a
236236
clone from server to client for clone protocol version "3" or greater.</p>
237237
238238
<h3>3.4 Push and Pull Cards</h3>
239239
240240
<p>Among the first cards in a client-to-server message are
@@ -385,11 +385,11 @@
385385
</blockquote>
386386
387387
<p>As of [/timeline?r=trunk&c=2015-03-19+03%3A57%3A46&n=20|2015-03-19], the configuration-name must be one of the
388388
following values:
389389
390
-<center><table border=0>
390
+<table border=0 align="center">
391391
<tr><td valign="top">
392392
<ul>
393393
<li> css
394394
<li> header
395395
<li> footer
@@ -436,11 +436,11 @@
436436
<li> @reportfmt
437437
<li> @user
438438
<li> @concealed
439439
<li> @shun
440440
</ul></td></tr>
441
-</table></center>
441
+</table>
442442
443443
<p>New configuration-names are likely to be added in future releases of
444444
Fossil. If the server receives a configuration-name that it does not
445445
understand, the entire reqconfig card is silently ignored. The reqconfig
446446
card might also be ignored if the user lacks sufficient privilege to
@@ -453,11 +453,11 @@
453453
The value of the configuration item is returned to the client using a
454454
"config" card.
455455
456456
<p>If the configuration-name begins with "@", that refers to a class of
457457
values instead of a single value. The content of these configuration items
458
-is returned in a "config" card that contains pure SQL text that is
458
+is returned in a "config" card that contains pure SQL text that is
459459
intended to be evaluated by the client.
460460
461461
<p>The @user and @concealed configuration items contain sensitive information
462462
and are ignored for clients without sufficient privilege.
463463
@@ -491,11 +491,11 @@
491491
</blockquote>
492492
493493
<p>The error message is English text that is encoded in order to
494494
be a single token.
495495
A space (ASCII 0x20) is represented as "\s" (ASCII 0x5C, 0x73). A
496
-newline (ASCII 0x0a) is "\n" (ASCII 0x6C, x6E). A backslash
496
+newline (ASCII 0x0a) is "\n" (ASCII 0x6C, x6E). A backslash
497497
(ASCII 0x5C) is represented as two backslashes "\\". Apart from
498498
space and newline, no other whitespace characters nor any
499499
unprintable characters are allowed in
500500
the error message.</p>
501501
@@ -658,11 +658,11 @@
658658
<ol>
659659
<li>The client sends one or more PUSH HTTP requests to the server.
660660
The request and reply content type is "application/x-fossil".
661661
<li>HTTP request content is compressed using zlib.
662662
<li>The content of request and reply consists of cards with one
663
- card per line.
663
+ card per line.
664664
<li>Card formats are:
665665
<ul>
666666
<li> <b>login</b> <i>userid nonce signature</i>
667667
<li> <b>push</b> <i>servercode projectcode</i>
668668
<li> <b>pull</b> <i>servercode projectcode</i>
669669
--- www/sync.wiki
+++ www/sync.wiki
@@ -15,11 +15,11 @@
15 Synchronization is simply the process of sharing artifacts between
16 servers so that all servers have copies of all artifacts. Because
17 artifacts are unordered, the order in which artifacts are received
18 at a server is inconsequential. It is assumed that the SHA1 hashes
19 of artifacts are unique - that every artifact has a different SHA1 hash.
20 To a first approximation, synchronization proceeds by sharing lists
21 SHA1 hashes of available artifacts, then sharing those artifacts that
22 are not found on one side or the other of the connection. In practice,
23 a repository might contain millions of artifacts. The list of
24 SHA1 hashes for this many artifacts can be large. So optimizations are
25 employed that usually reduce the number of SHA1 hashes that need to be
@@ -150,11 +150,11 @@
150 terminates the login card. The signature is the SHA1 hash of
151 the concatenation of the nonce and the users password.</p>
152
153 <p>For each login card, the server looks up the user and verifies
154 that the nonce matches the SHA1 hash of the remainder of the
155 message. It then checks the signature hash to make sure the
156 signature matches. If everything
157 checks out, then the client is granted all privileges of the
158 specified user.</p>
159
160 <p>Privileges are cumulative. There can be multiple successful
@@ -162,11 +162,11 @@
162 privileges of each individual login.</p>
163
164 <h3>3.3 File and Compressed File Cards</h3>
165
166 <p>Artifacts are transferred using either "file" cards, or "cfile" cards.
167 (The name "file" card comes from the fact that most artifacts correspond to
168 files, and "cfile" is just a compressed file.)
169 </p>
170
171 <h4>3.3.1 File Cards</h4>
172
@@ -230,11 +230,11 @@
230 artifact. If the cfile card has four arguments, then the payload is a
231 delta and the second argument is the ID of another artifact that is the
232 source of the delta and the third argument is the original size of the
233 delta artifact.</p>
234
235 <p>Unlike file cards, cfile cards are only sent in one direction during a
236 clone from server to client for clone protocol version "3" or greater.</p>
237
238 <h3>3.4 Push and Pull Cards</h3>
239
240 <p>Among the first cards in a client-to-server message are
@@ -385,11 +385,11 @@
385 </blockquote>
386
387 <p>As of [/timeline?r=trunk&c=2015-03-19+03%3A57%3A46&n=20|2015-03-19], the configuration-name must be one of the
388 following values:
389
390 <center><table border=0>
391 <tr><td valign="top">
392 <ul>
393 <li> css
394 <li> header
395 <li> footer
@@ -436,11 +436,11 @@
436 <li> @reportfmt
437 <li> @user
438 <li> @concealed
439 <li> @shun
440 </ul></td></tr>
441 </table></center>
442
443 <p>New configuration-names are likely to be added in future releases of
444 Fossil. If the server receives a configuration-name that it does not
445 understand, the entire reqconfig card is silently ignored. The reqconfig
446 card might also be ignored if the user lacks sufficient privilege to
@@ -453,11 +453,11 @@
453 The value of the configuration item is returned to the client using a
454 "config" card.
455
456 <p>If the configuration-name begins with "@", that refers to a class of
457 values instead of a single value. The content of these configuration items
458 is returned in a "config" card that contains pure SQL text that is
459 intended to be evaluated by the client.
460
461 <p>The @user and @concealed configuration items contain sensitive information
462 and are ignored for clients without sufficient privilege.
463
@@ -491,11 +491,11 @@
491 </blockquote>
492
493 <p>The error message is English text that is encoded in order to
494 be a single token.
495 A space (ASCII 0x20) is represented as "\s" (ASCII 0x5C, 0x73). A
496 newline (ASCII 0x0a) is "\n" (ASCII 0x6C, x6E). A backslash
497 (ASCII 0x5C) is represented as two backslashes "\\". Apart from
498 space and newline, no other whitespace characters nor any
499 unprintable characters are allowed in
500 the error message.</p>
501
@@ -658,11 +658,11 @@
658 <ol>
659 <li>The client sends one or more PUSH HTTP requests to the server.
660 The request and reply content type is "application/x-fossil".
661 <li>HTTP request content is compressed using zlib.
662 <li>The content of request and reply consists of cards with one
663 card per line.
664 <li>Card formats are:
665 <ul>
666 <li> <b>login</b> <i>userid nonce signature</i>
667 <li> <b>push</b> <i>servercode projectcode</i>
668 <li> <b>pull</b> <i>servercode projectcode</i>
669
--- www/sync.wiki
+++ www/sync.wiki
@@ -15,11 +15,11 @@
15 Synchronization is simply the process of sharing artifacts between
16 servers so that all servers have copies of all artifacts. Because
17 artifacts are unordered, the order in which artifacts are received
18 at a server is inconsequential. It is assumed that the SHA1 hashes
19 of artifacts are unique - that every artifact has a different SHA1 hash.
20 To a first approximation, synchronization proceeds by sharing lists
21 SHA1 hashes of available artifacts, then sharing those artifacts that
22 are not found on one side or the other of the connection. In practice,
23 a repository might contain millions of artifacts. The list of
24 SHA1 hashes for this many artifacts can be large. So optimizations are
25 employed that usually reduce the number of SHA1 hashes that need to be
@@ -150,11 +150,11 @@
150 terminates the login card. The signature is the SHA1 hash of
151 the concatenation of the nonce and the users password.</p>
152
153 <p>For each login card, the server looks up the user and verifies
154 that the nonce matches the SHA1 hash of the remainder of the
155 message. It then checks the signature hash to make sure the
156 signature matches. If everything
157 checks out, then the client is granted all privileges of the
158 specified user.</p>
159
160 <p>Privileges are cumulative. There can be multiple successful
@@ -162,11 +162,11 @@
162 privileges of each individual login.</p>
163
164 <h3>3.3 File and Compressed File Cards</h3>
165
166 <p>Artifacts are transferred using either "file" cards, or "cfile" cards.
167 (The name "file" card comes from the fact that most artifacts correspond to
168 files, and "cfile" is just a compressed file.)
169 </p>
170
171 <h4>3.3.1 File Cards</h4>
172
@@ -230,11 +230,11 @@
230 artifact. If the cfile card has four arguments, then the payload is a
231 delta and the second argument is the ID of another artifact that is the
232 source of the delta and the third argument is the original size of the
233 delta artifact.</p>
234
235 <p>Unlike file cards, cfile cards are only sent in one direction during a
236 clone from server to client for clone protocol version "3" or greater.</p>
237
238 <h3>3.4 Push and Pull Cards</h3>
239
240 <p>Among the first cards in a client-to-server message are
@@ -385,11 +385,11 @@
385 </blockquote>
386
387 <p>As of [/timeline?r=trunk&c=2015-03-19+03%3A57%3A46&n=20|2015-03-19], the configuration-name must be one of the
388 following values:
389
390 <table border=0 align="center">
391 <tr><td valign="top">
392 <ul>
393 <li> css
394 <li> header
395 <li> footer
@@ -436,11 +436,11 @@
436 <li> @reportfmt
437 <li> @user
438 <li> @concealed
439 <li> @shun
440 </ul></td></tr>
441 </table>
442
443 <p>New configuration-names are likely to be added in future releases of
444 Fossil. If the server receives a configuration-name that it does not
445 understand, the entire reqconfig card is silently ignored. The reqconfig
446 card might also be ignored if the user lacks sufficient privilege to
@@ -453,11 +453,11 @@
453 The value of the configuration item is returned to the client using a
454 "config" card.
455
456 <p>If the configuration-name begins with "@", that refers to a class of
457 values instead of a single value. The content of these configuration items
458 is returned in a "config" card that contains pure SQL text that is
459 intended to be evaluated by the client.
460
461 <p>The @user and @concealed configuration items contain sensitive information
462 and are ignored for clients without sufficient privilege.
463
@@ -491,11 +491,11 @@
491 </blockquote>
492
493 <p>The error message is English text that is encoded in order to
494 be a single token.
495 A space (ASCII 0x20) is represented as "\s" (ASCII 0x5C, 0x73). A
496 newline (ASCII 0x0a) is "\n" (ASCII 0x6C, x6E). A backslash
497 (ASCII 0x5C) is represented as two backslashes "\\". Apart from
498 space and newline, no other whitespace characters nor any
499 unprintable characters are allowed in
500 the error message.</p>
501
@@ -658,11 +658,11 @@
658 <ol>
659 <li>The client sends one or more PUSH HTTP requests to the server.
660 The request and reply content type is "application/x-fossil".
661 <li>HTTP request content is compressed using zlib.
662 <li>The content of request and reply consists of cards with one
663 card per line.
664 <li>Card formats are:
665 <ul>
666 <li> <b>login</b> <i>userid nonce signature</i>
667 <li> <b>push</b> <i>servercode projectcode</i>
668 <li> <b>pull</b> <i>servercode projectcode</i>
669
--- www/tech_overview.wiki
+++ www/tech_overview.wiki
@@ -5,12 +5,12 @@
55
66
<h2>1.0 Introduction</h2>
77
88
At its lowest level, a Fossil repository consists of an unordered set
99
of immutable "artifacts". You might think of these artifacts as "files",
10
-since in many cases the artifacts are exactly that.
11
-But other "control artifacts"
10
+since in many cases the artifacts are exactly that.
11
+But other "control artifacts"
1212
are also included in the mix. These control artifacts define the relationships
1313
between artifacts - which files go together to form a particular
1414
version of the project, who checked in that version and when, what was
1515
the check-in comment, what wiki pages are included with the project, what
1616
are the edit histories of each wiki page, what bug reports or tickets are
@@ -17,21 +17,21 @@
1717
included, who contributed to the evolution of each ticket, and so forth.
1818
This low-level file format is called the "global state" of
1919
the repository, since this is the information that is synced to peer
2020
repositories using push and pull operations. The low-level file format
2121
is also called "enduring" since it is intended to last for many years.
22
-The details of the low-level, enduring, global file format
22
+The details of the low-level, enduring, global file format
2323
are [./fileformat.wiki | described separately].
2424
2525
This article is about how Fossil is currently implemented. Instead of
2626
dealing with vague abstractions of "enduring file formats" as the
2727
[./fileformat.wiki | other document] does, this article provides
28
-some detail on how Fossil actually stores information on disk.
28
+some detail on how Fossil actually stores information on disk.
2929
3030
<h2>2.0 Three Databases</h2>
3131
32
-Fossil stores state information in
32
+Fossil stores state information in
3333
[http://www.sqlite.org/ | SQLite] database files.
3434
SQLite keeps an entire relational database, including multiple tables and
3535
indices, in a single disk file. The SQLite library allows the database
3636
files to be efficiently queried and updated using the industry-standard
3737
SQL language. SQLite updates are atomic, so even in the event of
@@ -46,11 +46,11 @@
4646
</ol>
4747
4848
The configuration database is a one-per-user database that holds
4949
global configuration information used by Fossil. There is one
5050
repository database per project. The repository database is the
51
-file that people are normally referring to when they say
51
+file that people are normally referring to when they say
5252
"a Fossil repository". The checkout database is found in the working
5353
checkout for a project and contains state information that is unique
5454
to that working checkout.
5555
5656
Fossil does not always use all three database files. The web interface,
@@ -65,11 +65,11 @@
6565
SQLite's [http://www.sqlite.org/lang_attach.html | ATTACH] command.
6666
6767
The chart below provides a quick summary of how each of these
6868
database files are used by Fossil, with detailed discussion following.
6969
70
-<center><table border="1" width="80%" cellpadding="0">
70
+<table border="1" width="80%" cellpadding="0" align="center">
7171
<tr>
7272
<td width="33%" valign="top">
7373
<h3 align="center">Configuration Database<br>"~/.fossil"</h3>
7474
<ul>
7575
<li>Global [/help/setting |settings]
@@ -103,11 +103,10 @@
103103
<li>Information needed to "[/help/undo|undo]" or "[/help/redo|redo]"
104104
</ul>
105105
</td>
106106
</tr>
107107
</table>
108
-</center>
109108
110109
<h3>2.1 The Configuration Database</h3>
111110
112111
The configuration database holds cross-repository preferences and a list of all
113112
repositories for a single user.
@@ -135,11 +134,11 @@
135134
You can override this default location by defining the environment
136135
variable FOSSIL_HOME pointing to an appropriate (writable) directory.
137136
138137
<h3>2.2 Repository Databases</h3>
139138
140
-The repository database is the file that is commonly referred to as
139
+The repository database is the file that is commonly referred to as
141140
"the repository". This is because the repository database contains,
142141
among other things, the complete revision, ticket, and wiki history for
143142
a project. It is customary to name the repository database after then
144143
name of the project, with a ".fossil" suffix. For example, the repository
145144
database for the self-hosting Fossil repository is called "fossil.fossil"
@@ -146,11 +145,11 @@
146145
and the repository database for SQLite is called "sqlite.fossil".
147146
148147
<h4>2.2.1 Global Project State</h4>
149148
150149
The bulk of the repository database (typically 75 to 85%) consists
151
-of the artifacts that comprise the
150
+of the artifacts that comprise the
152151
[./fileformat.wiki | enduring, global, shared state] of the project.
153152
The artifacts are stored as BLOBs, compressed using
154153
[http://www.zlib.net/ | zlib compression] and, where applicable,
155154
using [./delta_encoder_algorithm.wiki | delta compression].
156155
The combination of zlib and delta compression results in a considerable
@@ -160,26 +159,26 @@
160159
32 MB of space in the repository database, for a compression ratio
161160
of about 64:1. The average size of a content BLOB in the database
162161
is around 500 bytes.
163162
164163
Note that the zlib and delta compression is not an inherent part of the
165
-Fossil file format; it is just an optimization.
164
+Fossil file format; it is just an optimization.
166165
The enduring file format for Fossil is the unordered
167166
set of artifacts. The compression techniques are just a detail of
168167
how the current implementation of Fossil happens to store these artifacts
169168
efficiently on disk.
170169
171170
All of the original uncompressed and undeltaed artifacts can be extracted
172
-from a Fossil repository database using
171
+from a Fossil repository database using
173172
the [/help/deconstruct | fossil deconstruct]
174173
command. Individual artifacts can be extracted using the
175174
[/help/artifact | fossil artifact] command.
176175
When accessing the repository database using raw SQL and the
177176
[/help/sqlite3 | fossil sql] command, the extension function
178177
"<tt>content()</tt>" with a single argument which is the SHA1 hash
179178
of an artifact will return the complete undeleted and uncompressed
180
-content of that artifact.
179
+content of that artifact.
181180
182181
Going the other way, the [/help/reconstruct | fossil reconstruct]
183182
command will scan a directory hierarchy and add all files found to
184183
a new repository database. The [/help/import | fossil import] command
185184
works by reading the input git-fast-export stream and using it to construct
@@ -225,11 +224,11 @@
225224
by [/help/sync | fossil sync]. That is because it is entirely reasonable
226225
that two different websites for the same project might have completely
227226
different display preferences and user communities. One instance of the
228227
project might be a fork of the other, for example, which pulls from the
229228
other but never pushes and extends the project in ways that the keepers of
230
-the other website disapprove of.
229
+the other website disapprove of.
231230
232231
Display and processing information includes the following:
233232
234233
* The name and description of the project
235234
* The CSS file, header, and footer used by all web pages
@@ -242,31 +241,31 @@
242241
global values defined in the per-user configuration database.
243242
244243
Though the display and processing preferences do not move between
245244
repository instances using [/help/sync | fossil sync], this information
246245
can be shared between repositories using the
247
-[/help/config | fossil config push] and
246
+[/help/config | fossil config push] and
248247
[/help/config | fossil config pull] commands.
249248
The display and processing information is also copied into new
250249
repositories when they are created using
251250
[/help/clone | fossil clone].
252251
253252
<h4>2.2.4 User Credentials And Privileges</h4>
254253
255254
Just because two development teams are collaborating on a project and allow
256
-push and/or pull between their repositories does not mean that they
255
+push and/or pull between their repositories does not mean that they
257256
trust each other enough to share passwords and access privileges.
258257
Hence the names and emails and passwords and privileges of users are
259258
considered private information that is kept locally in each repository.
260259
261260
Each repository database has a table holding the username, privileges,
262261
and login credentials for users authorized to interact with that particular
263
-database. In addition, there is a table named "concealed" that maps the
262
+database. In addition, there is a table named "concealed" that maps the
264263
SHA1 hash of each users email address back into their true email address.
265264
The concealed table allows just the SHA1 hash of email addresses to
266265
be stored in tickets, and thus prevents actual email addresses from falling
267
-into the hands of spammers who happen to clone the repository.
266
+into the hands of spammers who happen to clone the repository.
268267
269268
The content of the user and concealed tables can be pushed and pulled using the
270269
[/help/config | fossil config push] and
271270
[/help/config | fossil config pull] commands with the "user" and
272271
"email" as the AREA argument, but only if you have administrative
@@ -278,11 +277,11 @@
278277
project - is intended to be an append-only database. In other words,
279278
new artifacts can be added but artifacts can never be removed. But
280279
it sometimes happens that inappropriate content is mistakenly or
281280
maliciously added to a repository. The only way to get rid of
282281
the undesired content is to [./shunning.wiki | "shun"] it.
283
-The "shun" table in the repository database records the SHA1 hash of
282
+The "shun" table in the repository database records the SHA1 hash of
284283
all shunned artifacts.
285284
286285
The shun table can be pushed or pulled using
287286
the [/help/config | fossil config] command with the "shun" AREA argument.
288287
The shun table is also copied during a [/help/clone | clone].
289288
--- www/tech_overview.wiki
+++ www/tech_overview.wiki
@@ -5,12 +5,12 @@
5
6 <h2>1.0 Introduction</h2>
7
8 At its lowest level, a Fossil repository consists of an unordered set
9 of immutable "artifacts". You might think of these artifacts as "files",
10 since in many cases the artifacts are exactly that.
11 But other "control artifacts"
12 are also included in the mix. These control artifacts define the relationships
13 between artifacts - which files go together to form a particular
14 version of the project, who checked in that version and when, what was
15 the check-in comment, what wiki pages are included with the project, what
16 are the edit histories of each wiki page, what bug reports or tickets are
@@ -17,21 +17,21 @@
17 included, who contributed to the evolution of each ticket, and so forth.
18 This low-level file format is called the "global state" of
19 the repository, since this is the information that is synced to peer
20 repositories using push and pull operations. The low-level file format
21 is also called "enduring" since it is intended to last for many years.
22 The details of the low-level, enduring, global file format
23 are [./fileformat.wiki | described separately].
24
25 This article is about how Fossil is currently implemented. Instead of
26 dealing with vague abstractions of "enduring file formats" as the
27 [./fileformat.wiki | other document] does, this article provides
28 some detail on how Fossil actually stores information on disk.
29
30 <h2>2.0 Three Databases</h2>
31
32 Fossil stores state information in
33 [http://www.sqlite.org/ | SQLite] database files.
34 SQLite keeps an entire relational database, including multiple tables and
35 indices, in a single disk file. The SQLite library allows the database
36 files to be efficiently queried and updated using the industry-standard
37 SQL language. SQLite updates are atomic, so even in the event of
@@ -46,11 +46,11 @@
46 </ol>
47
48 The configuration database is a one-per-user database that holds
49 global configuration information used by Fossil. There is one
50 repository database per project. The repository database is the
51 file that people are normally referring to when they say
52 "a Fossil repository". The checkout database is found in the working
53 checkout for a project and contains state information that is unique
54 to that working checkout.
55
56 Fossil does not always use all three database files. The web interface,
@@ -65,11 +65,11 @@
65 SQLite's [http://www.sqlite.org/lang_attach.html | ATTACH] command.
66
67 The chart below provides a quick summary of how each of these
68 database files are used by Fossil, with detailed discussion following.
69
70 <center><table border="1" width="80%" cellpadding="0">
71 <tr>
72 <td width="33%" valign="top">
73 <h3 align="center">Configuration Database<br>"~/.fossil"</h3>
74 <ul>
75 <li>Global [/help/setting |settings]
@@ -103,11 +103,10 @@
103 <li>Information needed to "[/help/undo|undo]" or "[/help/redo|redo]"
104 </ul>
105 </td>
106 </tr>
107 </table>
108 </center>
109
110 <h3>2.1 The Configuration Database</h3>
111
112 The configuration database holds cross-repository preferences and a list of all
113 repositories for a single user.
@@ -135,11 +134,11 @@
135 You can override this default location by defining the environment
136 variable FOSSIL_HOME pointing to an appropriate (writable) directory.
137
138 <h3>2.2 Repository Databases</h3>
139
140 The repository database is the file that is commonly referred to as
141 "the repository". This is because the repository database contains,
142 among other things, the complete revision, ticket, and wiki history for
143 a project. It is customary to name the repository database after then
144 name of the project, with a ".fossil" suffix. For example, the repository
145 database for the self-hosting Fossil repository is called "fossil.fossil"
@@ -146,11 +145,11 @@
146 and the repository database for SQLite is called "sqlite.fossil".
147
148 <h4>2.2.1 Global Project State</h4>
149
150 The bulk of the repository database (typically 75 to 85%) consists
151 of the artifacts that comprise the
152 [./fileformat.wiki | enduring, global, shared state] of the project.
153 The artifacts are stored as BLOBs, compressed using
154 [http://www.zlib.net/ | zlib compression] and, where applicable,
155 using [./delta_encoder_algorithm.wiki | delta compression].
156 The combination of zlib and delta compression results in a considerable
@@ -160,26 +159,26 @@
160 32 MB of space in the repository database, for a compression ratio
161 of about 64:1. The average size of a content BLOB in the database
162 is around 500 bytes.
163
164 Note that the zlib and delta compression is not an inherent part of the
165 Fossil file format; it is just an optimization.
166 The enduring file format for Fossil is the unordered
167 set of artifacts. The compression techniques are just a detail of
168 how the current implementation of Fossil happens to store these artifacts
169 efficiently on disk.
170
171 All of the original uncompressed and undeltaed artifacts can be extracted
172 from a Fossil repository database using
173 the [/help/deconstruct | fossil deconstruct]
174 command. Individual artifacts can be extracted using the
175 [/help/artifact | fossil artifact] command.
176 When accessing the repository database using raw SQL and the
177 [/help/sqlite3 | fossil sql] command, the extension function
178 "<tt>content()</tt>" with a single argument which is the SHA1 hash
179 of an artifact will return the complete undeleted and uncompressed
180 content of that artifact.
181
182 Going the other way, the [/help/reconstruct | fossil reconstruct]
183 command will scan a directory hierarchy and add all files found to
184 a new repository database. The [/help/import | fossil import] command
185 works by reading the input git-fast-export stream and using it to construct
@@ -225,11 +224,11 @@
225 by [/help/sync | fossil sync]. That is because it is entirely reasonable
226 that two different websites for the same project might have completely
227 different display preferences and user communities. One instance of the
228 project might be a fork of the other, for example, which pulls from the
229 other but never pushes and extends the project in ways that the keepers of
230 the other website disapprove of.
231
232 Display and processing information includes the following:
233
234 * The name and description of the project
235 * The CSS file, header, and footer used by all web pages
@@ -242,31 +241,31 @@
242 global values defined in the per-user configuration database.
243
244 Though the display and processing preferences do not move between
245 repository instances using [/help/sync | fossil sync], this information
246 can be shared between repositories using the
247 [/help/config | fossil config push] and
248 [/help/config | fossil config pull] commands.
249 The display and processing information is also copied into new
250 repositories when they are created using
251 [/help/clone | fossil clone].
252
253 <h4>2.2.4 User Credentials And Privileges</h4>
254
255 Just because two development teams are collaborating on a project and allow
256 push and/or pull between their repositories does not mean that they
257 trust each other enough to share passwords and access privileges.
258 Hence the names and emails and passwords and privileges of users are
259 considered private information that is kept locally in each repository.
260
261 Each repository database has a table holding the username, privileges,
262 and login credentials for users authorized to interact with that particular
263 database. In addition, there is a table named "concealed" that maps the
264 SHA1 hash of each users email address back into their true email address.
265 The concealed table allows just the SHA1 hash of email addresses to
266 be stored in tickets, and thus prevents actual email addresses from falling
267 into the hands of spammers who happen to clone the repository.
268
269 The content of the user and concealed tables can be pushed and pulled using the
270 [/help/config | fossil config push] and
271 [/help/config | fossil config pull] commands with the "user" and
272 "email" as the AREA argument, but only if you have administrative
@@ -278,11 +277,11 @@
278 project - is intended to be an append-only database. In other words,
279 new artifacts can be added but artifacts can never be removed. But
280 it sometimes happens that inappropriate content is mistakenly or
281 maliciously added to a repository. The only way to get rid of
282 the undesired content is to [./shunning.wiki | "shun"] it.
283 The "shun" table in the repository database records the SHA1 hash of
284 all shunned artifacts.
285
286 The shun table can be pushed or pulled using
287 the [/help/config | fossil config] command with the "shun" AREA argument.
288 The shun table is also copied during a [/help/clone | clone].
289
--- www/tech_overview.wiki
+++ www/tech_overview.wiki
@@ -5,12 +5,12 @@
5
6 <h2>1.0 Introduction</h2>
7
8 At its lowest level, a Fossil repository consists of an unordered set
9 of immutable "artifacts". You might think of these artifacts as "files",
10 since in many cases the artifacts are exactly that.
11 But other "control artifacts"
12 are also included in the mix. These control artifacts define the relationships
13 between artifacts - which files go together to form a particular
14 version of the project, who checked in that version and when, what was
15 the check-in comment, what wiki pages are included with the project, what
16 are the edit histories of each wiki page, what bug reports or tickets are
@@ -17,21 +17,21 @@
17 included, who contributed to the evolution of each ticket, and so forth.
18 This low-level file format is called the "global state" of
19 the repository, since this is the information that is synced to peer
20 repositories using push and pull operations. The low-level file format
21 is also called "enduring" since it is intended to last for many years.
22 The details of the low-level, enduring, global file format
23 are [./fileformat.wiki | described separately].
24
25 This article is about how Fossil is currently implemented. Instead of
26 dealing with vague abstractions of "enduring file formats" as the
27 [./fileformat.wiki | other document] does, this article provides
28 some detail on how Fossil actually stores information on disk.
29
30 <h2>2.0 Three Databases</h2>
31
32 Fossil stores state information in
33 [http://www.sqlite.org/ | SQLite] database files.
34 SQLite keeps an entire relational database, including multiple tables and
35 indices, in a single disk file. The SQLite library allows the database
36 files to be efficiently queried and updated using the industry-standard
37 SQL language. SQLite updates are atomic, so even in the event of
@@ -46,11 +46,11 @@
46 </ol>
47
48 The configuration database is a one-per-user database that holds
49 global configuration information used by Fossil. There is one
50 repository database per project. The repository database is the
51 file that people are normally referring to when they say
52 "a Fossil repository". The checkout database is found in the working
53 checkout for a project and contains state information that is unique
54 to that working checkout.
55
56 Fossil does not always use all three database files. The web interface,
@@ -65,11 +65,11 @@
65 SQLite's [http://www.sqlite.org/lang_attach.html | ATTACH] command.
66
67 The chart below provides a quick summary of how each of these
68 database files are used by Fossil, with detailed discussion following.
69
70 <table border="1" width="80%" cellpadding="0" align="center">
71 <tr>
72 <td width="33%" valign="top">
73 <h3 align="center">Configuration Database<br>"~/.fossil"</h3>
74 <ul>
75 <li>Global [/help/setting |settings]
@@ -103,11 +103,10 @@
103 <li>Information needed to "[/help/undo|undo]" or "[/help/redo|redo]"
104 </ul>
105 </td>
106 </tr>
107 </table>
 
108
109 <h3>2.1 The Configuration Database</h3>
110
111 The configuration database holds cross-repository preferences and a list of all
112 repositories for a single user.
@@ -135,11 +134,11 @@
134 You can override this default location by defining the environment
135 variable FOSSIL_HOME pointing to an appropriate (writable) directory.
136
137 <h3>2.2 Repository Databases</h3>
138
139 The repository database is the file that is commonly referred to as
140 "the repository". This is because the repository database contains,
141 among other things, the complete revision, ticket, and wiki history for
142 a project. It is customary to name the repository database after then
143 name of the project, with a ".fossil" suffix. For example, the repository
144 database for the self-hosting Fossil repository is called "fossil.fossil"
@@ -146,11 +145,11 @@
145 and the repository database for SQLite is called "sqlite.fossil".
146
147 <h4>2.2.1 Global Project State</h4>
148
149 The bulk of the repository database (typically 75 to 85%) consists
150 of the artifacts that comprise the
151 [./fileformat.wiki | enduring, global, shared state] of the project.
152 The artifacts are stored as BLOBs, compressed using
153 [http://www.zlib.net/ | zlib compression] and, where applicable,
154 using [./delta_encoder_algorithm.wiki | delta compression].
155 The combination of zlib and delta compression results in a considerable
@@ -160,26 +159,26 @@
159 32 MB of space in the repository database, for a compression ratio
160 of about 64:1. The average size of a content BLOB in the database
161 is around 500 bytes.
162
163 Note that the zlib and delta compression is not an inherent part of the
164 Fossil file format; it is just an optimization.
165 The enduring file format for Fossil is the unordered
166 set of artifacts. The compression techniques are just a detail of
167 how the current implementation of Fossil happens to store these artifacts
168 efficiently on disk.
169
170 All of the original uncompressed and undeltaed artifacts can be extracted
171 from a Fossil repository database using
172 the [/help/deconstruct | fossil deconstruct]
173 command. Individual artifacts can be extracted using the
174 [/help/artifact | fossil artifact] command.
175 When accessing the repository database using raw SQL and the
176 [/help/sqlite3 | fossil sql] command, the extension function
177 "<tt>content()</tt>" with a single argument which is the SHA1 hash
178 of an artifact will return the complete undeleted and uncompressed
179 content of that artifact.
180
181 Going the other way, the [/help/reconstruct | fossil reconstruct]
182 command will scan a directory hierarchy and add all files found to
183 a new repository database. The [/help/import | fossil import] command
184 works by reading the input git-fast-export stream and using it to construct
@@ -225,11 +224,11 @@
224 by [/help/sync | fossil sync]. That is because it is entirely reasonable
225 that two different websites for the same project might have completely
226 different display preferences and user communities. One instance of the
227 project might be a fork of the other, for example, which pulls from the
228 other but never pushes and extends the project in ways that the keepers of
229 the other website disapprove of.
230
231 Display and processing information includes the following:
232
233 * The name and description of the project
234 * The CSS file, header, and footer used by all web pages
@@ -242,31 +241,31 @@
241 global values defined in the per-user configuration database.
242
243 Though the display and processing preferences do not move between
244 repository instances using [/help/sync | fossil sync], this information
245 can be shared between repositories using the
246 [/help/config | fossil config push] and
247 [/help/config | fossil config pull] commands.
248 The display and processing information is also copied into new
249 repositories when they are created using
250 [/help/clone | fossil clone].
251
252 <h4>2.2.4 User Credentials And Privileges</h4>
253
254 Just because two development teams are collaborating on a project and allow
255 push and/or pull between their repositories does not mean that they
256 trust each other enough to share passwords and access privileges.
257 Hence the names and emails and passwords and privileges of users are
258 considered private information that is kept locally in each repository.
259
260 Each repository database has a table holding the username, privileges,
261 and login credentials for users authorized to interact with that particular
262 database. In addition, there is a table named "concealed" that maps the
263 SHA1 hash of each users email address back into their true email address.
264 The concealed table allows just the SHA1 hash of email addresses to
265 be stored in tickets, and thus prevents actual email addresses from falling
266 into the hands of spammers who happen to clone the repository.
267
268 The content of the user and concealed tables can be pushed and pulled using the
269 [/help/config | fossil config push] and
270 [/help/config | fossil config pull] commands with the "user" and
271 "email" as the AREA argument, but only if you have administrative
@@ -278,11 +277,11 @@
277 project - is intended to be an append-only database. In other words,
278 new artifacts can be added but artifacts can never be removed. But
279 it sometimes happens that inappropriate content is mistakenly or
280 maliciously added to a repository. The only way to get rid of
281 the undesired content is to [./shunning.wiki | "shun"] it.
282 The "shun" table in the repository database records the SHA1 hash of
283 all shunned artifacts.
284
285 The shun table can be pushed or pulled using
286 the [/help/config | fossil config] command with the "shun" AREA argument.
287 The shun table is also copied during a [/help/clone | clone].
288
--- www/webpage-ex.md
+++ www/webpage-ex.md
@@ -64,10 +64,15 @@
6464
6565
* <a target='_blank' class='exbtn'
6666
href='$ROOT/timeline?u=drh&c=2014-01-08&y=ci'>Example</a>
6767
Show check-ins circa 2014-01-08 by user "drh".
6868
69
+ * <a target='_blank' class='exbtn'
70
+ href='$ROOT/timeline?from=version-1.34&to=version-1.35&chng=src/timeline.c,src/doc.c'>Example</a>
71
+ Show all check-ins between version-1.34 and version-1.35 that make
72
+ changes to either of the files src/timeline.c or src/doc.c.
73
+
6974
<big><b>&rarr;</b></big> (Hint: In the pages above, click the graph nodes
7075
for any two check-ins or files to see a diff.)
7176
<big><b>&larr;</b></big>
7277
7378
* <a target='_blank' class='exbtn'
7479
--- www/webpage-ex.md
+++ www/webpage-ex.md
@@ -64,10 +64,15 @@
64
65 * <a target='_blank' class='exbtn'
66 href='$ROOT/timeline?u=drh&c=2014-01-08&y=ci'>Example</a>
67 Show check-ins circa 2014-01-08 by user "drh".
68
 
 
 
 
 
69 <big><b>&rarr;</b></big> (Hint: In the pages above, click the graph nodes
70 for any two check-ins or files to see a diff.)
71 <big><b>&larr;</b></big>
72
73 * <a target='_blank' class='exbtn'
74
--- www/webpage-ex.md
+++ www/webpage-ex.md
@@ -64,10 +64,15 @@
64
65 * <a target='_blank' class='exbtn'
66 href='$ROOT/timeline?u=drh&c=2014-01-08&y=ci'>Example</a>
67 Show check-ins circa 2014-01-08 by user "drh".
68
69 * <a target='_blank' class='exbtn'
70 href='$ROOT/timeline?from=version-1.34&to=version-1.35&chng=src/timeline.c,src/doc.c'>Example</a>
71 Show all check-ins between version-1.34 and version-1.35 that make
72 changes to either of the files src/timeline.c or src/doc.c.
73
74 <big><b>&rarr;</b></big> (Hint: In the pages above, click the graph nodes
75 for any two check-ins or files to see a diff.)
76 <big><b>&larr;</b></big>
77
78 * <a target='_blank' class='exbtn'
79

Keyboard Shortcuts

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