Eskil

Check-in [0ac12f1aa4]
Login

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

Overview
Comment:Allow plugins to yield if Eskil is run in Tcl 8.6 or newer
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 0ac12f1aa4e85606e4a11ed13eb1b2eab852aa3c
User & Date: peter 2015-03-18 23:25:13.463
Context
2015-03-19
22:31
Syntax check caught up with latest changes check-in: 398b37698c user: peter tags: trunk
2015-03-18
23:25
Allow plugins to yield if Eskil is run in Tcl 8.6 or newer check-in: 0ac12f1aa4 user: peter tags: trunk
21:27
Added pdf plugin check-in: bcf8c3d856 user: peter tags: trunk
Changes
Unified Diff Ignore Whitespace Patch
Changes to Changes.




1
2
3
4
5
6
7




2015-03-18
 Added command line flag "-pluginallow" to allow a plugin to run in a standard
 interpreter instead of a safe one.
 Added pdf plugin.

2015-03-17
 Added command line flag "-sep" to set a separator for table-like files
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
2015-03-18
 Allow plugins to yield if Eskil is run in Tcl 8.6 or newer.
 Added swap plugin to exemplify this.

2015-03-18
 Added command line flag "-pluginallow" to allow a plugin to run in a standard
 interpreter instead of a safe one.
 Added pdf plugin.

2015-03-17
 Added command line flag "-sep" to set a separator for table-like files
Changes to htdocs/changes.wiki.
1
2
3
4
5
6
7
8
9
10
11
12


13
14
15
16
17
18
19
<title>Changes</title>

Upcoming changes (not yet released):

  *  Mercurial support for Directory Diff, Commit, Revert and Log.
  *  Plugins can read ::argv to know the given command line.
  *  New plugin for CSV files
  *  Added option -sep, to set a separator that makes input be interpreted
     in a table like manner.
  *  New plugin for PDF files
  *  Added option -pluginallow to run plugins in a standard interpreter instead
     of a safe one. Thus a plugin could use e.g. exec.



Changes in v2.7 (2015-03-09):

  *  Directory Diff support for GIT, Fossil and Subversion.
     Directly browse and compare two revisions.
  *  Plugins in Directory Diff.
  *  Added option -printFont to select font for PDF generation.












>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<title>Changes</title>

Upcoming changes (not yet released):

  *  Mercurial support for Directory Diff, Commit, Revert and Log.
  *  Plugins can read ::argv to know the given command line.
  *  New plugin for CSV files
  *  Added option -sep, to set a separator that makes input be interpreted
     in a table like manner.
  *  New plugin for PDF files
  *  Added option -pluginallow to run plugins in a standard interpreter instead
     of a safe one. Thus a plugin could use e.g. exec.
  *  Allow plugins to yield if Eskil is run in Tcl 8.6 or newer.
     Added swap plugin to exemplify this.

Changes in v2.7 (2015-03-09):

  *  Directory Diff support for GIT, Fossil and Subversion.
     Directly browse and compare two revisions.
  *  Plugins in Directory Diff.
  *  Added option -printFont to select font for PDF generation.
Changes to htdocs/plugins.wiki.
58
59
60
61
62
63
64





65
66
67
68
69
70
71
A plugin may give a result that has a line-by-line correspondence to
the original, in which case the preprocessed data is used for comparing
while the original is used for displaying.  The PreProcess procedure
should return 0 to signify this case.

If the PreProcess procedure returns 1, the processed data is used also for
displaying.






<h1>Directory plugin</h1>

To be used for file comparison in a directory diff, the following procedure
should be defined in the plugin file:

<pre>proc FileCompare {ch1 ch2 info1 info2} {...}</pre>







>
>
>
>
>







58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
A plugin may give a result that has a line-by-line correspondence to
the original, in which case the preprocessed data is used for comparing
while the original is used for displaying.  The PreProcess procedure
should return 0 to signify this case.

If the PreProcess procedure returns 1, the processed data is used also for
displaying.

If Eskil is run with Tcl 8.6 or newer, PreProcess is run as a couroutine
and may yield. The left and right side will then be called alternately
until they return. This allows a plugin to take both sides into account
for decisions if needed.

