Fossil

Check-in [142200b90a]
Login

Check-in [142200b90a]

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

Overview
Comment:Corrections to the new 'styleHeader' and 'styleFooter' TH1 commands. Modify TH1 integration code to keep track of when it opens databases. Modify 'test-th-hook' command to permit TH1 tracing. Corrections to new TH1 command test results.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 142200b90adb5cdc0c0a51f56887198458e98df8
User & Date: mistachkin 2014-06-15 00:38:46.464
Context
2014-06-15
01:15
Better cleaning in the MSVC makefile. ... (check-in: f83946c669 user: mistachkin tags: trunk)
00:41
Merge updates from trunk. ... (check-in: 9f3dd72d93 user: mistachkin tags: dbCloseConfig)
00:38
Corrections to the new 'styleHeader' and 'styleFooter' TH1 commands. Modify TH1 integration code to keep track of when it opens databases. Modify 'test-th-hook' command to permit TH1 tracing. Corrections to new TH1 command test results. ... (check-in: 142200b90a user: mistachkin tags: trunk)
00:37
Handling missing th1-setup file in the test suite helpers saveTh1SetupFile and restoreTh1SetupFile. ... (check-in: 5f701f195d user: mistachkin tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/main.c.
153
154
155
156
157
158
159

160
161
162
163
164
165
166
  int sslNotAvailable;    /* SSL is not available.  Do not redirect to https: */
  Blob cgiIn;             /* Input to an xfer www method */
  int cgiOutput;          /* Write error and status messages to CGI */
  int xferPanic;          /* Write error messages in XFER protocol */
  int fullHttpReply;      /* True for full HTTP reply.  False for CGI reply */
  Th_Interp *interp;      /* The TH1 interpreter */
  char *th1Setup;         /* The TH1 post-creation setup script, if any */

  FILE *httpIn;           /* Accept HTTP input from here */
  FILE *httpOut;          /* Send HTTP output here */
  int xlinkClusterOnly;   /* Set when cloning.  Only process clusters */
  int fTimeFormat;        /* 1 for UTC.  2 for localtime.  0 not yet selected */
  int *aCommitFile;       /* Array of files to be committed */
  int markPrivate;        /* All new artifacts are private if true */
  int clockSkewSeen;      /* True if clocks on client and server out of sync */







>







153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
  int sslNotAvailable;    /* SSL is not available.  Do not redirect to https: */
  Blob cgiIn;             /* Input to an xfer www method */
  int cgiOutput;          /* Write error and status messages to CGI */
  int xferPanic;          /* Write error messages in XFER protocol */
  int fullHttpReply;      /* True for full HTTP reply.  False for CGI reply */
  Th_Interp *interp;      /* The TH1 interpreter */
  char *th1Setup;         /* The TH1 post-creation setup script, if any */
  int th1Flags;           /* The TH1 integration state flags */
  FILE *httpIn;           /* Accept HTTP input from here */
  FILE *httpOut;          /* Send HTTP output here */
  int xlinkClusterOnly;   /* Set when cloning.  Only process clusters */
  int fTimeFormat;        /* 1 for UTC.  2 for localtime.  0 not yet selected */
  int *aCommitFile;       /* Array of files to be committed */
  int markPrivate;        /* All new artifacts are private if true */
  int clockSkewSeen;      /* True if clocks on client and server out of sync */
Changes to src/th_main.c.
28
29
30
31
32
33
34

35
36
37
38








39
40
41
42
43
44
45
46
47
48
49







50
51
52
53
54
55
56
** interpreter creation and initialization process.
*/
#define TH_INIT_NONE        ((u32)0x00000000) /* No flags. */
#define TH_INIT_NEED_CONFIG ((u32)0x00000001) /* Open configuration first? */
#define TH_INIT_FORCE_TCL   ((u32)0x00000002) /* Force Tcl to be enabled? */
#define TH_INIT_FORCE_RESET ((u32)0x00000004) /* Force TH1 commands re-added? */
#define TH_INIT_FORCE_SETUP ((u32)0x00000008) /* Force eval of setup script? */

#define TH_INIT_DEFAULT     (TH_INIT_NONE)    /* Default flags. */
#define TH_INIT_HOOK        (TH_INIT_NEED_CONFIG | TH_INIT_FORCE_SETUP)
#endif









#ifdef FOSSIL_ENABLE_TH1_HOOKS
/*
** These are the "well-known" TH1 error messages that occur when no hook is
** registered to be called prior to executing a command or processing a web
** page, respectively.  If one of these errors is seen, it will not be sent
** or displayed to the remote user or local interactive user, respectively.
*/
#define NO_COMMAND_HOOK_ERROR "no such command:  command_hook"
#define NO_WEBPAGE_HOOK_ERROR "no such command:  webpage_hook"
#endif








/*
** 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;








>




>
>
>
>
>
>
>
>











>
>
>
>
>
>
>







28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
** interpreter creation and initialization process.
*/
#define TH_INIT_NONE        ((u32)0x00000000) /* No flags. */
#define TH_INIT_NEED_CONFIG ((u32)0x00000001) /* Open configuration first? */
#define TH_INIT_FORCE_TCL   ((u32)0x00000002) /* Force Tcl to be enabled? */
#define TH_INIT_FORCE_RESET ((u32)0x00000004) /* Force TH1 commands re-added? */
#define TH_INIT_FORCE_SETUP ((u32)0x00000008) /* Force eval of setup script? */
#define TH_INIT_MASK        ((u32)0x0000000F) /* All possible init flags. */
#define TH_INIT_DEFAULT     (TH_INIT_NONE)    /* Default flags. */
#define TH_INIT_HOOK        (TH_INIT_NEED_CONFIG | TH_INIT_FORCE_SETUP)
#endif

/*
** Flags set by functions in this file to keep track of integration state
** information.  These flags should not be used outside of this file.
*/
#define TH_STATE_CONFIG     ((u32)0x00000010) /* We opened the config. */
#define TH_STATE_REPOSITORY ((u32)0x00000020) /* We opened the repository. */
#define TH_STATE_MASK       ((u32)0x00000030) /* All possible state flags. */

#ifdef FOSSIL_ENABLE_TH1_HOOKS
/*
** These are the "well-known" TH1 error messages that occur when no hook is
** registered to be called prior to executing a command or processing a web
** page, respectively.  If one of these errors is seen, it will not be sent
** or displayed to the remote user or local interactive user, respectively.
*/
#define NO_COMMAND_HOOK_ERROR "no such command:  command_hook"
#define NO_WEBPAGE_HOOK_ERROR "no such command:  webpage_hook"
#endif

/*
** 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)

/*
** 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;

719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
  int argc,
  const char **argv,
  int *argl
){
  if( argc!=2 ){
    return Th_WrongNumArgs(interp, "styleHeader TITLE");
  }
  if( g.zConfigDbName ){
    style_header("%s", argv[1]);
    Th_SetResult(interp, 0, 0);
    return TH_OK;
  }else{
    Th_SetResult(interp, "configuration unavailable", -1);
    return TH_ERROR;
  }
}

/*
** TH1 command:     styleFooter
**
** Render the configured style footer.
*/
static int styleFooterCmd(
  Th_Interp *interp,
  void *p,
  int argc,
  const char **argv,
  int *argl
){
  if( argc!=1 ){
    return Th_WrongNumArgs(interp, "styleFooter");
  }
  if( g.zConfigDbName ){
    style_footer();
    Th_SetResult(interp, 0, 0);
    return TH_OK;
  }else{
    Th_SetResult(interp, "configuration unavailable", -1);
    return TH_ERROR;
  }
}

#ifdef _WIN32
# include <windows.h>
#else







|




|



















|




|







735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
  int argc,
  const char **argv,
  int *argl
){
  if( argc!=2 ){
    return Th_WrongNumArgs(interp, "styleHeader TITLE");
  }
  if( Th_IsRepositoryOpen() ){
    style_header("%s", argv[1]);
    Th_SetResult(interp, 0, 0);
    return TH_OK;
  }else{
    Th_SetResult(interp, "repository unavailable", -1);
    return TH_ERROR;
  }
}

