Fossil SCM

Add compile-time option to enable TH1 memory leak tracking. Also, fix a TH1 memory leak and improve a couple #ifdef's.

mistachkin 2021-03-18 22:57 trunk
Commit e5293dc281b5a140e17c2ba228fd40b43fdf691a80941cdbf67075cecb116a72
+8 -1
--- src/main.c
+++ src/main.c
@@ -349,11 +349,11 @@
349349
/*
350350
** Zero, unlock, and free the saved database encryption key now.
351351
*/
352352
db_unsave_encryption_key();
353353
#endif
354
-#if defined(_WIN32) || defined(__BIONIC__) && !defined(FOSSIL_HAVE_GETPASS)
354
+#if defined(_WIN32) || (defined(__BIONIC__) && !defined(FOSSIL_HAVE_GETPASS))
355355
/*
356356
** Free the secure getpass() buffer now.
357357
*/
358358
freepass();
359359
#endif
@@ -388,10 +388,17 @@
388388
*/
389389
if( fossil_getenv("TH1_DELETE_INTERP")!=0 ){
390390
if( g.interp ){
391391
Th_DeleteInterp(g.interp); g.interp = 0;
392392
}
393
+#if defined(TH_MEMDEBUG)
394
+ if( Th_GetOutstandingMalloc()!=0 ){
395
+ fossil_print("Th_GetOutstandingMalloc() => %d\n",
396
+ Th_GetOutstandingMalloc());
397
+ }
398
+ assert( Th_GetOutstandingMalloc()==0 );
399
+#endif
393400
}
394401
}
395402
396403
/*
397404
** Convert all arguments from mbcs (or unicode) to UTF-8. Then
398405
--- src/main.c
+++ src/main.c
@@ -349,11 +349,11 @@
349 /*
350 ** Zero, unlock, and free the saved database encryption key now.
351 */
352 db_unsave_encryption_key();
353 #endif
354 #if defined(_WIN32) || defined(__BIONIC__) && !defined(FOSSIL_HAVE_GETPASS)
355 /*
356 ** Free the secure getpass() buffer now.
357 */
358 freepass();
359 #endif
@@ -388,10 +388,17 @@
388 */
389 if( fossil_getenv("TH1_DELETE_INTERP")!=0 ){
390 if( g.interp ){
391 Th_DeleteInterp(g.interp); g.interp = 0;
392 }
 
 
 
 
 
 
 
393 }
394 }
395
396 /*
397 ** Convert all arguments from mbcs (or unicode) to UTF-8. Then
398
--- src/main.c
+++ src/main.c
@@ -349,11 +349,11 @@
349 /*
350 ** Zero, unlock, and free the saved database encryption key now.
351 */
352 db_unsave_encryption_key();
353 #endif
354 #if defined(_WIN32) || (defined(__BIONIC__) && !defined(FOSSIL_HAVE_GETPASS))
355 /*
356 ** Free the secure getpass() buffer now.
357 */
358 freepass();
359 #endif
@@ -388,10 +388,17 @@
388 */
389 if( fossil_getenv("TH1_DELETE_INTERP")!=0 ){
390 if( g.interp ){
391 Th_DeleteInterp(g.interp); g.interp = 0;
392 }
393 #if defined(TH_MEMDEBUG)
394 if( Th_GetOutstandingMalloc()!=0 ){
395 fossil_print("Th_GetOutstandingMalloc() => %d\n",
396 Th_GetOutstandingMalloc());
397 }
398 assert( Th_GetOutstandingMalloc()==0 );
399 #endif
400 }
401 }
402
403 /*
404 ** Convert all arguments from mbcs (or unicode) to UTF-8. Then
405
+15 -3
--- src/makemake.tcl
+++ src/makemake.tcl
@@ -1478,11 +1478,11 @@
14781478
OBJDIR = $(T)
14791479
OX = $(OBJDIR)
14801480
O = .obj
14811481
E = .exe
14821482
P = .pdb
1483
-OPTLEVEL= /Os
1483
+DBGOPTS = /Od
14841484
14851485
INSTALLDIR = .
14861486
!ifdef DESTDIR
14871487
INSTALLDIR = $(DESTDIR)\$(INSTALLDIR)
14881488
!endif
@@ -1673,16 +1673,28 @@
16731673
CRTFLAGS = /MTd
16741674
!else
16751675
CRTFLAGS = /MT
16761676
!endif
16771677
!endif
1678
+
1679
+!if $(OPTIMIZATIONS)>3
1680
+RELOPTS = /Os
1681
+!elseif $(OPTIMIZATIONS)>2
1682
+RELOPTS = /Ox
1683
+!elseif $(OPTIMIZATIONS)>1
1684
+RELOPTS = /O2
1685
+!elseif $(OPTIMIZATIONS)>0
1686
+RELOPTS = /O1
1687
+!else
1688
+RELOPTS =
1689
+!endif
16781690
16791691
!if $(DEBUG)!=0
1680
-CFLAGS = $(CFLAGS) /Zi $(CRTFLAGS) /Od /DFOSSIL_DEBUG
1692
+CFLAGS = $(CFLAGS) /Zi $(CRTFLAGS) $(DBGOPTS) /DFOSSIL_DEBUG /DTH_MEMDEBUG
16811693
LDFLAGS = $(LDFLAGS) /DEBUG
16821694
!else
1683
-CFLAGS = $(CFLAGS) $(CRTFLAGS) $(OPTLEVEL)
1695
+CFLAGS = $(CFLAGS) $(CRTFLAGS) $(RELOPTS)
16841696
!endif
16851697
16861698
BCC = $(CC) $(CFLAGS)
16871699
TCC = $(CC) /c $(CFLAGS) $(MSCDEF) $(INCL)
16881700
RCC = $(RC) /D_WIN32 /D_MSC_VER $(MSCDEF) $(INCL)
16891701
--- src/makemake.tcl
+++ src/makemake.tcl
@@ -1478,11 +1478,11 @@
1478 OBJDIR = $(T)
1479 OX = $(OBJDIR)
1480 O = .obj
1481 E = .exe
1482 P = .pdb
1483 OPTLEVEL= /Os
1484
1485 INSTALLDIR = .
1486 !ifdef DESTDIR
1487 INSTALLDIR = $(DESTDIR)\$(INSTALLDIR)
1488 !endif
@@ -1673,16 +1673,28 @@
1673 CRTFLAGS = /MTd
1674 !else
1675 CRTFLAGS = /MT
1676 !endif
1677 !endif
 
 
 
 
 
 
 
 
 
 
 
 
1678
1679 !if $(DEBUG)!=0
1680 CFLAGS = $(CFLAGS) /Zi $(CRTFLAGS) /Od /DFOSSIL_DEBUG
1681 LDFLAGS = $(LDFLAGS) /DEBUG
1682 !else
1683 CFLAGS = $(CFLAGS) $(CRTFLAGS) $(OPTLEVEL)
1684 !endif
1685
1686 BCC = $(CC) $(CFLAGS)
1687 TCC = $(CC) /c $(CFLAGS) $(MSCDEF) $(INCL)
1688 RCC = $(RC) /D_WIN32 /D_MSC_VER $(MSCDEF) $(INCL)
1689
--- src/makemake.tcl
+++ src/makemake.tcl
@@ -1478,11 +1478,11 @@
1478 OBJDIR = $(T)
1479 OX = $(OBJDIR)
1480 O = .obj
1481 E = .exe
1482 P = .pdb
1483 DBGOPTS = /Od
1484
1485 INSTALLDIR = .
1486 !ifdef DESTDIR
1487 INSTALLDIR = $(DESTDIR)\$(INSTALLDIR)
1488 !endif
@@ -1673,16 +1673,28 @@
1673 CRTFLAGS = /MTd
1674 !else
1675 CRTFLAGS = /MT
1676 !endif
1677 !endif
1678
1679 !if $(OPTIMIZATIONS)>3
1680 RELOPTS = /Os
1681 !elseif $(OPTIMIZATIONS)>2
1682 RELOPTS = /Ox
1683 !elseif $(OPTIMIZATIONS)>1
1684 RELOPTS = /O2
1685 !elseif $(OPTIMIZATIONS)>0
1686 RELOPTS = /O1
1687 !else
1688 RELOPTS =
1689 !endif
1690
1691 !if $(DEBUG)!=0
1692 CFLAGS = $(CFLAGS) /Zi $(CRTFLAGS) $(DBGOPTS) /DFOSSIL_DEBUG /DTH_MEMDEBUG
1693 LDFLAGS = $(LDFLAGS) /DEBUG
1694 !else
1695 CFLAGS = $(CFLAGS) $(CRTFLAGS) $(RELOPTS)
1696 !endif
1697
1698 BCC = $(CC) $(CFLAGS)
1699 TCC = $(CC) /c $(CFLAGS) $(MSCDEF) $(INCL)
1700 RCC = $(RC) /D_WIN32 /D_MSC_VER $(MSCDEF) $(INCL)
1701
+47 -3
--- src/th.c
+++ src/th.c
@@ -222,11 +222,20 @@
222222
Buffer *pBuffer,
223223
const char *zAdd,
224224
int nAdd
225225
){
226226
int nNew = (pBuffer->nBuf+nAdd)*2+32;
227
+#if defined(TH_MEMDEBUG)
228
+ char *zNew = (char *)Th_Malloc(interp, nNew);
229
+ th_memcpy(zNew, pBuffer->zBuf, pBuffer->nBuf);
230
+ Th_Free(interp, pBuffer->zBuf);
231
+ pBuffer->zBuf = zNew;
232
+#else
233
+ int nOld = pBuffer->nBufAlloc;
227234
pBuffer->zBuf = Th_Realloc(interp, pBuffer->zBuf, nNew);
235
+ memset(pBuffer->zBuf+nOld, 0, nNew-nOld);
236
+#endif
228237
pBuffer->nBufAlloc = nNew;
229238
th_memcpy(&pBuffer->zBuf[pBuffer->nBuf], zAdd, nAdd);
230239
pBuffer->nBuf += nAdd;
231240
}
232241
static void thBufferWriteFast(
@@ -1535,10 +1544,37 @@
15351544
}else{
15361545
return (char *)Th_Malloc(pInterp, 1);
15371546
}
15381547
}
15391548
1549
+#if defined(TH_MEMDEBUG)
1550
+/*
1551
+** Wrappers around the supplied malloc() and free()
1552
+*/
1553
+void *Th_DbgMalloc(Th_Interp *pInterp, int nByte){
1554
+ void *p;
1555
+ Th_Vtab *pVtab = pInterp->pVtab;
1556
+ if( pVtab ){
1557
+ p = pVtab->xMalloc(nByte);
1558
+ if( p ) memset(p, 0, nByte);
1559
+ }else{
1560
+ p = Th_SysMalloc(pInterp, nByte);
1561
+ }
1562
+ return p;
1563
+}
1564
+void Th_DbgFree(Th_Interp *pInterp, void *z){
1565
+ if( z ){
1566
+ Th_Vtab *pVtab = pInterp->pVtab;
1567
+ if( pVtab ){
1568
+ pVtab->xFree(z);
1569
+ }else{
1570
+ Th_SysFree(pInterp, z);
1571
+ }
1572
+ }
1573
+}
1574
+#endif
1575
+
15401576
/*
15411577
** Install a new th1 command.
15421578
**
15431579
** If a command of the same name already exists, it is deleted automatically.
15441580
*/
@@ -1821,16 +1857,24 @@
18211857
}
18221858
18231859
/*
18241860
** Create a new interpreter.
18251861
*/
1826
-Th_Interp * Th_CreateInterp(void){
1862
+Th_Interp * Th_CreateInterp(Th_Vtab *pVtab){
1863
+ int nByte = sizeof(Th_Interp) + sizeof(Th_Frame);
18271864
Th_Interp *p;
18281865
18291866
/* Allocate and initialise the interpreter and the global frame */
1830
- p = Th_Malloc(0, sizeof(Th_Interp) + sizeof(Th_Frame));
1831
- memset(p, 0, sizeof(Th_Interp));
1867
+#if defined(TH_MEMDEBUG)
1868
+ if( pVtab ){
1869
+ p = pVtab->xMalloc(nByte);
1870
+ memset(p, 0, nByte);
1871
+ p->pVtab = pVtab;
1872
+ }else
1873
+#endif
1874
+ p = Th_SysMalloc(0, nByte);
1875
+
18321876
p->paCmd = Th_HashNew(p);
18331877
thPushFrame(p, (Th_Frame *)&p[1]);
18341878
thInitialize(p);
18351879
18361880
return p;
18371881
--- src/th.c
+++ src/th.c
@@ -222,11 +222,20 @@
222 Buffer *pBuffer,
223 const char *zAdd,
224 int nAdd
225 ){
226 int nNew = (pBuffer->nBuf+nAdd)*2+32;
 
 
 
 
 
 
 
227 pBuffer->zBuf = Th_Realloc(interp, pBuffer->zBuf, nNew);
 
 
228 pBuffer->nBufAlloc = nNew;
229 th_memcpy(&pBuffer->zBuf[pBuffer->nBuf], zAdd, nAdd);
230 pBuffer->nBuf += nAdd;
231 }
232 static void thBufferWriteFast(
@@ -1535,10 +1544,37 @@
1535 }else{
1536 return (char *)Th_Malloc(pInterp, 1);
1537 }
1538 }
1539
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1540 /*
1541 ** Install a new th1 command.
1542 **
1543 ** If a command of the same name already exists, it is deleted automatically.
1544 */
@@ -1821,16 +1857,24 @@
1821 }
1822
1823 /*
1824 ** Create a new interpreter.
1825 */
1826 Th_Interp * Th_CreateInterp(void){
 
1827 Th_Interp *p;
1828
1829 /* Allocate and initialise the interpreter and the global frame */
1830 p = Th_Malloc(0, sizeof(Th_Interp) + sizeof(Th_Frame));
1831 memset(p, 0, sizeof(Th_Interp));
 
 
 
 
 
 
 
1832 p->paCmd = Th_HashNew(p);
1833 thPushFrame(p, (Th_Frame *)&p[1]);
1834 thInitialize(p);
1835
1836 return p;
1837
--- src/th.c
+++ src/th.c
@@ -222,11 +222,20 @@
222 Buffer *pBuffer,
223 const char *zAdd,
224 int nAdd
225 ){
226 int nNew = (pBuffer->nBuf+nAdd)*2+32;
227 #if defined(TH_MEMDEBUG)
228 char *zNew = (char *)Th_Malloc(interp, nNew);
229 th_memcpy(zNew, pBuffer->zBuf, pBuffer->nBuf);
230 Th_Free(interp, pBuffer->zBuf);
231 pBuffer->zBuf = zNew;
232 #else
233 int nOld = pBuffer->nBufAlloc;
234 pBuffer->zBuf = Th_Realloc(interp, pBuffer->zBuf, nNew);
235 memset(pBuffer->zBuf+nOld, 0, nNew-nOld);
236 #endif
237 pBuffer->nBufAlloc = nNew;
238 th_memcpy(&pBuffer->zBuf[pBuffer->nBuf], zAdd, nAdd);
239 pBuffer->nBuf += nAdd;
240 }
241 static void thBufferWriteFast(
@@ -1535,10 +1544,37 @@
1544 }else{
1545 return (char *)Th_Malloc(pInterp, 1);
1546 }
1547 }
1548
1549 #if defined(TH_MEMDEBUG)
1550 /*
1551 ** Wrappers around the supplied malloc() and free()
1552 */
1553 void *Th_DbgMalloc(Th_Interp *pInterp, int nByte){
1554 void *p;
1555 Th_Vtab *pVtab = pInterp->pVtab;
1556 if( pVtab ){
1557 p = pVtab->xMalloc(nByte);
1558 if( p ) memset(p, 0, nByte);
1559 }else{
1560 p = Th_SysMalloc(pInterp, nByte);
1561 }
1562 return p;
1563 }
1564 void Th_DbgFree(Th_Interp *pInterp, void *z){
1565 if( z ){
1566 Th_Vtab *pVtab = pInterp->pVtab;
1567 if( pVtab ){
1568 pVtab->xFree(z);
1569 }else{
1570 Th_SysFree(pInterp, z);
1571 }
1572 }
1573 }
1574 #endif
1575
1576 /*
1577 ** Install a new th1 command.
1578 **
1579 ** If a command of the same name already exists, it is deleted automatically.
1580 */
@@ -1821,16 +1857,24 @@
1857 }
1858
1859 /*
1860 ** Create a new interpreter.
1861 */
1862 Th_Interp * Th_CreateInterp(Th_Vtab *pVtab){
1863 int nByte = sizeof(Th_Interp) + sizeof(Th_Frame);
1864 Th_Interp *p;
1865
1866 /* Allocate and initialise the interpreter and the global frame */
1867 #if defined(TH_MEMDEBUG)
1868 if( pVtab ){
1869 p = pVtab->xMalloc(nByte);
1870 memset(p, 0, nByte);
1871 p->pVtab = pVtab;
1872 }else
1873 #endif
1874 p = Th_SysMalloc(0, nByte);
1875
1876 p->paCmd = Th_HashNew(p);
1877 thPushFrame(p, (Th_Frame *)&p[1]);
1878 thInitialize(p);
1879
1880 return p;
1881
+21 -6
--- src/th.h
+++ src/th.h
@@ -21,11 +21,11 @@
2121
typedef struct Th_Interp Th_Interp;
2222
2323
/*
2424
** Create and delete interpreters.
2525
*/
26
-Th_Interp * Th_CreateInterp(void);
26
+Th_Interp * Th_CreateInterp(Th_Vtab *);
2727
void Th_DeleteInterp(Th_Interp *);
2828
2929
/*
3030
** Evaluate an TH program in the stack frame identified by parameter
3131
** iFrame, according to the following rules:
@@ -121,16 +121,31 @@
121121
122122
/*
123123
** Access the memory management functions associated with the specified
124124
** interpreter.
125125
*/
126
+#if defined(TH_MEMDEBUG)
127
+void *Th_DbgMalloc(Th_Interp *, int);
128
+void Th_DbgFree(Th_Interp *, void *);
129
+#endif
130
+
126131
void *fossil_malloc_zero(size_t);
127
-void *fossil_realloc(void*,size_t);
128
-void fossil_free(void*);
129
-#define Th_Malloc(I,N) fossil_malloc_zero(N)
130
-#define Th_Realloc(I,P,N) fossil_realloc(P,N)
131
-#define Th_Free(I,P) fossil_free(P)
132
+void *fossil_realloc(void *, size_t);
133
+void fossil_free(void *);
134
+
135
+#define Th_SysMalloc(I,N) fossil_malloc_zero((N))
136
+#define Th_SysRealloc(I,P,N) fossil_realloc((P),(N))
137
+#define Th_SysFree(I,P) fossil_free((P))
138
+
139
+#if defined(TH_MEMDEBUG)
140
+# define Th_Malloc(I,N) Th_DbgMalloc((I),(N))
141
+# define Th_Free(I,P) Th_DbgFree((I),(P))
142
+#else
143
+# define Th_Malloc(I,N) Th_SysMalloc((I),(N))
144
+# define Th_Realloc(I,P,N) Th_SysRealloc((I),(P),(N))
145
+# define Th_Free(I,P) Th_SysFree((I),(P))
146
+#endif
132147
133148
/*
134149
** Functions for handling TH lists.
135150
*/
136151
int Th_ListAppend(Th_Interp *, char **, int *, const char *, int);
137152
--- src/th.h
+++ src/th.h
@@ -21,11 +21,11 @@
21 typedef struct Th_Interp Th_Interp;
22
23 /*
24 ** Create and delete interpreters.
25 */
26 Th_Interp * Th_CreateInterp(void);
27 void Th_DeleteInterp(Th_Interp *);
28
29 /*
30 ** Evaluate an TH program in the stack frame identified by parameter
31 ** iFrame, according to the following rules:
@@ -121,16 +121,31 @@
121
122 /*
123 ** Access the memory management functions associated with the specified
124 ** interpreter.
125 */
 
 
 
 
 
126 void *fossil_malloc_zero(size_t);
127 void *fossil_realloc(void*,size_t);
128 void fossil_free(void*);
129 #define Th_Malloc(I,N) fossil_malloc_zero(N)
130 #define Th_Realloc(I,P,N) fossil_realloc(P,N)
131 #define Th_Free(I,P) fossil_free(P)
 
 
 
 
 
 
 
 
 
 
132
133 /*
134 ** Functions for handling TH lists.
135 */
136 int Th_ListAppend(Th_Interp *, char **, int *, const char *, int);
137
--- src/th.h
+++ src/th.h
@@ -21,11 +21,11 @@
21 typedef struct Th_Interp Th_Interp;
22
23 /*
24 ** Create and delete interpreters.
25 */
26 Th_Interp * Th_CreateInterp(Th_Vtab *);
27 void Th_DeleteInterp(Th_Interp *);
28
29 /*
30 ** Evaluate an TH program in the stack frame identified by parameter
31 ** iFrame, according to the following rules:
@@ -121,16 +121,31 @@
121
122 /*
123 ** Access the memory management functions associated with the specified
124 ** interpreter.
125 */
126 #if defined(TH_MEMDEBUG)
127 void *Th_DbgMalloc(Th_Interp *, int);
128 void Th_DbgFree(Th_Interp *, void *);
129 #endif
130
131 void *fossil_malloc_zero(size_t);
132 void *fossil_realloc(void *, size_t);
133 void fossil_free(void *);
134
135 #define Th_SysMalloc(I,N) fossil_malloc_zero((N))
136 #define Th_SysRealloc(I,P,N) fossil_realloc((P),(N))
137 #define Th_SysFree(I,P) fossil_free((P))
138
139 #if defined(TH_MEMDEBUG)
140 # define Th_Malloc(I,N) Th_DbgMalloc((I),(N))
141 # define Th_Free(I,P) Th_DbgFree((I),(P))
142 #else
143 # define Th_Malloc(I,N) Th_SysMalloc((I),(N))
144 # define Th_Realloc(I,P,N) Th_SysRealloc((I),(P),(N))
145 # define Th_Free(I,P) Th_SysFree((I),(P))
146 #endif
147
148 /*
149 ** Functions for handling TH lists.
150 */
151 int Th_ListAppend(Th_Interp *, char **, int *, const char *, int);
152
+50 -4
--- src/th_main.c
+++ src/th_main.c
@@ -68,10 +68,46 @@
6868
** configuration ("user") database are currently open.
6969
*/
7070
#define Th_IsRepositoryOpen() (g.repositoryOpen)
7171
#define Th_IsConfigOpen() (g.zConfigDbName!=0)
7272
73
+/*
74
+** When memory debugging is enabled, use our custom memory allocator.
75
+*/
76
+#if defined(TH_MEMDEBUG)
77
+/*
78
+** Global variable counting the number of outstanding calls to malloc()
79
+** made by the th1 implementation. This is used to catch memory leaks
80
+** in the interpreter. Obviously, it also means th1 is not threadsafe.
81
+*/
82
+static int nOutstandingMalloc = 0;
83
+
84
+/*
85
+** Implementations of malloc() and free() to pass to the interpreter.
86
+*/
87
+static void *xMalloc(unsigned int n){
88
+ void *p = fossil_malloc(n);
89
+ if( p ){
90
+ nOutstandingMalloc++;
91
+ }
92
+ return p;
93
+}
94
+static void xFree(void *p){
95
+ if( p ){
96
+ nOutstandingMalloc--;
97
+ }
98
+ free(p);
99
+}
100
+static Th_Vtab vtab = { xMalloc, xFree };
101
+
102
+/*
103
+** Returns the number of outstanding TH1 memory allocations.
104
+*/
105
+int Th_GetOutstandingMalloc(){
106
+ return nOutstandingMalloc;
107
+}
108
+#endif
73109
74110
/*
75111
** Generate a TH1 trace message if debugging is enabled.
76112
*/
77113
void Th_Trace(const char *zFormat, ...){
@@ -350,11 +386,11 @@
350386
if(0==pOut && pThOut!=0){
351387
pOut = pThOut;
352388
}
353389
if(TH_INIT_NO_ENCODE & g.th1Flags){
354390
encode = 0;
355
- }
391
+ }
356392
if( enableOutput && n ){
357393
if( n<0 ) n = strlen(z);
358394
if( encode ){
359395
z = htmlize(z, n);
360396
n = strlen(z);
@@ -627,10 +663,11 @@
627663
blob_zero(&title); blob_zero(&body);
628664
markdown_to_html(&src, &title, &body);
629665
Th_ListAppend(interp, &zValue, &nValue, blob_str(&title), blob_size(&title));
630666
Th_ListAppend(interp, &zValue, &nValue, blob_str(&body), blob_size(&body));
631667
Th_SetResult(interp, zValue, nValue);
668
+ Th_Free(interp, zValue);
632669
return TH_OK;
633670
}
634671
635672
/*
636673
** TH1 command: decorate STRING
@@ -810,15 +847,15 @@
810847
}else if( azCap[i][0]=='*' ){
811848
rc = 1;
812849
}else{
813850
rc = login_has_capability(azCap[i], anCap[i], 0);
814851
}
815
- break;
852
+ break;
816853
}
817854
Th_Free(interp, azCap);
818855
Th_SetResultInt(interp, rc);
819
- return TH_OK;
856
+ return TH_OK;
820857
}
821858
822859
823860
/*
824861
** TH1 command: searchable STRING...
@@ -2356,11 +2393,20 @@
23562393
}
23572394
if( forceReset || forceTcl || g.interp==0 ){
23582395
int created = 0;
23592396
int i;
23602397
if( g.interp==0 ){
2361
- g.interp = Th_CreateInterp();
2398
+ Th_Vtab *pVtab = 0;
2399
+#if defined(TH_MEMDEBUG)
2400
+ if( fossil_getenv("TH1_DELETE_INTERP")!=0 ){
2401
+ pVtab = &vtab;
2402
+ if( g.thTrace ){
2403
+ Th_Trace("th1-init MEMDEBUG ENABLED<br />\n");
2404
+ }
2405
+ }
2406
+#endif
2407
+ g.interp = Th_CreateInterp(pVtab);
23622408
created = 1;
23632409
}
23642410
if( forceReset || created ){
23652411
th_register_language(g.interp); /* Basic scripting commands. */
23662412
}
23672413
--- src/th_main.c
+++ src/th_main.c
@@ -68,10 +68,46 @@
68 ** configuration ("user") database are currently open.
69 */
70 #define Th_IsRepositoryOpen() (g.repositoryOpen)
71 #define Th_IsConfigOpen() (g.zConfigDbName!=0)
72
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
73
74 /*
75 ** Generate a TH1 trace message if debugging is enabled.
76 */
77 void Th_Trace(const char *zFormat, ...){
@@ -350,11 +386,11 @@
350 if(0==pOut && pThOut!=0){
351 pOut = pThOut;
352 }
353 if(TH_INIT_NO_ENCODE & g.th1Flags){
354 encode = 0;
355 }
356 if( enableOutput && n ){
357 if( n<0 ) n = strlen(z);
358 if( encode ){
359 z = htmlize(z, n);
360 n = strlen(z);
@@ -627,10 +663,11 @@
627 blob_zero(&title); blob_zero(&body);
628 markdown_to_html(&src, &title, &body);
629 Th_ListAppend(interp, &zValue, &nValue, blob_str(&title), blob_size(&title));
630 Th_ListAppend(interp, &zValue, &nValue, blob_str(&body), blob_size(&body));
631 Th_SetResult(interp, zValue, nValue);
 
632 return TH_OK;
633 }
634
635 /*
636 ** TH1 command: decorate STRING
@@ -810,15 +847,15 @@
810 }else if( azCap[i][0]=='*' ){
811 rc = 1;
812 }else{
813 rc = login_has_capability(azCap[i], anCap[i], 0);
814 }
815 break;
816 }
817 Th_Free(interp, azCap);
818 Th_SetResultInt(interp, rc);
819 return TH_OK;
820 }
821
822
823 /*
824 ** TH1 command: searchable STRING...
@@ -2356,11 +2393,20 @@
2356 }
2357 if( forceReset || forceTcl || g.interp==0 ){
2358 int created = 0;
2359 int i;
2360 if( g.interp==0 ){
2361 g.interp = Th_CreateInterp();
 
 
 
 
 
 
 
 
 
2362 created = 1;
2363 }
2364 if( forceReset || created ){
2365 th_register_language(g.interp); /* Basic scripting commands. */
2366 }
2367
--- src/th_main.c
+++ src/th_main.c
@@ -68,10 +68,46 @@
68 ** configuration ("user") database are currently open.
69 */
70 #define Th_IsRepositoryOpen() (g.repositoryOpen)
71 #define Th_IsConfigOpen() (g.zConfigDbName!=0)
72
73 /*
74 ** When memory debugging is enabled, use our custom memory allocator.
75 */
76 #if defined(TH_MEMDEBUG)
77 /*
78 ** Global variable counting the number of outstanding calls to malloc()
79 ** made by the th1 implementation. This is used to catch memory leaks
80 ** in the interpreter. Obviously, it also means th1 is not threadsafe.
81 */
82 static int nOutstandingMalloc = 0;
83
84 /*
85 ** Implementations of malloc() and free() to pass to the interpreter.
86 */
87 static void *xMalloc(unsigned int n){
88 void *p = fossil_malloc(n);
89 if( p ){
90 nOutstandingMalloc++;
91 }
92 return p;
93 }
94 static void xFree(void *p){
95 if( p ){
96 nOutstandingMalloc--;
97 }
98 free(p);
99 }
100 static Th_Vtab vtab = { xMalloc, xFree };
101
102 /*
103 ** Returns the number of outstanding TH1 memory allocations.
104 */
105 int Th_GetOutstandingMalloc(){
106 return nOutstandingMalloc;
107 }
108 #endif
109
110 /*
111 ** Generate a TH1 trace message if debugging is enabled.
112 */
113 void Th_Trace(const char *zFormat, ...){
@@ -350,11 +386,11 @@
386 if(0==pOut && pThOut!=0){
387 pOut = pThOut;
388 }
389 if(TH_INIT_NO_ENCODE & g.th1Flags){
390 encode = 0;
391 }
392 if( enableOutput && n ){
393 if( n<0 ) n = strlen(z);
394 if( encode ){
395 z = htmlize(z, n);
396 n = strlen(z);
@@ -627,10 +663,11 @@
663 blob_zero(&title); blob_zero(&body);
664 markdown_to_html(&src, &title, &body);
665 Th_ListAppend(interp, &zValue, &nValue, blob_str(&title), blob_size(&title));
666 Th_ListAppend(interp, &zValue, &nValue, blob_str(&body), blob_size(&body));
667 Th_SetResult(interp, zValue, nValue);
668 Th_Free(interp, zValue);
669 return TH_OK;
670 }
671
672 /*
673 ** TH1 command: decorate STRING
@@ -810,15 +847,15 @@
847 }else if( azCap[i][0]=='*' ){
848 rc = 1;
849 }else{
850 rc = login_has_capability(azCap[i], anCap[i], 0);
851 }
852 break;
853 }
854 Th_Free(interp, azCap);
855 Th_SetResultInt(interp, rc);
856 return TH_OK;
857 }
858
859
860 /*
861 ** TH1 command: searchable STRING...
@@ -2356,11 +2393,20 @@
2393 }
2394 if( forceReset || forceTcl || g.interp==0 ){
2395 int created = 0;
2396 int i;
2397 if( g.interp==0 ){
2398 Th_Vtab *pVtab = 0;
2399 #if defined(TH_MEMDEBUG)
2400 if( fossil_getenv("TH1_DELETE_INTERP")!=0 ){
2401 pVtab = &vtab;
2402 if( g.thTrace ){
2403 Th_Trace("th1-init MEMDEBUG ENABLED<br />\n");
2404 }
2405 }
2406 #endif
2407 g.interp = Th_CreateInterp(pVtab);
2408 created = 1;
2409 }
2410 if( forceReset || created ){
2411 th_register_language(g.interp); /* Basic scripting commands. */
2412 }
2413
+1 -1
--- src/user.c
+++ src/user.c
@@ -38,11 +38,11 @@
3838
if( z[i]>0 && z[i]<' ' ) z[i] = ' ';
3939
}
4040
blob_append(pBlob, z, -1);
4141
}
4242
43
-#if defined(_WIN32) || defined(__BIONIC__) && !defined(FOSSIL_HAVE_GETPASS)
43
+#if defined(_WIN32) || (defined(__BIONIC__) && !defined(FOSSIL_HAVE_GETPASS))
4444
#ifdef _WIN32
4545
#include <conio.h>
4646
#endif
4747
4848
/*
4949
--- src/user.c
+++ src/user.c
@@ -38,11 +38,11 @@
38 if( z[i]>0 && z[i]<' ' ) z[i] = ' ';
39 }
40 blob_append(pBlob, z, -1);
41 }
42
43 #if defined(_WIN32) || defined(__BIONIC__) && !defined(FOSSIL_HAVE_GETPASS)
44 #ifdef _WIN32
45 #include <conio.h>
46 #endif
47
48 /*
49
--- src/user.c
+++ src/user.c
@@ -38,11 +38,11 @@
38 if( z[i]>0 && z[i]<' ' ) z[i] = ' ';
39 }
40 blob_append(pBlob, z, -1);
41 }
42
43 #if defined(_WIN32) || (defined(__BIONIC__) && !defined(FOSSIL_HAVE_GETPASS))
44 #ifdef _WIN32
45 #include <conio.h>
46 #endif
47
48 /*
49
+15 -3
--- win/Makefile.msc
+++ win/Makefile.msc
@@ -14,11 +14,11 @@
1414
OBJDIR = $(T)
1515
OX = $(OBJDIR)
1616
O = .obj
1717
E = .exe
1818
P = .pdb
19
-OPTLEVEL= /Os
19
+DBGOPTS = /Od
2020
2121
INSTALLDIR = .
2222
!ifdef DESTDIR
2323
INSTALLDIR = $(DESTDIR)\$(INSTALLDIR)
2424
!endif
@@ -209,16 +209,28 @@
209209
CRTFLAGS = /MTd
210210
!else
211211
CRTFLAGS = /MT
212212
!endif
213213
!endif
214
+
215
+!if $(OPTIMIZATIONS)>3
216
+RELOPTS = /Os
217
+!elseif $(OPTIMIZATIONS)>2
218
+RELOPTS = /Ox
219
+!elseif $(OPTIMIZATIONS)>1
220
+RELOPTS = /O2
221
+!elseif $(OPTIMIZATIONS)>0
222
+RELOPTS = /O1
223
+!else
224
+RELOPTS =
225
+!endif
214226
215227
!if $(DEBUG)!=0
216
-CFLAGS = $(CFLAGS) /Zi $(CRTFLAGS) /Od /DFOSSIL_DEBUG
228
+CFLAGS = $(CFLAGS) /Zi $(CRTFLAGS) $(DBGOPTS) /DFOSSIL_DEBUG /DTH_MEMDEBUG
217229
LDFLAGS = $(LDFLAGS) /DEBUG
218230
!else
219
-CFLAGS = $(CFLAGS) $(CRTFLAGS) $(OPTLEVEL)
231
+CFLAGS = $(CFLAGS) $(CRTFLAGS) $(RELOPTS)
220232
!endif
221233
222234
BCC = $(CC) $(CFLAGS)
223235
TCC = $(CC) /c $(CFLAGS) $(MSCDEF) $(INCL)
224236
RCC = $(RC) /D_WIN32 /D_MSC_VER $(MSCDEF) $(INCL)
225237
--- win/Makefile.msc
+++ win/Makefile.msc
@@ -14,11 +14,11 @@
14 OBJDIR = $(T)
15 OX = $(OBJDIR)
16 O = .obj
17 E = .exe
18 P = .pdb
19 OPTLEVEL= /Os
20
21 INSTALLDIR = .
22 !ifdef DESTDIR
23 INSTALLDIR = $(DESTDIR)\$(INSTALLDIR)
24 !endif
@@ -209,16 +209,28 @@
209 CRTFLAGS = /MTd
210 !else
211 CRTFLAGS = /MT
212 !endif
213 !endif
 
 
 
 
 
 
 
 
 
 
 
 
214
215 !if $(DEBUG)!=0
216 CFLAGS = $(CFLAGS) /Zi $(CRTFLAGS) /Od /DFOSSIL_DEBUG
217 LDFLAGS = $(LDFLAGS) /DEBUG
218 !else
219 CFLAGS = $(CFLAGS) $(CRTFLAGS) $(OPTLEVEL)
220 !endif
221
222 BCC = $(CC) $(CFLAGS)
223 TCC = $(CC) /c $(CFLAGS) $(MSCDEF) $(INCL)
224 RCC = $(RC) /D_WIN32 /D_MSC_VER $(MSCDEF) $(INCL)
225
--- win/Makefile.msc
+++ win/Makefile.msc
@@ -14,11 +14,11 @@
14 OBJDIR = $(T)
15 OX = $(OBJDIR)
16 O = .obj
17 E = .exe
18 P = .pdb
19 DBGOPTS = /Od
20
21 INSTALLDIR = .
22 !ifdef DESTDIR
23 INSTALLDIR = $(DESTDIR)\$(INSTALLDIR)
24 !endif
@@ -209,16 +209,28 @@
209 CRTFLAGS = /MTd
210 !else
211 CRTFLAGS = /MT
212 !endif
213 !endif
214
215 !if $(OPTIMIZATIONS)>3
216 RELOPTS = /Os
217 !elseif $(OPTIMIZATIONS)>2
218 RELOPTS = /Ox
219 !elseif $(OPTIMIZATIONS)>1
220 RELOPTS = /O2
221 !elseif $(OPTIMIZATIONS)>0
222 RELOPTS = /O1
223 !else
224 RELOPTS =
225 !endif
226
227 !if $(DEBUG)!=0
228 CFLAGS = $(CFLAGS) /Zi $(CRTFLAGS) $(DBGOPTS) /DFOSSIL_DEBUG /DTH_MEMDEBUG
229 LDFLAGS = $(LDFLAGS) /DEBUG
230 !else
231 CFLAGS = $(CFLAGS) $(CRTFLAGS) $(RELOPTS)
232 !endif
233
234 BCC = $(CC) $(CFLAGS)
235 TCC = $(CC) /c $(CFLAGS) $(MSCDEF) $(INCL)
236 RCC = $(RC) /D_WIN32 /D_MSC_VER $(MSCDEF) $(INCL)
237

Keyboard Shortcuts

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