Fossil

Changes On Branch th1-malloc-debugging
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Changes In Branch th1-malloc-debugging Excluding Merge-Ins

This is equivalent to a diff from b2e83470 to 9c36e633

2021-03-19
03:10
Add compile-time option to enable TH1 memory leak tracking. Also, fix TH1 memory leak, improve a couple #ifdef's, and fix JSON assert in fossil_print_error() seen when an invalid repository is specified. ... (check-in: 999e33cc user: mistachkin tags: trunk)
02:49
Be sure to set the default value for the OPTIMIZATIONS nmake macro, i.e. to avoid an expression syntax error. ... (Closed-Leaf check-in: 9c36e633 user: mistachkin tags: th1-malloc-debugging)
2021-03-18
23:31
Fix JSON assert in fossil_print_error() seen when an invalid repository is specified. ... (check-in: 44cf2e91 user: mistachkin tags: th1-malloc-debugging)
22:57
Add compile-time option to enable TH1 memory leak tracking. Also, fix a TH1 memory leak and improve a couple #ifdef's. ... (check-in: e5293dc2 user: mistachkin tags: th1-malloc-debugging)
22:09
Add the --reset option to the "fossil test-backoffice-lease" command. ... (check-in: b2e83470 user: drh tags: trunk)
15:20
Add information on how to remove a Windows service, per forum post 0bcffc517f. ... (check-in: 366fda0c user: danield tags: trunk)

Changes to src/main.c.

347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
  if( once++ ) return; /* Ensure that this routine only runs once */
#if USE_SEE
  /*
  ** Zero, unlock, and free the saved database encryption key now.
  */
  db_unsave_encryption_key();
#endif
#if defined(_WIN32) || defined(__BIONIC__) && !defined(FOSSIL_HAVE_GETPASS)
  /*
  ** Free the secure getpass() buffer now.
  */
  freepass();
#endif
#if defined(_WIN32) && !defined(_WIN64) && defined(FOSSIL_ENABLE_TCL) && \
    defined(USE_TCL_STUBS)







|







347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
  if( once++ ) return; /* Ensure that this routine only runs once */
#if USE_SEE
  /*
  ** Zero, unlock, and free the saved database encryption key now.
  */
  db_unsave_encryption_key();
#endif
#if defined(_WIN32) || (defined(__BIONIC__) && !defined(FOSSIL_HAVE_GETPASS))
  /*
  ** Free the secure getpass() buffer now.
  */
  freepass();
#endif
#if defined(_WIN32) && !defined(_WIN64) && defined(FOSSIL_ENABLE_TCL) && \
    defined(USE_TCL_STUBS)
386
387
388
389
390
391
392







393
394
395
396
397
398
399
  ** FIXME: The next two lines cannot always be enabled; however, they
  **        are very useful for tracking down TH1 memory leaks.
  */
  if( fossil_getenv("TH1_DELETE_INTERP")!=0 ){
    if( g.interp ){
      Th_DeleteInterp(g.interp); g.interp = 0;
    }







  }
}

/*
** Convert all arguments from mbcs (or unicode) to UTF-8. Then
** search g.argv for arguments "--args FILENAME". If found, then
** (1) remove the two arguments from g.argv







>
>
>
>
>
>
>







386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
  ** FIXME: The next two lines cannot always be enabled; however, they
  **        are very useful for tracking down TH1 memory leaks.
  */
  if( fossil_getenv("TH1_DELETE_INTERP")!=0 ){
    if( g.interp ){
      Th_DeleteInterp(g.interp); g.interp = 0;
    }
#if defined(TH_MEMDEBUG)
    if( Th_GetOutstandingMalloc()!=0 ){
      fossil_print("Th_GetOutstandingMalloc() => %d\n",
                   Th_GetOutstandingMalloc());
    }
    assert( Th_GetOutstandingMalloc()==0 );
#endif
  }
}