<h1>Directory plugin</h1>

To be used for file comparison in a directory diff, the following procedure
should be defined in the plugin file:

<pre>proc FileCompare {ch1 ch2 info1 info2} {...}</pre>
Added plugins/swap.tcl.


































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
##Eskil Plugin : Swap sides of contents

# Example file for a plugin.
# A plugin must start exactly like this one.
# The text after : is the summary you can get at the command line

# This plugin swaps data between files. A fairly useless thing.
# This is to test and exemplify how to use yield in a plugin.

# A plugin must define this procedure to do the job.
# side: left or right
# chi:  An input channel for reading the original file.
# cho:  An output channel for writing the processed file.
proc PreProcess {side chi cho} {
    if {[info commands yield] eq ""} {
        puts $cho "Swap plugin must be run with Tcl 8.6 or newer"
        return 1
    }
    # Read all data from both sides
    set ::data($side) [read $chi]
    yield

    # Output data from other side
    if {$side eq "left"} {
        puts $cho $::data(right)
    } else {
        puts $cho $::data(left)
    }

    # Signal that the file after processing should be used both
    # for comparison and for displaying.
    return 1
}
Changes to src/plugin.tcl.
177
178
179
180
181
182
183



184
185




186
187













188
189
190
191
192
193
194
    set chi2 [open $::eskil($top,rightFile) r]
    set cho2 [open $out2 w]
    interp share {} $chi $::eskil($top,plugin)
    interp share {} $cho $::eskil($top,plugin)
    interp share {} $chi2 $::eskil($top,plugin)
    interp share {} $cho2 $::eskil($top,plugin)




    # TODO: When allowing 8.6, do this in coroutines allowing each call
    # to yield and to alternate between them until done




    set usenew1 [$::eskil($top,plugin) eval [list PreProcess left $chi $cho]]
    set usenew2 [$::eskil($top,plugin) eval [list PreProcess right $chi2 $cho2]]














    if {$allow} {
        $::eskil($top,plugin) eval close $chi
        $::eskil($top,plugin) eval close $cho
        $::eskil($top,plugin) eval close $chi2
        $::eskil($top,plugin) eval close $cho2
    } else {







>
>
>
|
|
>
>
>
>
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>







177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
    set chi2 [open $::eskil($top,rightFile) r]
    set cho2 [open $out2 w]
    interp share {} $chi $::eskil($top,plugin)
    interp share {} $cho $::eskil($top,plugin)
    interp share {} $chi2 $::eskil($top,plugin)
    interp share {} $cho2 $::eskil($top,plugin)

    set cmd1 [list PreProcess left $chi $cho]
    set cmd2 [list PreProcess right $chi2 $cho2]
    if {[info commands yield] ne ""} {
        # When in 8.6, this is done in coroutines allowing each call
        # to yield and to alternate between them until done
        set c1 __plugin_cr1$top
        set c2 __plugin_cr2$top
        set cmd1 [linsert $cmd1 0 coroutine $c1]
        set cmd2 [linsert $cmd2 0 coroutine $c2]
        set usenew1 [$::eskil($top,plugin) eval $cmd1]
        set usenew2 [$::eskil($top,plugin) eval $cmd2]
        interp alias {} pnw $::eskil($top,plugin) namespace which
        while {[pnw $c1] ne {} || [pnw $c2] ne {}} {
            if {[pnw $c1] ne {}} {
                set usenew1 [$::eskil($top,plugin) eval $c1]
            }
            if {[pnw $c2] ne {}} {
                set usenew2 [$::eskil($top,plugin) eval $c2]
            }
        }
    } else {
        set usenew1 [$::eskil($top,plugin) eval $cmd1]
        set usenew2 [$::eskil($top,plugin) eval $cmd2]
    }

    if {$allow} {
        $::eskil($top,plugin) eval close $chi
        $::eskil($top,plugin) eval close $cho
        $::eskil($top,plugin) eval close $chi2
        $::eskil($top,plugin) eval close $cho2
    } else {