Fossil SCM

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.

mistachkin 2012-11-20 06:04 trunk
Commit b058c8a944f96c98712ad4c8eab65fee3f362e0c
--- src/configure.c
+++ src/configure.c
@@ -89,10 +89,11 @@
8989
{ "timeline-block-markup", CONFIGSET_SKIN },
9090
{ "timeline-max-comment", CONFIGSET_SKIN },
9191
{ "adunit", CONFIGSET_SKIN },
9292
{ "adunit-omit-if-admin", CONFIGSET_SKIN },
9393
{ "adunit-omit-if-user", CONFIGSET_SKIN },
94
+ { "th1-setup", CONFIGSET_ALL },
9495
9596
#ifdef FOSSIL_ENABLE_TCL
9697
{ "tcl", CONFIGSET_SKIN|CONFIGSET_TKT|CONFIGSET_XFER },
9798
{ "tcl-setup", CONFIGSET_SKIN|CONFIGSET_TKT|CONFIGSET_XFER },
9899
#endif
99100
--- src/configure.c
+++ src/configure.c
@@ -89,10 +89,11 @@
89 { "timeline-block-markup", CONFIGSET_SKIN },
90 { "timeline-max-comment", CONFIGSET_SKIN },
91 { "adunit", CONFIGSET_SKIN },
92 { "adunit-omit-if-admin", CONFIGSET_SKIN },
93 { "adunit-omit-if-user", CONFIGSET_SKIN },
 
94
95 #ifdef FOSSIL_ENABLE_TCL
96 { "tcl", CONFIGSET_SKIN|CONFIGSET_TKT|CONFIGSET_XFER },
97 { "tcl-setup", CONFIGSET_SKIN|CONFIGSET_TKT|CONFIGSET_XFER },
98 #endif
99
--- src/configure.c
+++ src/configure.c
@@ -89,10 +89,11 @@
89 { "timeline-block-markup", CONFIGSET_SKIN },
90 { "timeline-max-comment", CONFIGSET_SKIN },
91 { "adunit", CONFIGSET_SKIN },
92 { "adunit-omit-if-admin", CONFIGSET_SKIN },
93 { "adunit-omit-if-user", CONFIGSET_SKIN },
94 { "th1-setup", CONFIGSET_ALL },
95
96 #ifdef FOSSIL_ENABLE_TCL
97 { "tcl", CONFIGSET_SKIN|CONFIGSET_TKT|CONFIGSET_XFER },
98 { "tcl-setup", CONFIGSET_SKIN|CONFIGSET_TKT|CONFIGSET_XFER },
99 #endif
100
+5
--- src/db.c
+++ src/db.c
@@ -2055,10 +2055,11 @@
20552055
{ "repo-cksum", 0, 0, 0, "on" },
20562056
{ "self-register", 0, 0, 0, "off" },
20572057
{ "ssl-ca-location",0, 40, 0, "" },
20582058
{ "ssl-identity", 0, 40, 0, "" },
20592059
{ "ssh-command", 0, 40, 0, "" },
2060
+ { "th1-setup", 0, 40, 0, "" },
20602061
#ifdef FOSSIL_ENABLE_TCL
20612062
{ "tcl", 0, 0, 0, "off" },
20622063
{ "tcl-setup", 0, 40, 0, "" },
20632064
#endif
20642065
{ "web-browser", 0, 32, 0, "" },
@@ -2232,10 +2233,14 @@
22322233
** expressions and scripts. Default: off.
22332234
**
22342235
** tcl-setup This is the setup script to be evaluated after creating
22352236
** and initializing the Tcl interpreter. By default, this
22362237
** is empty and no extra setup is performed.
2238
+**
2239
+** th1-setup This is the setup script to be evaluated after creating
2240
+** and initializing the TH1 interpreter. By default, this
2241
+** is empty and no extra setup is performed.
22372242
**
22382243
** web-browser A shell command used to launch your preferred
22392244
** web browser when given a URL as an argument.
22402245
** Defaults to "start" on windows, "open" on Mac,
22412246
** and "firefox" on Unix.
22422247
--- src/db.c
+++ src/db.c
@@ -2055,10 +2055,11 @@
2055 { "repo-cksum", 0, 0, 0, "on" },
2056 { "self-register", 0, 0, 0, "off" },
2057 { "ssl-ca-location",0, 40, 0, "" },
2058 { "ssl-identity", 0, 40, 0, "" },
2059 { "ssh-command", 0, 40, 0, "" },
 
