aboutsummaryrefslogtreecommitdiff
path: root/tcl6.tcl
blob: d62b8957300018c2622e1534b57b9bccac28c302 (plain)
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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# (c) 2008 Steve Bennett <steveb@workware.net.au>
#
# Loads a Tcl6-compatible environment plus some newer features,
# including stdio, array, file, clock, glob, regexp, regsub, lsearch, case, ::env

package provide tcl6 1.0

package require stdio

# Extremely simple autoload approach
set autoload {glob glob array array}

proc unknown {cmd args} {
	if {[info exists ::autoload($cmd)]} {
		package require $::autoload($cmd)
		return [uplevel 1 $cmd $args]
	}
	error "invalid command name \"$cmd\""
}

# Set up the ::env array
set env [env]

# Very basic lsearch -exact with no options
proc lsearch {list value} {
	set i 0
	foreach elem $list {
		if {$elem eq $value} {
			return $i
		}
		incr i
	}
	return -1
}

# Internal function to match a value agains a list of patterns
proc _case_search_patterns {patterns value} {
	set i 0
	foreach pattern $patterns {
		if {[string match $pattern $value]} {
			return $i
		}
		incr i
	}
	return -1
}

# case var ?in? pattern action ?pattern action ...?
proc case {var args} {
	# Skip dummy parameter
	if {[lindex $args 0] eq "in"} {
		set args [lrange $args 1 end]
	}

	# Check for single arg form
	if {[llength $args] == 1} {
		set args [lindex $args 0]
	}

	# Check for odd number of args
	if {[llength $args] % 2 != 0} {
		error "extra case pattern with no body"
	}

	#puts "looking for $var in '$args'"
	foreach {value action} $args {
		if {$value eq "default"} {
			set do_action $action
			continue
		} else {
			if {[_case_search_patterns $value $var] >= 0} {
				set do_action $action
				break
			}
		}
	}

	if {[info exists do_action]} {
		return [uplevel 1 $do_action]
	}
}

# Optional argument is a glob pattern
proc parray {arrayname {pattern *}} {
    upvar $arrayname a

	set max 0
    foreach name [array names a $pattern]] {
		if {[string length $name] > $max} {
			set max [string length $name]
		}
    }
    incr max [string length $arrayname]
    incr max 2
    foreach name [lsort [array names a $pattern]] {
		puts [format "%-${max}s = $a($name)" $arrayname\($name\)]
    }
}

set ::tcl_platform(platform) unix