/*
** Convert all arguments from mbcs (or unicode) to UTF-8. Then
** search g.argv for arguments "--args FILENAME". If found, then
** (1) remove the two arguments from g.argv

Changes to src/makemake.tcl.

1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
SRCDIR  = $(B)\src
T       = .
OBJDIR  = $(T)
OX      = $(OBJDIR)
O       = .obj
E       = .exe
P       = .pdb
OPTLEVEL= /Os

INSTALLDIR = .
!ifdef DESTDIR
INSTALLDIR = $(DESTDIR)\$(INSTALLDIR)
!endif

# When building out of source, this Makefile needs to know the path to the base







|







1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
SRCDIR  = $(B)\src
T       = .
OBJDIR  = $(T)
OX      = $(OBJDIR)
O       = .obj
E       = .exe
P       = .pdb
DBGOPTS = /Od

INSTALLDIR = .
!ifdef DESTDIR
INSTALLDIR = $(DESTDIR)\$(INSTALLDIR)
!endif

# When building out of source, this Makefile needs to know the path to the base
1499
1500
1501
1502
1503
1504
1505





1506
1507
1508
1509
1510
1511
1512
!endif

# Perl is only necessary if OpenSSL support is enabled and it is built from
# source code.  The PERLDIR environment variable, if it exists, should point
# to the directory containing the main Perl executable specified here (i.e.
# "perl.exe").
PERL    = perl.exe






# Enable debugging symbols?
!ifndef DEBUG
DEBUG = 0
!endif
!ifdef FOSSIL_DEBUG
DEBUG = 1







>
>
>
>
>







1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
!endif

# Perl is only necessary if OpenSSL support is enabled and it is built from
# source code.  The PERLDIR environment variable, if it exists, should point
# to the directory containing the main Perl executable specified here (i.e.
# "perl.exe").
PERL    = perl.exe

# Enable use of available compiler optimizations?
!ifndef OPTIMIZATIONS
OPTIMIZATIONS = 2
!endif

# Enable debugging symbols?
!ifndef DEBUG
DEBUG = 0
!endif
!ifdef FOSSIL_DEBUG
DEBUG = 1
1671
1672
1673
1674
1675
1676
1677
1678












1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
!else
!if $(DEBUG)!=0
CRTFLAGS = /MTd
!else
CRTFLAGS = /MT
!endif
!endif













!if $(DEBUG)!=0
CFLAGS    = $(CFLAGS) /Zi $(CRTFLAGS) /Od /DFOSSIL_DEBUG
LDFLAGS   = $(LDFLAGS) /DEBUG
!else
CFLAGS    = $(CFLAGS) $(CRTFLAGS) $(OPTLEVEL)
!endif

BCC       = $(CC) $(CFLAGS)
TCC       = $(CC) /c $(CFLAGS) $(MSCDEF) $(INCL)
RCC       = $(RC) /D_WIN32 /D_MSC_VER $(MSCDEF) $(INCL)
MTC       = mt
LIBS      = ws2_32.lib advapi32.lib dnsapi.lib








>
>
>
>
>
>
>
>
>
>
>
>

|


|







1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
!else
!if $(DEBUG)!=0
CRTFLAGS = /MTd
!else
CRTFLAGS = /MT
!endif
!endif

!if $(OPTIMIZATIONS)>3
RELOPTS = /Os
!elseif $(OPTIMIZATIONS)>2
RELOPTS = /Ox
!elseif $(OPTIMIZATIONS)>1
RELOPTS = /O2
!elseif $(OPTIMIZATIONS)>0
RELOPTS = /O1
!else
RELOPTS =
!endif

!if $(DEBUG)!=0
CFLAGS    = $(CFLAGS) /Zi $(CRTFLAGS) $(DBGOPTS) /DFOSSIL_DEBUG /DTH_MEMDEBUG
LDFLAGS   = $(LDFLAGS) /DEBUG
!else
CFLAGS    = $(CFLAGS) $(CRTFLAGS) $(RELOPTS)
!endif

BCC       = $(CC) $(CFLAGS)
TCC       = $(CC) /c $(CFLAGS) $(MSCDEF) $(INCL)
RCC       = $(RC) /D_WIN32 /D_MSC_VER $(MSCDEF) $(INCL)
MTC       = mt
LIBS      = ws2_32.lib advapi32.lib dnsapi.lib

Changes to src/printf.c.

1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
#ifdef FOSSIL_ENABLE_JSON
  if( g.json.isJsonMode!=0 ){
    /*
    ** Avoid calling into the JSON support subsystem if it
    ** has not yet been initialized, e.g. early SQLite log
    ** messages, etc.
    */
    assert(json_is_bootstrapped_early());
    json_err( 0, z, 1 );
    if( g.isHTTP && !g.json.preserveRc ){
      rc = 0 /* avoid HTTP 500 */;
    }
    if( g.cgiOutput==1 ){
      g.cgiOutput = 2;
      cgi_reply();







|







1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
#ifdef FOSSIL_ENABLE_JSON
  if( g.json.isJsonMode!=0 ){
    /*
    ** Avoid calling into the JSON support subsystem if it
    ** has not yet been initialized, e.g. early SQLite log
    ** messages, etc.
    */
    if( !json_is_bootstrapped_early() ) json_bootstrap_early();
    json_err( 0, z, 1 );
    if( g.isHTTP && !g.json.preserveRc ){
      rc = 0 /* avoid HTTP 500 */;
    }
    if( g.cgiOutput==1 ){
      g.cgiOutput = 2;
      cgi_reply();
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
#ifdef FOSSIL_ENABLE_JSON
  if( g.json.isJsonMode!=0 ){
    /*
    ** Avoid calling into the JSON support subsystem if it
    ** has not yet been initialized, e.g. early SQLite log
    ** messages, etc.
    */
    assert(json_is_bootstrapped_early());
    json_warn( FSL_JSON_W_UNKNOWN, "%s", z );
  }else
#endif
  {
    if( g.cgiOutput==1 ){
      etag_cancel();
      cgi_printf("<p class=\"generalError\">\n%h\n</p>\n", z);







|







1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
#ifdef FOSSIL_ENABLE_JSON
  if( g.json.isJsonMode!=0 ){
    /*
    ** Avoid calling into the JSON support subsystem if it
    ** has not yet been initialized, e.g. early SQLite log
    ** messages, etc.
    */
    if( !json_is_bootstrapped_early() ) json_bootstrap_early();
    json_warn( FSL_JSON_W_UNKNOWN, "%s", z );
  }else
#endif
  {
    if( g.cgiOutput==1 ){
      etag_cancel();
      cgi_printf("<p class=\"generalError\">\n%h\n</p>\n", z);

Changes to src/th.c.

220
221
222
223
224
225
226







227


228
229
230
231
232
233
234
static void thBufferWriteResize(
  Th_Interp *interp,
  Buffer *pBuffer,
  const char *zAdd,
  int nAdd
){
  int nNew = (pBuffer->nBuf+nAdd)*2+32;







  pBuffer->zBuf = Th_Realloc(interp, pBuffer->zBuf, nNew);


  pBuffer->nBufAlloc = nNew;
  th_memcpy(&pBuffer->zBuf[pBuffer->nBuf], zAdd, nAdd);
  pBuffer->nBuf += nAdd;
}
static void thBufferWriteFast(
  Th_Interp *interp,
  Buffer *pBuffer,







>
>
>
>
>
>
>

>
>







220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
static void thBufferWriteResize(
  Th_Interp *interp,
  Buffer *pBuffer,
  const char *zAdd,
  int nAdd
){
  int nNew = (pBuffer->nBuf+nAdd)*2+32;
#if defined(TH_MEMDEBUG)
  char *zNew = (char *)Th_Malloc(interp, nNew);
  th_memcpy(zNew, pBuffer->zBuf, pBuffer->nBuf);
  Th_Free(interp, pBuffer->zBuf);
  pBuffer->zBuf = zNew;
#else
  int nOld = pBuffer->nBufAlloc;
  pBuffer->zBuf = Th_Realloc(interp, pBuffer->zBuf, nNew);
  memset(pBuffer->zBuf+nOld, 0, nNew-nOld);
#endif
  pBuffer->nBufAlloc = nNew;
  th_memcpy(&pBuffer->zBuf[pBuffer->nBuf], zAdd, nAdd);
  pBuffer->nBuf += nAdd;
}
static void thBufferWriteFast(
  Th_Interp *interp,
  Buffer *pBuffer,
1533
1534
1535
1536
1537
1538
1539



























1540
1541
1542
1543
1544
1545
1546
    pInterp->nResult = 0;
    return zResult;
  }else{
    return (char *)Th_Malloc(pInterp, 1);
  }
}




























/*
** Install a new th1 command.
**
** If a command of the same name already exists, it is deleted automatically.
*/
int Th_CreateCommand(
  Th_Interp *interp,







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
    pInterp->nResult = 0;
    return zResult;
  }else{
    return (char *)Th_Malloc(pInterp, 1);
  }
}

#if defined(TH_MEMDEBUG)
/*
** Wrappers around the supplied malloc() and free()
*/
void *Th_DbgMalloc(Th_Interp *pInterp, int nByte){
  void *p;
  Th_Vtab *pVtab = pInterp->pVtab;
  if( pVtab ){
    p = pVtab->xMalloc(nByte);
    if( p ) memset(p, 0, nByte);
  }else{
    p = Th_SysMalloc(pInterp, nByte);
  }
  return p;
}
void Th_DbgFree(Th_Interp *pInterp, void *z){
  if( z ){
    Th_Vtab *pVtab = pInterp->pVtab;
    if( pVtab ){
      pVtab->xFree(z);
    }else{
      Th_SysFree(pInterp, z);
    }
  }
}
#endif

/*
** Install a new th1 command.
**
** If a command of the same name already exists, it is deleted automatically.
*/
int Th_CreateCommand(
  Th_Interp *interp,
1819
1820
1821
1822
1823
1824
1825
1826

1827
1828
1829


1830
1831





1832
1833
1834
1835
1836
1837
1838
  /* Delete the interpreter structure itself. */
  Th_Free(interp, (void *)interp);
}

/*
** Create a new interpreter.
*/
Th_Interp * Th_CreateInterp(void){

  Th_Interp *p;

  /* Allocate and initialise the interpreter and the global frame */


  p = Th_Malloc(0, sizeof(Th_Interp) + sizeof(Th_Frame));
  memset(p, 0, sizeof(Th_Interp));





  p->paCmd = Th_HashNew(p);
  thPushFrame(p, (Th_Frame *)&p[1]);
  thInitialize(p);

  return p;
}








|
>



>
>
|
|
>
>
>
>
>







1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
  /* Delete the interpreter structure itself. */
  Th_Free(interp, (void *)interp);
}

/*
** Create a new interpreter.
*/
Th_Interp * Th_CreateInterp(Th_Vtab *pVtab){
  int nByte = sizeof(Th_Interp) + sizeof(Th_Frame);
  Th_Interp *p;

  /* Allocate and initialise the interpreter and the global frame */
#if defined(TH_MEMDEBUG)
  if( pVtab ){
    p = pVtab->xMalloc(nByte);
    memset(p, 0, nByte);
    p->pVtab = pVtab;
  }else
#endif
  p = Th_SysMalloc(0, nByte);

  p->paCmd = Th_HashNew(p);
  thPushFrame(p, (Th_Frame *)&p[1]);
  thInitialize(p);

  return p;
}

Changes to src/th.h.

19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
** Opaque handle for interpeter.
*/
typedef struct Th_Interp Th_Interp;

/*
** Create and delete interpreters.
*/
Th_Interp * Th_CreateInterp(void);
void Th_DeleteInterp(Th_Interp *);

/*
** Evaluate an TH program in the stack frame identified by parameter
** iFrame, according to the following rules:
**
**   * If iFrame is 0, this means the current frame.







|







19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
** Opaque handle for interpeter.
*/
typedef struct Th_Interp Th_Interp;

/*
** Create and delete interpreters.
*/
Th_Interp * Th_CreateInterp(Th_Vtab *);
void Th_DeleteInterp(Th_Interp *);

/*
** Evaluate an TH program in the stack frame identified by parameter
** iFrame, according to the following rules:
**
**   * If iFrame is 0, this means the current frame.
119
120
121
122
123
124
125





126
127
128

129
130
131









132
133
134
135
136
137
138
*/
int Th_ErrorMessage(Th_Interp *, const char *, const char *, int);

/*
** Access the memory management functions associated with the specified
** interpreter.
*/





void *fossil_malloc_zero(size_t);
void *fossil_realloc(void*,size_t);
void fossil_free(void*);

#define Th_Malloc(I,N)     fossil_malloc_zero(N)
#define Th_Realloc(I,P,N)  fossil_realloc(P,N)
#define Th_Free(I,P)       fossil_free(P)










/*
** Functions for handling TH lists.
*/
int Th_ListAppend(Th_Interp *, char **, int *, const char *, int);
int Th_SplitList(Th_Interp *, const char *, int, char ***, int **, int *);








>
>
>
>
>

|
|
>
|
|
|
>
>
>
>
>
>
>
>
>







119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
*/
int Th_ErrorMessage(Th_Interp *, const char *, const char *, int);

/*
** Access the memory management functions associated with the specified
** interpreter.
*/
#if defined(TH_MEMDEBUG)
void *Th_DbgMalloc(Th_Interp *, int);
void Th_DbgFree(Th_Interp *, void *);
#endif

void *fossil_malloc_zero(size_t);
void *fossil_realloc(void *, size_t);
void fossil_free(void *);

#define Th_SysMalloc(I,N)     fossil_malloc_zero((N))
#define Th_SysRealloc(I,P,N)  fossil_realloc((P),(N))
#define Th_SysFree(I,P)       fossil_free((P))

#if defined(TH_MEMDEBUG)
#  define Th_Malloc(I,N)      Th_DbgMalloc((I),(N))
#  define Th_Free(I,P)        Th_DbgFree((I),(P))
#else
#  define Th_Malloc(I,N)      Th_SysMalloc((I),(N))
#  define Th_Realloc(I,P,N)   Th_SysRealloc((I),(P),(N))
#  define Th_Free(I,P)        Th_SysFree((I),(P))
#endif

/*
** Functions for handling TH lists.
*/
int Th_ListAppend(Th_Interp *, char **, int *, const char *, int);
int Th_SplitList(Th_Interp *, const char *, int, char ***, int **, int *);

Changes to src/th_main.c.

66
67
68
69
70
71
72




































73
74
75
76
77
78
79
/*
** These macros are used within this file to detect if the repository and
** configuration ("user") database are currently open.
*/
#define Th_IsRepositoryOpen()     (g.repositoryOpen)
#define Th_IsConfigOpen()         (g.zConfigDbName!=0)






































/*
** Generate a TH1 trace message if debugging is enabled.
*/
void Th_Trace(const char *zFormat, ...){
  va_list ap;
  va_start(ap, zFormat);







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
/*
** These macros are used within this file to detect if the repository and
** configuration ("user") database are currently open.
*/
#define Th_IsRepositoryOpen()     (g.repositoryOpen)
#define Th_IsConfigOpen()         (g.zConfigDbName!=0)

/*
** When memory debugging is enabled, use our custom memory allocator.
*/
#if defined(TH_MEMDEBUG)
/*
** Global variable counting the number of outstanding calls to malloc()
** made by the th1 implementation. This is used to catch memory leaks
** in the interpreter. Obviously, it also means th1 is not threadsafe.
*/
static int nOutstandingMalloc = 0;

/*
** Implementations of malloc() and free() to pass to the interpreter.
*/
static void *xMalloc(unsigned int n){
  void *p = fossil_malloc(n);
  if( p ){
    nOutstandingMalloc++;
  }
  return p;
}
static void xFree(void *p){
  if( p ){
    nOutstandingMalloc--;
  }
  free(p);
}
static Th_Vtab vtab = { xMalloc, xFree };

/*
** Returns the number of outstanding TH1 memory allocations.
*/
int Th_GetOutstandingMalloc(){
  return nOutstandingMalloc;
}
#endif

/*
** Generate a TH1 trace message if debugging is enabled.
*/
void Th_Trace(const char *zFormat, ...){
  va_list ap;
  va_start(ap, zFormat);
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
*/
static void sendText(Blob * pOut, const char *z, int n, int encode){
  if(0==pOut && pThOut!=0){
    pOut = pThOut;
  }
  if(TH_INIT_NO_ENCODE & g.th1Flags){
    encode = 0;
  }     
  if( enableOutput && n ){
    if( n<0 ) n = strlen(z);
    if( encode ){
      z = htmlize(z, n);
      n = strlen(z);
    }
    if(pOut!=0){







|







384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
*/
static void sendText(Blob * pOut, const char *z, int n, int encode){
  if(0==pOut && pThOut!=0){
    pOut = pThOut;
  }
  if(TH_INIT_NO_ENCODE & g.th1Flags){
    encode = 0;
  }
  if( enableOutput && n ){
    if( n<0 ) n = strlen(z);
    if( encode ){
      z = htmlize(z, n);
      n = strlen(z);
    }
    if(pOut!=0){
625
626
627
628
629
630
631

632
633
634
635
636
637
638
  blob_zero(&src);
  blob_init(&src, (char*)argv[1], argl[1]);
  blob_zero(&title); blob_zero(&body);
  markdown_to_html(&src, &title, &body);
  Th_ListAppend(interp, &zValue, &nValue, blob_str(&title), blob_size(&title));
  Th_ListAppend(interp, &zValue, &nValue, blob_str(&body), blob_size(&body));
  Th_SetResult(interp, zValue, nValue);

  return TH_OK;
}

/*
** TH1 command: decorate STRING
** TH1 command: wiki STRING
**







>







661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
  blob_zero(&src);
  blob_init(&src, (char*)argv[1], argl[1]);
  blob_zero(&title); blob_zero(&body);
  markdown_to_html(&src, &title, &body);
  Th_ListAppend(interp, &zValue, &nValue, blob_str(&title), blob_size(&title));
  Th_ListAppend(interp, &zValue, &nValue, blob_str(&body), blob_size(&body));
  Th_SetResult(interp, zValue, nValue);
  Th_Free(interp, zValue);
  return TH_OK;
}

/*
** TH1 command: decorate STRING
** TH1 command: wiki STRING
**
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
    }else if( azCap[i][0]=='@' ){
      rc = login_has_capability(azCap[i]+1, anCap[i]-1, LOGIN_ANON);
    }else if( azCap[i][0]=='*' ){
      rc = 1;
    }else{
      rc = login_has_capability(azCap[i], anCap[i], 0);
    }
    break;   
  }
  Th_Free(interp, azCap);
  Th_SetResultInt(interp, rc);
  return TH_OK; 
}


/*
** TH1 command: searchable STRING...
**
** Return true if searching in any of the document classes identified







|



|







845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
    }else if( azCap[i][0]=='@' ){
      rc = login_has_capability(azCap[i]+1, anCap[i]-1, LOGIN_ANON);
    }else if( azCap[i][0]=='*' ){
      rc = 1;
    }else{
      rc = login_has_capability(azCap[i], anCap[i], 0);
    }
    break;
  }
  Th_Free(interp, azCap);
  Th_SetResultInt(interp, rc);
  return TH_OK;
}


/*
** TH1 command: searchable STRING...
**
** Return true if searching in any of the document classes identified
2354
2355
2356
2357
2358
2359
2360









2361
2362
2363
2364
2365
2366
2367
2368
    */
    Th_OpenConfig(!noRepo);
  }
  if( forceReset || forceTcl || g.interp==0 ){
    int created = 0;
    int i;
    if( g.interp==0 ){









      g.interp = Th_CreateInterp();
      created = 1;
    }
    if( forceReset || created ){
      th_register_language(g.interp);     /* Basic scripting commands. */
    }
#ifdef FOSSIL_ENABLE_TCL
    if( forceTcl || fossil_getenv("TH1_ENABLE_TCL")!=0 ||







>
>
>
>
>
>
>
>
>
|







2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
    */
    Th_OpenConfig(!noRepo);
  }
  if( forceReset || forceTcl || g.interp==0 ){
    int created = 0;
    int i;
    if( g.interp==0 ){
      Th_Vtab *pVtab = 0;
#if defined(TH_MEMDEBUG)
      if( fossil_getenv("TH1_DELETE_INTERP")!=0 ){
        pVtab = &vtab;
        if( g.thTrace ){
          Th_Trace("th1-init MEMDEBUG ENABLED<br />\n");
        }
      }
#endif
      g.interp = Th_CreateInterp(pVtab);
      created = 1;
    }
    if( forceReset || created ){
      th_register_language(g.interp);     /* Basic scripting commands. */
    }
#ifdef FOSSIL_ENABLE_TCL
    if( forceTcl || fossil_getenv("TH1_ENABLE_TCL")!=0 ||

Changes to src/user.c.

36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
       break;
    }
    if( z[i]>0 && z[i]<' ' ) z[i] = ' ';
  }
  blob_append(pBlob, z, -1);
}

#if defined(_WIN32) || defined(__BIONIC__) && !defined(FOSSIL_HAVE_GETPASS)
#ifdef _WIN32
#include <conio.h>
#endif

/*
** getpass() for Windows and Android.
*/







|







36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
       break;
    }
    if( z[i]>0 && z[i]<' ' ) z[i] = ' ';
  }
  blob_append(pBlob, z, -1);
}

#if defined(_WIN32) || (defined(__BIONIC__) && !defined(FOSSIL_HAVE_GETPASS))
#ifdef _WIN32
#include <conio.h>
#endif

/*
** getpass() for Windows and Android.
*/

Changes to win/Makefile.msc.

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
SRCDIR  = $(B)\src
T       = .
OBJDIR  = $(T)
OX      = $(OBJDIR)
O       = .obj
E       = .exe
P       = .pdb
OPTLEVEL= /Os

INSTALLDIR = .
!ifdef DESTDIR
INSTALLDIR = $(DESTDIR)\$(INSTALLDIR)
!endif

# When building out of source, this Makefile needs to know the path to the base







|







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
SRCDIR  = $(B)\src
T       = .
OBJDIR  = $(T)
OX      = $(OBJDIR)
O       = .obj
E       = .exe
P       = .pdb
DBGOPTS = /Od

INSTALLDIR = .
!ifdef DESTDIR
INSTALLDIR = $(DESTDIR)\$(INSTALLDIR)
!endif

# When building out of source, this Makefile needs to know the path to the base
35
36
37
38
39
40
41





42
43
44
45
46
47
48
!endif

# Perl is only necessary if OpenSSL support is enabled and it is built from
# source code.  The PERLDIR environment variable, if it exists, should point
# to the directory containing the main Perl executable specified here (i.e.
# "perl.exe").
PERL    = perl.exe






# Enable debugging symbols?
!ifndef DEBUG
DEBUG = 0
!endif
!ifdef FOSSIL_DEBUG
DEBUG = 1







>
>
>
>
>







35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
!endif

# Perl is only necessary if OpenSSL support is enabled and it is built from
# source code.  The PERLDIR environment variable, if it exists, should point
# to the directory containing the main Perl executable specified here (i.e.
# "perl.exe").
PERL    = perl.exe

# Enable use of available compiler optimizations?
!ifndef OPTIMIZATIONS
OPTIMIZATIONS = 2
!endif

# Enable debugging symbols?
!ifndef DEBUG
DEBUG = 0
!endif
!ifdef FOSSIL_DEBUG
DEBUG = 1
207
208
209
210
211
212
213
214












215
216
217
218
219
220
221
222
223
224
225
226
!else
!if $(DEBUG)!=0
CRTFLAGS = /MTd
!else
CRTFLAGS = /MT
!endif
!endif













!if $(DEBUG)!=0
CFLAGS    = $(CFLAGS) /Zi $(CRTFLAGS) /Od /DFOSSIL_DEBUG
LDFLAGS   = $(LDFLAGS) /DEBUG
!else
CFLAGS    = $(CFLAGS) $(CRTFLAGS) $(OPTLEVEL)
!endif

BCC       = $(CC) $(CFLAGS)
TCC       = $(CC) /c $(CFLAGS) $(MSCDEF) $(INCL)
RCC       = $(RC) /D_WIN32 /D_MSC_VER $(MSCDEF) $(INCL)
MTC       = mt
LIBS      = ws2_32.lib advapi32.lib dnsapi.lib








>
>
>
>
>
>
>
>
>
>
>
>

|


|







212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
!else
!if $(DEBUG)!=0
CRTFLAGS = /MTd
!else
CRTFLAGS = /MT
!endif
!endif

!if $(OPTIMIZATIONS)>3
RELOPTS = /Os
!elseif $(OPTIMIZATIONS)>2
RELOPTS = /Ox
!elseif $(OPTIMIZATIONS)>1
RELOPTS = /O2
!elseif $(OPTIMIZATIONS)>0
RELOPTS = /O1
!else
RELOPTS =
!endif

!if $(DEBUG)!=0
CFLAGS    = $(CFLAGS) /Zi $(CRTFLAGS) $(DBGOPTS) /DFOSSIL_DEBUG /DTH_MEMDEBUG
LDFLAGS   = $(LDFLAGS) /DEBUG
!else
CFLAGS    = $(CFLAGS) $(CRTFLAGS) $(RELOPTS)
!endif

BCC       = $(CC) $(CFLAGS)
TCC       = $(CC) /c $(CFLAGS) $(MSCDEF) $(INCL)
RCC       = $(RC) /D_WIN32 /D_MSC_VER $(MSCDEF) $(INCL)
MTC       = mt
LIBS      = ws2_32.lib advapi32.lib dnsapi.lib