2060 #ifdef FOSSIL_ENABLE_TCL
2061 { "tcl", 0, 0, 0, "off" },
2062 { "tcl-setup", 0, 40, 0, "" },
2063 #endif
2064 { "web-browser", 0, 32, 0, "" },
@@ -2232,10 +2233,14 @@
2232 ** expressions and scripts. Default: off.
2233 **
2234 ** tcl-setup This is the setup script to be evaluated after creating
2235 ** and initializing the Tcl interpreter. By default, this
2236 ** is empty and no extra setup is performed.
 
 
 
 
2237 **
2238 ** web-browser A shell command used to launch your preferred
2239 ** web browser when given a URL as an argument.
2240 ** Defaults to "start" on windows, "open" on Mac,
2241 ** and "firefox" on Unix.
2242
--- src/db.c
+++ src/db.c
@@ -2055,10 +2055,11 @@
2055 { "repo-cksum", 0, 0, 0, "on" },
2056 { "self-register", 0, 0, 0, "off" },
2057 { "ssl-ca-location",0, 40, 0, "" },
2058 { "ssl-identity", 0, 40, 0, "" },
2059 { "ssh-command", 0, 40, 0, "" },
2060 { "th1-setup", 0, 40, 0, "" },
2061 #ifdef FOSSIL_ENABLE_TCL
2062 { "tcl", 0, 0, 0, "off" },
2063 { "tcl-setup", 0, 40, 0, "" },
2064 #endif
2065 { "web-browser", 0, 32, 0, "" },
@@ -2232,10 +2233,14 @@
2233 ** expressions and scripts. Default: off.
2234 **
2235 ** tcl-setup This is the setup script to be evaluated after creating
2236 ** and initializing the Tcl interpreter. By default, this
2237 ** is empty and no extra setup is performed.
2238 **
2239 ** th1-setup This is the setup script to be evaluated after creating
2240 ** and initializing the TH1 interpreter. By default, this
2241 ** is empty and no extra setup is performed.
2242 **
2243 ** web-browser A shell command used to launch your preferred
2244 ** web browser when given a URL as an argument.
2245 ** Defaults to "start" on windows, "open" on Mac,
2246 ** and "firefox" on Unix.
2247
+2 -1
--- src/main.c
+++ src/main.c
@@ -130,11 +130,11 @@
130130
int fSqlPrint; /* True if -sqlprint flag is present */
131131
int fQuiet; /* True if -quiet flag is present */
132132
int fHttpTrace; /* Trace outbound HTTP requests */
133133
int fSystemTrace; /* Trace calls to fossil_system(), --systemtrace */
134134
int fSshTrace; /* Trace the SSH setup traffic */
135
- int fNoSync; /* Do not do an autosync even. --nosync */
135
+ int fNoSync; /* Do not do an autosync ever. --nosync */
136136
char *zPath; /* Name of webpage being served */
137137
char *zExtra; /* Extra path information past the webpage name */
138138
char *zBaseURL; /* Full text of the URL being served */
139139
char *zTop; /* Parent directory of zPath */
140140
const char *zContentType; /* The content type of the input HTTP request */
@@ -144,10 +144,11 @@
144144
Blob cgiIn; /* Input to an xfer www method */
145145
int cgiOutput; /* Write error and status messages to CGI */
146146
int xferPanic; /* Write error messages in XFER protocol */
147147
int fullHttpReply; /* True for full HTTP reply. False for CGI reply */
148148
Th_Interp *interp; /* The TH1 interpreter */
149
+ char *th1Setup; /* The TH1 post-creation setup script, if any */
149150
FILE *httpIn; /* Accept HTTP input from here */
150151
FILE *httpOut; /* Send HTTP output here */
151152
int xlinkClusterOnly; /* Set when cloning. Only process clusters */
152153
int fTimeFormat; /* 1 for UTC. 2 for localtime. 0 not yet selected */
153154
int *aCommitFile; /* Array of files to be committed */
154155
--- src/main.c
+++ src/main.c
@@ -130,11 +130,11 @@
130 int fSqlPrint; /* True if -sqlprint flag is present */
131 int fQuiet; /* True if -quiet flag is present */
132 int fHttpTrace; /* Trace outbound HTTP requests */
133 int fSystemTrace; /* Trace calls to fossil_system(), --systemtrace */
134 int fSshTrace; /* Trace the SSH setup traffic */
135 int fNoSync; /* Do not do an autosync even. --nosync */
136 char *zPath; /* Name of webpage being served */
137 char *zExtra; /* Extra path information past the webpage name */
138 char *zBaseURL; /* Full text of the URL being served */
139 char *zTop; /* Parent directory of zPath */
140 const char *zContentType; /* The content type of the input HTTP request */
@@ -144,10 +144,11 @@
144 Blob cgiIn; /* Input to an xfer www method */
145 int cgiOutput; /* Write error and status messages to CGI */
146 int xferPanic; /* Write error messages in XFER protocol */
147 int fullHttpReply; /* True for full HTTP reply. False for CGI reply */
148 Th_Interp *interp; /* The TH1 interpreter */
 
