File: common

package info (click to toggle)
tcllib 2.0%2Bdfsg-5
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 83,560 kB
  • sloc: tcl: 306,798; ansic: 14,272; sh: 3,035; xml: 1,766; yacc: 1,157; pascal: 881; makefile: 124; perl: 84; f90: 84; python: 33; ruby: 13; php: 11
file content (239 lines) | stat: -rw-r--r-- 6,690 bytes parent folder | download | duplicates (9)
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
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
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
# -*- tcl -*-
# Code common to the various control files.
#
# Copyright (c) 2009 by Andreas Kupries <andreas_kupries@users.sourceforge.net>
# All rights reserved.
#
# RCS: @(#) $Id: common,v 1.3 2009/04/29 02:09:46 andreas_kupries Exp $

# -------------------------------------------------------------------------

# Similar to TestFiles in devtools/testutilities.tcl, but not
# identical.  Here we do not expect source'able test suites, but data
# files, organized in sections under a main directory.

proc TestFilesProcess {maindir section inset outset -> nv lv iv dv ev script} {
    upvar 1 $nv n $lv label $dv data $ev expected $iv inputfile

    set pattern $maindir/$section/$inset/*

    set files [TestFilesGlob $pattern]
    if {![llength $files]} {
	return -code error "No files matching \"$pattern\""
    }
    foreach src $files {
	if {[string match *README* $src]} continue
	if {[file isdirectory      $src]} continue

	set srcname  [file tail $src]
	set exp      [localPath $maindir]/$section/$outset/$srcname
	set data     [fileutil::cat $src]
	set expected [string trim [fileutil::cat $exp]]
	set expected [string map [list @ $::tcltest::testsDirectory] $expected]

	regexp -- {^([0-9]+)}    $srcname -> n
	regsub -all -- {^[0-9]+} $srcname {} label

	scan $n %d n
	set label [string trim [string map {_ { }} $label]]
	set inputfile $src

	uplevel 1 $script
    }
    return
}

# -------------------------------------------------------------------------

proc setup_plugins {} {
    global env

    array_unset env LANG*
    array_unset env LC_*
    set env(LANG) C ; # Usually default if nothing is set, OS X requires this.

    set paths [join [list \
			 [tcllibPath doctools2] \
			 [tcllibPath struct] \
			 [tcllibPath textutil]] \
		   [expr {$::tcl_platform(platform) eq "windows" ? ";" : ":"}]]

    # Initialize the paths an import plugin manager should use when
    # searching for an import plugin used by the code under test, and
    # also provide the paths enabling the import plugins to find their
    # supporting packages as well.

    set env(DOCTOOLS_IDX_IMPORT_PLUGINS) $paths

    # Initialize the paths an export plugin manager should use when
    # searching for an export plugin used by the code under test, and
    # also provide the paths enabling the export plugins to find their
    # supporting packages as well.

    set env(DOCTOOLS_IDX_EXPORT_PLUGINS) $paths

    return
}

# -------------------------------------------------------------------------

proc stripcomments {text} {
    set pattern {[[:space:]]*\[comment[[:space:]][[:space:]]*\{[^\}]*\}[[:space:]]*\][[:space:]]*}
    regsub -all -- $pattern $text {} text
    return $text
}

proc striphtmlcomments {text {n {}}} {
    set pattern {<!--.*?-->}
    if {$n eq {}} {
	regsub -all -- $pattern $text {} text
    } else {
	while {$n} {
	    regsub -- $pattern $text {} text
	    incr n -1
	}
    }
    return $text
}

proc stripmanmacros {text} {
    return [string map [list \n[doctools::nroff::man_macros::contents] {}] $text]
}

proc stripnroffcomments {text {n {}}} {
#    return $text
    set pattern "'\\\\\"\[^\n\]*\n"
    if {$n eq {}} {
	regsub -all -- $pattern $text {} text
    } else {
	while {$n} {
	    regsub -- $pattern $text {} text
	    incr n -1
	}
    }
    return $text
}

# -------------------------------------------------------------------------

# Validate a serialization against the tree it
# was generated from.

proc validate_serial {t serial {rootname {}}} {
    if {$rootname == {}} {
	set rootname [$t rootname]
    }

    # List length is multiple of 3
    if {[llength $serial] % 3} {
	return serial/wrong#elements
    }

    # Scan through list and built a number helper
    # structures (arrays).

    array set a  {}
    array set p  {}
    array set ch {}
    foreach {node parent attr} $serial {
	# Node has to exist in tree
	if {![$t exists $node]} {
	    return node/$node/unknown
	}
	if {![info exists ch($node)]} {set ch($node) {}}
	# Parent reference has to be empty or
	# integer, == 0 %3, >=0, < length serial
	if {$parent != {}} {
	    if {![string is integer -strict $parent]} {
		return node/$node/parent/no-integer/$parent
	    }
	    if {$parent % 3} {
		return node/$node/parent/not-triple/$parent
	    }
	    if {$parent < 0} {
		return node/$node/parent/out-of-bounds/$parent
	    }
	    if {$parent >= [llength $serial]} {
		return node/$node/parent/out-of-bounds/$parent
	    }
	    # Resolve parent index into node name, has to match
	    set parentnode [lindex $serial $parent]
	    if {![$t exists $parentnode]} {
		return node/$node/parent/unknown/$parent/$parentnode
	    }
	    if {![string equal [$t parent $node] $parentnode]} {
		return node/$node/parent/mismatch/$parent/$parentnode/[$t parent $node]
	    }
	    lappend ch($parentnode) $node
	} else {
	    set p($node) {}
	}
	# Attr list has to be of even length.
	if {[llength $attr] % 2} {
	    return attr/$node/wrong#elements
	}
	# Attr have to exist and match in all respects
	if {![string equal \
		[dictsort $attr] \
		[dictsort [$t getall $node]]]} {
	    return attr/$node/mismatch
	}
    }
    # Second pass, check that the children information is encoded
    # correctly. Reconstructed data has to match originals.

    foreach {node parent attr} $serial {
	if {![string equal $ch($node) [$t children $node]]} {
	    return node/$node/children/mismatch
	}
    }

    # Reverse check
    # - List of nodes from the 'rootname' and check
    #   that it and all its children are present
    #   in the structure.

    set ::FOO {}
    $t walk $rootname n {walker $n}

    foreach n $::FOO {
	if {![info exists ch($n)]} {
	    return node/$n/mismatch/reachable/missing
	}
    }
    if {[llength $::FOO] != [llength $serial]/3} {
	return structure/mismatch/#nodes/multiples
    }
    if {[llength $::FOO] != [array size ch]} {
	return structure/mismatch/#nodes/multiples/ii
    }
    return ok
}

# Callbacks for tree walking.
# Remember the node in a global variable.

proc walker {node} {
    lappend ::FOO $node
}

proc match_tree {ta tb} {
    match_node $ta [$ta rootname] $tb [$tb rootname]
    return
}

proc match_node {ta a tb b} {
    if {[dictsort [$ta getall $a]] ne [dictsort [$tb getall $b]]} {
	return -code error "$ta/$a at $tb/$b, attribute mismatch (([dictsort [$ta getall $a]]) ne ([dictsort [$tb getall $b]]))"
    }
    if {[llength [$ta children $a]] != [llength [$tb children $b]]} {
	return -code error "$ta/$a at $tb/$b, children mismatch"
    }
    foreach ca [$ta children $a] cb [$tb children $b] {
	match_node $ta $ca $tb $cb
    }
    return
}

# -------------------------------------------------------------------------
return