source: tol/tolsh/tolsh.vfs/lib/tcllib1.10/rcs/rcs.tcl @ 8597867d

1941-docker-image-to-testdevel
Last change on this file since 8597867d was 8597867d, checked in by Jorge Pérez <josp.jorge@…>, 16 years ago

closes #976, se incluye tcllib1.10, base64 debe eliminarse del raiz de lib ya que esta incluido en tcllib

git-svn-id: ​https://www.tol-project.org/svn/tolp/trunk@2556 be4846ae-f051-483a-831f-b64e7d08527f

  • Property mode set to 100644
File size: 6.1 KB
RevLine 
[8597867d]1# rcs.tcl --
2#
3#       Utilities for RCS related operations.
4#
5# Copyright (c) 2005 by Colin McCormack <coldstore@users.sourceforge.net>
6# Copyright (c) 2005 by Andreas Kupries <andreas_kupries@users.sourceforge.net>
7#
8# See the file "license.terms" for information on usage and redistribution
9# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
10#
11# RCS: @(#) $Id: rcs.tcl,v 1.4 2005/09/28 04:51:23 andreas_kupries Exp $
12
13# ### ### ### ######### ######### #########
14## Requisites.
15
16package require Tcl 8.4
17
18# ### ### ### ######### ######### #########
19## API Implementation
20
21namespace eval rcs {}
22
23# ::rcs::text2dict --
24#
25# Convert a text into a dictionary. The dictionary is keyed by line
26# numbers, and the value is the text of the corresponding line. The
27# first line has index/number 1.
28#
29# Arguments
30# - text        The text to convert.
31#
32# Results
33#  A dictionary containing the text in split form.
34#
35# Side effects
36#  None
37
38proc ::rcs::text2dict {text} {
39    array set lines {}
40    set lnum 0
41    foreach line [split $text \n] {
42        set lines([incr lnum]) $line
43    }
44    return [array get lines]
45}
46
47# ::rcs::file2dict --
48#
49# Convert a text stored in a file into a dictionary. The dictionary is
50# keyed by line numbers, and the value is the text of the
51# corresponding line. The first line has index/number 1.
52#
53# Arguments
54# - file        The path of the file containing the text to convert.
55#
56# Results
57#  A dictionary containing the text in split form.
58#
59# Side effects
60#  None
61
62proc ::rcs::file2dict {filename} {
63    set chan [open $filename r]
64    set text [read $chan]
65    close $chan
66
67    return [text2dict $text]
68}
69
70# ::rcs::dict2text --
71#
72# Converts a dictionary as created by the 2dict commands back into a
73# text. The dictionary is keyed by line numbers, and the value is the
74# text of the corresponding line. The first line has index/number 1.
75# The dictionary may have gaps in the line numbers.
76#
77# Arguments
78# - dict        The dictionary to convert.
79#
80# Results
81#  The text stored in the dictionary.
82#
83# Side effects
84#  None
85
86proc ::rcs::dict2text {dict} {
87    array set lines $dict
88    set result {}
89    foreach lnum [lsort -integer [array names lines]] {
90        lappend result $lines($lnum)
91    }
92    return [join $result \n]
93}
94
95# ::rcs::dict2file --
96#
97# Converts a dictionary as created by the 2dict commands back into a
98# text and stores it into the specified file. The dictionary is keyed
99# by line numbers, and the value is the text of the corresponding
100# line. The first line has index/number 1.  The dictionary may have
101# gaps in the line numbers.
102#
103# Arguments
104# - filename    The path to the file to store the reconstructed text into.
105# - dict        The dictionary to convert.
106#
107# Results
108#  None.
109#
110# Side effects
111#  None
112
113proc ::rcs::dict2file {filename dict} {
114    set chan [open $filename w]
115    puts -nonewline $chan [dict2text $dict]
116    close $chan
117}
118
119# ::rcs::decodeRcsPatch --
120#
121# Converts a text containing a RCS patch (diff -n format) into a list
122# of patch commands. Each element of the list is a list containing the
123# patch command and its arguments, in this order.
124#
125# The valid patch commands are 'a' and 'd'. 'a' has two arguments, the
126# index of the line where to add the text, and the text itself. The
127# 'd' command has two arguments as well, the index of the first line
128# to delete, and the number of lines to delete.
129#
130# Arguments
131# - patch       The text in diff -n format, the patch to parse.
132#
133# Results
134#   A list containing the patch as sequence of commands.
135#
136# Side effects
137#  None
138
139proc ::rcs::decodeRcsPatch {patch} {
140    set patch [split $patch \n]
141    set plen  [llength $patch]
142    set at    0
143    set res   {}
144
145    while {$at < $plen} {
146        # I use an index into the list to avoid shifting the list
147        # elements down with each line processed. That is a lot of
148        # memcpy's.
149
150        set cmd [string trim [lindex $patch $at]]
151        incr at
152
153        switch -glob -- $cmd {
154            "" {}
155            a* {
156                foreach {start len} [split [string range $cmd 1 end]] break
157
158                set to [expr {$at + $len - 1}]
159                lappend res [list \
160                                 a \
161                                 $start \
162                                 [join [lrange $patch $at $to] \n]]
163                incr to
164                set at $to
165            }
166            d* {
167                foreach {start len} [split [string range $cmd 1 end]] break
168                lappend res [list d $start $len]
169            }
170            default {
171                return -code error "Unknown patch command: '$cmd'"
172            }
173        }
174    }
175
176    return $res
177}
178
179# ::rcs::encodeRcsPatch --
180#
181# Converts a list of patch commands into a text containing the same
182# command as a RCS patch (i.e. in diff -n format). See decodePatch for
183# a description of the input format.
184#
185# Arguments
186# - patch       The patch as list of patch commands.
187#
188# Results
189#   A text containing the patch in diff -n format.
190#
191# Side effects
192#  None
193
194proc ::rcs::encodeRcsPatch {patch} {
195    set res {}
196
197    foreach cmd $patch {
198        foreach {op a b} $cmd break
199
200        switch -exact -- $op {
201            a {
202                # a = index of line where to add
203                # b = text to add
204
205                set  lines [llength [split $b \n]]
206
207                lappend res "a$a $lines"
208                lappend res $b
209            }
210            d {
211                # a = index of first line to delete.
212                # b = #lines to delete.
213
214                lappend res "d$a $b"
215            }
216            default {
217                return -code error "Unknown patch command: '$op'"
218            }
219        }
220    }
221
222    return [join $res \n]\n
223}
224
225# ::rcs::applyRcsPatch --
226#
227# Apply a patch in the format returned by decodeRcsPatch to a text in
228# the format returned by the xx2dict commands. The result is
229# dictionary containing the modified text. Use the dict2xx commands to
230# convert this back into a regular text.
231#
232# Arguments
233# - text        The text (as dict) to patch
234# - patch       The patch (as cmd list) to apply.
235#
236# Results
237#  The modified text (as dict)
238#
239# Side effects
240#  None
241
242proc ::rcs::applyRcsPatch {text patch} {
243    array set lines $text
244
245    foreach cmd $patch {
246        foreach {op a b} $cmd break
247
248        switch -exact -- $op {
249            a {
250                # a = index of line where to add
251                # b = text to add
252
253                if {[info exists lines($a)]} {
254                    append lines($a) \n $b
255                } else {
256                    set lines($a) $b
257                }
258            }
259            d {
260                # a = index of first line to delete.
261                # b = #lines to delete.
262
263                while {$b > 0} {
264                    unset lines($a)
265                    incr a
266                    incr b -1
267                }
268            }
269            default {
270                return -code error "Unknown patch command: '$op'"
271            }
272        }
273    }
274
275    return [array get lines]
276}
277
278# ### ### ### ######### ######### #########
279## Ready for use.
280
281package provide rcs 0.1
Note: See TracBrowser for help on using the repository browser.