| | @@ -20,10 +20,23 @@ |
| 20 | 20 | */ |
| 21 | 21 | #include "config.h" |
| 22 | 22 | #include "th_main.h" |
| 23 | 23 | #include "sqlite3.h" |
| 24 | 24 | |
| 25 | +#if INTERFACE |
| 26 | +/* |
| 27 | +** Flag parameters to the Th_FossilInit() routine used to control the |
| 28 | +** interpreter creation and initialization process. |
| 29 | +*/ |
| 30 | +#define TH_INIT_NONE ((u32)0x00000000) /* No flags. */ |
| 31 | +#define TH_INIT_NEED_CONFIG ((u32)0x00000001) /* Open configuration first? */ |
| 32 | +#define TH_INIT_FORCE_TCL ((u32)0x00000002) /* Force Tcl to be enabled? */ |
| 33 | +#define TH_INIT_FORCE_RESET ((u32)0x00000004) /* Force TH commands re-added? */ |
| 34 | +#define TH_INIT_FORCE_SETUP ((u32)0x00000008) /* Force eval of setup script? */ |
| 35 | +#define TH_INIT_DEFAULT (TH_INIT_NONE) /* Default flags. */ |
| 36 | +#endif |
| 37 | + |
| 25 | 38 | /* |
| 26 | 39 | ** Global variable counting the number of outstanding calls to malloc() |
| 27 | 40 | ** made by the th1 implementation. This is used to catch memory leaks |
| 28 | 41 | ** in the interpreter. Obviously, it also means th1 is not threadsafe. |
| 29 | 42 | */ |
| | @@ -810,12 +823,16 @@ |
| 810 | 823 | ** Make sure the interpreter has been initialized. Initialize it if |
| 811 | 824 | ** it has not been already. |
| 812 | 825 | ** |
| 813 | 826 | ** The interpreter is stored in the g.interp global variable. |
| 814 | 827 | */ |
| 815 | | -void Th_FossilInit(int needConfig, int forceSetup){ |
| 828 | +void Th_FossilInit(u32 flags){ |
| 816 | 829 | int wasInit = 0; |
| 830 | + int needConfig = flags & TH_INIT_NEED_CONFIG; |
| 831 | + int forceReset = flags & TH_INIT_FORCE_RESET; |
| 832 | + int forceTcl = flags & TH_INIT_FORCE_TCL; |
| 833 | + int forceSetup = flags & TH_INIT_FORCE_SETUP; |
| 817 | 834 | static unsigned int aFlags[] = { 0, 1, WIKI_LINKSONLY }; |
| 818 | 835 | static struct _Command { |
| 819 | 836 | const char *zName; |
| 820 | 837 | Th_CommandProc xProc; |
| 821 | 838 | void *pContext; |
| | @@ -850,16 +867,18 @@ |
| 850 | 867 | ** the necessary database connections are open prior to continuing. |
| 851 | 868 | */ |
| 852 | 869 | db_find_and_open_repository(OPEN_ANY_SCHEMA | OPEN_OK_NOT_FOUND, 0); |
| 853 | 870 | db_open_config(0); |
| 854 | 871 | } |
| 855 | | - if( g.interp==0 ){ |
| 872 | + if( forceReset || forceTcl || g.interp==0 ){ |
| 856 | 873 | int i; |
| 857 | | - g.interp = Th_CreateInterp(&vtab); |
| 858 | | - th_register_language(g.interp); /* Basic scripting commands. */ |
| 874 | + if( g.interp==0 ) g.interp = Th_CreateInterp(&vtab); |
| 875 | + if( forceReset || g.interp==0 ){ |
| 876 | + th_register_language(g.interp); /* Basic scripting commands. */ |
| 877 | + } |
| 859 | 878 | #ifdef FOSSIL_ENABLE_TCL |
| 860 | | - if( getenv("TH1_ENABLE_TCL")!=0 || db_get_boolean("tcl", 0) ){ |
| 879 | + if( forceTcl || getenv("TH1_ENABLE_TCL")!=0 || db_get_boolean("tcl", 0) ){ |
| 861 | 880 | if( !g.tcl.setup ){ |
| 862 | 881 | g.tcl.setup = db_get("tcl-setup", 0); /* Grab Tcl setup script. */ |
| 863 | 882 | } |
| 864 | 883 | th_register_tcl(g.interp, &g.tcl); /* Tcl integration commands. */ |
| 865 | 884 | } |
| | @@ -894,11 +913,11 @@ |
| 894 | 913 | |
| 895 | 914 | /* |
| 896 | 915 | ** Store a string value in a variable in the interpreter. |
| 897 | 916 | */ |
| 898 | 917 | void Th_Store(const char *zName, const char *zValue){ |
| 899 | | - Th_FossilInit(0, 0); |
| 918 | + Th_FossilInit(TH_INIT_DEFAULT); |
| 900 | 919 | if( zValue ){ |
| 901 | 920 | if( g.thTrace ){ |
| 902 | 921 | Th_Trace("set %h {%h}<br />\n", zName, zValue); |
| 903 | 922 | } |
| 904 | 923 | Th_SetVar(g.interp, zName, -1, zValue, strlen(zValue)); |
| | @@ -909,11 +928,11 @@ |
| 909 | 928 | ** Store an integer value in a variable in the interpreter. |
| 910 | 929 | */ |
| 911 | 930 | void Th_StoreInt(const char *zName, int iValue){ |
| 912 | 931 | Blob value; |
| 913 | 932 | char *zValue; |
| 914 | | - Th_FossilInit(0, 0); |
| 933 | + Th_FossilInit(TH_INIT_DEFAULT); |
| 915 | 934 | blob_zero(&value); |
| 916 | 935 | blob_appendf(&value, "%d", iValue); |
| 917 | 936 | zValue = blob_str(&value); |
| 918 | 937 | if( g.thTrace ){ |
| 919 | 938 | Th_Trace("set %h {%h}<br />\n", zName, zValue); |
| | @@ -935,11 +954,11 @@ |
| 935 | 954 | ** Retrieve a string value from the interpreter. If no such |
| 936 | 955 | ** variable exists, return NULL. |
| 937 | 956 | */ |
| 938 | 957 | char *Th_Fetch(const char *zName, int *pSize){ |
| 939 | 958 | int rc; |
| 940 | | - Th_FossilInit(0, 0); |
| 959 | + Th_FossilInit(TH_INIT_DEFAULT); |
| 941 | 960 | rc = Th_GetVar(g.interp, (char*)zName, -1); |
| 942 | 961 | if( rc==TH_OK ){ |
| 943 | 962 | return (char*)Th_GetResult(g.interp, pSize); |
| 944 | 963 | }else{ |
| 945 | 964 | return 0; |
| | @@ -1015,11 +1034,11 @@ |
| 1015 | 1034 | int Th_Render(const char *z){ |
| 1016 | 1035 | int i = 0; |
| 1017 | 1036 | int n; |
| 1018 | 1037 | int rc = TH_OK; |
| 1019 | 1038 | char *zResult; |
| 1020 | | - Th_FossilInit(0, 0); |
| 1039 | + Th_FossilInit(TH_INIT_DEFAULT); |
| 1021 | 1040 | while( z[i] ){ |
| 1022 | 1041 | if( z[i]=='$' && (n = validVarName(&z[i+1]))>0 ){ |
| 1023 | 1042 | const char *zVar; |
| 1024 | 1043 | int nVar; |
| 1025 | 1044 | int encode = 1; |
| | @@ -1095,11 +1114,11 @@ |
| 1095 | 1114 | db_open_config(0); |
| 1096 | 1115 | } |
| 1097 | 1116 | if( g.argc!=3 ){ |
| 1098 | 1117 | usage("script"); |
| 1099 | 1118 | } |
| 1100 | | - Th_FossilInit(0, 0); |
| 1119 | + Th_FossilInit(TH_INIT_DEFAULT); |
| 1101 | 1120 | rc = Th_Eval(g.interp, 0, g.argv[2], -1); |
| 1102 | 1121 | zRc = Th_ReturnCodeName(rc, 1); |
| 1103 | 1122 | fossil_print("%s%s%s\n", zRc, zRc ? ": " : "", Th_GetResult(g.interp, 0)); |
| 1104 | 1123 | Th_PrintTraceLog(); |
| 1105 | 1124 | } |
| 1106 | 1125 | |