Fossil SCM

Merged in memleak-fixes brach. This fixes several genuine leaks, including 2 in manifest parsing, and cleans up the large work caches during atexit() in order to (A) separate that valgrind noise from the real leaks and (B) leave a better impression on those running valgrind.

stephan 2019-12-23 02:08 trunk merge
Commit 4cf8dbe39820f1062f1ff5687081d86390b72f57cbfcfa2be624e0842ce70cd1
+6
--- src/bag.c
+++ src/bag.c
@@ -48,10 +48,16 @@
4848
int cnt; /* Number of integers in the bag */
4949
int sz; /* Number of slots in a[] */
5050
int used; /* Number of used slots in a[] */
5151
int *a; /* Hash table of integers that are in the bag */
5252
};
53
+/*
54
+** An expression for statically initializing a Bag instance, to be
55
+** assigned to Bag instances at their declaration point. It has
56
+** the same effect as passing the Bag to bag_init().
57
+*/
58
+#define Bag_INIT {0,0,0,0}
5359
#endif
5460
5561
/*
5662
** Initialize a Bag structure
5763
*/
5864
--- src/bag.c
+++ src/bag.c
@@ -48,10 +48,16 @@
48 int cnt; /* Number of integers in the bag */
49 int sz; /* Number of slots in a[] */
50 int used; /* Number of used slots in a[] */
51 int *a; /* Hash table of integers that are in the bag */
52 };
 
 
 
 
 
 
53 #endif
54
55 /*
56 ** Initialize a Bag structure
57 */
58
--- src/bag.c
+++ src/bag.c
@@ -48,10 +48,16 @@
48 int cnt; /* Number of integers in the bag */
49 int sz; /* Number of slots in a[] */
50 int used; /* Number of used slots in a[] */
51 int *a; /* Hash table of integers that are in the bag */
52 };
53 /*
54 ** An expression for statically initializing a Bag instance, to be
55 ** assigned to Bag instances at their declaration point. It has
56 ** the same effect as passing the Bag to bag_init().
57 */
58 #define Bag_INIT {0,0,0,0}
59 #endif
60
61 /*
62 ** Initialize a Bag structure
63 */
64
+6
--- src/bag.c
+++ src/bag.c
@@ -48,10 +48,16 @@
4848
int cnt; /* Number of integers in the bag */
4949
int sz; /* Number of slots in a[] */
5050
int used; /* Number of used slots in a[] */
5151
int *a; /* Hash table of integers that are in the bag */
5252
};
53
+/*
54
+** An expression for statically initializing a Bag instance, to be
55
+** assigned to Bag instances at their declaration point. It has
56
+** the same effect as passing the Bag to bag_init().
57
+*/
58
+#define Bag_INIT {0,0,0,0}
5359
#endif
5460
5561
/*
5662
** Initialize a Bag structure
5763
*/
5864
--- src/bag.c
+++ src/bag.c
@@ -48,10 +48,16 @@
48 int cnt; /* Number of integers in the bag */
49 int sz; /* Number of slots in a[] */
50 int used; /* Number of used slots in a[] */
51 int *a; /* Hash table of integers that are in the bag */
52 };
 
 
 
 
 
 
53 #endif
54
55 /*
56 ** Initialize a Bag structure
57 */
58
--- src/bag.c
+++ src/bag.c
@@ -48,10 +48,16 @@
48 int cnt; /* Number of integers in the bag */
49 int sz; /* Number of slots in a[] */
50 int used; /* Number of used slots in a[] */
51 int *a; /* Hash table of integers that are in the bag */
52 };
53 /*
54 ** An expression for statically initializing a Bag instance, to be
55 ** assigned to Bag instances at their declaration point. It has
56 ** the same effect as passing the Bag to bag_init().
57 */
58 #define Bag_INIT {0,0,0,0}
59 #endif
60
61 /*
62 ** Initialize a Bag structure
63 */
64
+9 -2
--- src/content.c
+++ src/content.c
@@ -99,22 +99,29 @@
9999
blob_zero(pBlob);
100100
bag_insert(&contentCache.inCache, rid);
101101
}
102102
103103
/*
104
-** Clear the content cache.
104
+** Clear the content cache. If it is passed true, it
105
+** also frees all associated memory, otherwise it may
106
+** retain parts for future uses of the cache.
105107
*/
106
-void content_clear_cache(void){
108
+void content_clear_cache(int bFreeIt){
107109
int i;
108110
for(i=0; i<contentCache.n; i++){
109111
blob_reset(&contentCache.a[i].content);
110112
}
111113
bag_clear(&contentCache.missing);
112114
bag_clear(&contentCache.available);
113115
bag_clear(&contentCache.inCache);
114116
contentCache.n = 0;
115117
contentCache.szTotal = 0;
118
+ if(bFreeIt){
119
+ fossil_free(contentCache.a);
120
+ contentCache.a = 0;
121
+ contentCache.nAlloc = 0;
122
+ }
116123
}
117124
118125
/*
119126
** Return the srcid associated with rid. Or return 0 if rid is
120127
** original content and not a delta.
121128
--- src/content.c
+++ src/content.c
@@ -99,22 +99,29 @@
99 blob_zero(pBlob);
100 bag_insert(&contentCache.inCache, rid);
101 }
102
103 /*
104 ** Clear the content cache.
 
 
105 */
106 void content_clear_cache(void){
107 int i;
108 for(i=0; i<contentCache.n; i++){
109 blob_reset(&contentCache.a[i].content);
110 }
111 bag_clear(&contentCache.missing);
112 bag_clear(&contentCache.available);
113 bag_clear(&contentCache.inCache);
114 contentCache.n = 0;
115 contentCache.szTotal = 0;
 
 
 
 
 
116 }
117
118 /*
119 ** Return the srcid associated with rid. Or return 0 if rid is
120 ** original content and not a delta.
121
--- src/content.c
+++ src/content.c
@@ -99,22 +99,29 @@
99 blob_zero(pBlob);
100 bag_insert(&contentCache.inCache, rid);
101 }
102
103 /*
104 ** Clear the content cache. If it is passed true, it
105 ** also frees all associated memory, otherwise it may
106 ** retain parts for future uses of the cache.
107 */
108 void content_clear_cache(int bFreeIt){
109 int i;
110 for(i=0; i<contentCache.n; i++){
111 blob_reset(&contentCache.a[i].content);
112 }
113 bag_clear(&contentCache.missing);
114 bag_clear(&contentCache.available);
115 bag_clear(&contentCache.inCache);
116 contentCache.n = 0;
117 contentCache.szTotal = 0;
118 if(bFreeIt){
119 fossil_free(contentCache.a);
120 contentCache.a = 0;
121 contentCache.nAlloc = 0;
122 }
123 }
124
125 /*
126 ** Return the srcid associated with rid. Or return 0 if rid is
127 ** original content and not a delta.
128
+6
--- src/db.c
+++ src/db.c
@@ -1628,11 +1628,13 @@
16281628
assert( g.localOpen );
16291629
assert( g.zLocalRoot );
16301630
if( zRepo==0 ){
16311631
zRepo = db_lget("repository", 0);
16321632
if( zRepo && !file_is_absolute_path(zRepo) ){
1633
+ char * zFree = zRepo;
16331634
zRepo = mprintf("%s%s", g.zLocalRoot, zRepo);
1635
+ fossil_free(zFree);
16341636
}
16351637
}
16361638
return zRepo;
16371639
}
16381640
@@ -2633,11 +2635,15 @@
26332635
db_swap_connections();
26342636
}
26352637
if( pSetting!=0 && pSetting->versionable ){
26362638
/* This is a versionable setting, try and get the info from a
26372639
** checked out file */
2640
+ char * zZ = z;
26382641
z = db_get_versioned(zName, z);
2642
+ if(zZ != z){
2643
+ fossil_free(zZ);
2644
+ }
26392645
}
26402646
if( z==0 ){
26412647
if( zDefault==0 && pSetting && pSetting->def[0] ){
26422648
z = fossil_strdup(pSetting->def);
26432649
}else{
26442650
--- src/db.c
+++ src/db.c
@@ -1628,11 +1628,13 @@
1628 assert( g.localOpen );
1629 assert( g.zLocalRoot );
1630 if( zRepo==0 ){
1631 zRepo = db_lget("repository", 0);
1632 if( zRepo && !file_is_absolute_path(zRepo) ){
 
1633 zRepo = mprintf("%s%s", g.zLocalRoot, zRepo);
 
1634 }
1635 }
1636 return zRepo;
1637 }
1638
@@ -2633,11 +2635,15 @@
2633 db_swap_connections();
2634 }
2635 if( pSetting!=0 && pSetting->versionable ){
2636 /* This is a versionable setting, try and get the info from a
2637 ** checked out file */
 
2638 z = db_get_versioned(zName, z);
 
 
 
2639 }
2640 if( z==0 ){
2641 if( zDefault==0 && pSetting && pSetting->def[0] ){
2642 z = fossil_strdup(pSetting->def);
2643 }else{
2644
--- src/db.c
+++ src/db.c
@@ -1628,11 +1628,13 @@
1628 assert( g.localOpen );
1629 assert( g.zLocalRoot );
1630 if( zRepo==0 ){
1631 zRepo = db_lget("repository", 0);
1632 if( zRepo && !file_is_absolute_path(zRepo) ){
1633 char * zFree = zRepo;
1634 zRepo = mprintf("%s%s", g.zLocalRoot, zRepo);
1635 fossil_free(zFree);
1636 }
1637 }
1638 return zRepo;
1639 }
1640
@@ -2633,11 +2635,15 @@
2635 db_swap_connections();
2636 }
2637 if( pSetting!=0 && pSetting->versionable ){
2638 /* This is a versionable setting, try and get the info from a
2639 ** checked out file */
2640 char * zZ = z;
2641 z = db_get_versioned(zName, z);
2642 if(zZ != z){
2643 fossil_free(zZ);
2644 }
2645 }
2646 if( z==0 ){
2647 if( zDefault==0 && pSetting && pSetting->def[0] ){
2648 z = fossil_strdup(pSetting->def);
2649 }else{
2650
+4 -1
--- src/import.c
+++ src/import.c
@@ -212,12 +212,12 @@
212212
/*
213213
** Use data accumulated in gg from a "tag" record to add a new
214214
** control artifact to the BLOB table.
215215
*/
216216
static void finish_tag(void){
217
- Blob record, cksum;
218217
if( gg.zDate && gg.zTag && gg.zFrom && gg.zUser ){
218
+ Blob record, cksum;
219219
blob_zero(&record);
220220
blob_appendf(&record, "D %s\n", gg.zDate);
221221
blob_appendf(&record, "T +sym-%F%F%F %s", gimport.zTagPre, gg.zTag,
222222
gimport.zTagSuf, gg.zFrom);
223223
if( gg.zComment ){
@@ -226,10 +226,11 @@
226226
blob_appendf(&record, "\nU %F\n", gg.zUser);
227227
md5sum_blob(&record, &cksum);
228228
blob_appendf(&record, "Z %b\n", &cksum);
229229
fast_insert_content(&record, 0, 0, 1);
230230
blob_reset(&cksum);
231
+ blob_reset(&record);
231232
}
232233
import_reset(0);
233234
}
234235
235236
/*
@@ -336,10 +337,12 @@
336337
**
337338
** This behavior seems like a bug in git-fast-export, but it is easier
338339
** to work around the problem than to fix git-fast-export.
339340
*/
340341
if( gg.tagCommit && gg.zDate && gg.zUser && gg.zFrom ){
342
+ record.nUsed = 0
343
+ /*in case fast_insert_comment() did not indirectly blob_reset() it */;
341344
blob_appendf(&record, "D %s\n", gg.zDate);
342345
blob_appendf(&record, "T +sym-%F%F%F %s\n", gimport.zBranchPre, gg.zBranch,
343346
gimport.zBranchSuf, gg.zPrevCheckin);
344347
blob_appendf(&record, "U %F\n", gg.zUser);
345348
md5sum_blob(&record, &cksum);
346349
--- src/import.c
+++ src/import.c
@@ -212,12 +212,12 @@
212 /*
213 ** Use data accumulated in gg from a "tag" record to add a new
214 ** control artifact to the BLOB table.
215 */
216 static void finish_tag(void){
217 Blob record, cksum;
218 if( gg.zDate && gg.zTag && gg.zFrom && gg.zUser ){
 
219 blob_zero(&record);
220 blob_appendf(&record, "D %s\n", gg.zDate);
221 blob_appendf(&record, "T +sym-%F%F%F %s", gimport.zTagPre, gg.zTag,
222 gimport.zTagSuf, gg.zFrom);
223 if( gg.zComment ){
@@ -226,10 +226,11 @@
226 blob_appendf(&record, "\nU %F\n", gg.zUser);
227 md5sum_blob(&record, &cksum);
228 blob_appendf(&record, "Z %b\n", &cksum);
229 fast_insert_content(&record, 0, 0, 1);
230 blob_reset(&cksum);
 
231 }
232 import_reset(0);
233 }
234
235 /*
@@ -336,10 +337,12 @@
336 **
337 ** This behavior seems like a bug in git-fast-export, but it is easier
338 ** to work around the problem than to fix git-fast-export.
339 */
340 if( gg.tagCommit && gg.zDate && gg.zUser && gg.zFrom ){
 
 
341 blob_appendf(&record, "D %s\n", gg.zDate);
342 blob_appendf(&record, "T +sym-%F%F%F %s\n", gimport.zBranchPre, gg.zBranch,
343 gimport.zBranchSuf, gg.zPrevCheckin);
344 blob_appendf(&record, "U %F\n", gg.zUser);
345 md5sum_blob(&record, &cksum);
346
--- src/import.c
+++ src/import.c
@@ -212,12 +212,12 @@
212 /*
213 ** Use data accumulated in gg from a "tag" record to add a new
214 ** control artifact to the BLOB table.
215 */
216 static void finish_tag(void){
 
217 if( gg.zDate && gg.zTag && gg.zFrom && gg.zUser ){
218 Blob record, cksum;
219 blob_zero(&record);
220 blob_appendf(&record, "D %s\n", gg.zDate);
221 blob_appendf(&record, "T +sym-%F%F%F %s", gimport.zTagPre, gg.zTag,
222 gimport.zTagSuf, gg.zFrom);
223 if( gg.zComment ){
@@ -226,10 +226,11 @@
226 blob_appendf(&record, "\nU %F\n", gg.zUser);
227 md5sum_blob(&record, &cksum);
228 blob_appendf(&record, "Z %b\n", &cksum);
229 fast_insert_content(&record, 0, 0, 1);
230 blob_reset(&cksum);
231 blob_reset(&record);
232 }
233 import_reset(0);
234 }
235
236 /*
@@ -336,10 +337,12 @@
337 **
338 ** This behavior seems like a bug in git-fast-export, but it is easier
339 ** to work around the problem than to fix git-fast-export.
340 */
341 if( gg.tagCommit && gg.zDate && gg.zUser && gg.zFrom ){
342 record.nUsed = 0
343 /*in case fast_insert_comment() did not indirectly blob_reset() it */;
344 blob_appendf(&record, "D %s\n", gg.zDate);
345 blob_appendf(&record, "T +sym-%F%F%F %s\n", gimport.zBranchPre, gg.zBranch,
346 gimport.zBranchSuf, gg.zPrevCheckin);
347 blob_appendf(&record, "U %F\n", gg.zUser);
348 md5sum_blob(&record, &cksum);
349
+3
--- src/main.c
+++ src/main.c
@@ -364,10 +364,13 @@
364364
#endif
365365
free(g.zErrMsg);
366366
if(g.db){
367367
db_close(0);
368368
}
369
+ manifest_clear_cache();
370
+ content_clear_cache(1);
371
+ rebuild_clear_cache();
369372
/*
370373
** FIXME: The next two lines cannot always be enabled; however, they
371374
** are very useful for tracking down TH1 memory leaks.
372375
*/
373376
if( fossil_getenv("TH1_DELETE_INTERP")!=0 ){
374377
--- src/main.c
+++ src/main.c
@@ -364,10 +364,13 @@
364 #endif
365 free(g.zErrMsg);
366 if(g.db){
367 db_close(0);
368 }
 
 
 
369 /*
370 ** FIXME: The next two lines cannot always be enabled; however, they
371 ** are very useful for tracking down TH1 memory leaks.
372 */
373 if( fossil_getenv("TH1_DELETE_INTERP")!=0 ){
374
--- src/main.c
+++ src/main.c
@@ -364,10 +364,13 @@
364 #endif
365 free(g.zErrMsg);
366 if(g.db){
367 db_close(0);
368 }
369 manifest_clear_cache();
370 content_clear_cache(1);
371 rebuild_clear_cache();
372 /*
373 ** FIXME: The next two lines cannot always be enabled; however, they
374 ** are very useful for tracking down TH1 memory leaks.
375 */
376 if( fossil_getenv("TH1_DELETE_INTERP")!=0 ){
377
+21 -7
--- src/manifest.c
+++ src/manifest.c
@@ -68,11 +68,11 @@
6868
*/
6969
struct Manifest {
7070
Blob content; /* The original content blob */
7171
int type; /* Type of artifact. One of CFTYPE_xxxxx */
7272
int rid; /* The blob-id for this manifest */
73
- char *zBaseline; /* Baseline manifest. The B card. */
73
+ const char *zBaseline;/* Baseline manifest. The B card. */
7474
Manifest *pBaseline; /* The actual baseline manifest */
7575
char *zComment; /* Decoded comment. The C card. */
7676
double rDate; /* Date and time from D card. 0.0 if no D card. */
7777
char *zUser; /* Name of the user from the U card. */
7878
char *zRepoCksum; /* MD5 checksum of the baseline content. R card. */
@@ -384,10 +384,23 @@
384384
385385
/*
386386
** Shorthand for a control-artifact parsing error
387387
*/
388388
#define SYNTAX(T) {zErr=(T); goto manifest_syntax_error;}
389
+
390
+/*
391
+** A cache of manifest IDs which manifest_parse() has seen in this
392
+** session.
393
+*/
394
+static Bag seenManifests = Bag_INIT;
395
+/*
396
+** Frees all memory owned by the manifest "has-seen" cache. Intended
397
+** to be called only from the app's atexit() handler.
398
+*/
399
+void manifest_clear_cache(){
400
+ bag_clear(&seenManifests);
401
+}
389402
390403
/*
391404
** Parse a blob into a Manifest object. The Manifest object
392405
** takes over the input blob and will free it when the
393406
** Manifest object is freed. Zeros are inserted into the blob
@@ -428,23 +441,22 @@
428441
char *zUuid;
429442
int sz = 0;
430443
int isRepeat;
431444
int nSelfTag = 0; /* Number of T cards referring to this manifest */
432445
int nSimpleTag = 0; /* Number of T cards with "+" prefix */
433
- static Bag seen;
434446
const char *zErr = 0;
435447
unsigned int m;
436448
unsigned int seenCard = 0; /* Which card types have been seen */
437449
char zErrBuf[100]; /* Write error messages here */
438450
439451
if( rid==0 ){
440452
isRepeat = 1;
441
- }else if( bag_find(&seen, rid) ){
453
+ }else if( bag_find(&seenManifests, rid) ){
442454
isRepeat = 1;
443455
}else{
444456
isRepeat = 0;
445
- bag_insert(&seen, rid);
457
+ bag_insert(&seenManifests, rid);
446458
}
447459
448460
/* Every structural artifact ends with a '\n' character. Exit early
449461
** if that is not the case for this artifact.
450462
*/
@@ -1704,11 +1716,11 @@
17041716
*/
17051717
static int manifest_add_checkin_linkages(
17061718
int rid, /* The RID of the check-in */
17071719
Manifest *p, /* Manifest for this check-in */
17081720
int nParent, /* Number of parents for this check-in */
1709
- char **azParent /* hashes for each parent */
1721
+ char * const * azParent /* hashes for each parent */
17101722
){
17111723
int i;
17121724
int parentid = 0;
17131725
char zBaseId[30]; /* Baseline manifest RID for deltas. "NULL" otherwise */
17141726
Stmt q;
@@ -2087,12 +2099,13 @@
20872099
if( (p = manifest_cache_find(rid))!=0 ){
20882100
blob_reset(pContent);
20892101
}else if( (p = manifest_parse(pContent, rid, 0))==0 ){
20902102
assert( blob_is_reset(pContent) || pContent==0 );
20912103
if( (flags & MC_NO_ERRORS)==0 ){
2092
- fossil_error(1, "syntax error in manifest [%S]",
2093
- db_text(0, "SELECT uuid FROM blob WHERE rid=%d",rid));
2104
+ char * zErrUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d",rid);
2105
+ fossil_error(1, "syntax error in manifest [%S]", zErrUuid);
2106
+ fossil_free(zErrUuid);
20942107
}
20952108
return 0;
20962109
}
20972110
if( g.xlinkClusterOnly && p->type!=CFTYPE_CLUSTER ){
20982111
manifest_destroy(p);
@@ -2197,10 +2210,11 @@
21972210
case '-': type = 0; break; /* Cancel prior occurrences */
21982211
case '+': type = 1; break; /* Apply to target only */
21992212
case '*': type = 2; break; /* Propagate to descendants */
22002213
default:
22012214
fossil_error(1, "unknown tag type in manifest: %s", p->aTag);
2215
+ manifest_destroy(p);
22022216
return 0;
22032217
}
22042218
tag_insert(&p->aTag[i].zName[1], type, p->aTag[i].zValue,
22052219
rid, p->rDate, tid);
22062220
}
22072221
--- src/manifest.c
+++ src/manifest.c
@@ -68,11 +68,11 @@
68 */
69 struct Manifest {
70 Blob content; /* The original content blob */
71 int type; /* Type of artifact. One of CFTYPE_xxxxx */
72 int rid; /* The blob-id for this manifest */
73 char *zBaseline; /* Baseline manifest. The B card. */
74 Manifest *pBaseline; /* The actual baseline manifest */
75 char *zComment; /* Decoded comment. The C card. */
76 double rDate; /* Date and time from D card. 0.0 if no D card. */
77 char *zUser; /* Name of the user from the U card. */
78 char *zRepoCksum; /* MD5 checksum of the baseline content. R card. */
@@ -384,10 +384,23 @@
384
385 /*
386 ** Shorthand for a control-artifact parsing error
387 */
388 #define SYNTAX(T) {zErr=(T); goto manifest_syntax_error;}
 
 
 
 
 
 
 
 
 
 
 
 
 
389
390 /*
391 ** Parse a blob into a Manifest object. The Manifest object
392 ** takes over the input blob and will free it when the
393 ** Manifest object is freed. Zeros are inserted into the blob
@@ -428,23 +441,22 @@
428 char *zUuid;
429 int sz = 0;
430 int isRepeat;
431 int nSelfTag = 0; /* Number of T cards referring to this manifest */
432 int nSimpleTag = 0; /* Number of T cards with "+" prefix */
433 static Bag seen;
434 const char *zErr = 0;
435 unsigned int m;
436 unsigned int seenCard = 0; /* Which card types have been seen */
437 char zErrBuf[100]; /* Write error messages here */
438
439 if( rid==0 ){
440 isRepeat = 1;
441 }else if( bag_find(&seen, rid) ){
442 isRepeat = 1;
443 }else{
444 isRepeat = 0;
445 bag_insert(&seen, rid);
446 }
447
448 /* Every structural artifact ends with a '\n' character. Exit early
449 ** if that is not the case for this artifact.
450 */
@@ -1704,11 +1716,11 @@
1704 */
1705 static int manifest_add_checkin_linkages(
1706 int rid, /* The RID of the check-in */
1707 Manifest *p, /* Manifest for this check-in */
1708 int nParent, /* Number of parents for this check-in */
1709 char **azParent /* hashes for each parent */
1710 ){
1711 int i;
1712 int parentid = 0;
1713 char zBaseId[30]; /* Baseline manifest RID for deltas. "NULL" otherwise */
1714 Stmt q;
@@ -2087,12 +2099,13 @@
2087 if( (p = manifest_cache_find(rid))!=0 ){
2088 blob_reset(pContent);
2089 }else if( (p = manifest_parse(pContent, rid, 0))==0 ){
2090 assert( blob_is_reset(pContent) || pContent==0 );
2091 if( (flags & MC_NO_ERRORS)==0 ){
2092 fossil_error(1, "syntax error in manifest [%S]",
2093 db_text(0, "SELECT uuid FROM blob WHERE rid=%d",rid));
 
2094 }
2095 return 0;
2096 }
2097 if( g.xlinkClusterOnly && p->type!=CFTYPE_CLUSTER ){
2098 manifest_destroy(p);
@@ -2197,10 +2210,11 @@
2197 case '-': type = 0; break; /* Cancel prior occurrences */
2198 case '+': type = 1; break; /* Apply to target only */
2199 case '*': type = 2; break; /* Propagate to descendants */
2200 default:
2201 fossil_error(1, "unknown tag type in manifest: %s", p->aTag);
 
2202 return 0;
2203 }
2204 tag_insert(&p->aTag[i].zName[1], type, p->aTag[i].zValue,
2205 rid, p->rDate, tid);
2206 }
2207
--- src/manifest.c
+++ src/manifest.c
@@ -68,11 +68,11 @@
68 */
69 struct Manifest {
70 Blob content; /* The original content blob */
71 int type; /* Type of artifact. One of CFTYPE_xxxxx */
72 int rid; /* The blob-id for this manifest */
73 const char *zBaseline;/* Baseline manifest. The B card. */
74 Manifest *pBaseline; /* The actual baseline manifest */
75 char *zComment; /* Decoded comment. The C card. */
76 double rDate; /* Date and time from D card. 0.0 if no D card. */
77 char *zUser; /* Name of the user from the U card. */
78 char *zRepoCksum; /* MD5 checksum of the baseline content. R card. */
@@ -384,10 +384,23 @@
384
385 /*
386 ** Shorthand for a control-artifact parsing error
387 */
388 #define SYNTAX(T) {zErr=(T); goto manifest_syntax_error;}
389
390 /*
391 ** A cache of manifest IDs which manifest_parse() has seen in this
392 ** session.
393 */
394 static Bag seenManifests = Bag_INIT;
395 /*
396 ** Frees all memory owned by the manifest "has-seen" cache. Intended
397 ** to be called only from the app's atexit() handler.
398 */
399 void manifest_clear_cache(){
400 bag_clear(&seenManifests);
401 }
402
403 /*
404 ** Parse a blob into a Manifest object. The Manifest object
405 ** takes over the input blob and will free it when the
406 ** Manifest object is freed. Zeros are inserted into the blob
@@ -428,23 +441,22 @@
441 char *zUuid;
442 int sz = 0;
443 int isRepeat;
444 int nSelfTag = 0; /* Number of T cards referring to this manifest */
445 int nSimpleTag = 0; /* Number of T cards with "+" prefix */
 
446 const char *zErr = 0;
447 unsigned int m;
448 unsigned int seenCard = 0; /* Which card types have been seen */
449 char zErrBuf[100]; /* Write error messages here */
450
451 if( rid==0 ){
452 isRepeat = 1;
453 }else if( bag_find(&seenManifests, rid) ){
454 isRepeat = 1;
455 }else{
456 isRepeat = 0;
457 bag_insert(&seenManifests, rid);
458 }
459
460 /* Every structural artifact ends with a '\n' character. Exit early
461 ** if that is not the case for this artifact.
462 */
@@ -1704,11 +1716,11 @@
1716 */
1717 static int manifest_add_checkin_linkages(
1718 int rid, /* The RID of the check-in */
1719 Manifest *p, /* Manifest for this check-in */
1720 int nParent, /* Number of parents for this check-in */
1721 char * const * azParent /* hashes for each parent */
1722 ){
1723 int i;
1724 int parentid = 0;
1725 char zBaseId[30]; /* Baseline manifest RID for deltas. "NULL" otherwise */
1726 Stmt q;
@@ -2087,12 +2099,13 @@
2099 if( (p = manifest_cache_find(rid))!=0 ){
2100 blob_reset(pContent);
2101 }else if( (p = manifest_parse(pContent, rid, 0))==0 ){
2102 assert( blob_is_reset(pContent) || pContent==0 );
2103 if( (flags & MC_NO_ERRORS)==0 ){
2104 char * zErrUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d",rid);
2105 fossil_error(1, "syntax error in manifest [%S]", zErrUuid);
2106 fossil_free(zErrUuid);
2107 }
2108 return 0;
2109 }
2110 if( g.xlinkClusterOnly && p->type!=CFTYPE_CLUSTER ){
2111 manifest_destroy(p);
@@ -2197,10 +2210,11 @@
2210 case '-': type = 0; break; /* Cancel prior occurrences */
2211 case '+': type = 1; break; /* Apply to target only */
2212 case '*': type = 2; break; /* Propagate to descendants */
2213 default:
2214 fossil_error(1, "unknown tag type in manifest: %s", p->aTag);
2215 manifest_destroy(p);
2216 return 0;
2217 }
2218 tag_insert(&p->aTag[i].zName[1], type, p->aTag[i].zValue,
2219 rid, p->rDate, tid);
2220 }
2221
+13 -6
--- src/rebuild.c
+++ src/rebuild.c
@@ -176,18 +176,18 @@
176176
177177
/*
178178
** Variables used to store state information about an on-going "rebuild"
179179
** or "deconstruct".
180180
*/
181
-static int totalSize; /* Total number of artifacts to process */
182
-static int processCnt; /* Number processed so far */
183
-static int ttyOutput; /* Do progress output */
184
-static Bag bagDone; /* Bag of records rebuilt */
181
+static int totalSize; /* Total number of artifacts to process */
182
+static int processCnt; /* Number processed so far */
183
+static int ttyOutput; /* Do progress output */
184
+static Bag bagDone = Bag_INIT; /* Bag of records rebuilt */
185185
186186
static char *zFNameFormat; /* Format string for filenames on deconstruct */
187187
static int cchFNamePrefix; /* Length of directory prefix in zFNameFormat */
188
-static char *zDestDir; /* Destination directory on deconstruct */
188
+static const char *zDestDir;/* Destination directory on deconstruct */
189189
static int prefixLength; /* Length of directory prefix for deconstruct */
190190
static int fKeepRid1; /* Flag to preserve RID=1 on de- and reconstruct */
191191
192192
193193
/*
@@ -201,10 +201,17 @@
201201
fflush(stdout);
202202
lastOutput = permill;
203203
}
204204
}
205205
206
+/*
207
+** Frees rebuild-level cached state. Intended only to be called by the
208
+** app-level atexit() handler.
209
+*/
210
+void rebuild_clear_cache(){
211
+ bag_clear(&bagDone);
212
+}
206213
207214
/*
208215
** Called after each artifact is processed
209216
*/
210217
static void rebuild_step_done(int rid){
@@ -366,11 +373,11 @@
366373
Stmt s, q;
367374
int errCnt = 0;
368375
int incrSize;
369376
Blob sql;
370377
371
- bag_init(&bagDone);
378
+ bag_clear(&bagDone);
372379
ttyOutput = doOut;
373380
processCnt = 0;
374381
if (ttyOutput && !g.fQuiet) {
375382
percent_complete(0);
376383
}
377384
--- src/rebuild.c
+++ src/rebuild.c
@@ -176,18 +176,18 @@
176
177 /*
178 ** Variables used to store state information about an on-going "rebuild"
179 ** or "deconstruct".
180 */
181 static int totalSize; /* Total number of artifacts to process */
182 static int processCnt; /* Number processed so far */
183 static int ttyOutput; /* Do progress output */
184 static Bag bagDone; /* Bag of records rebuilt */
185
186 static char *zFNameFormat; /* Format string for filenames on deconstruct */
187 static int cchFNamePrefix; /* Length of directory prefix in zFNameFormat */
188 static char *zDestDir; /* Destination directory on deconstruct */
189 static int prefixLength; /* Length of directory prefix for deconstruct */
190 static int fKeepRid1; /* Flag to preserve RID=1 on de- and reconstruct */
191
192
193 /*
@@ -201,10 +201,17 @@
201 fflush(stdout);
202 lastOutput = permill;
203 }
204 }
205
 
 
 
 
 
 
 
206
207 /*
208 ** Called after each artifact is processed
209 */
210 static void rebuild_step_done(int rid){
@@ -366,11 +373,11 @@
366 Stmt s, q;
367 int errCnt = 0;
368 int incrSize;
369 Blob sql;
370
371 bag_init(&bagDone);
372 ttyOutput = doOut;
373 processCnt = 0;
374 if (ttyOutput && !g.fQuiet) {
375 percent_complete(0);
376 }
377
--- src/rebuild.c
+++ src/rebuild.c
@@ -176,18 +176,18 @@
176
177 /*
178 ** Variables used to store state information about an on-going "rebuild"
179 ** or "deconstruct".
180 */
181 static int totalSize; /* Total number of artifacts to process */
182 static int processCnt; /* Number processed so far */
183 static int ttyOutput; /* Do progress output */
184 static Bag bagDone = Bag_INIT; /* Bag of records rebuilt */
185
186 static char *zFNameFormat; /* Format string for filenames on deconstruct */
187 static int cchFNamePrefix; /* Length of directory prefix in zFNameFormat */
188 static const char *zDestDir;/* Destination directory on deconstruct */
189 static int prefixLength; /* Length of directory prefix for deconstruct */
190 static int fKeepRid1; /* Flag to preserve RID=1 on de- and reconstruct */
191
192
193 /*
@@ -201,10 +201,17 @@
201 fflush(stdout);
202 lastOutput = permill;
203 }
204 }
205
206 /*
207 ** Frees rebuild-level cached state. Intended only to be called by the
208 ** app-level atexit() handler.
209 */
210 void rebuild_clear_cache(){
211 bag_clear(&bagDone);
212 }
213
214 /*
215 ** Called after each artifact is processed
216 */
217 static void rebuild_step_done(int rid){
@@ -366,11 +373,11 @@
373 Stmt s, q;
374 int errCnt = 0;
375 int incrSize;
376 Blob sql;
377
378 bag_clear(&bagDone);
379 ttyOutput = doOut;
380 processCnt = 0;
381 if (ttyOutput && !g.fQuiet) {
382 percent_complete(0);
383 }
384
+2 -1
--- src/tkt.c
+++ src/tkt.c
@@ -364,11 +364,11 @@
364364
365365
/*
366366
** Recreate the TICKET and TICKETCHNG tables.
367367
*/
368368
void ticket_create_table(int separateConnection){
369
- const char *zSql;
369
+ char *zSql;
370370
371371
db_multi_exec(
372372
"DROP TABLE IF EXISTS ticket;"
373373
"DROP TABLE IF EXISTS ticketchng;"
374374
);
@@ -377,10 +377,11 @@
377377
if( db_transaction_nesting_depth() ) db_end_transaction(0);
378378
db_init_database(g.zRepositoryName, zSql, 0);
379379
}else{
380380
db_multi_exec("%s", zSql/*safe-for-%s*/);
381381
}
382
+ fossil_free(zSql);
382383
}
383384
384385
/*
385386
** Repopulate the TICKET and TICKETCHNG tables from scratch using all
386387
** available ticket artifacts.
387388
--- src/tkt.c
+++ src/tkt.c
@@ -364,11 +364,11 @@
364
365 /*
366 ** Recreate the TICKET and TICKETCHNG tables.
367 */
368 void ticket_create_table(int separateConnection){
369 const char *zSql;
370
371 db_multi_exec(
372 "DROP TABLE IF EXISTS ticket;"
373 "DROP TABLE IF EXISTS ticketchng;"
374 );
@@ -377,10 +377,11 @@
377 if( db_transaction_nesting_depth() ) db_end_transaction(0);
378 db_init_database(g.zRepositoryName, zSql, 0);
379 }else{
380 db_multi_exec("%s", zSql/*safe-for-%s*/);
381 }
 
382 }
383
384 /*
385 ** Repopulate the TICKET and TICKETCHNG tables from scratch using all
386 ** available ticket artifacts.
387
--- src/tkt.c
+++ src/tkt.c
@@ -364,11 +364,11 @@
364
365 /*
366 ** Recreate the TICKET and TICKETCHNG tables.
367 */
368 void ticket_create_table(int separateConnection){
369 char *zSql;
370
371 db_multi_exec(
372 "DROP TABLE IF EXISTS ticket;"
373 "DROP TABLE IF EXISTS ticketchng;"
374 );
@@ -377,10 +377,11 @@
377 if( db_transaction_nesting_depth() ) db_end_transaction(0);
378 db_init_database(g.zRepositoryName, zSql, 0);
379 }else{
380 db_multi_exec("%s", zSql/*safe-for-%s*/);
381 }
382 fossil_free(zSql);
383 }
384
385 /*
386 ** Repopulate the TICKET and TICKETCHNG tables from scratch using all
387 ** available ticket artifacts.
388
+3 -2
--- src/tktsetup.c
+++ src/tktsetup.c
@@ -96,13 +96,14 @@
9696
@ );
9797
@ CREATE INDEX ticketchng_idx1 ON ticketchng(tkt_id, tkt_mtime);
9898
;
9999
100100
/*
101
-** Return the ticket table definition
101
+** Return the ticket table definition in heap-allocated
102
+** memory owned by the caller.
102103
*/
103
-const char *ticket_table_schema(void){
104
+char *ticket_table_schema(void){
104105
return db_get("ticket-table", zDefaultTicketTable);
105106
}
106107
107108
/*
108109
** Common implementation for the ticket setup editor pages.
109110
--- src/tktsetup.c
+++ src/tktsetup.c
@@ -96,13 +96,14 @@
96 @ );
97 @ CREATE INDEX ticketchng_idx1 ON ticketchng(tkt_id, tkt_mtime);
98 ;
99
100 /*
101 ** Return the ticket table definition
 
102 */
103 const char *ticket_table_schema(void){
104 return db_get("ticket-table", zDefaultTicketTable);
105 }
106
107 /*
108 ** Common implementation for the ticket setup editor pages.
109
--- src/tktsetup.c
+++ src/tktsetup.c
@@ -96,13 +96,14 @@
96 @ );
97 @ CREATE INDEX ticketchng_idx1 ON ticketchng(tkt_id, tkt_mtime);
98 ;
99
100 /*
101 ** Return the ticket table definition in heap-allocated
102 ** memory owned by the caller.
103 */
104 char *ticket_table_schema(void){
105 return db_get("ticket-table", zDefaultTicketTable);
106 }
107
108 /*
109 ** Common implementation for the ticket setup editor pages.
110
+1 -1
--- src/verify.c
+++ src/verify.c
@@ -68,11 +68,11 @@
6868
** Invoke verify_rid() on every record that has been added or modified
6969
** in the repository, in order to make sure that the repository is sane.
7070
*/
7171
static int verify_at_commit(void){
7272
int rid;
73
- content_clear_cache();
73
+ content_clear_cache(0);
7474
inFinalVerify = 1;
7575
rid = bag_first(&toVerify);
7676
while( rid>0 ){
7777
verify_rid(rid);
7878
rid = bag_next(&toVerify, rid);
7979
--- src/verify.c
+++ src/verify.c
@@ -68,11 +68,11 @@
68 ** Invoke verify_rid() on every record that has been added or modified
69 ** in the repository, in order to make sure that the repository is sane.
70 */
71 static int verify_at_commit(void){
72 int rid;
73 content_clear_cache();
74 inFinalVerify = 1;
75 rid = bag_first(&toVerify);
76 while( rid>0 ){
77 verify_rid(rid);
78 rid = bag_next(&toVerify, rid);
79
--- src/verify.c
+++ src/verify.c
@@ -68,11 +68,11 @@
68 ** Invoke verify_rid() on every record that has been added or modified
69 ** in the repository, in order to make sure that the repository is sane.
70 */
71 static int verify_at_commit(void){
72 int rid;
73 content_clear_cache(0);
74 inFinalVerify = 1;
75 rid = bag_first(&toVerify);
76 while( rid>0 ){
77 verify_rid(rid);
78 rid = bag_next(&toVerify, rid);
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