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: |
142200b90adb5cdc0c0a51f568871984 |
| 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
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 |
int argc,
const char **argv,
int *argl
){
if( argc!=2 ){
return Th_WrongNumArgs(interp, "styleHeader TITLE");
}
| | | | | | 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 |
/*
** Attempts to open the configuration ("user") database. Optionally, also
** attempts to try to find the repository and open it.
*/
void Th_OpenConfig(
int openRepository
){
| | > > > > | > > | > > > > > > > | > > | > | 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 |
fossil test-th-eval "trace {}"
test th1-trace-1 {$RESULT eq {}}
###############################################################################
fossil test-th-eval --th-trace "trace {}"
| > | > > > > > > > | | > > > > > > | | > > > > > | 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?"}}
|
| ︙ | ︙ |