/*
** TH1 command:     styleFooter
**
** Render the configured style footer.
*/
static int styleFooterCmd(
  Th_Interp *interp,
  void *p,
  int argc,
  const char **argv,
  int *argl
){
  if( argc!=1 ){
    return Th_WrongNumArgs(interp, "styleFooter");
  }
  if( Th_IsRepositoryOpen() ){
    style_footer();
    Th_SetResult(interp, 0, 0);
    return TH_OK;
  }else{
    Th_SetResult(interp, "repository unavailable", -1);
    return TH_ERROR;
  }
}

#ifdef _WIN32
# include <windows.h>
#else
1160
1161
1162
1163
1164
1165
1166
1167
1168




1169


1170






1171
1172
1173
1174
1175
1176
1177
1178
1179

1180


1181
1182

1183
1184
1185
1186
1187
1188
1189
/*
** Attempts to open the configuration ("user") database.  Optionally, also
** attempts to try to find the repository and open it.
*/
void Th_OpenConfig(
  int openRepository
){
  if( openRepository ){
    db_find_and_open_repository(OPEN_ANY_SCHEMA | OPEN_OK_NOT_FOUND, 0);




  }


  db_open_config(0);






}

/*
** Attempts to close the configuration ("user") database.  Optionally, also
** attempts to close the repository.
*/
void Th_CloseConfig(
  int closeRepository
){

  db_close_config();


  if( closeRepository ){
    db_close(1);

  }
}