149 FILE *httpIn; /* Accept HTTP input from here */
150 FILE *httpOut; /* Send HTTP output here */
151 int xlinkClusterOnly; /* Set when cloning. Only process clusters */
152 int fTimeFormat; /* 1 for UTC. 2 for localtime. 0 not yet selected */
153 int *aCommitFile; /* Array of files to be committed */
154
--- src/main.c
+++ src/main.c
@@ -130,11 +130,11 @@
130 int fSqlPrint; /* True if -sqlprint flag is present */
131 int fQuiet; /* True if -quiet flag is present */
132 int fHttpTrace; /* Trace outbound HTTP requests */
133 int fSystemTrace; /* Trace calls to fossil_system(), --systemtrace */
134 int fSshTrace; /* Trace the SSH setup traffic */
135 int fNoSync; /* Do not do an autosync ever. --nosync */
136 char *zPath; /* Name of webpage being served */
137 char *zExtra; /* Extra path information past the webpage name */
138 char *zBaseURL; /* Full text of the URL being served */
139 char *zTop; /* Parent directory of zPath */
140 const char *zContentType; /* The content type of the input HTTP request */
@@ -144,10 +144,11 @@
144 Blob cgiIn; /* Input to an xfer www method */
145 int cgiOutput; /* Write error and status messages to CGI */
146 int xferPanic; /* Write error messages in XFER protocol */
147 int fullHttpReply; /* True for full HTTP reply. False for CGI reply */
148 Th_Interp *interp; /* The TH1 interpreter */
149 char *th1Setup; /* The TH1 post-creation setup script, if any */
150 FILE *httpIn; /* Accept HTTP input from here */
151 FILE *httpOut; /* Send HTTP output here */
152 int xlinkClusterOnly; /* Set when cloning. Only process clusters */
153 int fTimeFormat; /* 1 for UTC. 2 for localtime. 0 not yet selected */
154 int *aCommitFile; /* Array of files to be committed */
155
+83 -8
--- src/th_main.c
+++ src/th_main.c
@@ -77,10 +77,28 @@
7777
if( argc!=2 ){
7878
return Th_WrongNumArgs(interp, "enable_output BOOLEAN");
7979
}
8080
return Th_ToInt(interp, argv[1], argl[1], &enableOutput);
8181
}
82
+
83
+/*
84
+** Return a name for a TH1 return code.
85
+*/
86
+const char *Th_ReturnCodeName(int rc){
87
+ static char zRc[32];
88
+ switch( rc ){
89
+ case TH_OK: return "TH_OK";
90
+ case TH_ERROR: return "TH_ERROR";
91
+ case TH_BREAK: return "TH_BREAK";
92
+ case TH_RETURN: return "TH_RETURN";
93
+ case TH_CONTINUE: return "TH_CONTINUE";
94
+ default: {
95
+ sqlite3_snprintf(sizeof(zRc),zRc,"return code %d",rc);
96
+ }
97
+ }
98
+ return zRc;
99
+}
82100
83101
/*
84102
** Send text to the appropriate output: Either to the console
85103
** or to the CGI reply buffer.
86104
*/
@@ -98,10 +116,19 @@
98116
fflush(stdout);
99117
}
100118
if( encode ) free((char*)z);
101119
}
102120
}
121
+
122
+static void sendError(const char *z, int n, int forceCgi){
123
+ if( forceCgi || g.cgiOutput ){
124
+ sendText("<hr><p class=\"thmainError\">", -1, 0);
125
+ }
126
+ sendText("ERROR: ", -1, 0);
127
+ sendText((char*)z, n, 1);
128
+ sendText(forceCgi || g.cgiOutput ? "</p>" : "\n", -1, 0);
129
+}
103130
104131
/*
105132
** TH command: puts STRING
106133
** TH command: html STRING
107134
**
@@ -510,11 +537,12 @@
510537
** Make sure the interpreter has been initialized. Initialize it if
511538
** it has not been already.
512539
**
513540
** The interpreter is stored in the g.interp global variable.
514541
*/
515
-void Th_FossilInit(void){
542
+void Th_FossilInit(int needConfig, int forceSetup){
543
+ int wasInit = 0;
516544
static struct _Command {
517545
const char *zName;
518546
Th_CommandProc xProc;
519547
void *pContext;
520548
} aCommand[] = {
@@ -532,40 +560,89 @@
532560
{"repository", repositoryCmd, 0},
533561
{"utime", utimeCmd, 0},
534562
{"stime", stimeCmd, 0},
535563
{0, 0, 0}
536564
};
565
+ if( needConfig ){
566
+ /*
567
+ ** This function uses several settings which may be defined in the
568
+ ** repository and/or the global configuration. Since the caller
569
+ ** passed a non-zero value for the needConfig parameter, make sure
570
+ ** the necessary database connections are open prior to continuing.
571
+ */
572
+ db_find_and_open_repository(OPEN_OK_NOT_FOUND, 0);
573
+ db_open_config(0);
574
+ }
537575
if( g.interp==0 ){
538576
int i;
539577
g.interp = Th_CreateInterp(&vtab);
540578
th_register_language(g.interp); /* Basic scripting commands. */
541579
#ifdef FOSSIL_ENABLE_TCL
542580
if( getenv("TH1_ENABLE_TCL")!=0 || db_get_boolean("tcl", 0) ){
543
- g.tcl.setup = db_get("tcl-setup", 0); /* Grab optional setup script. */
581
+ if( !g.tcl.setup ){
582
+ g.tcl.setup = db_get("tcl-setup", 0); /* Grab Tcl setup script. */
583
+ }
544584
th_register_tcl(g.interp, &g.tcl); /* Tcl integration commands. */
545585
}
546586
#endif
547587
for(i=0; i<sizeof(aCommand)/sizeof(aCommand[0]); i++){
548588
if ( !aCommand[i].zName || !aCommand[i].xProc ) continue;
549589
Th_CreateCommand(g.interp, aCommand[i].zName, aCommand[i].xProc,
550590
aCommand[i].pContext, 0);
551591
}
592
+ }else{
593
+ wasInit = 1;
594
+ }
595
+ if( forceSetup || !wasInit ){
596
+ int rc = TH_OK;
597
+ if( !g.th1Setup ){
598
+ g.th1Setup = db_get("th1-setup", 0); /* Grab TH1 setup script. */
599
+ }
600
+ if( g.th1Setup ){
601
+ rc = Th_Eval(g.interp, 0, g.th1Setup, -1);
602
+ if( rc==TH_ERROR ){
603
+ int nResult = 0;
604
+ char *zResult = (char*)Th_GetResult(g.interp, &nResult);
605
+ sendError(zResult, nResult, 0);
606
+ }
607
+ }
608
+ if( g.thTrace ){
609
+ Th_Trace("th1-setup {%h} => %h<br />\n", g.th1Setup,
610
+ Th_ReturnCodeName(rc));
611
+ }
552612
}
553613
}
554614
555615
/*
556616
** Store a string value in a variable in the interpreter.
557617
*/
558618
void Th_Store(const char *zName, const char *zValue){
559
- Th_FossilInit();
619
+ Th_FossilInit(0, 0);
560620
if( zValue ){
561621
if( g.thTrace ){
562622
Th_Trace("set %h {%h}<br />\n", zName, zValue);
563623
}
564624
Th_SetVar(g.interp, zName, -1, zValue, strlen(zValue));
565625
}
566626
}
627
+
628
+/*
629
+** Store an integer value in a variable in the interpreter.
630
+*/
631
+void Th_StoreInt(const char *zName, int iValue){
632
+ Blob value;
633
+ char *zValue;
634
+ Th_FossilInit(0, 0);
635
+ blob_zero(&value);
636
+ blob_appendf(&value, "%d", iValue);
637
+ zValue = blob_str(&value);
638
+ if( g.thTrace ){
639
+ Th_Trace("set %h {%h}<br />\n", zName, zValue);
640
+ }
641
+ Th_SetVar(g.interp, zName, -1, zValue, strlen(zValue));
642
+ blob_reset(&value);
643
+}
567644
568645
/*
569646
** Unset a variable.
570647
*/
571648
void Th_Unstore(const char *zName){
@@ -578,11 +655,11 @@
578655
** Retrieve a string value from the interpreter. If no such
579656
** variable exists, return NULL.
580657
*/
581658
char *Th_Fetch(const char *zName, int *pSize){
582659
int rc;
583
- Th_FossilInit();
660
+ Th_FossilInit(0, 0);
584661
rc = Th_GetVar(g.interp, (char*)zName, -1);
585662
if( rc==TH_OK ){
586663
return (char*)Th_GetResult(g.interp, pSize);
587664
}else{
588665
return 0;
@@ -658,11 +735,11 @@
658735
int Th_Render(const char *z){
659736
int i = 0;
660737
int n;
661738
int rc = TH_OK;
662739
char *zResult;
663
- Th_FossilInit();
740
+ Th_FossilInit(0, 0);
664741
while( z[i] ){
665742
if( z[i]=='$' && (n = validVarName(&z[i+1]))>0 ){
666743
const char *zVar;
667744
int nVar;
668745
int encode = 1;
@@ -694,14 +771,12 @@
694771
}else{
695772
i++;
696773
}
697774
}
698775
if( rc==TH_ERROR ){
699
- sendText("<hr><p class=\"thmainError\">ERROR: ", -1, 0);
700776
zResult = (char*)Th_GetResult(g.interp, &n);
701
- sendText((char*)zResult, n, 1);
702
- sendText("</p>", -1, 0);
777
+ sendError(zResult, n, 1);
703778
}else{
704779
sendText(z, i, 0);
705780
}
706781
return rc;
707782
}
708783
--- src/th_main.c
+++ src/th_main.c
@@ -77,10 +77,28 @@
77 if( argc!=2 ){
78 return Th_WrongNumArgs(interp, "enable_output BOOLEAN");
79 }
80 return Th_ToInt(interp, argv[1], argl[1], &enableOutput);
81 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
82
83 /*
84 ** Send text to the appropriate output: Either to the console
85 ** or to the CGI reply buffer.
86 */
@@ -98,10 +116,19 @@
98 fflush(stdout);
99 }
100 if( encode ) free((char*)z);
101 }
102 }
 
 
 
 
 
 
 
 
 
103
104 /*
105 ** TH command: puts STRING
106 ** TH command: html STRING
107 **
@@ -510,11 +537,12 @@
510 ** Make sure the interpreter has been initialized. Initialize it if
511 ** it has not been already.
512 **
513 ** The interpreter is stored in the g.interp global variable.
514 */
515 void Th_FossilInit(void){
 
516 static struct _Command {
517 const char *zName;
518 Th_CommandProc xProc;
519 void *pContext;
520 } aCommand[] = {
@@ -532,40 +560,89 @@
532 {"repository", repositoryCmd, 0},
533 {"utime", utimeCmd, 0},
534 {"stime", stimeCmd, 0},
535 {0, 0, 0}
536 };
 
 
 
 
 
 
 
 
 
 
537 if( g.interp==0 ){
538 int i;
539 g.interp = Th_CreateInterp(&vtab);
540 th_register_language(g.interp); /* Basic scripting commands. */
541 #ifdef FOSSIL_ENABLE_TCL
542 if( getenv("TH1_ENABLE_TCL")!=0 || db_get_boolean("tcl", 0) ){
543 g.tcl.setup = db_get("tcl-setup", 0); /* Grab optional setup script. */
 
 
544 th_register_tcl(g.interp, &g.tcl); /* Tcl integration commands. */
545 }
546 #endif
547 for(i=0; i<sizeof(aCommand)/sizeof(aCommand[0]); i++){
548 if ( !aCommand[i].zName || !aCommand[i].xProc ) continue;
549 Th_CreateCommand(g.interp, aCommand[i].zName, aCommand[i].xProc,
550 aCommand[i].pContext, 0);
551 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
552 }
553 }
554
555 /*
556 ** Store a string value in a variable in the interpreter.
557 */
558 void Th_Store(const char *zName, const char *zValue){
559 Th_FossilInit();
560 if( zValue ){
561 if( g.thTrace ){
562 Th_Trace("set %h {%h}<br />\n", zName, zValue);
563 }
564 Th_SetVar(g.interp, zName, -1, zValue, strlen(zValue));
565 }
566 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
567
568 /*
569 ** Unset a variable.
570 */
571 void Th_Unstore(const char *zName){
@@ -578,11 +655,11 @@
578 ** Retrieve a string value from the interpreter. If no such
579 ** variable exists, return NULL.
580 */
581 char *Th_Fetch(const char *zName, int *pSize){
582 int rc;
583 Th_FossilInit();
584 rc = Th_GetVar(g.interp, (char*)zName, -1);
585 if( rc==TH_OK ){
586 return (char*)Th_GetResult(g.interp, pSize);
587 }else{
588 return 0;
@@ -658,11 +735,11 @@
658 int Th_Render(const char *z){
659 int i = 0;
660 int n;
661 int rc = TH_OK;
662 char *zResult;
663 Th_FossilInit();
664 while( z[i] ){
665 if( z[i]=='$' && (n = validVarName(&z[i+1]))>0 ){
666 const char *zVar;
667 int nVar;
668 int encode = 1;
@@ -694,14 +771,12 @@
694 }else{
695 i++;
696 }
697 }
698 if( rc==TH_ERROR ){
699 sendText("<hr><p class=\"thmainError\">ERROR: ", -1, 0);
700 zResult = (char*)Th_GetResult(g.interp, &n);
701 sendText((char*)zResult, n, 1);
702 sendText("</p>", -1, 0);
703 }else{
704 sendText(z, i, 0);
705 }
706 return rc;
707 }
708
--- src/th_main.c
+++ src/th_main.c
@@ -77,10 +77,28 @@
77 if( argc!=2 ){
78 return Th_WrongNumArgs(interp, "enable_output BOOLEAN");
79 }
80 return Th_ToInt(interp, argv[1], argl[1], &enableOutput);
81 }
82
83 /*
84 ** Return a name for a TH1 return code.
85 */
86 const char *Th_ReturnCodeName(int rc){
87 static char zRc[32];
88 switch( rc ){
89 case TH_OK: return "TH_OK";
90 case TH_ERROR: return "TH_ERROR";
91 case TH_BREAK: return "TH_BREAK";
92 case TH_RETURN: return "TH_RETURN";
93 case TH_CONTINUE: return "TH_CONTINUE";
94 default: {
95 sqlite3_snprintf(sizeof(zRc),zRc,"return code %d",rc);
96 }
97 }
98 return zRc;
99 }
100
101 /*
102 ** Send text to the appropriate output: Either to the console
103 ** or to the CGI reply buffer.
104 */
@@ -98,10 +116,19 @@
116 fflush(stdout);
117 }
118 if( encode ) free((char*)z);
119 }
120 }
121
122 static void sendError(const char *z, int n, int forceCgi){
123 if( forceCgi || g.cgiOutput ){
124 sendText("<hr><p class=\"thmainError\">", -1, 0);
125 }
126 sendText("ERROR: ", -1, 0);
127 sendText((char*)z, n, 1);
128 sendText(forceCgi || g.cgiOutput ? "</p>" : "\n", -1, 0);
129 }
130
131 /*
132 ** TH command: puts STRING
133 ** TH command: html STRING
134 **
@@ -510,11 +537,12 @@
537 ** Make sure the interpreter has been initialized. Initialize it if
538 ** it has not been already.
539 **
540 ** The interpreter is stored in the g.interp global variable.
541 */
542 void Th_FossilInit(int needConfig, int forceSetup){
543 int wasInit = 0;
544 static struct _Command {
545 const char *zName;
546 Th_CommandProc xProc;
547 void *pContext;
548 } aCommand[] = {
@@ -532,40 +560,89 @@
560 {"repository", repositoryCmd, 0},
561 {"utime", utimeCmd, 0},
562 {"stime", stimeCmd, 0},
563 {0, 0, 0}
564 };
565 if( needConfig ){
566 /*
567 ** This function uses several settings which may be defined in the
568 ** repository and/or the global configuration. Since the caller
569 ** passed a non-zero value for the needConfig parameter, make sure
570 ** the necessary database connections are open prior to continuing.
571 */
572 db_find_and_open_repository(OPEN_OK_NOT_FOUND, 0);
573 db_open_config(0);
574 }
575 if( g.interp==0 ){
576 int i;
577 g.interp = Th_CreateInterp(&vtab);
578 th_register_language(g.interp); /* Basic scripting commands. */
579 #ifdef FOSSIL_ENABLE_TCL
580 if( getenv("TH1_ENABLE_TCL")!=0 || db_get_boolean("tcl", 0) ){
581 if( !g.tcl.setup ){
582 g.tcl.setup = db_get("tcl-setup", 0); /* Grab Tcl setup script. */
583 }
584 th_register_tcl(g.interp, &g.tcl); /* Tcl integration commands. */
585 }
586 #endif
587 for(i=0; i<sizeof(aCommand)/sizeof(aCommand[0]); i++){
588 if ( !aCommand[i].zName || !aCommand[i].xProc ) continue;
589 Th_CreateCommand(g.interp, aCommand[i].zName, aCommand[i].xProc,
590 aCommand[i].pContext, 0);
591 }
592 }else{
593 wasInit = 1;
594 }
595 if( forceSetup || !wasInit ){
596 int rc = TH_OK;
597 if( !g.th1Setup ){
598 g.th1Setup = db_get("th1-setup", 0); /* Grab TH1 setup script. */
599 }
600 if( g.th1Setup ){
601 rc = Th_Eval(g.interp, 0, g.th1Setup, -1);
602 if( rc==TH_ERROR ){
603 int nResult = 0;
604 char *zResult = (char*)Th_GetResult(g.interp, &nResult);
605 sendError(zResult, nResult, 0);
606 }
607 }
608 if( g.thTrace ){
609 Th_Trace("th1-setup {%h} => %h<br />\n", g.th1Setup,
610 Th_ReturnCodeName(rc));
611 }
612 }
613 }
614
615 /*
616 ** Store a string value in a variable in the interpreter.
617 */
618 void Th_Store(const char *zName, const char *zValue){
619 Th_FossilInit(0, 0);
620 if( zValue ){
621 if( g.thTrace ){
622 Th_Trace("set %h {%h}<br />\n", zName, zValue);
623 }
624 Th_SetVar(g.interp, zName, -1, zValue, strlen(zValue));
625 }
626 }
627
628 /*
629 ** Store an integer value in a variable in the interpreter.
630 */
631 void Th_StoreInt(const char *zName, int iValue){
632 Blob value;
633 char *zValue;
634 Th_FossilInit(0, 0);
635 blob_zero(&value);
636 blob_appendf(&value, "%d", iValue);
637 zValue = blob_str(&value);
638 if( g.thTrace ){
639 Th_Trace("set %h {%h}<br />\n", zName, zValue);
640 }
641 Th_SetVar(g.interp, zName, -1, zValue, strlen(zValue));
642 blob_reset(&value);
643 }
644
645 /*
646 ** Unset a variable.
647 */
648 void Th_Unstore(const char *zName){
@@ -578,11 +655,11 @@
655 ** Retrieve a string value from the interpreter. If no such
656 ** variable exists, return NULL.
657 */
658 char *Th_Fetch(const char *zName, int *pSize){
659 int rc;
660 Th_FossilInit(0, 0);
661 rc = Th_GetVar(g.interp, (char*)zName, -1);
662 if( rc==TH_OK ){
663 return (char*)Th_GetResult(g.interp, pSize);
664 }else{
665 return 0;
@@ -658,11 +735,11 @@
735 int Th_Render(const char *z){
736 int i = 0;
737 int n;
738 int rc = TH_OK;
739 char *zResult;
740 Th_FossilInit(0, 0);
741 while( z[i] ){
742 if( z[i]=='$' && (n = validVarName(&z[i+1]))>0 ){
743 const char *zVar;
744 int nVar;
745 int encode = 1;
@@ -694,14 +771,12 @@
771 }else{
772 i++;
773 }
774 }
775 if( rc==TH_ERROR ){
 
776 zResult = (char*)Th_GetResult(g.interp, &n);
777 sendError(zResult, n, 1);
 
778 }else{
779 sendText(z, i, 0);
780 }
781 return rc;
782 }
783
+2 -2
--- src/tkt.c
+++ src/tkt.c
@@ -238,21 +238,21 @@
238238
/*
239239
** Create the subscript interpreter and load the "common" code.
240240
*/
241241
void ticket_init(void){
242242
const char *zConfig;
243
- Th_FossilInit();
243
+ Th_FossilInit(0, 0);
244244
zConfig = ticket_common_code();
245245
Th_Eval(g.interp, 0, zConfig, -1);
246246
}
247247
248248
/*
249249
** Create the subscript interpreter and load the "change" code.
250250
*/
251251
int ticket_change(void){
252252
const char *zConfig;
253
- Th_FossilInit();
253
+ Th_FossilInit(0, 0);
254254
zConfig = ticket_change_code();
255255
return Th_Eval(g.interp, 0, zConfig, -1);
256256
}
257257
258258
/*
259259
--- src/tkt.c
+++ src/tkt.c
@@ -238,21 +238,21 @@
238 /*
239 ** Create the subscript interpreter and load the "common" code.
240 */
241 void ticket_init(void){
242 const char *zConfig;
243 Th_FossilInit();
244 zConfig = ticket_common_code();
245 Th_Eval(g.interp, 0, zConfig, -1);
246 }
247
248 /*
249 ** Create the subscript interpreter and load the "change" code.
250 */
251 int ticket_change(void){
252 const char *zConfig;
253 Th_FossilInit();
254 zConfig = ticket_change_code();
255 return Th_Eval(g.interp, 0, zConfig, -1);
256 }
257
258 /*
259
--- src/tkt.c
+++ src/tkt.c
@@ -238,21 +238,21 @@
238 /*
239 ** Create the subscript interpreter and load the "common" code.
240 */
241 void ticket_init(void){
242 const char *zConfig;
243 Th_FossilInit(0, 0);
244 zConfig = ticket_common_code();
245 Th_Eval(g.interp, 0, zConfig, -1);
246 }
247
248 /*
249 ** Create the subscript interpreter and load the "change" code.
250 */
251 int ticket_change(void){
252 const char *zConfig;
253 Th_FossilInit(0, 0);
254 zConfig = ticket_change_code();
255 return Th_Eval(g.interp, 0, zConfig, -1);
256 }
257
258 /*
259
+1 -1
--- src/xfer.c
+++ src/xfer.c
@@ -800,11 +800,11 @@
800800
*/
801801
static int run_script(const char *zScript){
802802
if( !zScript ){
803803
return TH_OK; /* No script, return success. */
804804
}
805
- Th_FossilInit(); /* Make sure TH1 is ready. */
805
+ Th_FossilInit(0, 0); /* Make sure TH1 is ready. */
806806
return Th_Eval(g.interp, 0, zScript, -1);
807807
}
808808
809809
/*
810810
** Run the pre-transfer TH1 script, if any, and returns the return code.
811811
--- src/xfer.c
+++ src/xfer.c
@@ -800,11 +800,11 @@
800 */
801 static int run_script(const char *zScript){
802 if( !zScript ){
803 return TH_OK; /* No script, return success. */
804 }
805 Th_FossilInit(); /* Make sure TH1 is ready. */
806 return Th_Eval(g.interp, 0, zScript, -1);
807 }
808
809 /*
810 ** Run the pre-transfer TH1 script, if any, and returns the return code.
811
--- src/xfer.c
+++ src/xfer.c
@@ -800,11 +800,11 @@
800 */
801 static int run_script(const char *zScript){
802 if( !zScript ){
803 return TH_OK; /* No script, return success. */
804 }
805 Th_FossilInit(0, 0); /* Make sure TH1 is ready. */
806 return Th_Eval(g.interp, 0, zScript, -1);
807 }
808
809 /*
810 ** Run the pre-transfer TH1 script, if any, and returns the return code.
811

Keyboard Shortcuts

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