Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Add 'th1-setup' setting for the optional TH1 script to evaluate after creating and initializing the TH1 interpreter. Revise TH1 integration in preparation for generalized hooks. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA1: |
b058c8a944f96c98712ad4c8eab65fee |
| User & Date: | mistachkin 2012-11-20 06:04:19.932 |
Context
|
2012-11-20
| ||
| 08:21 | If applicable, use the OPEN_ANY_SCHEMA flag in Th_FossilInit. ... (check-in: 3c1ad1def9 user: mistachkin tags: trunk) | |
| 06:26 | Proof-of-concept for generalized TH1 command/webpage hooks. ... (check-in: caad77934b user: mistachkin tags: th1Hooks) | |
| 06:04 | Add 'th1-setup' setting for the optional TH1 script to evaluate after creating and initializing the TH1 interpreter. Revise TH1 integration in preparation for generalized hooks. ... (check-in: b058c8a944 user: mistachkin tags: trunk) | |
|
2012-11-19
| ||
| 23:57 | Fix harmless compiler warning in the wiki rendering code. ... (check-in: 60f71ba20a user: mistachkin tags: trunk) | |
Changes
Changes to src/configure.c.
| ︙ | ︙ | |||
87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
{ "background-image", CONFIGSET_SKIN },
{ "index-page", CONFIGSET_SKIN },
{ "timeline-block-markup", CONFIGSET_SKIN },
{ "timeline-max-comment", CONFIGSET_SKIN },
{ "adunit", CONFIGSET_SKIN },
{ "adunit-omit-if-admin", CONFIGSET_SKIN },
{ "adunit-omit-if-user", CONFIGSET_SKIN },
#ifdef FOSSIL_ENABLE_TCL
{ "tcl", CONFIGSET_SKIN|CONFIGSET_TKT|CONFIGSET_XFER },
{ "tcl-setup", CONFIGSET_SKIN|CONFIGSET_TKT|CONFIGSET_XFER },
#endif
{ "project-name", CONFIGSET_PROJ },
| > | 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
{ "background-image", CONFIGSET_SKIN },
{ "index-page", CONFIGSET_SKIN },
{ "timeline-block-markup", CONFIGSET_SKIN },
{ "timeline-max-comment", CONFIGSET_SKIN },
{ "adunit", CONFIGSET_SKIN },
{ "adunit-omit-if-admin", CONFIGSET_SKIN },
{ "adunit-omit-if-user", CONFIGSET_SKIN },
{ "th1-setup", CONFIGSET_ALL },
#ifdef FOSSIL_ENABLE_TCL
{ "tcl", CONFIGSET_SKIN|CONFIGSET_TKT|CONFIGSET_XFER },
{ "tcl-setup", CONFIGSET_SKIN|CONFIGSET_TKT|CONFIGSET_XFER },
#endif
{ "project-name", CONFIGSET_PROJ },
|
| ︙ | ︙ |
Changes to src/db.c.
| ︙ | ︙ | |||
2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 |
{ "proxy", 0, 32, 0, "off" },
{ "relative-paths",0, 0, 0, "on" },
{ "repo-cksum", 0, 0, 0, "on" },
{ "self-register", 0, 0, 0, "off" },
{ "ssl-ca-location",0, 40, 0, "" },
{ "ssl-identity", 0, 40, 0, "" },
{ "ssh-command", 0, 40, 0, "" },
#ifdef FOSSIL_ENABLE_TCL
{ "tcl", 0, 0, 0, "off" },
{ "tcl-setup", 0, 40, 0, "" },
#endif
{ "web-browser", 0, 32, 0, "" },
{ "white-foreground", 0, 0, 0, "off" },
{ 0,0,0,0,0 }
| > | 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 |
{ "proxy", 0, 32, 0, "off" },
{ "relative-paths",0, 0, 0, "on" },
{ "repo-cksum", 0, 0, 0, "on" },
{ "self-register", 0, 0, 0, "off" },
{ "ssl-ca-location",0, 40, 0, "" },
{ "ssl-identity", 0, 40, 0, "" },
{ "ssh-command", 0, 40, 0, "" },
{ "th1-setup", 0, 40, 0, "" },
#ifdef FOSSIL_ENABLE_TCL
{ "tcl", 0, 0, 0, "off" },
{ "tcl-setup", 0, 40, 0, "" },
#endif
{ "web-browser", 0, 32, 0, "" },
{ "white-foreground", 0, 0, 0, "off" },
{ 0,0,0,0,0 }
|
| ︙ | ︙ | |||
2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 | ** scripts to be evaluated from TH1. Additionally, the Tcl ** interpreter will be able to evaluate arbitrary TH1 ** expressions and scripts. Default: off. ** ** tcl-setup This is the setup script to be evaluated after creating ** and initializing the Tcl interpreter. By default, this ** is empty and no extra setup is performed. ** ** web-browser A shell command used to launch your preferred ** web browser when given a URL as an argument. ** Defaults to "start" on windows, "open" on Mac, ** and "firefox" on Unix. ** ** Options: | > > > > | 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 | ** scripts to be evaluated from TH1. Additionally, the Tcl ** interpreter will be able to evaluate arbitrary TH1 ** expressions and scripts. Default: off. ** ** tcl-setup This is the setup script to be evaluated after creating ** and initializing the Tcl interpreter. By default, this ** is empty and no extra setup is performed. ** ** th1-setup This is the setup script to be evaluated after creating ** and initializing the TH1 interpreter. By default, this ** is empty and no extra setup is performed. ** ** web-browser A shell command used to launch your preferred ** web browser when given a URL as an argument. ** Defaults to "start" on windows, "open" on Mac, ** and "firefox" on Unix. ** ** Options: |
| ︙ | ︙ |
Changes to src/main.c.
| ︙ | ︙ | |||
128 129 130 131 132 133 134 | int fSqlTrace; /* True if --sqltrace flag is present */ int fSqlStats; /* True if --sqltrace or --sqlstats are present */ int fSqlPrint; /* True if -sqlprint flag is present */ int fQuiet; /* True if -quiet flag is present */ int fHttpTrace; /* Trace outbound HTTP requests */ int fSystemTrace; /* Trace calls to fossil_system(), --systemtrace */ int fSshTrace; /* Trace the SSH setup traffic */ | | > | 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 154 155 156 | int fSqlTrace; /* True if --sqltrace flag is present */ int fSqlStats; /* True if --sqltrace or --sqlstats are present */ int fSqlPrint; /* True if -sqlprint flag is present */ int fQuiet; /* True if -quiet flag is present */ int fHttpTrace; /* Trace outbound HTTP requests */ int fSystemTrace; /* Trace calls to fossil_system(), --systemtrace */ int fSshTrace; /* Trace the SSH setup traffic */ int fNoSync; /* Do not do an autosync ever. --nosync */ char *zPath; /* Name of webpage being served */ char *zExtra; /* Extra path information past the webpage name */ char *zBaseURL; /* Full text of the URL being served */ char *zTop; /* Parent directory of zPath */ const char *zContentType; /* The content type of the input HTTP request */ int iErrPriority; /* Priority of current error message */ char *zErrMsg; /* Text of an error message */ 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 */ |
| ︙ | ︙ |
Changes to src/th_main.c.
| ︙ | ︙ | |||
75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
int *argl
){
if( argc!=2 ){
return Th_WrongNumArgs(interp, "enable_output BOOLEAN");
}
return Th_ToInt(interp, argv[1], argl[1], &enableOutput);
}
/*
** Send text to the appropriate output: Either to the console
** or to the CGI reply buffer.
*/
static void sendText(const char *z, int n, int encode){
if( enableOutput && n ){
| > > > > > > > > > > > > > > > > > > | 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 |
int *argl
){
if( argc!=2 ){
return Th_WrongNumArgs(interp, "enable_output BOOLEAN");
}
return Th_ToInt(interp, argv[1], argl[1], &enableOutput);
}
/*
** Return a name for a TH1 return code.
*/
const char *Th_ReturnCodeName(int rc){
static char zRc[32];
switch( rc ){
case TH_OK: return "TH_OK";
case TH_ERROR: return "TH_ERROR";
case TH_BREAK: return "TH_BREAK";
case TH_RETURN: return "TH_RETURN";
case TH_CONTINUE: return "TH_CONTINUE";
default: {
sqlite3_snprintf(sizeof(zRc),zRc,"return code %d",rc);
}
}
return zRc;
}
/*
** Send text to the appropriate output: Either to the console
** or to the CGI reply buffer.
*/
static void sendText(const char *z, int n, int encode){
if( enableOutput && n ){
|
| ︙ | ︙ | |||
96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
}else{
fwrite(z, 1, n, stdout);
fflush(stdout);
}
if( encode ) free((char*)z);
}
}
/*
** TH command: puts STRING
** TH command: html STRING
**
** Output STRING as HTML (html) or unchanged (puts).
*/
| > > > > > > > > > | 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
}else{
fwrite(z, 1, n, stdout);
fflush(stdout);
}
if( encode ) free((char*)z);
}
}
static void sendError(const char *z, int n, int forceCgi){
if( forceCgi || g.cgiOutput ){
sendText("<hr><p class=\"thmainError\">", -1, 0);
}
sendText("ERROR: ", -1, 0);
sendText((char*)z, n, 1);
sendText(forceCgi || g.cgiOutput ? "</p>" : "\n", -1, 0);
}
/*
** TH command: puts STRING
** TH command: html STRING
**
** Output STRING as HTML (html) or unchanged (puts).
*/
|
| ︙ | ︙ | |||
508 509 510 511 512 513 514 | /* ** Make sure the interpreter has been initialized. Initialize it if ** it has not been already. ** ** The interpreter is stored in the g.interp global variable. */ | | > | 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 |
/*
** Make sure the interpreter has been initialized. Initialize it if
** it has not been already.
**
** The interpreter is stored in the g.interp global variable.
*/
void Th_FossilInit(int needConfig, int forceSetup){
int wasInit = 0;
static struct _Command {
const char *zName;
Th_CommandProc xProc;
void *pContext;
} aCommand[] = {
{"anycap", anycapCmd, 0},
{"combobox", comboboxCmd, 0},
|
| ︙ | ︙ | |||
530 531 532 533 534 535 536 537 538 539 540 541 542 |
{"puts", putsCmd, (void*)1},
{"wiki", wikiCmd, 0},
{"repository", repositoryCmd, 0},
{"utime", utimeCmd, 0},
{"stime", stimeCmd, 0},
{0, 0, 0}
};
if( g.interp==0 ){
int i;
g.interp = Th_CreateInterp(&vtab);
th_register_language(g.interp); /* Basic scripting commands. */
#ifdef FOSSIL_ENABLE_TCL
if( getenv("TH1_ENABLE_TCL")!=0 || db_get_boolean("tcl", 0) ){
| > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > | | 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 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 |
{"puts", putsCmd, (void*)1},
{"wiki", wikiCmd, 0},
{"repository", repositoryCmd, 0},
{"utime", utimeCmd, 0},
{"stime", stimeCmd, 0},
{0, 0, 0}
};
if( needConfig ){
/*
** This function uses several settings which may be defined in the
** repository and/or the global configuration. Since the caller
** passed a non-zero value for the needConfig parameter, make sure
** the necessary database connections are open prior to continuing.
*/
db_find_and_open_repository(OPEN_OK_NOT_FOUND, 0);
db_open_config(0);
}
if( g.interp==0 ){
int i;
g.interp = Th_CreateInterp(&vtab);
th_register_language(g.interp); /* Basic scripting commands. */
#ifdef FOSSIL_ENABLE_TCL
if( getenv("TH1_ENABLE_TCL")!=0 || db_get_boolean("tcl", 0) ){
if( !g.tcl.setup ){
g.tcl.setup = db_get("tcl-setup", 0); /* Grab Tcl setup script. */
}
th_register_tcl(g.interp, &g.tcl); /* Tcl integration commands. */
}
#endif
for(i=0; i<sizeof(aCommand)/sizeof(aCommand[0]); i++){
if ( !aCommand[i].zName || !aCommand[i].xProc ) continue;
Th_CreateCommand(g.interp, aCommand[i].zName, aCommand[i].xProc,
aCommand[i].pContext, 0);
}
}else{
wasInit = 1;
}
if( forceSetup || !wasInit ){
int rc = TH_OK;
if( !g.th1Setup ){
g.th1Setup = db_get("th1-setup", 0); /* Grab TH1 setup script. */
}
if( g.th1Setup ){
rc = Th_Eval(g.interp, 0, g.th1Setup, -1);
if( rc==TH_ERROR ){
int nResult = 0;
char *zResult = (char*)Th_GetResult(g.interp, &nResult);
sendError(zResult, nResult, 0);
}
}
if( g.thTrace ){
Th_Trace("th1-setup {%h} => %h<br />\n", g.th1Setup,
Th_ReturnCodeName(rc));
}
}
}
/*
** Store a string value in a variable in the interpreter.
*/
void Th_Store(const char *zName, const char *zValue){
Th_FossilInit(0, 0);
if( zValue ){
if( g.thTrace ){
Th_Trace("set %h {%h}<br />\n", zName, zValue);
}
Th_SetVar(g.interp, zName, -1, zValue, strlen(zValue));
}
}
/*
** Store an integer value in a variable in the interpreter.
*/
void Th_StoreInt(const char *zName, int iValue){
Blob value;
char *zValue;
Th_FossilInit(0, 0);
blob_zero(&value);
blob_appendf(&value, "%d", iValue);
zValue = blob_str(&value);
if( g.thTrace ){
Th_Trace("set %h {%h}<br />\n", zName, zValue);
}
Th_SetVar(g.interp, zName, -1, zValue, strlen(zValue));
blob_reset(&value);
}
/*
** Unset a variable.
*/
void Th_Unstore(const char *zName){
if( g.interp ){
Th_UnsetVar(g.interp, (char*)zName, -1);
}
}
/*
** Retrieve a string value from the interpreter. If no such
** variable exists, return NULL.
*/
char *Th_Fetch(const char *zName, int *pSize){
int rc;
Th_FossilInit(0, 0);
rc = Th_GetVar(g.interp, (char*)zName, -1);
if( rc==TH_OK ){
return (char*)Th_GetResult(g.interp, pSize);
}else{
return 0;
}
}
|
| ︙ | ︙ | |||
656 657 658 659 660 661 662 |
** on either stdout or into CGI.
*/
int Th_Render(const char *z){
int i = 0;
int n;
int rc = TH_OK;
char *zResult;
| | | 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 |
** on either stdout or into CGI.
*/
int Th_Render(const char *z){
int i = 0;
int n;
int rc = TH_OK;
char *zResult;
Th_FossilInit(0, 0);
while( z[i] ){
if( z[i]=='$' && (n = validVarName(&z[i+1]))>0 ){
const char *zVar;
int nVar;
int encode = 1;
sendText(z, i, 0);
if( z[i+1]=='<' ){
|
| ︙ | ︙ | |||
692 693 694 695 696 697 698 |
if( z[0] ){ z += 6; }
i = 0;
}else{
i++;
}
}
if( rc==TH_ERROR ){
| < | < | 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 |
if( z[0] ){ z += 6; }
i = 0;
}else{
i++;
}
}
if( rc==TH_ERROR ){
zResult = (char*)Th_GetResult(g.interp, &n);
sendError(zResult, n, 1);
}else{
sendText(z, i, 0);
}
return rc;
}
/*
|
| ︙ | ︙ |
Changes to src/tkt.c.
| ︙ | ︙ | |||
236 237 238 239 240 241 242 |
}
/*
** Create the subscript interpreter and load the "common" code.
*/
void ticket_init(void){
const char *zConfig;
| | | | 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 |
}
/*
** Create the subscript interpreter and load the "common" code.
*/
void ticket_init(void){
const char *zConfig;
Th_FossilInit(0, 0);
zConfig = ticket_common_code();
Th_Eval(g.interp, 0, zConfig, -1);
}
/*
** Create the subscript interpreter and load the "change" code.
*/
int ticket_change(void){
const char *zConfig;
Th_FossilInit(0, 0);
zConfig = ticket_change_code();
return Th_Eval(g.interp, 0, zConfig, -1);
}
/*
** Recreate the ticket table.
*/
|
| ︙ | ︙ |
Changes to src/xfer.c.
| ︙ | ︙ | |||
798 799 800 801 802 803 804 |
** Run the specified TH1 script, if any, and returns the return code or TH_OK
** when there is no script.
*/
static int run_script(const char *zScript){
if( !zScript ){
return TH_OK; /* No script, return success. */
}
| | | 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 |
** Run the specified TH1 script, if any, and returns the return code or TH_OK
** when there is no script.
*/
static int run_script(const char *zScript){
if( !zScript ){
return TH_OK; /* No script, return success. */
}
Th_FossilInit(0, 0); /* Make sure TH1 is ready. */
return Th_Eval(g.interp, 0, zScript, -1);
}
/*
** Run the pre-transfer TH1 script, if any, and returns the return code.
*/
static int run_common_script(void){
|
| ︙ | ︙ |