/*
** Make sure the interpreter has been initialized.  Initialize it if
** it has not been already.
**







|

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









>
|
>
>
|

>







1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
/*
** Attempts to open the configuration ("user") database.  Optionally, also
** attempts to try to find the repository and open it.
*/
void Th_OpenConfig(
  int openRepository
){
  if( openRepository && !Th_IsRepositoryOpen() ){
    db_find_and_open_repository(OPEN_ANY_SCHEMA | OPEN_OK_NOT_FOUND, 0);
    if( Th_IsRepositoryOpen() ){
      g.th1Flags |= TH_STATE_REPOSITORY;
    }else{
      g.th1Flags &= ~TH_STATE_REPOSITORY;
    }
  }
  if( !Th_IsConfigOpen() ){
    db_open_config(0);
    if( Th_IsConfigOpen() ){
      g.th1Flags |= TH_STATE_CONFIG;
    }else{
      g.th1Flags &= ~TH_STATE_CONFIG;
    }
  }
}

/*
** Attempts to close the configuration ("user") database.  Optionally, also
** attempts to close the repository.
*/
void Th_CloseConfig(
  int closeRepository
){
  if( g.th1Flags & TH_STATE_CONFIG ){
    db_close_config();
    g.th1Flags &= ~TH_STATE_CONFIG;
  }
  if( closeRepository && (g.th1Flags & TH_STATE_REPOSITORY) ){
    db_close(1);
    g.th1Flags &= ~TH_STATE_REPOSITORY;
  }
}

/*
** Make sure the interpreter has been initialized.  Initialize it if
** it has not been already.
**
1282
1283
1284
1285
1286
1287
1288


1289
1290
1291
1292
1293
1294
1295
      }
    }
    if( g.thTrace ){
      Th_Trace("th1-setup {%h} => %h<br />\n", g.th1Setup,
               Th_ReturnCodeName(rc, 0));
    }
  }


}

/*
** Store a string value in a variable in the interpreter.
*/
void Th_Store(const char *zName, const char *zValue){
  Th_FossilInit(TH_INIT_DEFAULT);







>
>







1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
      }
    }
    if( g.thTrace ){
      Th_Trace("th1-setup {%h} => %h<br />\n", g.th1Setup,
               Th_ReturnCodeName(rc, 0));
    }
  }
  g.th1Flags &= ~TH_INIT_MASK;
  g.th1Flags |= (flags & TH_INIT_MASK);
}

