Fossil SCM

Begin adding a TH1 script trace mechanism actived by the --th_trace option on the "server" and "ui" commands. The implementation is incomplete, but the plane is landing....

drh 2008-10-24 18:23 trunk
Commit f55c6a1b62ccda5987d8273290443ce329edd958
+6
--- src/main.c
+++ src/main.c
@@ -124,10 +124,12 @@
124124
/* For defense against Cross-site Request Forgery attacks */
125125
char zCsrfToken[12]; /* Value of the anti-CSRF token */
126126
int okCsrf; /* Anti-CSRF token is present and valid */
127127
128128
FILE *fDebug; /* Write debug information here, if the file exists */
129
+ int thTrace; /* True to enable TH1 debugging output */
130
+ Blob thLog; /* Text of the TH1 debugging output */
129131
130132
/* Storage for the aux() and/or option() SQL function arguments */
131133
int nAux; /* Number of distinct aux() or option() values */
132134
const char *azAuxName[MX_AUX]; /* Name of each aux() or option() value */
133135
char *azAuxParam[MX_AUX]; /* Param of each aux() or option() value */
@@ -706,10 +708,14 @@
706708
int iPort;
707709
const char *zPort;
708710
char *zBrowser;
709711
char *zBrowserCmd = 0;
710712
713
+ g.thTrace = find_option("th_trace", 0, 0)!=0;
714
+ if( g.thTrace ){
715
+ blob_zero(&g.thLog);
716
+ }
711717
zPort = find_option("port", "P", 1);
712718
if( zPort ){
713719
iPort = atoi(zPort);
714720
}else{
715721
iPort = 8080;
716722
--- src/main.c
+++ src/main.c
@@ -124,10 +124,12 @@
124 /* For defense against Cross-site Request Forgery attacks */
125 char zCsrfToken[12]; /* Value of the anti-CSRF token */
126 int okCsrf; /* Anti-CSRF token is present and valid */
127
128 FILE *fDebug; /* Write debug information here, if the file exists */
 
 
129
130 /* Storage for the aux() and/or option() SQL function arguments */
131 int nAux; /* Number of distinct aux() or option() values */
132 const char *azAuxName[MX_AUX]; /* Name of each aux() or option() value */
133 char *azAuxParam[MX_AUX]; /* Param of each aux() or option() value */
@@ -706,10 +708,14 @@
706 int iPort;
707 const char *zPort;
708 char *zBrowser;
709 char *zBrowserCmd = 0;
710
 
 
 
 
711 zPort = find_option("port", "P", 1);
712 if( zPort ){
713 iPort = atoi(zPort);
714 }else{
715 iPort = 8080;
716
--- src/main.c
+++ src/main.c
@@ -124,10 +124,12 @@
124 /* For defense against Cross-site Request Forgery attacks */
125 char zCsrfToken[12]; /* Value of the anti-CSRF token */
126 int okCsrf; /* Anti-CSRF token is present and valid */
127
128 FILE *fDebug; /* Write debug information here, if the file exists */
129 int thTrace; /* True to enable TH1 debugging output */
130 Blob thLog; /* Text of the TH1 debugging output */
131
132 /* Storage for the aux() and/or option() SQL function arguments */
133 int nAux; /* Number of distinct aux() or option() values */
134 const char *azAuxName[MX_AUX]; /* Name of each aux() or option() value */
135 char *azAuxParam[MX_AUX]; /* Param of each aux() or option() value */
@@ -706,10 +708,14 @@
708 int iPort;
709 const char *zPort;
710 char *zBrowser;
711 char *zBrowserCmd = 0;
712
713 g.thTrace = find_option("th_trace", 0, 0)!=0;
714 if( g.thTrace ){
715 blob_zero(&g.thLog);
716 }
717 zPort = find_option("port", "P", 1);
718 if( zPort ){
719 iPort = atoi(zPort);
720 }else{
721 iPort = 8080;
722
+13
--- src/style.c
+++ src/style.c
@@ -88,10 +88,12 @@
8888
va_start(ap, zTitleFormat);
8989
zTitle = vmprintf(zTitleFormat, ap);
9090
va_end(ap);
9191
9292
cgi_destination(CGI_HEADER);
93
+
94
+ if( g.thTrace ) Th_Trace("BEGIN_HEADER<br />\n", -1);
9395
9496
/* Generate the header up through the main menu */
9597
Th_Store("project_name", db_get("project-name","Unnamed Fossil Project"));
9698
Th_Store("title", zTitle);
9799
Th_Store("baseurl", g.zBaseURL);
@@ -100,11 +102,13 @@
100102
Th_Store("manifest_version", MANIFEST_VERSION);
101103
Th_Store("manifest_date", MANIFEST_DATE);
102104
if( g.zLogin ){
103105
Th_Store("login", g.zLogin);
104106
}
107
+ if( g.thTrace ) Th_Trace("BEGIN_HEADER_SCRIPT<br />\n", -1);
105108
Th_Render(zHeader);
109
+ if( g.thTrace ) Th_Trace("END_HEADER<br />\n", -1);
106110
Th_Unstore("title"); /* Avoid collisions with ticket field names */
107111
cgi_destination(CGI_BODY);
108112
g.cgiPanic = 1;
109113
headerHasBeenGenerated = 1;
110114
}
@@ -141,11 +145,20 @@
141145
142146
/* Put the footer at the bottom of the page.
143147
*/
144148
@ </div>
145149
zFooter = db_get("footer", (char*)zDefaultFooter);
150
+ if( g.thTrace ) Th_Trace("BEGIN_FOOTER<br />\n", -1);
146151
Th_Render(zFooter);
152
+ if( g.thTrace ) Th_Trace("END_FOOTER<br />\n", -1);
153
+
154
+ /* Render trace log if TH1 tracing is enabled. */
155
+ if( g.thTrace ){
156
+ cgi_append_content("<font color=\"red\"><hr>\n", -1);
157
+ cgi_append_content(blob_str(&g.thLog), blob_size(&g.thLog));
158
+ cgi_append_content("</font>\n", -1);
159
+ }
147160
}
148161
149162
/* @-comment: // */
150163
/*
151164
** The default page header.
152165
--- src/style.c
+++ src/style.c
@@ -88,10 +88,12 @@
88 va_start(ap, zTitleFormat);
89 zTitle = vmprintf(zTitleFormat, ap);
90 va_end(ap);
91
92 cgi_destination(CGI_HEADER);
 
 
93
94 /* Generate the header up through the main menu */
95 Th_Store("project_name", db_get("project-name","Unnamed Fossil Project"));
96 Th_Store("title", zTitle);
97 Th_Store("baseurl", g.zBaseURL);
@@ -100,11 +102,13 @@
100 Th_Store("manifest_version", MANIFEST_VERSION);
101 Th_Store("manifest_date", MANIFEST_DATE);
102 if( g.zLogin ){
103 Th_Store("login", g.zLogin);
104 }
 
105 Th_Render(zHeader);
 
106 Th_Unstore("title"); /* Avoid collisions with ticket field names */
107 cgi_destination(CGI_BODY);
108 g.cgiPanic = 1;
109 headerHasBeenGenerated = 1;
110 }
@@ -141,11 +145,20 @@
141
142 /* Put the footer at the bottom of the page.
143 */
144 @ </div>
145 zFooter = db_get("footer", (char*)zDefaultFooter);
 
