Fossil SCM

Add new globalState command to TH1, with tests.

mistachkin 2014-07-24 03:12 trunk
Commit 995173d05138837af9de5ed5bde4d708999566e8
2 files changed +133 -63 +83
+133 -63
--- src/th_main.c
+++ src/th_main.c
@@ -145,14 +145,14 @@
145145
**
146146
** Escape all characters of STRING which have special meaning in URI
147147
** components. Return a new string result.
148148
*/
149149
static int httpizeCmd(
150
- Th_Interp *interp,
151
- void *p,
152
- int argc,
153
- const char **argv,
150
+ Th_Interp *interp,
151
+ void *p,
152
+ int argc,
153
+ const char **argv,
154154
int *argl
155155
){
156156
char *zOut;
157157
if( argc!=2 ){
158158
return Th_WrongNumArgs(interp, "httpize STRING");
@@ -172,14 +172,14 @@
172172
** TH1 command: enable_output BOOLEAN
173173
**
174174
** Enable or disable the puts and hputs commands.
175175
*/
176176
static int enableOutputCmd(
177
- Th_Interp *interp,
178
- void *p,
179
- int argc,
180
- const char **argv,
177
+ Th_Interp *interp,
178
+ void *p,
179
+ int argc,
180
+ const char **argv,
181181
int *argl
182182
){
183183
int rc;
184184
if( argc<2 || argc>3 ){
185185
return Th_WrongNumArgs(interp, "enable_output [LABEL] BOOLEAN");
@@ -245,17 +245,17 @@
245245
246246
/*
247247
** TH1 command: puts STRING
248248
** TH1 command: html STRING
249249
**
250
-** Output STRING escaped for HTML (html) or unchanged (puts).
250
+** Output STRING escaped for HTML (html) or unchanged (puts).
251251
*/
252252
static int putsCmd(
253
- Th_Interp *interp,
254
- void *pConvert,
255
- int argc,
256
- const char **argv,
253
+ Th_Interp *interp,
254
+ void *pConvert,
255
+ int argc,
256
+ const char **argv,
257257
int *argl
258258
){
259259
if( argc!=2 ){
260260
return Th_WrongNumArgs(interp, "puts STRING");
261261
}
@@ -267,14 +267,14 @@
267267
** TH1 command: wiki STRING
268268
**
269269
** Render the input string as wiki.
270270
*/
271271
static int wikiCmd(
272
- Th_Interp *interp,
273
- void *p,
274
- int argc,
275
- const char **argv,
272
+ Th_Interp *interp,
273
+ void *p,
274
+ int argc,
275
+ const char **argv,
276276
int *argl
277277
){
278278
int flags = WIKI_INLINE | WIKI_NOBADLINKS | *(unsigned int*)p;
279279
if( argc!=2 ){
280280
return Th_WrongNumArgs(interp, "wiki STRING");
@@ -293,14 +293,14 @@
293293
**
294294
** Escape all characters of STRING which have special meaning in HTML.
295295
** Return a new string result.
296296
*/
297297
static int htmlizeCmd(
298
- Th_Interp *interp,
299
- void *p,
300
- int argc,
301
- const char **argv,
298
+ Th_Interp *interp,
299
+ void *p,
300
+ int argc,
301
+ const char **argv,
302302
int *argl
303303
){
304304
char *zOut;
305305
if( argc!=2 ){
306306
return Th_WrongNumArgs(interp, "htmlize STRING");
@@ -317,14 +317,14 @@
317317
** Return a string which is the current time and date. If the
318318
** -local option is used, the date appears using localtime instead
319319
** of UTC.
320320
*/
321321
static int dateCmd(
322
- Th_Interp *interp,
323
- void *p,
324
- int argc,
325
- const char **argv,
322
+ Th_Interp *interp,
323
+ void *p,
324
+ int argc,
325
+ const char **argv,
326326
int *argl
327327
){
328328
char *zOut;
329329
if( argc>=2 && argl[1]==6 && memcmp(argv[1],"-local",6)==0 ){
330330
zOut = db_text("??", "SELECT datetime('now'%s)", timeline_utc());
@@ -340,14 +340,14 @@
340340
** TH1 command: hascap STRING...
341341
**
342342
** Return true if the user has all of the capabilities listed in STRING.
343343
*/
344344
static int hascapCmd(
345
- Th_Interp *interp,
346
- void *p,
347
- int argc,
348
- const char **argv,
345
+ Th_Interp *interp,
346
+ void *p,
347
+ int argc,
348
+ const char **argv,
349349
int *argl
350350
){
351351
int rc = 0, i;
352352
if( argc<2 ){
353353
return Th_WrongNumArgs(interp, "hascap STRING ...");
@@ -377,14 +377,14 @@
377377
** "json" = FOSSIL_ENABLE_JSON
378378
** "markdown" = FOSSIL_ENABLE_MARKDOWN
379379
**
380380
*/
381381
static int hasfeatureCmd(
382
- Th_Interp *interp,
383
- void *p,
384
- int argc,
385
- const char **argv,
382
+ Th_Interp *interp,
383
+ void *p,
384
+ int argc,
385
+ const char **argv,
386386
int *argl
387387
){
388388
int rc = 0;
389389
char const * zArg;
390390
if( argc!=2 ){
@@ -475,14 +475,14 @@
475475
** TH1 command: anycap STRING
476476
**
477477
** Return true if the user has any one of the capabilities listed in STRING.
478478
*/
479479
static int anycapCmd(
480
- Th_Interp *interp,
481
- void *p,
482
- int argc,
483
- const char **argv,
480
+ Th_Interp *interp,
481
+ void *p,
482
+ int argc,
483
+ const char **argv,
484484
int *argl
485485
){
486486
int rc = 0;
487487
int i;
488488
if( argc!=2 ){
@@ -508,13 +508,13 @@
508508
** If NUMLINES is greater than one then the display is a listbox
509509
** with the number of lines given.
510510
*/
511511
static int comboboxCmd(
512512
Th_Interp *interp,
513
- void *p,
514
- int argc,
515
- const char **argv,
513
+ void *p,
514
+ int argc,
515
+ const char **argv,
516516
int *argl
517517
){
518518
if( argc!=4 ){
519519
return Th_WrongNumArgs(interp, "combobox NAME TEXT-LIST NUMLINES");
520520
}
@@ -539,11 +539,11 @@
539539
sendText(z, -1, 0);
540540
free(z);
541541
blob_reset(&name);
542542
for(i=0; i<nElem; i++){
543543
zH = htmlize((char*)azElem[i], aszElem[i]);
544
- if( zValue && aszElem[i]==nValue
544
+ if( zValue && aszElem[i]==nValue
545545
&& memcmp(zValue, azElem[i], nValue)==0 ){
546546
z = mprintf("<option value=\"%s\" selected=\"selected\">%s</option>",
547547
zH, zH);
548548
}else{
549549
z = mprintf("<option value=\"%s\">%s</option>", zH, zH);
@@ -564,13 +564,13 @@
564564
** Return one more than the number of \n characters in STRING. But
565565
** never return less than MIN or more than MAX.
566566
*/
567567
static int linecntCmd(
568568
Th_Interp *interp,
569
- void *p,
570
- int argc,
571
- const char **argv,
569
+ void *p,
570
+ int argc,
571
+ const char **argv,
572572
int *argl
573573
){
574574
const char *z;
575575
int size, n, i;
576576
int iMin, iMax;
@@ -600,13 +600,13 @@
600600
** string if one is not currently open. Optionally, it will attempt to open
601601
** the repository if the boolean argument is non-zero.
602602
*/
603603
static int repositoryCmd(
604604
Th_Interp *interp,
605
- void *p,
606
- int argc,
607
- const char **argv,
605
+ void *p,
606
+ int argc,
607
+ const char **argv,
608608
int *argl
609609
){
610610
if( argc!=1 && argc!=2 ){
611611
return Th_WrongNumArgs(interp, "repository ?BOOLEAN?");
612612
}
@@ -669,10 +669,79 @@
669669
Th_Trace("%s", argv[1]);
670670
}
671671
Th_SetResult(interp, 0, 0);
672672
return TH_OK;
673673
}
674
+
675
+/*
676
+** TH1 command: globalState NAME ?DEFAULT?
677
+**
678
+** Returns a string containing the value of the specified global state
679
+** variable -OR- the specified default value. Currently, the supported
680
+** items are:
681
+**
682
+** "checkout" = The active local checkout directory, if any.
683
+** "configuration" = The active configuration database file name,
684
+** if any.
685
+** "executable" = The fully qualified executable file name.
686
+** "log" = The error log file name, if any.
687
+** "repository" = The active local repository file name, if
688
+** any.
689
+** "top" = The base path for the active server instance,
690
+** if applicable.
691
+** "user" = The active user name, if any.
692
+** "vfs" = The SQLite VFS in use, if overridden.
693
+**
694
+** Attempts to query for unsupported global state variables will result
695
+** in a script error. Additional global state variables may be exposed
696
+** in the future.
697
+**
698
+** See also: checkout, repository, setting
699
+*/
700
+static int globalStateCmd(
701
+ Th_Interp *interp,
702
+ void *p,
703
+ int argc,
704
+ const char **argv,
705
+ int *argl
706
+){
707
+ const char *zDefault = 0;
708
+ if( argc!=2 && argc!=3 ){
709
+ return Th_WrongNumArgs(interp, "globalState NAME ?DEFAULT?");
710
+ }
711
+ if( argc==3 ){
712
+ zDefault = argv[2];
713
+ }
714
+ if( fossil_strnicmp(argv[1], "checkout\0", 9)==0 ){
715
+ Th_SetResult(interp, g.zLocalRoot ? g.zLocalRoot : zDefault, -1);
716
+ return TH_OK;
717
+ }else if( fossil_strnicmp(argv[1], "configuration\0", 14)==0 ){
718
+ Th_SetResult(interp, g.zConfigDbName ? g.zConfigDbName : zDefault, -1);
719
+ return TH_OK;
720
+ }else if( fossil_strnicmp(argv[1], "executable\0", 11)==0 ){
721
+ Th_SetResult(interp, g.nameOfExe ? g.nameOfExe : zDefault, -1);
722
+ return TH_OK;
723
+ }else if( fossil_strnicmp(argv[1], "log\0", 4)==0 ){
724
+ Th_SetResult(interp, g.zErrlog ? g.zErrlog : zDefault, -1);
725
+ return TH_OK;
726
+ }else if( fossil_strnicmp(argv[1], "repository\0", 11)==0 ){
727
+ Th_SetResult(interp, g.zRepositoryName ? g.zRepositoryName : zDefault, -1);
728
+ return TH_OK;
729
+ }else if( fossil_strnicmp(argv[1], "top\0", 4)==0 ){
730
+ Th_SetResult(interp, g.zTop ? g.zTop : zDefault, -1);
731
+ return TH_OK;
732
+ }else if( fossil_strnicmp(argv[1], "user\0", 5)==0 ){
733
+ Th_SetResult(interp, g.zLogin ? g.zLogin : zDefault, -1);
734
+ return TH_OK;
735
+ }else if( fossil_strnicmp(argv[1], "vfs\0", 4)==0 ){
736
+ Th_SetResult(interp, g.zVfsName ? g.zVfsName : zDefault, -1);
737
+ return TH_OK;
738
+ }else{
739
+ Th_ErrorMessage(interp, "unsupported global state:", argv[1], argl[1]);
740
+ return TH_ERROR;
741
+ }
742
+}
674743
675744
/*
676745
** TH1 command: getParameter NAME ?DEFAULT?
677746
**
678747
** Return the value of the specified query parameter or the specified default
@@ -855,11 +924,11 @@
855924
getrusage(RUSAGE_SELF, &s);
856925
if( piUser ){
857926
*piUser = ((sqlite3_uint64)s.ru_utime.tv_sec)*1000000 + s.ru_utime.tv_usec;
858927
}
859928
if( piKernel ){
860
- *piKernel =
929
+ *piKernel =
861930
((sqlite3_uint64)s.ru_stime.tv_sec)*1000000 + s.ru_stime.tv_usec;
862931
}
863932
#endif
864933
}
865934
@@ -869,13 +938,13 @@
869938
** Return the number of microseconds of CPU time consumed by the current
870939
** process in user space.
871940
*/
872941
static int utimeCmd(
873942
Th_Interp *interp,
874
- void *p,
875
- int argc,
876
- const char **argv,
943
+ void *p,
944
+ int argc,
945
+ const char **argv,
877946
int *argl
878947
){
879948
sqlite3_uint64 x;
880949
char zUTime[50];
881950
getCpuTimes(&x, 0);
@@ -890,13 +959,13 @@
890959
** Return the number of microseconds of CPU time consumed by the current
891960
** process in system space.
892961
*/
893962
static int stimeCmd(
894963
Th_Interp *interp,
895
- void *p,
896
- int argc,
897
- const char **argv,
964
+ void *p,
965
+ int argc,
966
+ const char **argv,
898967
int *argl
899968
){
900969
sqlite3_uint64 x;
901970
char zUTime[50];
902971
getCpuTimes(0, &x);
@@ -907,18 +976,18 @@
907976
908977
909978
/*
910979
** TH1 command: randhex N
911980
**
912
-** Return N*2 random hexadecimal digits with N<50. If N is omitted,
981
+** Return N*2 random hexadecimal digits with N<50. If N is omitted,
913982
** use a value of 10.
914983
*/
915984
static int randhexCmd(
916985
Th_Interp *interp,
917
- void *p,
918
- int argc,
919
- const char **argv,
986
+ void *p,
987
+ int argc,
988
+ const char **argv,
920989
int *argl
921990
){
922991
int n;
923992
unsigned char aRand[50];
924993
unsigned char zOut[100];
@@ -950,13 +1019,13 @@
9501019
** "var". Result values are stored in variables with the column name prior
9511020
** to each invocation of CODE.
9521021
*/
9531022
static int queryCmd(
9541023
Th_Interp *interp,
955
- void *p,
956
- int argc,
957
- const char **argv,
1024
+ void *p,
1025
+ int argc,
1026
+ const char **argv,
9581027
int *argl
9591028
){
9601029
sqlite3_stmt *pStmt;
9611030
int rc;
9621031
const char *zSql;
@@ -1016,11 +1085,11 @@
10161085
rc = sqlite3_finalize(pStmt);
10171086
if( rc!=SQLITE_OK ){
10181087
Th_ErrorMessage(interp, "SQL error: ", sqlite3_errmsg(g.db), -1);
10191088
return TH_ERROR;
10201089
}
1021
- }
1090
+ }
10221091
return res;
10231092
}
10241093
10251094
/*
10261095
** TH1 command: setting name
@@ -1290,10 +1359,11 @@
12901359
{"combobox", comboboxCmd, 0},
12911360
{"date", dateCmd, 0},
12921361
{"decorate", wikiCmd, (void*)&aFlags[2]},
12931362
{"enable_output", enableOutputCmd, 0},
12941363
{"getParameter", getParameterCmd, 0},
1364
+ {"globalState", globalStateCmd, 0},
12951365
{"httpize", httpizeCmd, 0},
12961366
{"hascap", hascapCmd, 0},
12971367
{"hasfeature", hasfeatureCmd, 0},
12981368
{"html", putsCmd, (void*)&aFlags[0]},
12991369
{"htmlize", htmlizeCmd, 0},
@@ -1691,11 +1761,11 @@
16911761
}
16921762
#endif
16931763
16941764
/*
16951765
** The z[] input contains text mixed with TH1 scripts.
1696
-** The TH1 scripts are contained within <th1>...</th1>.
1766
+** The TH1 scripts are contained within <th1>...</th1>.
16971767
** TH1 variables are $aaa or $<aaa>. The first form of
16981768
** variable is literal. The second is run through htmlize
16991769
** before being inserted.
17001770
**
17011771
** This routine processes the template and writes the results
17021772
--- src/th_main.c
+++ src/th_main.c
@@ -145,14 +145,14 @@
145 **
146 ** Escape all characters of STRING which have special meaning in URI
147 ** components. Return a new string result.
148 */
149 static int httpizeCmd(
150 Th_Interp *interp,
151 void *p,
152 int argc,
153 const char **argv,
154 int *argl
155 ){
156 char *zOut;
157 if( argc!=2 ){
158 return Th_WrongNumArgs(interp, "httpize STRING");
@@ -172,14 +172,14 @@
172 ** TH1 command: enable_output BOOLEAN
173 **
174 ** Enable or disable the puts and hputs commands.
175 */
176 static int enableOutputCmd(
177 Th_Interp *interp,
178 void *p,
179 int argc,
180 const char **argv,
181 int *argl
182 ){
183 int rc;
184 if( argc<2 || argc>3 ){
185 return Th_WrongNumArgs(interp, "enable_output [LABEL] BOOLEAN");
@@ -245,17 +245,17 @@
245
246 /*
247 ** TH1 command: puts STRING
248 ** TH1 command: html STRING
249 **
250 ** Output STRING escaped for HTML (html) or unchanged (puts).
251 */
252 static int putsCmd(
253 Th_Interp *interp,
254 void *pConvert,
255 int argc,
256 const char **argv,
257 int *argl
258 ){
259 if( argc!=2 ){
260 return Th_WrongNumArgs(interp, "puts STRING");
261 }
@@ -267,14 +267,14 @@
267 ** TH1 command: wiki STRING
268 **
269 ** Render the input string as wiki.
270 */
271 static int wikiCmd(
272 Th_Interp *interp,
273 void *p,
274 int argc,
275 const char **argv,
276 int *argl
277 ){
278 int flags = WIKI_INLINE | WIKI_NOBADLINKS | *(unsigned int*)p;
279 if( argc!=2 ){
280 return Th_WrongNumArgs(interp, "wiki STRING");
@@ -293,14 +293,14 @@
293 **
294 ** Escape all characters of STRING which have special meaning in HTML.
295 ** Return a new string result.
296 */
297 static int htmlizeCmd(
298 Th_Interp *interp,
299 void *p,
300 int argc,
301 const char **argv,
302 int *argl
303 ){
304 char *zOut;
305 if( argc!=2 ){
306 return Th_WrongNumArgs(interp, "htmlize STRING");
@@ -317,14 +317,14 @@
317 ** Return a string which is the current time and date. If the
318 ** -local option is used, the date appears using localtime instead
319 ** of UTC.
320 */
321 static int dateCmd(
322 Th_Interp *interp,
323 void *p,
324 int argc,
325 const char **argv,
326 int *argl
327 ){
328 char *zOut;
329 if( argc>=2 && argl[1]==6 && memcmp(argv[1],"-local",6)==0 ){
330 zOut = db_text("??", "SELECT datetime('now'%s)", timeline_utc());
@@ -340,14 +340,14 @@
340 ** TH1 command: hascap STRING...
341 **
342 ** Return true if the user has all of the capabilities listed in STRING.
343 */
344 static int hascapCmd(
345 Th_Interp *interp,
346 void *p,
347 int argc,
348 const char **argv,
349 int *argl
350 ){
351 int rc = 0, i;
352 if( argc<2 ){
353 return Th_WrongNumArgs(interp, "hascap STRING ...");
@@ -377,14 +377,14 @@
377 ** "json" = FOSSIL_ENABLE_JSON
378 ** "markdown" = FOSSIL_ENABLE_MARKDOWN
379 **
380 */
381 static int hasfeatureCmd(
382 Th_Interp *interp,
383 void *p,
384 int argc,
385 const char **argv,
386 int *argl
387 ){
388 int rc = 0;
389 char const * zArg;
390 if( argc!=2 ){
@@ -475,14 +475,14 @@
475 ** TH1 command: anycap STRING
476 **
477 ** Return true if the user has any one of the capabilities listed in STRING.
478 */
479 static int anycapCmd(
480 Th_Interp *interp,
481 void *p,
482 int argc,
483 const char **argv,
484 int *argl
485 ){
486 int rc = 0;
487 int i;
488 if( argc!=2 ){
@@ -508,13 +508,13 @@
508 ** If NUMLINES is greater than one then the display is a listbox
509 ** with the number of lines given.
510 */
511 static int comboboxCmd(
512 Th_Interp *interp,
513 void *p,
514 int argc,
515 const char **argv,
516 int *argl
517 ){
518 if( argc!=4 ){
519 return Th_WrongNumArgs(interp, "combobox NAME TEXT-LIST NUMLINES");
520 }
@@ -539,11 +539,11 @@
539 sendText(z, -1, 0);
540 free(z);
541 blob_reset(&name);
542 for(i=0; i<nElem; i++){
543 zH = htmlize((char*)azElem[i], aszElem[i]);
544 if( zValue && aszElem[i]==nValue
545 && memcmp(zValue, azElem[i], nValue)==0 ){
546 z = mprintf("<option value=\"%s\" selected=\"selected\">%s</option>",
547 zH, zH);
548 }else{
549 z = mprintf("<option value=\"%s\">%s</option>", zH, zH);
@@ -564,13 +564,13 @@
564 ** Return one more than the number of \n characters in STRING. But
565 ** never return less than MIN or more than MAX.
566 */
567 static int linecntCmd(
568 Th_Interp *interp,
569 void *p,
570 int argc,
571 const char **argv,
572 int *argl
573 ){
574 const char *z;
575 int size, n, i;
576 int iMin, iMax;
@@ -600,13 +600,13 @@
600 ** string if one is not currently open. Optionally, it will attempt to open
601 ** the repository if the boolean argument is non-zero.
602 */
603 static int repositoryCmd(
604 Th_Interp *interp,
605 void *p,
606 int argc,
607 const char **argv,
608 int *argl
609 ){
610 if( argc!=1 && argc!=2 ){
611 return Th_WrongNumArgs(interp, "repository ?BOOLEAN?");
612 }
@@ -669,10 +669,79 @@
669 Th_Trace("%s", argv[1]);
670 }
671 Th_SetResult(interp, 0, 0);
672 return TH_OK;
673 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
674
675 /*
676 ** TH1 command: getParameter NAME ?DEFAULT?
677 **
678 ** Return the value of the specified query parameter or the specified default
@@ -855,11 +924,11 @@
855 getrusage(RUSAGE_SELF, &s);
856 if( piUser ){
857 *piUser = ((sqlite3_uint64)s.ru_utime.tv_sec)*1000000 + s.ru_utime.tv_usec;
858 }
859 if( piKernel ){
860 *piKernel =
861 ((sqlite3_uint64)s.ru_stime.tv_sec)*1000000 + s.ru_stime.tv_usec;
862 }
863 #endif
864 }
865
@@ -869,13 +938,13 @@
869 ** Return the number of microseconds of CPU time consumed by the current
870 ** process in user space.
871 */
872 static int utimeCmd(
873 Th_Interp *interp,
874 void *p,
875 int argc,
876 const char **argv,
877 int *argl
878 ){
879 sqlite3_uint64 x;
880 char zUTime[50];
881 getCpuTimes(&x, 0);
@@ -890,13 +959,13 @@
890 ** Return the number of microseconds of CPU time consumed by the current
891 ** process in system space.
892 */
893 static int stimeCmd(
894 Th_Interp *interp,
895 void *p,
896 int argc,
897 const char **argv,
898 int *argl
899 ){
900 sqlite3_uint64 x;
901 char zUTime[50];
902 getCpuTimes(0, &x);
@@ -907,18 +976,18 @@
907
908
909 /*
910 ** TH1 command: randhex N
911 **
912 ** Return N*2 random hexadecimal digits with N<50. If N is omitted,
913 ** use a value of 10.
914 */
915 static int randhexCmd(
916 Th_Interp *interp,
917 void *p,
918 int argc,
919 const char **argv,
920 int *argl
921 ){
922 int n;
923 unsigned char aRand[50];
924 unsigned char zOut[100];
@@ -950,13 +1019,13 @@
950 ** "var". Result values are stored in variables with the column name prior
951 ** to each invocation of CODE.
952 */
953 static int queryCmd(
954 Th_Interp *interp,
955 void *p,
956 int argc,
957 const char **argv,
958 int *argl
959 ){
960 sqlite3_stmt *pStmt;
961 int rc;
962 const char *zSql;
@@ -1016,11 +1085,11 @@
1016 rc = sqlite3_finalize(pStmt);
1017 if( rc!=SQLITE_OK ){
1018 Th_ErrorMessage(interp, "SQL error: ", sqlite3_errmsg(g.db), -1);
1019 return TH_ERROR;
1020 }
1021 }
1022 return res;
1023 }
1024
1025 /*
1026 ** TH1 command: setting name
@@ -1290,10 +1359,11 @@
1290 {"combobox", comboboxCmd, 0},
1291 {"date", dateCmd, 0},
1292 {"decorate", wikiCmd, (void*)&aFlags[2]},
1293 {"enable_output", enableOutputCmd, 0},
1294 {"getParameter", getParameterCmd, 0},
 
1295 {"httpize", httpizeCmd, 0},
1296 {"hascap", hascapCmd, 0},
1297 {"hasfeature", hasfeatureCmd, 0},
1298 {"html", putsCmd, (void*)&aFlags[0]},
1299 {"htmlize", htmlizeCmd, 0},
@@ -1691,11 +1761,11 @@
1691 }
1692 #endif
1693
1694 /*
1695 ** The z[] input contains text mixed with TH1 scripts.
1696 ** The TH1 scripts are contained within <th1>...</th1>.
1697 ** TH1 variables are $aaa or $<aaa>. The first form of
1698 ** variable is literal. The second is run through htmlize
1699 ** before being inserted.
1700 **
1701 ** This routine processes the template and writes the results
1702
--- src/th_main.c
+++ src/th_main.c
@@ -145,14 +145,14 @@
145 **
146 ** Escape all characters of STRING which have special meaning in URI
147 ** components. Return a new string result.
148 */
149 static int httpizeCmd(
150 Th_Interp *interp,
151 void *p,
152 int argc,
153 const char **argv,
154 int *argl
155 ){
156 char *zOut;
157 if( argc!=2 ){
158 return Th_WrongNumArgs(interp, "httpize STRING");
@@ -172,14 +172,14 @@
172 ** TH1 command: enable_output BOOLEAN
173 **
174 ** Enable or disable the puts and hputs commands.
175 */
176 static int enableOutputCmd(
177 Th_Interp *interp,
178 void *p,
179 int argc,
180 const char **argv,
181 int *argl
182 ){
183 int rc;
184 if( argc<2 || argc>3 ){
185 return Th_WrongNumArgs(interp, "enable_output [LABEL] BOOLEAN");
@@ -245,17 +245,17 @@
245
246 /*
247 ** TH1 command: puts STRING
248 ** TH1 command: html STRING
249 **
250 ** Output STRING escaped for HTML (html) or unchanged (puts).
251 */
252 static int putsCmd(
253 Th_Interp *interp,
254 void *pConvert,
255 int argc,
256 const char **argv,
257 int *argl
258 ){
259 if( argc!=2 ){
260 return Th_WrongNumArgs(interp, "puts STRING");
261 }
@@ -267,14 +267,14 @@
267 ** TH1 command: wiki STRING
268 **
269 ** Render the input string as wiki.
270 */
271 static int wikiCmd(
272 Th_Interp *interp,
273 void *p,
274 int argc,
275 const char **argv,
276 int *argl
277 ){
278 int flags = WIKI_INLINE | WIKI_NOBADLINKS | *(unsigned int*)p;
279 if( argc!=2 ){
280 return Th_WrongNumArgs(interp, "wiki STRING");
@@ -293,14 +293,14 @@
293 **
294 ** Escape all characters of STRING which have special meaning in HTML.
295 ** Return a new string result.
296 */
297 static int htmlizeCmd(
298 Th_Interp *interp,
299 void *p,
300 int argc,
301 const char **argv,
302 int *argl
303 ){
304 char *zOut;
305 if( argc!=2 ){
306 return Th_WrongNumArgs(interp, "htmlize STRING");
@@ -317,14 +317,14 @@
317 ** Return a string which is the current time and date. If the
318 ** -local option is used, the date appears using localtime instead
319 ** of UTC.
320 */
321 static int dateCmd(
322 Th_Interp *interp,
323 void *p,
324 int argc,
325 const char **argv,
326 int *argl
327 ){
328 char *zOut;
329 if( argc>=2 && argl[1]==6 && memcmp(argv[1],"-local",6)==0 ){
330 zOut = db_text("??", "SELECT datetime('now'%s)", timeline_utc());
@@ -340,14 +340,14 @@
340 ** TH1 command: hascap STRING...
341 **
342 ** Return true if the user has all of the capabilities listed in STRING.
343 */
344 static int hascapCmd(
345 Th_Interp *interp,
346 void *p,
347 int argc,
348 const char **argv,
349 int *argl
350 ){
351 int rc = 0, i;
352 if( argc<2 ){
353 return Th_WrongNumArgs(interp, "hascap STRING ...");
@@ -377,14 +377,14 @@
377 ** "json" = FOSSIL_ENABLE_JSON
378 ** "markdown" = FOSSIL_ENABLE_MARKDOWN
379 **
380 */
381 static int hasfeatureCmd(
382 Th_Interp *interp,
383 void *p,
384 int argc,
385 const char **argv,
386 int *argl
387 ){
388 int rc = 0;
389 char const * zArg;
390 if( argc!=2 ){
@@ -475,14 +475,14 @@
475 ** TH1 command: anycap STRING
476 **
477 ** Return true if the user has any one of the capabilities listed in STRING.
478 */
479 static int anycapCmd(
480 Th_Interp *interp,
481 void *p,
482 int argc,
483 const char **argv,
484 int *argl
485 ){
486 int rc = 0;
487 int i;
488 if( argc!=2 ){
@@ -508,13 +508,13 @@
508 ** If NUMLINES is greater than one then the display is a listbox
509 ** with the number of lines given.
510 */
511 static int comboboxCmd(
512 Th_Interp *interp,
513 void *p,
514 int argc,
515 const char **argv,
516 int *argl
517 ){
518 if( argc!=4 ){
519 return Th_WrongNumArgs(interp, "combobox NAME TEXT-LIST NUMLINES");
520 }
@@ -539,11 +539,11 @@
539 sendText(z, -1, 0);
540 free(z);
541 blob_reset(&name);
542 for(i=0; i<nElem; i++){
543 zH = htmlize((char*)azElem[i], aszElem[i]);
544 if( zValue && aszElem[i]==nValue
545 && memcmp(zValue, azElem[i], nValue)==0 ){
546 z = mprintf("<option value=\"%s\" selected=\"selected\">%s</option>",
547 zH, zH);
548 }else{
549 z = mprintf("<option value=\"%s\">%s</option>", zH, zH);
@@ -564,13 +564,13 @@
564 ** Return one more than the number of \n characters in STRING. But
565 ** never return less than MIN or more than MAX.
566 */
567 static int linecntCmd(
568 Th_Interp *interp,
569 void *p,
570 int argc,
571 const char **argv,
572 int *argl
573 ){
574 const char *z;
575 int size, n, i;
576 int iMin, iMax;
@@ -600,13 +600,13 @@
600 ** string if one is not currently open. Optionally, it will attempt to open
601 ** the repository if the boolean argument is non-zero.
602 */
603 static int repositoryCmd(
604 Th_Interp *interp,
605 void *p,
606 int argc,
607 const char **argv,
608 int *argl
609 ){
610 if( argc!=1 && argc!=2 ){
611 return Th_WrongNumArgs(interp, "repository ?BOOLEAN?");
612 }
@@ -669,10 +669,79 @@
669 Th_Trace("%s", argv[1]);
670 }
671 Th_SetResult(interp, 0, 0);
672 return TH_OK;
673 }
674
675 /*
676 ** TH1 command: globalState NAME ?DEFAULT?
677 **
678 ** Returns a string containing the value of the specified global state
679 ** variable -OR- the specified default value. Currently, the supported
680 ** items are:
681 **
682 ** "checkout" = The active local checkout directory, if any.
683 ** "configuration" = The active configuration database file name,
684 ** if any.
685 ** "executable" = The fully qualified executable file name.
686 ** "log" = The error log file name, if any.
687 ** "repository" = The active local repository file name, if
688 ** any.
689 ** "top" = The base path for the active server instance,
690 ** if applicable.
691 ** "user" = The active user name, if any.
692 ** "vfs" = The SQLite VFS in use, if overridden.
693 **
694 ** Attempts to query for unsupported global state variables will result
695 ** in a script error. Additional global state variables may be exposed
696 ** in the future.
697 **
698 ** See also: checkout, repository, setting
699 */
700 static int globalStateCmd(
701 Th_Interp *interp,
702 void *p,
703 int argc,
704 const char **argv,
705 int *argl
706 ){
707 const char *zDefault = 0;
708 if( argc!=2 && argc!=3 ){
709 return Th_WrongNumArgs(interp, "globalState NAME ?DEFAULT?");
710 }
711 if( argc==3 ){
712 zDefault = argv[2];
713 }
714 if( fossil_strnicmp(argv[1], "checkout\0", 9)==0 ){
715 Th_SetResult(interp, g.zLocalRoot ? g.zLocalRoot : zDefault, -1);
716 return TH_OK;
717 }else if( fossil_strnicmp(argv[1], "configuration\0", 14)==0 ){
718 Th_SetResult(interp, g.zConfigDbName ? g.zConfigDbName : zDefault, -1);
719 return TH_OK;
720 }else if( fossil_strnicmp(argv[1], "executable\0", 11)==0 ){
721 Th_SetResult(interp, g.nameOfExe ? g.nameOfExe : zDefault, -1);
722 return TH_OK;
723 }else if( fossil_strnicmp(argv[1], "log\0", 4)==0 ){
724 Th_SetResult(interp, g.zErrlog ? g.zErrlog : zDefault, -1);
725 return TH_OK;
726 }else if( fossil_strnicmp(argv[1], "repository\0", 11)==0 ){
727 Th_SetResult(interp, g.zRepositoryName ? g.zRepositoryName : zDefault, -1);
728 return TH_OK;
729 }else if( fossil_strnicmp(argv[1], "top\0", 4)==0 ){
730 Th_SetResult(interp, g.zTop ? g.zTop : zDefault, -1);
731 return TH_OK;
732 }else if( fossil_strnicmp(argv[1], "user\0", 5)==0 ){
733 Th_SetResult(interp, g.zLogin ? g.zLogin : zDefault, -1);
734 return TH_OK;
735 }else if( fossil_strnicmp(argv[1], "vfs\0", 4)==0 ){
736 Th_SetResult(interp, g.zVfsName ? g.zVfsName : zDefault, -1);
737 return TH_OK;
738 }else{
739 Th_ErrorMessage(interp, "unsupported global state:", argv[1], argl[1]);
740 return TH_ERROR;
741 }
742 }
743
744 /*
745 ** TH1 command: getParameter NAME ?DEFAULT?
746 **
747 ** Return the value of the specified query parameter or the specified default
@@ -855,11 +924,11 @@
924 getrusage(RUSAGE_SELF, &s);
925 if( piUser ){
926 *piUser = ((sqlite3_uint64)s.ru_utime.tv_sec)*1000000 + s.ru_utime.tv_usec;
927 }
928 if( piKernel ){
929 *piKernel =
930 ((sqlite3_uint64)s.ru_stime.tv_sec)*1000000 + s.ru_stime.tv_usec;
931 }
932 #endif
933 }
934
@@ -869,13 +938,13 @@
938 ** Return the number of microseconds of CPU time consumed by the current
939 ** process in user space.
940 */
941 static int utimeCmd(
942 Th_Interp *interp,
943 void *p,
944 int argc,
945 const char **argv,
946 int *argl
947 ){
948 sqlite3_uint64 x;
949 char zUTime[50];
950 getCpuTimes(&x, 0);
@@ -890,13 +959,13 @@
959 ** Return the number of microseconds of CPU time consumed by the current
960 ** process in system space.
961 */
962 static int stimeCmd(
963 Th_Interp *interp,
964 void *p,
965 int argc,
966 const char **argv,
967 int *argl
968 ){
969 sqlite3_uint64 x;
970 char zUTime[50];
971 getCpuTimes(0, &x);
@@ -907,18 +976,18 @@
976
977
978 /*
979 ** TH1 command: randhex N
980 **
981 ** Return N*2 random hexadecimal digits with N<50. If N is omitted,
982 ** use a value of 10.
983 */
984 static int randhexCmd(
985 Th_Interp *interp,
986 void *p,
987 int argc,
988 const char **argv,
989 int *argl
990 ){
991 int n;
992 unsigned char aRand[50];
993 unsigned char zOut[100];
@@ -950,13 +1019,13 @@
1019 ** "var". Result values are stored in variables with the column name prior
1020 ** to each invocation of CODE.
1021 */
1022 static int queryCmd(
1023 Th_Interp *interp,
1024 void *p,
1025 int argc,
1026 const char **argv,
1027 int *argl
1028 ){
1029 sqlite3_stmt *pStmt;
1030 int rc;
1031 const char *zSql;
@@ -1016,11 +1085,11 @@
1085 rc = sqlite3_finalize(pStmt);
1086 if( rc!=SQLITE_OK ){
1087 Th_ErrorMessage(interp, "SQL error: ", sqlite3_errmsg(g.db), -1);
1088 return TH_ERROR;
1089 }
1090 }
1091 return res;
1092 }
1093
1094 /*
1095 ** TH1 command: setting name
@@ -1290,10 +1359,11 @@
1359 {"combobox", comboboxCmd, 0},
1360 {"date", dateCmd, 0},
1361 {"decorate", wikiCmd, (void*)&aFlags[2]},
1362 {"enable_output", enableOutputCmd, 0},
1363 {"getParameter", getParameterCmd, 0},
1364 {"globalState", globalStateCmd, 0},
1365 {"httpize", httpizeCmd, 0},
1366 {"hascap", hascapCmd, 0},
1367 {"hasfeature", hasfeatureCmd, 0},
1368 {"html", putsCmd, (void*)&aFlags[0]},
1369 {"htmlize", htmlizeCmd, 0},
@@ -1691,11 +1761,11 @@
1761 }
1762 #endif
1763
1764 /*
1765 ** The z[] input contains text mixed with TH1 scripts.
1766 ** The TH1 scripts are contained within <th1>...</th1>.
1767 ** TH1 variables are $aaa or $<aaa>. The first form of
1768 ** variable is literal. The second is run through htmlize
1769 ** before being inserted.
1770 **
1771 ** This routine processes the template and writes the results
1772
--- test/th1.test
+++ test/th1.test
@@ -676,5 +676,88 @@
676676
677677
###############################################################################
678678
679679
fossil test-th-eval --th-open-config "artifact 0000000000 test/th1.test"
680680
test th1-artifact-9 {$RESULT eq {TH_ERROR: artifact not found}}
681
+
682
+###############################################################################
683
+
684
+fossil test-th-eval "globalState checkout"
685
+test th1-globalState-1 {[string length $RESULT] > 0}
686
+
687
+###############################################################################
688
+
689
+fossil test-th-eval "globalState checkout"
690
+test th1-globalState-2 {$RESULT eq [fossil test-th-eval checkout]}
691
+
692
+###############################################################################
693
+
694
+fossil test-th-eval "globalState configuration"
695
+test th1-globalState-3 {[string length $RESULT] == 0}
696
+
697
+###############################################################################
698
+
699
+fossil test-th-eval --th-open-config "globalState configuration"
700
+test th1-globalState-4 {[string length $RESULT] > 0}
701
+
702
+###############################################################################
703
+
704
+fossil test-th-eval "globalState executable"
705
+test th1-globalState-5 {[file rootname [file tail $RESULT]] eq "fossil"}
706
+
707
+###############################################################################
708
+
709
+fossil test-th-eval "globalState log"
710
+test th1-globalState-6 {[string length $RESULT] == 0}
711
+
712
+###############################################################################
713
+
714
+fossil test-th-eval --errorlog foserrors.log "globalState log"
715
+test th1-globalState-7 {$RESULT eq "foserrors.log"}
716
+
717
+###############################################################################
718
+
719
+fossil test-th-eval "globalState repository"
720
+test th1-globalState-8 {[string length $RESULT] > 0}
721
+
722
+###############################################################################
723
+
724
+fossil test-th-eval "globalState repository"
725
+test th1-globalState-9 {$RESULT eq [fossil test-th-eval repository]}
726
+
727
+###############################################################################
728
+
729
+fossil test-th-eval "globalState top"
730
+test th1-globalState-10 {[string length $RESULT] == 0}
731
+
732
+###############################################################################
733
+
734
+fossil test-th-eval "globalState user"
735
+test th1-globalState-11 {[string length $RESULT] == 0}
736
+
737
+###############################################################################
738
+
739
+fossil test-th-eval --user fossil-th1-test "globalState user"
740
+test th1-globalState-12 {$RESULT eq "fossil-th1-test"}
741
+
742
+###############################################################################
743
+
744
+fossil test-th-eval "globalState vfs"
745
+test th1-globalState-13 {[string length $RESULT] == 0}
746
+
747
+###############################################################################
748
+
749
+fossil test-th-eval "globalState vfs"
750
+test th1-globalState-14 {[string length $RESULT] == 0}
751
+
752
+###############################################################################
753
+
754
+if {$tcl_platform(platform) eq "windows"} then {
755
+ set altVfs win32-longpath
756
+} else {
757
+ set altVfs unix-dotfile
758
+}
759
+
760
+###############################################################################
761
+
762
+fossil test-th-eval --vfs $altVfs "globalState vfs"
763
+test th1-globalState-15 {$RESULT eq $altVfs}
681764
--- test/th1.test
+++ test/th1.test
@@ -676,5 +676,88 @@
676
677 ###############################################################################
678
679 fossil test-th-eval --th-open-config "artifact 0000000000 test/th1.test"
680 test th1-artifact-9 {$RESULT eq {TH_ERROR: artifact not found}}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
681
--- test/th1.test
+++ test/th1.test
@@ -676,5 +676,88 @@
676
677 ###############################################################################
678
679 fossil test-th-eval --th-open-config "artifact 0000000000 test/th1.test"
680 test th1-artifact-9 {$RESULT eq {TH_ERROR: artifact not found}}
681
682 ###############################################################################
683
684 fossil test-th-eval "globalState checkout"
685 test th1-globalState-1 {[string length $RESULT] > 0}
686
687 ###############################################################################
688
689 fossil test-th-eval "globalState checkout"
690 test th1-globalState-2 {$RESULT eq [fossil test-th-eval checkout]}
691
692 ###############################################################################
693
694 fossil test-th-eval "globalState configuration"
695 test th1-globalState-3 {[string length $RESULT] == 0}
696
697 ###############################################################################
698
699 fossil test-th-eval --th-open-config "globalState configuration"
700 test th1-globalState-4 {[string length $RESULT] > 0}
701
702 ###############################################################################
703
704 fossil test-th-eval "globalState executable"
705 test th1-globalState-5 {[file rootname [file tail $RESULT]] eq "fossil"}
706
707 ###############################################################################
708
709 fossil test-th-eval "globalState log"
710 test th1-globalState-6 {[string length $RESULT] == 0}
711
712 ###############################################################################
713
714 fossil test-th-eval --errorlog foserrors.log "globalState log"
715 test th1-globalState-7 {$RESULT eq "foserrors.log"}
716
717 ###############################################################################
718
719 fossil test-th-eval "globalState repository"
720 test th1-globalState-8 {[string length $RESULT] > 0}
721
722 ###############################################################################
723
724 fossil test-th-eval "globalState repository"
725 test th1-globalState-9 {$RESULT eq [fossil test-th-eval repository]}
726
727 ###############################################################################
728
729 fossil test-th-eval "globalState top"
730 test th1-globalState-10 {[string length $RESULT] == 0}
731
732 ###############################################################################
733
734 fossil test-th-eval "globalState user"
735 test th1-globalState-11 {[string length $RESULT] == 0}
736
737 ###############################################################################
738
739 fossil test-th-eval --user fossil-th1-test "globalState user"
740 test th1-globalState-12 {$RESULT eq "fossil-th1-test"}
741
742 ###############################################################################
743
744 fossil test-th-eval "globalState vfs"
745 test th1-globalState-13 {[string length $RESULT] == 0}
746
747 ###############################################################################
748
749 fossil test-th-eval "globalState vfs"
750 test th1-globalState-14 {[string length $RESULT] == 0}
751
752 ###############################################################################
753
754 if {$tcl_platform(platform) eq "windows"} then {
755 set altVfs win32-longpath
756 } else {
757 set altVfs unix-dotfile
758 }
759
760 ###############################################################################
761
762 fossil test-th-eval --vfs $altVfs "globalState vfs"
763 test th1-globalState-15 {$RESULT eq $altVfs}
764

Keyboard Shortcuts

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