/*
** Store a string value in a variable in the interpreter.
*/
void Th_Store(const char *zName, const char *zValue){
  Th_FossilInit(TH_INIT_DEFAULT);
1432
1433
1434
1435
1436
1437
1438

1439
1440
1441
1442
1443
1444
1445
int Th_CommandHook(
  const char *zName,
  char cmdFlags
){
  int rc = TH_OK;
  Th_OpenConfig(1);
  if( fossil_getenv("TH1_ENABLE_HOOKS")==0 && !db_get_boolean("th1-hooks", 0) ){

    return rc;
  }
  Th_CloseConfig(1);
  Th_FossilInit(TH_INIT_HOOK);
  Th_Store("cmd_name", zName);
  Th_StoreList("cmd_args", g.argv, g.argc);
  Th_StoreInt("cmd_flags", cmdFlags);







>







1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
int Th_CommandHook(
  const char *zName,
  char cmdFlags
){
  int rc = TH_OK;
  Th_OpenConfig(1);
  if( fossil_getenv("TH1_ENABLE_HOOKS")==0 && !db_get_boolean("th1-hooks", 0) ){
    Th_CloseConfig(1);
    return rc;
  }
  Th_CloseConfig(1);
  Th_FossilInit(TH_INIT_HOOK);
  Th_Store("cmd_name", zName);
  Th_StoreList("cmd_args", g.argv, g.argc);
  Th_StoreInt("cmd_flags", cmdFlags);
1479
1480
1481
1482
1483
1484
1485

1486
1487
1488
1489
1490
1491
1492
int Th_CommandNotify(
  const char *zName,
  char cmdFlags
){
  int rc = TH_OK;
  Th_OpenConfig(1);
  if( fossil_getenv("TH1_ENABLE_HOOKS")==0 && !db_get_boolean("th1-hooks", 0) ){

    return rc;
  }
  Th_CloseConfig(1);
  Th_FossilInit(TH_INIT_HOOK);
  Th_Store("cmd_name", zName);
  Th_StoreList("cmd_args", g.argv, g.argc);
  Th_StoreInt("cmd_flags", cmdFlags);







>







1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
int Th_CommandNotify(
  const char *zName,
  char cmdFlags
){
  int rc = TH_OK;
  Th_OpenConfig(1);
  if( fossil_getenv("TH1_ENABLE_HOOKS")==0 && !db_get_boolean("th1-hooks", 0) ){
    Th_CloseConfig(1);
    return rc;
  }
  Th_CloseConfig(1);
  Th_FossilInit(TH_INIT_HOOK);
  Th_Store("cmd_name", zName);
  Th_StoreList("cmd_args", g.argv, g.argc);
  Th_StoreInt("cmd_flags", cmdFlags);
1507
1508
1509
1510
1511
1512
1513

1514
1515
1516
1517
1518
1519
1520
int Th_WebpageHook(
  const char *zName,
  char cmdFlags
){
  int rc = TH_OK;
  Th_OpenConfig(1);
  if( fossil_getenv("TH1_ENABLE_HOOKS")==0 && !db_get_boolean("th1-hooks", 0) ){

    return rc;
  }
  Th_CloseConfig(1);
  Th_FossilInit(TH_INIT_HOOK);
  Th_Store("web_name", zName);
  Th_StoreList("web_args", g.argv, g.argc);
  Th_StoreInt("web_flags", cmdFlags);







>







1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
int Th_WebpageHook(
  const char *zName,
  char cmdFlags
){
  int rc = TH_OK;
  Th_OpenConfig(1);
  if( fossil_getenv("TH1_ENABLE_HOOKS")==0 && !db_get_boolean("th1-hooks", 0) ){
    Th_CloseConfig(1);
    return rc;
  }
  Th_CloseConfig(1);
  Th_FossilInit(TH_INIT_HOOK);
  Th_Store("web_name", zName);
  Th_StoreList("web_args", g.argv, g.argc);
  Th_StoreInt("web_flags", cmdFlags);
1554
1555
1556
1557
1558
1559
1560

1561
1562
1563
1564
1565
1566
1567
int Th_WebpageNotify(
  const char *zName,
  char cmdFlags
){
  int rc = TH_OK;
  Th_OpenConfig(1);
  if( fossil_getenv("TH1_ENABLE_HOOKS")==0 && !db_get_boolean("th1-hooks", 0) ){

    return rc;
  }
  Th_CloseConfig(1);
  Th_FossilInit(TH_INIT_HOOK);
  Th_Store("web_name", zName);
  Th_StoreList("web_args", g.argv, g.argc);
  Th_StoreInt("web_flags", cmdFlags);







>







1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
int Th_WebpageNotify(
  const char *zName,
  char cmdFlags
){
  int rc = TH_OK;
  Th_OpenConfig(1);
  if( fossil_getenv("TH1_ENABLE_HOOKS")==0 && !db_get_boolean("th1-hooks", 0) ){
    Th_CloseConfig(1);
    return rc;
  }
  Th_CloseConfig(1);
  Th_FossilInit(TH_INIT_HOOK);
  Th_Store("web_name", zName);
  Th_StoreList("web_args", g.argv, g.argc);
  Th_StoreInt("web_flags", cmdFlags);
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
/*
** COMMAND: test-th-hook
*/
void test_th_hook(void){
  int rc = TH_OK;
  int nResult = 0;
  char *zResult;

  if( g.argc<5 ){
    usage("TYPE NAME FLAGS");
  }
  if( fossil_stricmp(g.argv[2], "cmdhook")==0 ){
    rc = Th_CommandHook(g.argv[3], (char)atoi(g.argv[4]));
  }else if( fossil_stricmp(g.argv[2], "cmdnotify")==0 ){
    rc = Th_CommandNotify(g.argv[3], (char)atoi(g.argv[4]));
  }else if( fossil_stricmp(g.argv[2], "webhook")==0 ){
    rc = Th_WebpageHook(g.argv[3], (char)atoi(g.argv[4]));
  }else if( fossil_stricmp(g.argv[2], "webnotify")==0 ){
    rc = Th_WebpageNotify(g.argv[3], (char)atoi(g.argv[4]));
  }else{
    fossil_fatal("Unknown TH1 hook %s\n", g.argv[2]);
  }
  zResult = (char*)Th_GetResult(g.interp, &nResult);
  sendText("RESULT (", -1, 0);
  sendText(Th_ReturnCodeName(rc, 0), -1, 0);
  sendText("): ", -1, 0);
  sendText(zResult, nResult, 0);
  sendText("\n", -1, 0);

}
#endif







>




















>


1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
/*
** COMMAND: test-th-hook
*/
void test_th_hook(void){
  int rc = TH_OK;
  int nResult = 0;
  char *zResult;
  Th_InitTraceLog();
  if( g.argc<5 ){
    usage("TYPE NAME FLAGS");
  }
  if( fossil_stricmp(g.argv[2], "cmdhook")==0 ){
    rc = Th_CommandHook(g.argv[3], (char)atoi(g.argv[4]));
  }else if( fossil_stricmp(g.argv[2], "cmdnotify")==0 ){
    rc = Th_CommandNotify(g.argv[3], (char)atoi(g.argv[4]));
  }else if( fossil_stricmp(g.argv[2], "webhook")==0 ){
    rc = Th_WebpageHook(g.argv[3], (char)atoi(g.argv[4]));
  }else if( fossil_stricmp(g.argv[2], "webnotify")==0 ){
    rc = Th_WebpageNotify(g.argv[3], (char)atoi(g.argv[4]));
  }else{
    fossil_fatal("Unknown TH1 hook %s\n", g.argv[2]);
  }
  zResult = (char*)Th_GetResult(g.interp, &nResult);
  sendText("RESULT (", -1, 0);
  sendText(Th_ReturnCodeName(rc, 0), -1, 0);
  sendText("): ", -1, 0);
  sendText(zResult, nResult, 0);
  sendText("\n", -1, 0);
  Th_PrintTraceLog();
}
#endif
Changes to test/th1.test.
14
15
16
17
18
19
20





21
22
23
24
25
26
27
#   http://www.hwaci.com/drh/
#
############################################################################
#
# TH1 Commands
#






fossil test-th-eval --th-open-config "setting abc"
test th1-setting-1 {$RESULT eq ""}

###############################################################################

fossil test-th-eval --th-open-config "setting -- abc"
test th1-setting-2 {$RESULT eq ""}







>
>
>
>
>







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#   http://www.hwaci.com/drh/
#
############################################################################
#
# TH1 Commands
#

fossil test-th-eval --th-open-config "setting th1-hooks"
set th1Hooks [expr {$RESULT eq "1"}]

###############################################################################

fossil test-th-eval --th-open-config "setting abc"
test th1-setting-1 {$RESULT eq ""}

###############################################################################

fossil test-th-eval --th-open-config "setting -- abc"
test th1-setting-2 {$RESULT eq ""}
513
514
515
516
517
518
519

520
521





522
523
524

525
526
527
528
529
530
531
532
533

534
535





536
537
538

539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558





559
560
561
562
563
564
565

fossil test-th-eval "trace {}"
test th1-trace-1 {$RESULT eq {}}

###############################################################################

fossil test-th-eval --th-trace "trace {}"

test th1-trace-2 {[string map [list \r\n \n] [string trim $RESULT]] eq \
{------------------ BEGIN TRACE LOG ------------------





th1-setup {} => TH_OK<br />

------------------- END TRACE LOG -------------------}}


###############################################################################

fossil test-th-eval "trace {this is a trace message.}"
test th1-trace-3 {$RESULT eq {}}

###############################################################################

fossil test-th-eval --th-trace "trace {this is a trace message.}"

test th1-trace-4 {[string map [list \r\n \n] [string trim $RESULT]] eq \
{------------------ BEGIN TRACE LOG ------------------





th1-setup {} => TH_OK<br />
this is a trace message.
------------------- END TRACE LOG -------------------}}


###############################################################################

fossil test-th-eval "styleHeader {Page Title Here}"
test th1-header-1 {$RESULT eq {TH_ERROR: configuration unavailable}}

###############################################################################

fossil test-th-eval --th-open-config "styleHeader {Page Title Here}"
test th1-header-2 {[regexp -- {<title>Fossil: Page Title Here</title>} $RESULT]}

###############################################################################

fossil test-th-eval "styleFooter"
test th1-footer-1 {$RESULT eq {TH_ERROR: configuration unavailable}}

###############################################################################

fossil test-th-eval --th-open-config "styleFooter"
test th1-footer-2 {$RESULT eq {}}






###############################################################################

fossil test-th-eval "getParameter"
test th1-get-parameter-1 {$RESULT eq \
    {TH_ERROR: wrong # args: should be "getParameter NAME ?DEFAULT?"}}








>
|

>
>
>
>
>



>









>
|
|
>
>
>
>
>



>




|









|





>
>
>
>
>







518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589

fossil test-th-eval "trace {}"
test th1-trace-1 {$RESULT eq {}}

###############################################################################

fossil test-th-eval --th-trace "trace {}"
if {$th1Hooks} {
  test th1-trace-2 {[string map [list \r\n \n] [string trim $RESULT]] eq \
{------------------ BEGIN TRACE LOG ------------------

------------------- END TRACE LOG -------------------}}
} else {
  test th1-trace-2 {[string map [list \r\n \n] [string trim $RESULT]] eq \
      {------------------ BEGIN TRACE LOG ------------------
th1-setup {} => TH_OK<br />

------------------- END TRACE LOG -------------------}}
}

###############################################################################

fossil test-th-eval "trace {this is a trace message.}"
test th1-trace-3 {$RESULT eq {}}

###############################################################################

fossil test-th-eval --th-trace "trace {this is a trace message.}"
if {$th1Hooks} {
  test th1-trace-4 {[string map [list \r\n \n] [string trim $RESULT]] eq \
      {------------------ BEGIN TRACE LOG ------------------
this is a trace message.
------------------- END TRACE LOG -------------------}}
} else {
  test th1-trace-4 {[string map [list \r\n \n] [string trim $RESULT]] eq \
      {------------------ BEGIN TRACE LOG ------------------
th1-setup {} => TH_OK<br />
this is a trace message.
------------------- END TRACE LOG -------------------}}
}

###############################################################################

fossil test-th-eval "styleHeader {Page Title Here}"
test th1-header-1 {$RESULT eq {TH_ERROR: repository unavailable}}

###############################################################################

fossil test-th-eval --th-open-config "styleHeader {Page Title Here}"
test th1-header-2 {[regexp -- {<title>Fossil: Page Title Here</title>} $RESULT]}

###############################################################################

fossil test-th-eval "styleFooter"
test th1-footer-1 {$RESULT eq {TH_ERROR: repository unavailable}}

###############################################################################

fossil test-th-eval --th-open-config "styleFooter"
test th1-footer-2 {$RESULT eq {}}

###############################################################################

fossil test-th-eval --th-open-config "styleHeader {}; styleFooter"
test th1-footer-3 {[regexp -- {</body></html>} $RESULT]}

###############################################################################

fossil test-th-eval "getParameter"
test th1-get-parameter-1 {$RESULT eq \
    {TH_ERROR: wrong # args: should be "getParameter NAME ?DEFAULT?"}}