Fossil

Check-in [f325b2343e]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Cherrypick [252aff3e62] and related clean-ups: Use built-in Tcl for "diff --tk" implementation if possible. Fallback is to spawn an external "tclsh" as before. This makes "fossil diff --tk" work with ActiveState Tcl on Win32 out-of-the-box.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | branch-1.28
Files: files | file ages | folders
SHA1: f325b2343e6a18f85a955683c568cd51c31cae11
User & Date: jan.nijtmans 2014-02-14 13:37:35.359
Context
2014-02-16
21:30
Cherrypick [b4dffdac5e]: Avoid unnecessary no-op write transactions on the server during a pull. Adapt changes.wiki with all candidate cherry-picks so far. check-in: ebac09bcf7 user: jan.nijtmans tags: branch-1.28
2014-02-14
13:37
Cherrypick [252aff3e62] and related clean-ups: Use built-in Tcl for "diff --tk" implementation if possible. Fallback is to spawn an external "tclsh" as before. This makes "fossil diff --tk" work with ActiveState Tcl on Win32 out-of-the-box. check-in: f325b2343e user: jan.nijtmans tags: branch-1.28
12:44
Cherrypick [7b30a7c7ef8977a7]: unbreak win/Makefile.mingw for modified SRCDIR check-in: 7ecb9d25f9 user: jan.nijtmans tags: branch-1.28
2014-02-04
20:52
Give window a chance to finish handling <Destroy> event. check-in: d7b0617cb5 user: jan.nijtmans tags: trunk
20:40
Improve some comments and whitespace. check-in: be267722ce user: mistachkin tags: trunk
20:30
Cleanup use of Tcl integration for launching the Tk diff viewer internally. check-in: fe9990adc7 user: mistachkin tags: trunk
09:34
Use built-in Tcl for "diff --tk" implementation if possible. Fallback is to spawn an external "tclsh" as before. check-in: 252aff3e62 user: jan.nijtmans tags: trunk
2014-02-03
12:39
Make sure that the close-button of tk's "diff" window ends the main-loop in all circumstances. Remove unnecessary space. check-in: c275d8ddbb user: jan.nijtmans tags: trunk
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/diffcmd.c.
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797

798
799
800
801
802
803
804
@       eval $sb set $xview
@     } else {
@       grid remove $sb
@     }
@   }
@   enableSync x
@ }
@ 
@ proc sync-y {first last} {
@   disableSync y
@   foreach c [cols] {
@     $c yview moveto $first
@   }
@   if {$first > 0 || $last < 1} {
@     grid .sby
@     .sby set $first $last
@   } else {
@     grid remove .sby
@   }
@   enableSync y
@ }
@ 
@ wm withdraw .
@ wm title . $CFG(TITLE)
@ wm iconname . $CFG(TITLE)
@ bind . <q> exit

@ bind . <Tab> {cycleDiffs; break}
@ bind . <<PrevWindow>> {cycleDiffs 1; break}
@ bind . <Return> {
@   event generate .files <1>
@   event generate .files <ButtonRelease-1>
@   break
@ }







|


















>







772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
@       eval $sb set $xview
@     } else {
@       grid remove $sb
@     }
@   }
@   enableSync x
@ }
@
@ proc sync-y {first last} {
@   disableSync y
@   foreach c [cols] {
@     $c yview moveto $first
@   }
@   if {$first > 0 || $last < 1} {
@     grid .sby
@     .sby set $first $last
@   } else {
@     grid remove .sby
@   }
@   enableSync y
@ }
@ 
@ wm withdraw .
@ wm title . $CFG(TITLE)
@ wm iconname . $CFG(TITLE)
@ bind . <q> exit
@ bind . <Destroy> {after 0 exit}
@ bind . <Tab> {cycleDiffs; break}
@ bind . <<PrevWindow>> {cycleDiffs 1; break}
@ bind . <Return> {
@   event generate .files <1>
@   event generate .files <ButtonRelease-1>
@   break
@ }
905
906
907
908
909
910
911


912
913
914
915
916
917
918
919
920
921
@ wm deiconify .
;

