OSDN Git Service

FIRST REPOSITORY
[eos/hostdependOTHERS.git] / I386LINUX / util / I386LINUX / lib / tcl8.4 / history.tcl
1 # history.tcl --
2 #
3 # Implementation of the history command.
4 #
5 # RCS: @(#) $Id: history.tcl,v 1.5 2001/05/17 08:18:56 hobbs Exp $
6 #
7 # Copyright (c) 1997 Sun Microsystems, Inc.
8 #
9 # See the file "license.terms" for information on usage and redistribution
10 # of this file, and for a DISCLAIMER OF ALL WARRANTIES.
11 #
12
13 # The tcl::history array holds the history list and
14 # some additional bookkeeping variables.
15 #
16 # nextid        the index used for the next history list item.
17 # keep          the max size of the history list
18 # oldest        the index of the oldest item in the history.
19
20 namespace eval tcl {
21     variable history
22     if {![info exists history]} {
23         array set history {
24             nextid      0
25             keep        20
26             oldest      -20
27         }
28     }
29 }
30
31 # history --
32 #
33 #       This is the main history command.  See the man page for its interface.
34 #       This does argument checking and calls helper procedures in the
35 #       history namespace.
36
37 proc history {args} {
38     set len [llength $args]
39     if {$len == 0} {
40         return [tcl::HistInfo]
41     }
42     set key [lindex $args 0]
43     set options "add, change, clear, event, info, keep, nextid, or redo"
44     switch -glob -- $key {
45         a* { # history add
46
47             if {$len > 3} {
48                 return -code error "wrong # args: should be \"history add event ?exec?\""
49             }
50             if {![string match $key* add]} {
51                 return -code error "bad option \"$key\": must be $options"
52             }
53             if {$len == 3} {
54                 set arg [lindex $args 2]
55                 if {! ([string match e* $arg] && [string match $arg* exec])} {
56                     return -code error "bad argument \"$arg\": should be \"exec\""
57                 }
58             }
59             return [tcl::HistAdd [lindex $args 1] [lindex $args 2]]
60         }
61         ch* { # history change
62
63             if {($len > 3) || ($len < 2)} {
64                 return -code error "wrong # args: should be \"history change newValue ?event?\""
65             }
66             if {![string match $key* change]} {
67                 return -code error "bad option \"$key\": must be $options"
68             }
69             if {$len == 2} {
70                 set event 0
71             } else {
72                 set event [lindex $args 2]
73             }
74
75             return [tcl::HistChange [lindex $args 1] $event]
76         }
77         cl* { # history clear
78
79             if {($len > 1)} {
80                 return -code error "wrong # args: should be \"history clear\""
81             }
82             if {![string match $key* clear]} {
83                 return -code error "bad option \"$key\": must be $options"
84             }
85             return [tcl::HistClear]
86         }
87         e* { # history event
88
89             if {$len > 2} {
90                 return -code error "wrong # args: should be \"history event ?event?\""
91             }
92             if {![string match $key* event]} {
93                 return -code error "bad option \"$key\": must be $options"
94             }
95             if {$len == 1} {
96                 set event -1
97             } else {
98                 set event [lindex $args 1]
99             }
100             return [tcl::HistEvent $event]
101         }
102         i* { # history info
103
104             if {$len > 2} {
105                 return -code error "wrong # args: should be \"history info ?count?\""
106             }
107             if {![string match $key* info]} {
108                 return -code error "bad option \"$key\": must be $options"
109             }
110             return [tcl::HistInfo [lindex $args 1]]
111         }
112         k* { # history keep
113
114             if {$len > 2} {
115                 return -code error "wrong # args: should be \"history keep ?count?\""
116             }
117             if {$len == 1} {
118                 return [tcl::HistKeep]
119             } else {
120                 set limit [lindex $args 1]
121                 if {[catch {expr {~$limit}}] || ($limit < 0)} {
122                     return -code error "illegal keep count \"$limit\""
123                 }
124                 return [tcl::HistKeep $limit]
125             }
126         }
127         n* { # history nextid
128
129             if {$len > 1} {
130                 return -code error "wrong # args: should be \"history nextid\""
131             }
132             if {![string match $key* nextid]} {
133                 return -code error "bad option \"$key\": must be $options"
134             }
135             return [expr {$tcl::history(nextid) + 1}]
136         }
137         r* { # history redo
138
139             if {$len > 2} {
140                 return -code error "wrong # args: should be \"history redo ?event?\""
141             }
142             if {![string match $key* redo]} {
143                 return -code error "bad option \"$key\": must be $options"
144             }
145             return [tcl::HistRedo [lindex $args 1]]
146         }
147         default {
148             return -code error "bad option \"$key\": must be $options"
149         }
150     }
151 }
152
153 # tcl::HistAdd --
154 #
155 #       Add an item to the history, and optionally eval it at the global scope
156 #
157 # Parameters:
158 #       command         the command to add
159 #       exec            (optional) a substring of "exec" causes the
160 #                       command to be evaled.
161 # Results:
162 #       If executing, then the results of the command are returned
163 #
164 # Side Effects:
165 #       Adds to the history list
166
167  proc tcl::HistAdd {command {exec {}}} {
168     variable history
169
170     # Do not add empty commands to the history
171     if {[string trim $command] == ""} {
172         return ""
173     }
174
175     set i [incr history(nextid)]
176     set history($i) $command
177     set j [incr history(oldest)]
178     if {[info exists history($j)]} {unset history($j)}
179     if {[string match e* $exec]} {
180         return [uplevel #0 $command]
181     } else {
182         return {}
183     }
184 }
185
186 # tcl::HistKeep --
187 #
188 #       Set or query the limit on the length of the history list
189 #
190 # Parameters:
191 #       limit   (optional) the length of the history list
192 #
193 # Results:
194 #       If no limit is specified, the current limit is returned
195 #
196 # Side Effects:
197 #       Updates history(keep) if a limit is specified
198
199  proc tcl::HistKeep {{limit {}}} {
200     variable history
201     if {[string length $limit] == 0} {
202         return $history(keep)
203     } else {
204         set oldold $history(oldest)
205         set history(oldest) [expr {$history(nextid) - $limit}]
206         for {} {$oldold <= $history(oldest)} {incr oldold} {
207             if {[info exists history($oldold)]} {unset history($oldold)}
208         }
209         set history(keep) $limit
210     }
211 }
212
213 # tcl::HistClear --
214 #
215 #       Erase the history list
216 #
217 # Parameters:
218 #       none
219 #
220 # Results:
221 #       none
222 #
223 # Side Effects:
224 #       Resets the history array, except for the keep limit
225
226  proc tcl::HistClear {} {
227     variable history
228     set keep $history(keep)
229     unset history
230     array set history [list \
231         nextid  0       \
232         keep    $keep   \
233         oldest  -$keep  \
234     ]
235 }
236
237 # tcl::HistInfo --
238 #
239 #       Return a pretty-printed version of the history list
240 #
241 # Parameters:
242 #       num     (optional) the length of the history list to return
243 #
244 # Results:
245 #       A formatted history list
246
247  proc tcl::HistInfo {{num {}}} {
248     variable history
249     if {$num == {}} {
250         set num [expr {$history(keep) + 1}]
251     }
252     set result {}
253     set newline ""
254     for {set i [expr {$history(nextid) - $num + 1}]} \
255             {$i <= $history(nextid)} {incr i} {
256         if {![info exists history($i)]} {
257             continue
258         }
259         set cmd [string trimright $history($i) \ \n]
260         regsub -all \n $cmd "\n\t" cmd
261         append result $newline[format "%6d  %s" $i $cmd]
262         set newline \n
263     }
264     return $result
265 }
266
267 # tcl::HistRedo --
268 #
269 #       Fetch the previous or specified event, execute it, and then
270 #       replace the current history item with that event.
271 #
272 # Parameters:
273 #       event   (optional) index of history item to redo.  Defaults to -1,
274 #               which means the previous event.
275 #
276 # Results:
277 #       Those of the command being redone.
278 #
279 # Side Effects:
280 #       Replaces the current history list item with the one being redone.
281
282  proc tcl::HistRedo {{event -1}} {
283     variable history
284     if {[string length $event] == 0} {
285         set event -1
286     }
287     set i [HistIndex $event]
288     if {$i == $history(nextid)} {
289         return -code error "cannot redo the current event"
290     }
291     set cmd $history($i)
292     HistChange $cmd 0
293     uplevel #0 $cmd
294 }
295
296 # tcl::HistIndex --
297 #
298 #       Map from an event specifier to an index in the history list.
299 #
300 # Parameters:
301 #       event   index of history item to redo.
302 #               If this is a positive number, it is used directly.
303 #               If it is a negative number, then it counts back to a previous
304 #               event, where -1 is the most recent event.
305 #               A string can be matched, either by being the prefix of
306 #               a command or by matching a command with string match.
307 #
308 # Results:
309 #       The index into history, or an error if the index didn't match.
310
311  proc tcl::HistIndex {event} {
312     variable history
313     if {[catch {expr {~$event}}]} {
314         for {set i [expr {$history(nextid)-1}]} {[info exists history($i)]} \
315                 {incr i -1} {
316             if {[string match $event* $history($i)]} {
317                 return $i;
318             }
319             if {[string match $event $history($i)]} {
320                 return $i;
321             }
322         }
323         return -code error "no event matches \"$event\""
324     } elseif {$event <= 0} {
325         set i [expr {$history(nextid) + $event}]
326     } else {
327         set i $event
328     }
329     if {$i <= $history(oldest)} {
330         return -code error "event \"$event\" is too far in the past"
331     }
332     if {$i > $history(nextid)} {
333         return -code error "event \"$event\" hasn't occured yet"
334     }
335     return $i
336 }
337
338 # tcl::HistEvent --
339 #
340 #       Map from an event specifier to the value in the history list.
341 #
342 # Parameters:
343 #       event   index of history item to redo.  See index for a
344 #               description of possible event patterns.
345 #
346 # Results:
347 #       The value from the history list.
348
349  proc tcl::HistEvent {event} {
350     variable history
351     set i [HistIndex $event]
352     if {[info exists history($i)]} {
353         return [string trimright $history($i) \ \n]
354     } else {
355         return "";
356     }
357 }
358
359 # tcl::HistChange --
360 #
361 #       Replace a value in the history list.
362 #
363 # Parameters:
364 #       cmd     The new value to put into the history list.
365 #       event   (optional) index of history item to redo.  See index for a
366 #               description of possible event patterns.  This defaults
367 #               to 0, which specifies the current event.
368 #
369 # Side Effects:
370 #       Changes the history list.
371
372  proc tcl::HistChange {cmd {event 0}} {
373     variable history
374     set i [HistIndex $event]
375     set history($i) $cmd
376 }