146 Th_Render(zFooter);
 
 
 
 
 
 
 
 
147 }
148
149 /* @-comment: // */
150 /*
151 ** The default page header.
152
--- src/style.c
+++ src/style.c
@@ -88,10 +88,12 @@
88 va_start(ap, zTitleFormat);
89 zTitle = vmprintf(zTitleFormat, ap);
90 va_end(ap);
91
92 cgi_destination(CGI_HEADER);
93
94 if( g.thTrace ) Th_Trace("BEGIN_HEADER<br />\n", -1);
95
96 /* Generate the header up through the main menu */
97 Th_Store("project_name", db_get("project-name","Unnamed Fossil Project"));
98 Th_Store("title", zTitle);
99 Th_Store("baseurl", g.zBaseURL);
@@ -100,11 +102,13 @@
102 Th_Store("manifest_version", MANIFEST_VERSION);
103 Th_Store("manifest_date", MANIFEST_DATE);
104 if( g.zLogin ){
105 Th_Store("login", g.zLogin);
106 }
107 if( g.thTrace ) Th_Trace("BEGIN_HEADER_SCRIPT<br />\n", -1);
108 Th_Render(zHeader);
109 if( g.thTrace ) Th_Trace("END_HEADER<br />\n", -1);
110 Th_Unstore("title"); /* Avoid collisions with ticket field names */
111 cgi_destination(CGI_BODY);
112 g.cgiPanic = 1;
113 headerHasBeenGenerated = 1;
114 }
@@ -141,11 +145,20 @@
145
146 /* Put the footer at the bottom of the page.
147 */
148 @ </div>
149 zFooter = db_get("footer", (char*)zDefaultFooter);
150 if( g.thTrace ) Th_Trace("BEGIN_FOOTER<br />\n", -1);
151 Th_Render(zFooter);
152 if( g.thTrace ) Th_Trace("END_FOOTER<br />\n", -1);
153
154 /* Render trace log if TH1 tracing is enabled. */
155 if( g.thTrace ){
156 cgi_append_content("<font color=\"red\"><hr>\n", -1);
157 cgi_append_content(blob_str(&g.thLog), blob_size(&g.thLog));
158 cgi_append_content("</font>\n", -1);
159 }
160 }
161
162 /* @-comment: // */
163 /*
164 ** The default page header.
165
+23 -2
--- src/th_main.c
+++ src/th_main.c
@@ -50,10 +50,20 @@
5050
}
5151
free(p);
5252
}
5353
static Th_Vtab vtab = { xMalloc, xFree };
5454
55
+/*
56
+** Generate a TH1 trace message if debugging is enabled.
57
+*/
58
+void Th_Trace(const char *zFormat, ...){
59
+ va_list ap;
60
+ va_start(ap, zFormat);
61
+ blob_vappendf(&g.thLog, zFormat, ap);
62
+ va_end(ap);
63
+}
64
+
5565
5666
/*
5767
** True if output is enabled. False if disabled.
5868
*/
5969
static int enableOutput = 1;
@@ -191,13 +201,18 @@
191201
void *p,
192202
int argc,
193203
const char **argv,
194204
int *argl
195205
){
206
+ int rc;
196207
if( argc!=2 ){
197208
return Th_WrongNumArgs(interp, "hascap STRING");
198209
}
210
+ rc = login_has_capability((char*)argv[1],argl[1]);
211
+ if( g.thTrace ){
212
+ Th_Trace("[hascap %.*h] => %d<br />\n", argl[1], argv[1], rc);
213
+ }
199214
Th_SetResultInt(interp, login_has_capability((char*)argv[1],argl[1]));
200215
return TH_OK;
201216
}
202217
203218
/*
@@ -292,11 +307,14 @@
292307
Th_SetResultInt(interp, n);
293308
return TH_OK;
294309
}
295310
296311
/*
297
-** Make sure the interpreter has been initialized.
312
+** Make sure the interpreter has been initialized. Initialize it if
313
+** it has not been already.
314
+**
315
+** The interpreter is stored in the g.interp global variable.
298316
*/
299317
void Th_FossilInit(void){
300318
static struct _Command {
301319
const char *zName;
302320
Th_CommandProc xProc;
@@ -327,11 +345,14 @@
327345
** Store a string value in a variable in the interpreter.
328346
*/
329347
void Th_Store(const char *zName, const char *zValue){
330348
Th_FossilInit();
331349
if( zValue ){
332
- Th_SetVar(g.interp, (char*)zName, -1, (char*)zValue, strlen(zValue));
350
+ if( g.thTrace ){
351
+ Th_Trace("set %h {%h}<br />\n", zName, zValue);
352
+ }
353
+ Th_SetVar(g.interp, zName, -1, zValue, strlen(zValue));
333354
}
334355
}
335356
336357
/*
337358
** Unset a variable.
338359
--- src/th_main.c
+++ src/th_main.c
@@ -50,10 +50,20 @@
50 }
51 free(p);
52 }
53 static Th_Vtab vtab = { xMalloc, xFree };
54
 
 
 
 
 
 
 
 
 
 
55
56 /*
57 ** True if output is enabled. False if disabled.
58 */
59 static int enableOutput = 1;
@@ -191,13 +201,18 @@
191 void *p,
192 int argc,
193 const char **argv,
194 int *argl
195 ){
 
196 if( argc!=2 ){
197 return Th_WrongNumArgs(interp, "hascap STRING");
198 }
 
 
 
 
199 Th_SetResultInt(interp, login_has_capability((char*)argv[1],argl[1]));
200 return TH_OK;
201 }
202
203 /*
@@ -292,11 +307,14 @@
292 Th_SetResultInt(interp, n);
293 return TH_OK;
294 }
295
296 /*
297 ** Make sure the interpreter has been initialized.
 
 
 
298 */
299 void Th_FossilInit(void){
300 static struct _Command {
301 const char *zName;
302 Th_CommandProc xProc;
@@ -327,11 +345,14 @@
327 ** Store a string value in a variable in the interpreter.
328 */
329 void Th_Store(const char *zName, const char *zValue){
330 Th_FossilInit();
331 if( zValue ){
332 Th_SetVar(g.interp, (char*)zName, -1, (char*)zValue, strlen(zValue));
 
 
 
333 }
334 }
335
336 /*
337 ** Unset a variable.
338
--- src/th_main.c
+++ src/th_main.c
@@ -50,10 +50,20 @@
50 }
51 free(p);
52 }
53 static Th_Vtab vtab = { xMalloc, xFree };
54
55 /*
56 ** Generate a TH1 trace message if debugging is enabled.
57 */
58 void Th_Trace(const char *zFormat, ...){
59 va_list ap;
60 va_start(ap, zFormat);
61 blob_vappendf(&g.thLog, zFormat, ap);
62 va_end(ap);
63 }
64
65
66 /*
67 ** True if output is enabled. False if disabled.
68 */
69 static int enableOutput = 1;
@@ -191,13 +201,18 @@
201 void *p,
202 int argc,
203 const char **argv,
204 int *argl
205 ){
206 int rc;
207 if( argc!=2 ){
208 return Th_WrongNumArgs(interp, "hascap STRING");
209 }
210 rc = login_has_capability((char*)argv[1],argl[1]);
211 if( g.thTrace ){
212 Th_Trace("[hascap %.*h] => %d<br />\n", argl[1], argv[1], rc);
213 }
214 Th_SetResultInt(interp, login_has_capability((char*)argv[1],argl[1]));
215 return TH_OK;
216 }
217
218 /*
@@ -292,11 +307,14 @@
307 Th_SetResultInt(interp, n);
308 return TH_OK;
309 }
310
311 /*
312 ** Make sure the interpreter has been initialized. Initialize it if
313 ** it has not been already.
314 **
315 ** The interpreter is stored in the g.interp global variable.
316 */
317 void Th_FossilInit(void){
318 static struct _Command {
319 const char *zName;
320 Th_CommandProc xProc;
@@ -327,11 +345,14 @@
345 ** Store a string value in a variable in the interpreter.
346 */
347 void Th_Store(const char *zName, const char *zValue){
348 Th_FossilInit();
349 if( zValue ){
350 if( g.thTrace ){
351 Th_Trace("set %h {%h}<br />\n", zName, zValue);
352 }
353 Th_SetVar(g.interp, zName, -1, zValue, strlen(zValue));
354 }
355 }
356
357 /*
358 ** Unset a variable.
359
+29 -19
--- src/tkt.c
+++ src/tkt.c
@@ -330,14 +330,17 @@
330330
"%s/tkthistory/%T", g.zTop, zUuid);
331331
style_submenu_element("Timeline", "Timeline Of This Ticket",
332332
"%s/tkttimeline/%T", g.zTop, zUuid);
333333
}
334334
style_header("View Ticket");
335
+ if( g.thTrace ) Th_Trace("BEGIN_TKTVIEW<br />\n", -1);
335336
ticket_init();
336337
initializeVariablesFromDb();
337338
zScript = ticket_viewpage_code();
339
+ if( g.thTrace ) Th_Trace("BEGIN_TKTVIEW_SCRIPT<br />\n", -1);
338340
Th_Render(zScript);
341
+ if( g.thTrace ) Th_Trace("END_TKTVIEW<br />\n", -1);
339342
style_footer();
340343
}
341344
342345
/*
343346
** TH command: append_field FIELD STRING
@@ -349,20 +352,24 @@
349352
*/
350353
static int appendRemarkCmd(
351354
Th_Interp *interp,
352355
void *p,
353356
int argc,
354
- const unsigned char **argv,
357
+ const char **argv,
355358
int *argl
356359
){
357360
int idx;
358361
359362
if( argc!=3 ){
360363
return Th_WrongNumArgs(interp, "append_field FIELD STRING");
361364
}
365
+ if( g.thTrace ){
366
+ Th_Trace("append_field %#h {%#h}<br />\n",
367
+ argl[1], argv[1], argl[2], argv[2]);
368
+ }
362369
for(idx=0; idx<nField; idx++){
363
- if( strncmp(azField[idx], (const char*)argv[1], argl[1])==0
370
+ if( strncmp(azField[idx], argv[1], argl[1])==0
364371
&& azField[idx][argl[1]]==0 ){
365372
break;
366373
}
367374
}
368375
if( idx>=nField ){
@@ -384,11 +391,11 @@
384391
*/
385392
static int submitTicketCmd(
386393
Th_Interp *interp,
387394
void *pUuid,
388395
int argc,
389
- const unsigned char **argv,
396
+ const char **argv,
390397
int *argl
391398
){
392399
char *zDate;
393400
const char *zUuid;
394401
int i;
@@ -432,24 +439,21 @@
432439
*(const char**)pUuid = zUuid;
433440
blob_appendf(&tktchng, "K %s\n", zUuid);
434441
blob_appendf(&tktchng, "U %F\n", g.zLogin ? g.zLogin : "");
435442
md5sum_blob(&tktchng, &cksum);
436443
blob_appendf(&tktchng, "Z %b\n", &cksum);
437
-
438
- if( strncmp(g.zPath,"debug_",6)==0 ){
439
- @ <hr><pre>
440
- @ %h(blob_str(&tktchng))
441
- @ </pre><hr>
442
- blob_zero(&tktchng);
443
- return TH_OK;
444
- }
445
-
446
- rid = content_put(&tktchng, 0, 0);
447
- if( rid==0 ){
448
- fossil_panic("trouble committing ticket: %s", g.zErrMsg);
449
- }
450
- manifest_crosslink(rid, &tktchng);
444
+ if( g.thTrace ){
445
+ Th_Trace("submit_ticket {\n<blockquote><pre>\n%h\n</pre></blockquote>\n"
446
+ "}<br />\n",
447
+ blob_str(&tktchng));
448
+ }else{
449
+ rid = content_put(&tktchng, 0, 0);
450
+ if( rid==0 ){
451
+ fossil_panic("trouble committing ticket: %s", g.zErrMsg);
452
+ }
453
+ manifest_crosslink(rid, &tktchng);
454
+ }
451455
return TH_RETURN;
452456
}
453457
454458
455459
/*
@@ -472,10 +476,11 @@
472476
if( !g.okNewTkt ){ login_needed(); return; }
473477
if( P("cancel") ){
474478
cgi_redirect("home");
475479
}
476480
style_header("New Ticket");
481
+ if( g.thTrace ) Th_Trace("BEGIN_TKTNEW<br />\n", -1);
477482
ticket_init();
478483
getAllTicketFields();
479484
initializeVariablesFromDb();
480485
initializeVariablesFromCGI();
481486
@ <form method="POST" action="%s(g.zBaseURL)/%s(g.zPath)">
@@ -483,15 +488,17 @@
483488
zScript = ticket_newpage_code();
484489
Th_Store("login", g.zLogin);
485490
Th_Store("date", db_text(0, "SELECT datetime('now')"));
486491
Th_CreateCommand(g.interp, "submit_ticket", submitTicketCmd,
487492
(void*)&zNewUuid, 0);
488
- if( Th_Render(zScript)==TH_RETURN && zNewUuid ){
493
+ if( g.thTrace ) Th_Trace("BEGIN_TKTNEW_SCRIPT<br />\n", -1);
494
+ if( Th_Render(zScript)==TH_RETURN && !g.thTrace && zNewUuid ){
489495
cgi_redirect(mprintf("%s/tktview/%s", g.zBaseURL, zNewUuid));
490496
return;
491497
}
492498
@ </form>
499
+ if( g.thTrace ) Th_Trace("END_TKTVIEW<br />\n", -1);
493500
style_footer();
494501
}
495502
496503
/*
497504
** WEBPAGE: tktedit
@@ -533,10 +540,11 @@
533540
if( nRec>1 ){
534541
@ <font color="red"><b>%d(nRec) tickets begin with: \"%h(zName)\"</b></font>
535542
style_footer();
536543
return;
537544
}
545
+ if( g.thTrace ) Th_Trace("BEGIN_TKTEDIT<br />\n", -1);
538546
ticket_init();
539547
getAllTicketFields();
540548
initializeVariablesFromCGI();
541549
initializeVariablesFromDb();
542550
@ <form method="POST" action="%s(g.zBaseURL)/%s(g.zPath)">
@@ -545,15 +553,17 @@
545553
zScript = ticket_editpage_code();
546554
Th_Store("login", g.zLogin);
547555
Th_Store("date", db_text(0, "SELECT datetime('now')"));
548556
Th_CreateCommand(g.interp, "append_field", appendRemarkCmd, 0, 0);
549557
Th_CreateCommand(g.interp, "submit_ticket", submitTicketCmd, (void*)&zName,0);
550
- if( Th_Render(zScript)==TH_RETURN && zName ){
558
+ if( g.thTrace ) Th_Trace("BEGIN_TKTEDIT_SCRIPT<br />\n", -1);
559
+ if( Th_Render(zScript)==TH_RETURN && !g.thTrace && zName ){
551560
cgi_redirect(mprintf("%s/tktview/%s", g.zBaseURL, zName));
552561
return;
553562
}
554563
@ </form>
564
+ if( g.thTrace ) Th_Trace("BEGIN_TKTEDIT<br />\n", -1);
555565
style_footer();
556566
}
557567
558568
/*
559569
** Check the ticket table schema in zSchema to see if it appears to
560570
--- src/tkt.c
+++ src/tkt.c
@@ -330,14 +330,17 @@
330 "%s/tkthistory/%T", g.zTop, zUuid);
331 style_submenu_element("Timeline", "Timeline Of This Ticket",
332 "%s/tkttimeline/%T", g.zTop, zUuid);
333 }
334 style_header("View Ticket");
 
335 ticket_init();
336 initializeVariablesFromDb();
337 zScript = ticket_viewpage_code();
 
338 Th_Render(zScript);
 
339 style_footer();
340 }
341
342 /*
343 ** TH command: append_field FIELD STRING
@@ -349,20 +352,24 @@
349 */
350 static int appendRemarkCmd(
351 Th_Interp *interp,
352 void *p,
353 int argc,
354 const unsigned char **argv,
355 int *argl
356 ){
357 int idx;
358
359 if( argc!=3 ){
360 return Th_WrongNumArgs(interp, "append_field FIELD STRING");
361 }
 
 
 
 
362 for(idx=0; idx<nField; idx++){
363 if( strncmp(azField[idx], (const char*)argv[1], argl[1])==0
364 && azField[idx][argl[1]]==0 ){
365 break;
366 }
367 }
368 if( idx>=nField ){
@@ -384,11 +391,11 @@
384 */
385 static int submitTicketCmd(
386 Th_Interp *interp,
387 void *pUuid,
388 int argc,
389 const unsigned char **argv,
390 int *argl
391 ){
392 char *zDate;
393 const char *zUuid;
394 int i;
@@ -432,24 +439,21 @@
432 *(const char**)pUuid = zUuid;
433 blob_appendf(&tktchng, "K %s\n", zUuid);
434 blob_appendf(&tktchng, "U %F\n", g.zLogin ? g.zLogin : "");
435 md5sum_blob(&tktchng, &cksum);
436 blob_appendf(&tktchng, "Z %b\n", &cksum);
437
438 if( strncmp(g.zPath,"debug_",6)==0 ){
439 @ <hr><pre>
440 @ %h(blob_str(&tktchng))
441 @ </pre><hr>
442 blob_zero(&tktchng);
443 return TH_OK;
444 }
445
446 rid = content_put(&tktchng, 0, 0);
447 if( rid==0 ){
448 fossil_panic("trouble committing ticket: %s", g.zErrMsg);
449 }
450 manifest_crosslink(rid, &tktchng);
451 return TH_RETURN;
452 }
453
454
455 /*
@@ -472,10 +476,11 @@
472 if( !g.okNewTkt ){ login_needed(); return; }
473 if( P("cancel") ){
474 cgi_redirect("home");
475 }
476 style_header("New Ticket");
 
477 ticket_init();
478 getAllTicketFields();
479 initializeVariablesFromDb();
480 initializeVariablesFromCGI();
481 @ <form method="POST" action="%s(g.zBaseURL)/%s(g.zPath)">
@@ -483,15 +488,17 @@
483 zScript = ticket_newpage_code();
484 Th_Store("login", g.zLogin);
485 Th_Store("date", db_text(0, "SELECT datetime('now')"));
486 Th_CreateCommand(g.interp, "submit_ticket", submitTicketCmd,
487 (void*)&zNewUuid, 0);
488 if( Th_Render(zScript)==TH_RETURN && zNewUuid ){
 
489 cgi_redirect(mprintf("%s/tktview/%s", g.zBaseURL, zNewUuid));
490 return;
491 }
492 @ </form>
 
493 style_footer();
494 }
495
496 /*
497 ** WEBPAGE: tktedit
@@ -533,10 +540,11 @@
533 if( nRec>1 ){
534 @ <font color="red"><b>%d(nRec) tickets begin with: \"%h(zName)\"</b></font>
535 style_footer();
536 return;
537 }
 
538 ticket_init();
539 getAllTicketFields();
540 initializeVariablesFromCGI();
541 initializeVariablesFromDb();
542 @ <form method="POST" action="%s(g.zBaseURL)/%s(g.zPath)">
@@ -545,15 +553,17 @@
545 zScript = ticket_editpage_code();
546 Th_Store("login", g.zLogin);
547 Th_Store("date", db_text(0, "SELECT datetime('now')"));
548 Th_CreateCommand(g.interp, "append_field", appendRemarkCmd, 0, 0);
549 Th_CreateCommand(g.interp, "submit_ticket", submitTicketCmd, (void*)&zName,0);
550 if( Th_Render(zScript)==TH_RETURN && zName ){
 
551 cgi_redirect(mprintf("%s/tktview/%s", g.zBaseURL, zName));
552 return;
553 }
554 @ </form>
 
555 style_footer();
556 }
557
558 /*
559 ** Check the ticket table schema in zSchema to see if it appears to
560
--- src/tkt.c
+++ src/tkt.c
@@ -330,14 +330,17 @@
330 "%s/tkthistory/%T", g.zTop, zUuid);
331 style_submenu_element("Timeline", "Timeline Of This Ticket",
332 "%s/tkttimeline/%T", g.zTop, zUuid);
333 }
334 style_header("View Ticket");
335 if( g.thTrace ) Th_Trace("BEGIN_TKTVIEW<br />\n", -1);
336 ticket_init();
337 initializeVariablesFromDb();
338 zScript = ticket_viewpage_code();
339 if( g.thTrace ) Th_Trace("BEGIN_TKTVIEW_SCRIPT<br />\n", -1);
340 Th_Render(zScript);
341 if( g.thTrace ) Th_Trace("END_TKTVIEW<br />\n", -1);
342 style_footer();
343 }
344
345 /*
346 ** TH command: append_field FIELD STRING
@@ -349,20 +352,24 @@
352 */
353 static int appendRemarkCmd(
354 Th_Interp *interp,
355 void *p,
356 int argc,
357 const char **argv,
358 int *argl
359 ){
360 int idx;
361
362 if( argc!=3 ){
363 return Th_WrongNumArgs(interp, "append_field FIELD STRING");
364 }
365 if( g.thTrace ){
366 Th_Trace("append_field %#h {%#h}<br />\n",
367 argl[1], argv[1], argl[2], argv[2]);
368 }
369 for(idx=0; idx<nField; idx++){
370 if( strncmp(azField[idx], argv[1], argl[1])==0
371 && azField[idx][argl[1]]==0 ){
372 break;
373 }
374 }
375 if( idx>=nField ){
@@ -384,11 +391,11 @@
391 */
392 static int submitTicketCmd(
393 Th_Interp *interp,
394 void *pUuid,
395 int argc,
396 const char **argv,
397 int *argl
398 ){
399 char *zDate;
400 const char *zUuid;
401 int i;
@@ -432,24 +439,21 @@
439 *(const char**)pUuid = zUuid;
440 blob_appendf(&tktchng, "K %s\n", zUuid);
441 blob_appendf(&tktchng, "U %F\n", g.zLogin ? g.zLogin : "");
442 md5sum_blob(&tktchng, &cksum);
443 blob_appendf(&tktchng, "Z %b\n", &cksum);
444 if( g.thTrace ){
445 Th_Trace("submit_ticket {\n<blockquote><pre>\n%h\n</pre></blockquote>\n"
446 "}<br />\n",
447 blob_str(&tktchng));
448 }else{
449 rid = content_put(&tktchng, 0, 0);
450 if( rid==0 ){
451 fossil_panic("trouble committing ticket: %s", g.zErrMsg);
452 }
453 manifest_crosslink(rid, &tktchng);
454 }
 
 
 
455 return TH_RETURN;
456 }
457
458
459 /*
@@ -472,10 +476,11 @@
476 if( !g.okNewTkt ){ login_needed(); return; }
477 if( P("cancel") ){
478 cgi_redirect("home");
479 }
480 style_header("New Ticket");
481 if( g.thTrace ) Th_Trace("BEGIN_TKTNEW<br />\n", -1);
482 ticket_init();
483 getAllTicketFields();
484 initializeVariablesFromDb();
485 initializeVariablesFromCGI();
486 @ <form method="POST" action="%s(g.zBaseURL)/%s(g.zPath)">
@@ -483,15 +488,17 @@
488 zScript = ticket_newpage_code();
489 Th_Store("login", g.zLogin);
490 Th_Store("date", db_text(0, "SELECT datetime('now')"));
491 Th_CreateCommand(g.interp, "submit_ticket", submitTicketCmd,
492 (void*)&zNewUuid, 0);
493 if( g.thTrace ) Th_Trace("BEGIN_TKTNEW_SCRIPT<br />\n", -1);
494 if( Th_Render(zScript)==TH_RETURN && !g.thTrace && zNewUuid ){
495 cgi_redirect(mprintf("%s/tktview/%s", g.zBaseURL, zNewUuid));
496 return;
497 }
498 @ </form>
499 if( g.thTrace ) Th_Trace("END_TKTVIEW<br />\n", -1);
500 style_footer();
501 }
502
503 /*
504 ** WEBPAGE: tktedit
@@ -533,10 +540,11 @@
540 if( nRec>1 ){
541 @ <font color="red"><b>%d(nRec) tickets begin with: \"%h(zName)\"</b></font>
542 style_footer();
543 return;
544 }
545 if( g.thTrace ) Th_Trace("BEGIN_TKTEDIT<br />\n", -1);
546 ticket_init();
547 getAllTicketFields();
548 initializeVariablesFromCGI();
549 initializeVariablesFromDb();
550 @ <form method="POST" action="%s(g.zBaseURL)/%s(g.zPath)">
@@ -545,15 +553,17 @@
553 zScript = ticket_editpage_code();
554 Th_Store("login", g.zLogin);
555 Th_Store("date", db_text(0, "SELECT datetime('now')"));
556 Th_CreateCommand(g.interp, "append_field", appendRemarkCmd, 0, 0);
557 Th_CreateCommand(g.interp, "submit_ticket", submitTicketCmd, (void*)&zName,0);
558 if( g.thTrace ) Th_Trace("BEGIN_TKTEDIT_SCRIPT<br />\n", -1);
559 if( Th_Render(zScript)==TH_RETURN && !g.thTrace && zName ){
560 cgi_redirect(mprintf("%s/tktview/%s", g.zBaseURL, zName));
561 return;
562 }
563 @ </form>
564 if( g.thTrace ) Th_Trace("BEGIN_TKTEDIT<br />\n", -1);
565 style_footer();
566 }
567
568 /*
569 ** Check the ticket table schema in zSchema to see if it appears to
570

Keyboard Shortcuts

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