Fossil SCM

Use built-in Tcl for "diff --tk" implementation if possible. Fallback is to spawn an external "tclsh" as before.

jan.nijtmans 2014-02-04 09:34 trunk
Commit 252aff3e6242f540fdee795d338a25888319eb26
+15 -2
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -908,13 +908,15 @@
908908
909909
/*
910910
** Show diff output in a Tcl/Tk window, in response to the --tk option
911911
** to the diff command.
912912
**
913
-** Steps:
913
+** If fossil has direct access to a Tcl interpreter (either loaded
914
+** dynamically through stubs or linked in statically), we can use it
915
+** directly. Otherwise:
914916
** (1) Write the Tcl/Tk script used for rendering into a temp file.
915
-** (2) Invoke "wish" on the temp file using fossil_system().
917
+** (2) Invoke "tclsh" on the temp file using fossil_system().
916918
** (3) Delete the temp file.
917919
*/
918920
void diff_tk(const char *zSubCmd, int firstArg){
919921
int i;
920922
Blob script;
@@ -944,10 +946,21 @@
944946
blob_appendf(&script, "}\n%s", zDiffScript);
945947
if( zTempFile ){
946948
blob_write_to_file(&script, zTempFile);
947949
fossil_print("To see diff, run: tclsh \"%s\"\n", zTempFile);
948950
}else{
951
+#if defined(FOSSIL_ENABLE_TCL)
952
+ Th_FossilInit(TH_INIT_DEFAULT | TH_INIT_FORCE_TCL);
953
+ if (runTclGui(g.interp, &g.tcl, blob_str(&script)) == TCL_OK){
954
+ blob_reset(&script);
955
+ return;
956
+ }
957
+ /* If evaluation of the script fails, the reason could be that Tk
958
+ * cannot be found by the built-in Tcl, or that Tcl cannot be
959
+ * loaded dynamically (e.g. Win64 Tcl in Win32 fossil). Try again
960
+ * using an external "tclsh", which might work in those two cases. */
961
+#endif
949962
zTempFile = write_blob_to_temp_file(&script);
950963
zCmd = mprintf("tclsh \"%s\"", zTempFile);
951964
fossil_system(zCmd);
952965
file_delete(zTempFile);
953966
fossil_free(zCmd);
954967
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -908,13 +908,15 @@
908
909 /*
910 ** Show diff output in a Tcl/Tk window, in response to the --tk option
911 ** to the diff command.
912 **
913 ** Steps:
 
 
914 ** (1) Write the Tcl/Tk script used for rendering into a temp file.
915 ** (2) Invoke "wish" on the temp file using fossil_system().
916 ** (3) Delete the temp file.
917 */
918 void diff_tk(const char *zSubCmd, int firstArg){
919 int i;
920 Blob script;
@@ -944,10 +946,21 @@
944 blob_appendf(&script, "}\n%s", zDiffScript);
945 if( zTempFile ){
946 blob_write_to_file(&script, zTempFile);
947 fossil_print("To see diff, run: tclsh \"%s\"\n", zTempFile);
948 }else{
 
 
 
 
 
 
 
 
 
 
 
949 zTempFile = write_blob_to_temp_file(&script);
950 zCmd = mprintf("tclsh \"%s\"", zTempFile);
951 fossil_system(zCmd);
952 file_delete(zTempFile);
953 fossil_free(zCmd);
954
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -908,13 +908,15 @@
908
909 /*
910 ** Show diff output in a Tcl/Tk window, in response to the --tk option
911 ** to the diff command.
912 **
913 ** If fossil has direct access to a Tcl interpreter (either loaded
914 ** dynamically through stubs or linked in statically), we can use it
915 ** directly. Otherwise:
916 ** (1) Write the Tcl/Tk script used for rendering into a temp file.
917 ** (2) Invoke "tclsh" on the temp file using fossil_system().
918 ** (3) Delete the temp file.
919 */
920 void diff_tk(const char *zSubCmd, int firstArg){
921 int i;
922 Blob script;
@@ -944,10 +946,21 @@
946 blob_appendf(&script, "}\n%s", zDiffScript);
947 if( zTempFile ){
948 blob_write_to_file(&script, zTempFile);
949 fossil_print("To see diff, run: tclsh \"%s\"\n", zTempFile);
950 }else{
951 #if defined(FOSSIL_ENABLE_TCL)
952 Th_FossilInit(TH_INIT_DEFAULT | TH_INIT_FORCE_TCL);
953 if (runTclGui(g.interp, &g.tcl, blob_str(&script)) == TCL_OK){
954 blob_reset(&script);
955 return;
956 }
957 /* If evaluation of the script fails, the reason could be that Tk
958 * cannot be found by the built-in Tcl, or that Tcl cannot be
959 * loaded dynamically (e.g. Win64 Tcl in Win32 fossil). Try again
960 * using an external "tclsh", which might work in those two cases. */
961 #endif
962 zTempFile = write_blob_to_temp_file(&script);
963 zCmd = mprintf("tclsh \"%s\"", zTempFile);
964 fossil_system(zCmd);
965 file_delete(zTempFile);
966 fossil_free(zCmd);
967
+1
--- src/th.h
+++ src/th.h
@@ -159,10 +159,11 @@
159159
int th_register_testvfs(Th_Interp *interp); /* th_testvfs.c */
160160
161161
#ifdef FOSSIL_ENABLE_TCL
162162
int th_register_tcl(Th_Interp *interp, void *pContext); /* th_tcl.c */
163163
int unloadTcl(Th_Interp *interp, void *pContext); /* th_tcl.c */
164
+int runTclGui(Th_Interp *, void *, const char *); /* th_tcl.c */
164165
#endif
165166
166167
/*
167168
** General purpose hash table from th_lang.c.
168169
*/
169170
--- src/th.h
+++ src/th.h
@@ -159,10 +159,11 @@
159 int th_register_testvfs(Th_Interp *interp); /* th_testvfs.c */
160
161 #ifdef FOSSIL_ENABLE_TCL
162 int th_register_tcl(Th_Interp *interp, void *pContext); /* th_tcl.c */
163 int unloadTcl(Th_Interp *interp, void *pContext); /* th_tcl.c */
 
164 #endif
165
166 /*
167 ** General purpose hash table from th_lang.c.
168 */
169
--- src/th.h
+++ src/th.h
@@ -159,10 +159,11 @@
159 int th_register_testvfs(Th_Interp *interp); /* th_testvfs.c */
160
161 #ifdef FOSSIL_ENABLE_TCL
162 int th_register_tcl(Th_Interp *interp, void *pContext); /* th_tcl.c */
163 int unloadTcl(Th_Interp *interp, void *pContext); /* th_tcl.c */
164 int runTclGui(Th_Interp *, void *, const char *); /* th_tcl.c */
165 #endif
166
167 /*
168 ** General purpose hash table from th_lang.c.
169 */
170
+20
--- src/th_tcl.c
+++ src/th_tcl.c
@@ -766,10 +766,30 @@
766766
}
767767
}
768768
Tcl_DecrRefCount(listPtr);
769769
return rc;
770770
}
771
+
772
+/*
773
+** Run a Tcl script. If the script succeeds, start the main loop until
774
+** there is no more work to be done or the script calls "exit".
775
+*/
776
+int runTclGui(Th_Interp *interp, void *pContext, const char *script){
777
+ struct TclContext *tclContext = (struct TclContext *)pContext;
778
+ int rc;
779
+
780
+ if( createTclInterp(interp, pContext)!=TH_OK ){
781
+ return TH_ERROR;
782
+ }
783
+ rc = Tcl_EvalEx(tclContext->interp, script, -1, TCL_EVAL_GLOBAL);
784
+ if (rc == TCL_OK){
785
+ while (Tcl_DoOneEvent(0)) {
786
+ /* do nothing */
787
+ }
788
+ }
789
+ return rc;
790
+}
771791
772792
/*
773793
** Creates and initializes a Tcl interpreter for use with the specified TH1
774794
** interpreter. Stores the created Tcl interpreter in the Tcl context supplied
775795
** by the caller.
776796
--- src/th_tcl.c
+++ src/th_tcl.c
@@ -766,10 +766,30 @@
766 }
767 }
768 Tcl_DecrRefCount(listPtr);
769 return rc;
770 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
771
772 /*
773 ** Creates and initializes a Tcl interpreter for use with the specified TH1
774 ** interpreter. Stores the created Tcl interpreter in the Tcl context supplied
775 ** by the caller.
776
--- src/th_tcl.c
+++ src/th_tcl.c
@@ -766,10 +766,30 @@
766 }
767 }
768 Tcl_DecrRefCount(listPtr);
769 return rc;
770 }
771
772 /*
773 ** Run a Tcl script. If the script succeeds, start the main loop until
774 ** there is no more work to be done or the script calls "exit".
775 */
776 int runTclGui(Th_Interp *interp, void *pContext, const char *script){
777 struct TclContext *tclContext = (struct TclContext *)pContext;
778 int rc;
779
780 if( createTclInterp(interp, pContext)!=TH_OK ){
781 return TH_ERROR;
782 }
783 rc = Tcl_EvalEx(tclContext->interp, script, -1, TCL_EVAL_GLOBAL);
784 if (rc == TCL_OK){
785 while (Tcl_DoOneEvent(0)) {
786 /* do nothing */
787 }
788 }
789 return rc;
790 }
791
792 /*
793 ** Creates and initializes a Tcl interpreter for use with the specified TH1
794 ** interpreter. Stores the created Tcl interpreter in the Tcl context supplied
795 ** by the caller.
796

Keyboard Shortcuts

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