/*
** Show diff output in a Tcl/Tk window, in response to the --tk option
** to the diff command.
** 


** Steps:
** (1) Write the Tcl/Tk script used for rendering into a temp file.
** (2) Invoke "wish" on the temp file using fossil_system().
** (3) Delete the temp file.
*/
void diff_tk(const char *zSubCmd, int firstArg){
  int i;
  Blob script;
  char *zTempFile = 0;
  char *zCmd;







>
>
|

|







906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
@ wm deiconify .
;

/*
** Show diff output in a Tcl/Tk window, in response to the --tk option
** to the diff command.
** 
** If fossil has direct access to a Tcl interpreter (either loaded
** dynamically through stubs or linked in statically), we can use it
** directly. Otherwise:
** (1) Write the Tcl/Tk script used for rendering into a temp file.
** (2) Invoke "tclsh" on the temp file using fossil_system().
** (3) Delete the temp file.
*/
void diff_tk(const char *zSubCmd, int firstArg){
  int i;
  Blob script;
  char *zTempFile = 0;
  char *zCmd;
941
942
943
944
945
946
947














948
949
950
951
952
953
954
    shell_escape(&script, z);
  }
  blob_appendf(&script, "}\n%s", zDiffScript);
  if( zTempFile ){
    blob_write_to_file(&script, zTempFile);
    fossil_print("To see diff, run: tclsh \"%s\"\n", zTempFile);
  }else{














    zTempFile = write_blob_to_temp_file(&script);
    zCmd = mprintf("tclsh \"%s\"", zTempFile);
    fossil_system(zCmd);
    file_delete(zTempFile);
    fossil_free(zCmd);
  }
  blob_reset(&script);







>
>
>
>
>
>
>
>
>
>
>
>
>
>







944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
    shell_escape(&script, z);
  }
  blob_appendf(&script, "}\n%s", zDiffScript);
  if( zTempFile ){
    blob_write_to_file(&script, zTempFile);
    fossil_print("To see diff, run: tclsh \"%s\"\n", zTempFile);
  }else{
#if defined(FOSSIL_ENABLE_TCL)
    Th_FossilInit(TH_INIT_DEFAULT);
    if( evaluateTclWithEvents(g.interp, &g.tcl, blob_str(&script),
                              blob_size(&script), 1)==TCL_OK ){
      blob_reset(&script);
      return;
    }
    /*
     * If evaluation of the Tcl script fails, the reason may be that Tk
     * could not be found by the loaded Tcl, or that Tcl cannot be loaded
     * dynamically (e.g. x64 Tcl with x86 Fossil).  Therefore, fallback
     * to using the external "tclsh", if available.
     */
#endif
    zTempFile = write_blob_to_temp_file(&script);
    zCmd = mprintf("tclsh \"%s\"", zTempFile);
    fossil_system(zCmd);
    file_delete(zTempFile);
    fossil_free(zCmd);
  }
  blob_reset(&script);
Changes to src/th.h.
155
156
157
158
159
160
161



162
163

164
165
166
167
168
169
170
*/
int th_register_language(Th_Interp *interp);            /* th_lang.c */
int th_register_sqlite(Th_Interp *interp);              /* th_sqlite.c */
int th_register_vfs(Th_Interp *interp);                 /* th_vfs.c */
int th_register_testvfs(Th_Interp *interp);             /* th_testvfs.c */

#ifdef FOSSIL_ENABLE_TCL



int th_register_tcl(Th_Interp *interp, void *pContext); /* th_tcl.c */
int unloadTcl(Th_Interp *interp, void *pContext);       /* th_tcl.c */

#endif

/*
** General purpose hash table from th_lang.c.
*/
typedef struct Th_Hash      Th_Hash;
typedef struct Th_HashEntry Th_HashEntry;







>
>
>
|
|
>







155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
*/
int th_register_language(Th_Interp *interp);            /* th_lang.c */
int th_register_sqlite(Th_Interp *interp);              /* th_sqlite.c */
int th_register_vfs(Th_Interp *interp);                 /* th_vfs.c */
int th_register_testvfs(Th_Interp *interp);             /* th_testvfs.c */

#ifdef FOSSIL_ENABLE_TCL
/*
** Interfaces to the full Tcl core library from "th_tcl.c".
*/
int th_register_tcl(Th_Interp *, void *);
int unloadTcl(Th_Interp *, void *);
int evaluateTclWithEvents(Th_Interp *, void *, const char *, int, int);
#endif

/*
** General purpose hash table from th_lang.c.
*/
typedef struct Th_Hash      Th_Hash;
typedef struct Th_HashEntry Th_HashEntry;
Changes to src/th_tcl.c.
764
765
766
767
768
769
770
































771
772
773
774
775
776
777
    if( !resultObjPtr ){
      rc = TCL_ERROR;
    }
  }
  Tcl_DecrRefCount(listPtr);
  return rc;
}

































/*
** Creates and initializes a Tcl interpreter for use with the specified TH1
** interpreter.  Stores the created Tcl interpreter in the Tcl context supplied
** by the caller.
*/
static int createTclInterp(







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
    if( !resultObjPtr ){
      rc = TCL_ERROR;
    }
  }
  Tcl_DecrRefCount(listPtr);
  return rc;
}

/*
** Evaluate a Tcl script, creating the Tcl interpreter if necessary. If the
** Tcl script succeeds, start a Tcl event loop until there are no more events
** remaining to process -OR- the script calls [exit].  If the bWait argument
** is zero, only process events that are already in the queue; otherwise,
** process events until the script terminates the Tcl event loop.
*/
int evaluateTclWithEvents(
  Th_Interp *interp,
  void *pContext,
  const char *zScript,
  int nScript,
  int bWait
){
  struct TclContext *tclContext = (struct TclContext *)pContext;
  Tcl_Interp *tclInterp;
  int rc;
  int flags = TCL_ALL_EVENTS;

  if( createTclInterp(interp, pContext)!=TH_OK ){
    return TH_ERROR;
  }
  tclInterp = tclContext->interp;
  rc = Tcl_EvalEx(tclInterp, zScript, nScript, TCL_EVAL_GLOBAL);
  if( rc!=TCL_OK ) return rc;
  if( !bWait ) flags |= TCL_DONT_WAIT;
  while( Tcl_DoOneEvent(flags) ){
    /* do nothing */
  }
  return rc;
}

/*
** Creates and initializes a Tcl interpreter for use with the specified TH1
** interpreter.  Stores the created Tcl interpreter in the Tcl context supplied
** by the caller.
*/
static int createTclInterp(