source: project/release/5/srfi-1/trunk/tests/larceny.scm @ 34718

Last change on this file since 34718 was 34718, checked in by sjamaan, 18 months ago

release/5: Replace use by import in eggs

File size: 18.5 KB
Line 
1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2;;;
3;;; List tests from Larceny, ported to CHICKEN by Mario Domenech Goulart.
4;;;
5;;; Copyright 1991, 1994, 1998 William D Clinger
6;;; Copyright 1998             Lars T Hansen
7;;; Copyright 1984 - 1993      Lightship Software, Incorporated
8;;;
9;;; Permission to copy this software, in whole or in part, to use this
10;;; software for any lawful purpose, and to redistribute this software
11;;; is granted subject to the following restriction:  Any publication
12;;; or redistribution of this software, whether on its own or
13;;; incorporated into other software, must bear the above copyright
14;;; notices and the following legend:
15;;;
16;;;     The Twobit compiler and the Larceny runtime system were
17;;;     developed by William Clinger and Lars Hansen with the
18;;;     assistance of Lightship Software and the College of Computer
19;;;     Science of Northeastern University.  This acknowledges that
20;;;     Clinger et al remain the sole copyright holders to Twobit
21;;;     and Larceny and that no rights pursuant to that status are
22;;;     waived or conveyed.
23;;;
24;;; Twobit and Larceny are provided as is.  The user specifically
25;;; acknowledges that Northeastern University, William Clinger, Lars
26;;; Hansen, and Lightship Software have not made any representations
27;;; or warranty with regard to performance of Twobit and Larceny,
28;;; their merchantability, or fitness for a particular purpose.  Users
29;;; further acknowledge that they have had the opportunity to inspect
30;;; Twobit and Larceny and will hold harmless Northeastern University,
31;;; William Clinger, Lars Hansen, and Lightship Software from any cost,
32;;; liability, or expense arising from, or in any way related to the
33;;; use of this software.
34;;;
35
36; Test suite for SRFI-1
37; 2003-12-29 / lth
38;
39; Note: In Larceny, we require that the procedures designated as
40; "linear update" variants in the spec (eg append!) side-effect their
41; arguments, and there are tests here that check that side-effecting
42; occurs.
43;
44; For linear update we only require that the cells of the result are
45; taken from the cells of the input.  We could be stricter and require
46; that the cells of the results are the cells of the input with only
47; the CDR changed, ie, values are never moved from one cell to another.
48
49(import srfi-1 test)
50
51; Test cases are ordered as in the spec.  R5RS procedures are left out.
52
53(test-begin "srfi-1")
54
55(test '(2 . 1) (xcons 1 2))
56
57(test 1 (cons* 1))
58
59(test '(1 2 3 4 . 5) (cons* 1 2 3 4 5) )
60
61(test '(#t #t #t #t #t) (make-list 5 #t))
62
63(test '() (make-list 0 #f))
64
65(test 3 (length (make-list 3)))
66
67(test '(0 1 2 3 4) (list-tabulate 5 (lambda (x) x)))
68
69(test '() (list-tabulate 0 (lambda (x) (error "FOO!"))))
70
71(test #t (call-with-current-continuation
72          (lambda (abort)
73            (let* ((c  (list 1 2 3 4 5))
74                   (cp (list-copy c)))
75              (or (equal? c cp)
76                  (abort #f))
77              (let loop ((c c) (cp cp))
78                (if (not (null? c))
79                    (begin
80                      (or (not (eq? c cp))
81                          (abort #f))
82                      (loop (cdr c) (cdr cp)))))
83              #t))))
84
85(test '(1 2 3 . 4) (list-copy '(1 2 3 . 4)))
86
87(test #f (list? (circular-list 1 2 3)))
88
89(test #t (let* ((a (list 'a))
90                (b (list 'b))
91                (c (list 'c))
92                (x (circular-list a b c)))
93           (and (eq? a (car x))
94                (eq? b (cadr x))
95                (eq? c (caddr x))
96                (eq? a (cadddr x)))))
97
98(test '() (iota 0))
99
100(test '(2 5 8 11 14) (iota 5 2 3))
101
102(test '(2 3 4 5 6) (iota 5 2))
103
104
105(test #t (proper-list? '(1 2 3 4 5)))
106
107(test #t (proper-list? '()))
108
109(test #f (proper-list? '(1 2 . 3)))
110
111(test #f (proper-list? (circular-list 1 2 3)))
112
113(test #f (circular-list? '(1 2 3 4 5)))
114
115(test #f (circular-list? '()))
116
117(test #f (circular-list? '(1 2 . 3)))
118
119(test #t (circular-list? (circular-list 1 2 3)))
120
121(test #f (dotted-list? '(1 2 3 4 5)))
122
123(test #f (dotted-list? '()))
124
125(test #t (dotted-list? '(1 2 . 3)))
126
127(test #f (dotted-list? (circular-list 1 2 3)))
128
129(test #t (null-list? '()))
130
131(test #f (null-list? '(1 2)))
132
133(test #f (null-list? (circular-list 1 2)))
134
135(test #t (not-pair? 1))
136
137(test #f (not-pair? (cons 1 2)))
138
139(test #t (list= = '(1 2 3) '(1 2 3) '(1 2 3)))
140
141(test #f (list= = '(1 2 3) '(1 2 3) '(1 4 3)))
142
143; Checks that l0 is not being used when testing l2, cf spec
144(test #t (list= (lambda (a b) (not (eq? a b))) '(#f #f #f) '(#t #t #t) '(#f #f #f)))
145
146(test #t (list= =))
147
148(test #t (= (first '(1 2 3 4 5 6 7 8 9 10)) 1))
149(test #t (= (second '(1 2 3 4 5 6 7 8 9 10)) 2))
150(test #t (= (third '(1 2 3 4 5 6 7 8 9 10)) 3))
151(test #t (= (fourth '(1 2 3 4 5 6 7 8 9 10)) 4))
152(test #t (= (fifth '(1 2 3 4 5 6 7 8 9 10)) 5))
153(test #t (= (sixth '(1 2 3 4 5 6 7 8 9 10)) 6))
154(test #t (= (seventh '(1 2 3 4 5 6 7 8 9 10)) 7))
155(test #t (= (eighth '(1 2 3 4 5 6 7 8 9 10)) 8))
156(test #t (= (ninth '(1 2 3 4 5 6 7 8 9 10)) 9))
157(test #t (= (tenth '(1 2 3 4 5 6 7 8 9 10)) 10))
158
159(test #t (let-values (((a b) (car+cdr '(1 . 2))))
160           (and (= a 1) (= b 2))))
161
162(test '(1 2 3) (take '(1 2 3 4 5 6) 3))
163
164(test '(1) (take '(1) 1))
165
166(test #t (let ((x (list 1 2 3 4 5 6)))
167           (eq? (cdddr x) (drop x 3))))
168
169(test #t (let ((x (list 1 2 3)))
170           (eq? x (drop x 0))))
171
172(test '(4 5 6) (take-right '(1 2 3 4 5 6) 3))
173
174(test #t (null? (take-right '(1 2 3 4 5 6) 0)))
175
176(test '(2 3 . 4) (take-right '(1 2 3 . 4) 2))
177
178(test 4 (take-right '(1 2 3 . 4) 0))
179
180(test '(1 2 3) (drop-right '(1 2 3 4 5 6) 3))
181
182(test '(1 2 3) (drop-right '(1 2 3) 0))
183
184(test '(1 2 3) (drop-right '(1 2 3 . 4) 0))
185
186(test #t (let ((x (list 1 2 3 4 5 6)))
187           (let ((y (take! x 3)))
188             (and (eq? x y)
189                  (eq? (cdr x) (cdr y))
190                  (eq? (cddr x) (cddr y))
191                  (equal? y '(1 2 3))))))
192
193(test #t (let ((x (list 1 2 3 4 5 6)))
194           (let ((y (drop-right! x 3)))
195             (and (eq? x y)
196                  (eq? (cdr x) (cdr y))
197                  (eq? (cddr x) (cddr y))
198                  (equal? y '(1 2 3))))))
199
200(test #t (let-values (((a b) (split-at '(1 2 3 4 5 6) 2)))
201           (and (equal? a '(1 2))
202                (equal? b '(3 4 5 6)))))
203
204(test #t (let* ((x (list 1 2 3 4 5 6))
205                (y (cddr x)))
206           (let-values (((a b) (split-at! x 2)))
207             (and (equal? a '(1 2))
208                  (eq? a x)
209                  (equal? b '(3 4 5 6))
210                  (eq? b y)))))
211
212(test 37 (last '(1 2 3 37)))
213
214(test #f (length+ (circular-list 1 2 3)))
215
216(test 4 (length+ '(1 2 3 4)))
217
218(test #t (let ((x (list 1 2))
219               (y (list 3 4))
220               (z (list 5 6)))
221           (let ((r (append! x y '() z)))
222             (and (equal? r '(1 2 3 4 5 6))
223                  (eq? r x)
224                  (eq? (cdr r) (cdr x))
225                  (eq? (cddr r) y)
226                  (eq? (cdddr r) (cdr y))
227                  (eq? (cddddr r) z)
228                  (eq? (cdr (cddddr r)) (cdr z))))))
229
230(test '(1 2 3 4 5 6 7 8 9)
231      (concatenate '((1 2 3) (4 5 6) () (7 8 9))))
232
233(test '(1 2 3 4 5 6 7 8 9)
234      (concatenate! `(,(list 1 2 3) ,(list 4 5 6) () ,(list 7 8 9))))
235
236(test '(1 2 3 4 5 6)
237      (append-reverse '(3 2 1) '(4 5 6)))
238
239(test '(1 2 3 4 5 6)
240      (append-reverse! (list 3 2 1) (list 4 5 6)))
241
242(test '((1 4) (2 5) (3 6))
243      (zip '(1 2 3) '(4 5 6)))
244
245(test '()
246      (zip '() '() '() '()))
247
248(test '((1 1))
249      (zip '(1) (circular-list 1 2)))
250
251(test '(1 2 3 4 5)
252      (unzip1 '((1) (2) (3) (4) (5))))
253
254(test #t (let-values (((a b) (unzip2 '((10 11) (20 21) (30 31)))))
255           (and (equal? a '(10 20 30))
256                (equal? b '(11 21 31)))))
257
258(test #t (let-values (((a b c) (unzip3 '((10 11 12) (20 21 22) (30 31 32)))))
259           (and (equal? a '(10 20 30))
260                (equal? b '(11 21 31))
261                (equal? c '(12 22 32)))))
262
263(test #t (let-values (((a b c d) (unzip4 '((10 11 12 13)
264                                           (20 21 22 23)
265                                           (30 31 32 33)))))
266           (and (equal? a '(10 20 30))
267                (equal? b '(11 21 31))
268                (equal? c '(12 22 32))
269                (equal? d '(13 23 33)))))
270
271(test #t (let-values (((a b c d e) (unzip5 '((10 11 12 13 14)
272                                             (20 21 22 23 24)
273                                             (30 31 32 33 34)))))
274           (and (equal? a '(10 20 30))
275                (equal? b '(11 21 31))
276                (equal? c '(12 22 32))
277                (equal? d '(13 23 33))
278                (equal? e '(14 24 34)))))
279
280(test 3 (count even? '(3 1 4 1 5 9 2 5 6)))
281
282(test 3 (count < '(1 2 4 8) '(2 4 6 8 10 12 14 16)))
283
284(test 2 (count < '(3 1 4 1) (circular-list 1 10)))
285
286(test '(c 3 b 2 a 1)
287      (fold cons* '() '(a b c) '(1 2 3 4 5)))
288
289(test '(a 1 b 2 c 3)
290      (fold-right cons* '() '(a b c) '(1 2 3 4 5)))
291
292(test #t (let* ((x (list 1 2 3))
293                (r (list x (cdr x) (cddr x)))
294                (y (pair-fold (lambda (pair tail)
295                                (set-cdr! pair tail) pair)
296                              '()
297                              x)))
298           (and (equal? y '(3 2 1))
299                (every (lambda (c) (memq c r)) (list y (cdr y) (cddr y)))
300                #t)))
301
302(test '((a b c) (b c) (c))
303      (pair-fold-right cons '() '(a b c)))
304
305(test 5 (reduce max 'illegal '(1 2 3 4 5)))
306
307(test 0 (reduce max 0 '()))
308
309(test '(1 2 3 4 5)
310      (reduce-right append 'illegal '((1 2) () (3 4 5))))
311
312(test '(1 4 9 16 25 36 49 64 81 100)
313      (unfold (lambda (x) (> x 10))
314              (lambda (x) (* x x))
315              (lambda (x) (+ x 1))
316              1))
317
318(test '(1 4 9 16 25 36 49 64 81 100)
319      (unfold-right zero?
320                    (lambda (x) (* x x))
321                    (lambda (x) (- x 1))
322                    10))
323
324(test '(4 1 5 1)
325      (map + '(3 1 4 1) (circular-list 1 0)))
326
327(test '(5 4 3 2 1)
328      (let ((v 1)
329            (l '()))
330        (for-each (lambda (x y)
331                    (let ((n v))
332                      (set! v (+ v 1))
333                      (set! l (cons n l))))
334                  '(0 0 0 0 0)
335                  (circular-list 1 2))
336        l))
337
338(test '(1 -1 3 -3 8 -8)
339      (append-map (lambda (x) (list x (- x))) '(1 3 8)))
340
341
342(test '(1 -1 3 -3 8 -8)
343      (append-map! (lambda (x) (list x (- x))) '(1 3 8)))
344
345(test #t (let* ((l (list 1 2 3))
346                (m (map! (lambda (x) (* x x)) l)))
347           (and (equal? m '(1 4 9))
348                (equal? l '(1 4 9)))))
349
350(test '(1 2 3 4 5)
351      (let ((v 1))
352        (map-in-order (lambda (x)
353                        (let ((n v))
354                          (set! v (+ v 1))
355                          n))
356                      '(0 0 0 0 0))))
357
358(test '((3) (2 3) (1 2 3))
359      (let ((xs (list 1 2 3))
360            (l '()))
361        (pair-for-each (lambda (x) (set! l (cons x l))) xs)
362        l))
363
364(test '(1 9 49)
365      (filter-map (lambda (x y) (and (number? x) (* x x)))
366                  '(a 1 b 3 c 7)
367                  (circular-list 1 2)))
368
369(test '(0 8 8 -4)
370      (filter even? '(0 7 8 8 43 -4)))
371
372(test #t (let-values (((a b) (partition symbol? '(one 2 3 four five 6))))
373           (and (equal? a '(one four five))
374                (equal? b '(2 3 6)))))
375
376(test '(7 43)
377      (remove even? '(0 7 8 8 43 -4)))
378
379(test #t (let* ((x (list 0 7 8 8 43 -4))
380                (y (pair-fold cons '() x))
381                (r (filter! even? x)))
382           (and (equal? '(0 8 8 -4) r)
383                (every (lambda (c) (memq c y)) (pair-fold cons '() r))
384                #t)))
385
386(test #t (let* ((x (list 'one 2 3 'four 'five 6))
387                (y (pair-fold cons '() x)))
388           (let-values (((a b) (partition! symbol? x)))
389             (and (equal? a '(one four five))
390                  (equal? b '(2 3 6))
391                  (every (lambda (c) (memq c y)) (pair-fold cons '() a))
392                  (every (lambda (c) (memq c y)) (pair-fold cons '() b))
393                  #t))))
394
395(test #t (let* ((x (list 0 7 8 8 43 -4))
396                (y (pair-fold cons '() x))
397                (r (remove! even? x)))
398           (and (equal? '(7 43) r)
399                (every (lambda (c) (memq c y)) (pair-fold cons '() r))
400                #t)))
401
402(test 4 (find even? '(3 1 4 1 5 9 8)))
403
404(test '(4 1 5 9 8)
405      (find-tail even? '(3 1 4 1 5 9 8)))
406
407(test #f (find-tail even? '(1 3 5 7)))
408
409(test '(2 18)
410      (take-while even? '(2 18 3 10 22 9)))
411
412(test #t (let* ((x (list 2 18 3 10 22 9))
413                (r (take-while! even? x)))
414           (and (equal? r '(2 18))
415                (eq? r x)
416                (eq? (cdr r) (cdr x)))))
417
418(test '(3 10 22 9)
419      (drop-while even? '(2 18 3 10 22 9)))
420
421(test #t (let-values (((a b) (span even? '(2 18 3 10 22 9))))
422           (and (equal? a '(2 18))
423                (equal? b '(3 10 22 9)))))
424
425(test #t (let-values (((a b) (break even? '(3 1 4 1 5 9))))
426           (and (equal? a '(3 1))
427                (equal? b '(4 1 5 9)))))
428
429(test #t (let* ((x     (list 2 18 3 10 22 9))
430                (cells (pair-fold cons '() x)))
431           (let-values (((a b) (span! even? x)))
432             (and (equal? a '(2 18))
433                  (equal? b '(3 10 22 9))
434                  (every (lambda (x) (memq x cells)) (pair-fold cons '() a))
435                  (every (lambda (x) (memq x cells)) (pair-fold cons '() b))
436                  #t))))
437
438(test #t (let* ((x     (list 3 1 4 1 5 9))
439                (cells (pair-fold cons '() x)))
440           (let-values (((a b) (break! even? x)))
441             (and (equal? a '(3 1))
442                  (equal? b '(4 1 5 9))
443                  (every (lambda (x) (memq x cells)) (pair-fold cons '() a))
444                  (every (lambda (x) (memq x cells)) (pair-fold cons '() b))
445                  #t))))
446
447(test #t (any integer? '(a 3 b 2.7)))
448
449(test #f (any integer? '(a 3.1 b 2.7)))
450
451(test #t (any < '(3 1 4 1 5) (circular-list 2 7 1 8 2)))
452
453(test 'yes (any (lambda (a b) (if (< a b) 'yes #f))
454                '(1 2 3) '(0 1 4)))
455
456(test #t (every integer? '(1 2 3)))
457
458(test #f (every integer? '(3 4 5.1)))
459
460(test #t (every < '(1 2 3) (circular-list 2 3 4)))
461
462(test 2 (list-index even? '(3 1 4 1 5 9)))
463
464(test 1 (list-index < '(3 1 4 1 5 9 2 5 6) '(2 7 1 8 2)))
465
466(test #f (list-index = '(3 1 4 1 5 9 2 5 6) '(2 7 1 8 2)))
467
468(test '(37 48)
469      (member 5 '(1 2 5 37 48) <))
470
471(test '(1 2 5)
472      (delete 5 '(1 48 2 5 37) <))
473
474(test '(1 2 7)
475      (delete 5 '(1 5 2 5 7)))
476
477(test #t (let* ((x     (list 1 48 2 5 37))
478                (cells (pair-fold cons '() x))
479                (r     (delete! 5 x <)))
480           (and (equal? r '(1 2 5))
481                (every (lambda (x) (memq x cells)) (pair-fold cons '() r))
482                #t)))
483
484(test '((a . 3) (b . 7) (c . 1))
485      (delete-duplicates '((a . 3) (b . 7) (a . 9) (c . 1))
486                         (lambda (x y) (eq? (car x) (car y)))))
487
488(test '(a b c z)
489      (delete-duplicates '(a b a c a b c z) eq?))
490
491(test #t (let* ((x     (list 'a 'b 'a 'c 'a 'b 'c 'z))
492                (cells (pair-fold cons '() x))
493                (r     (delete-duplicates! x)))
494           (and (equal? '(a b c z) r)
495                ;; XXX NOTE member, not memq as in original test
496                (every (lambda (x) (member x cells)) (pair-fold cons '() r))
497                #t)))
498
499(test '(3 . #t)
500      (assoc 6
501             '((4 . #t) (3 . #t) (5 . #t))
502             (lambda (x y)
503               (zero? (remainder x y)))))
504
505(test '((1 . #t) (2 . #f))
506      (alist-cons 1 #t '((2 . #f))))
507
508(test #t (let* ((a (list (cons 1 2) (cons 3 4)))
509                (b (alist-copy a)))
510           (and (equal? a b)
511                (every (lambda (x) (not (memq x b))) a)
512                (every (lambda (x) (not (memq x a))) b)
513                #t)))
514
515(test '((1 . #t) (2 . #t) (4 . #t))
516      (alist-delete 5 '((1 . #t) (2 . #t) (37 . #t) (4 . #t) (48 #t)) <))
517
518(test '((1 . #t) (2 . #t) (4 . #t))
519      (alist-delete 7 '((1 . #t) (2 . #t) (7 . #t) (4 . #t) (7 #t))))
520
521(test #t (let* ((x '((1 . #t) (2 . #t) (7 . #t) (4 . #t) (7 #t)))
522                (y (list-copy x))
523                (cells (pair-fold cons '() x))
524                (r (alist-delete! 7 x)))
525           (and (equal? r '((1 . #t) (2 . #t) (4 . #t)))
526                (every (lambda (x) (memq x cells)) (pair-fold cons '() r))
527                (every (lambda (x) (memq x y)) r)
528                #t)))
529
530(test #t (lset<= eq? '(a) '(a b a) '(a b c c)))
531
532(test #f (lset<= eq? '(a) '(a b a) '(a)))
533
534(test #t (lset<= eq?))
535
536(test #t (lset<= eq? '(a)))
537
538(test #t (lset= eq? '(b e a) '(a e b) '(e e b a)))
539
540(test #f (lset= eq? '(b e a) '(a e b) '(e e b a c)))
541
542(test #t (lset= eq?))
543
544(test #t (lset= eq? '(a)))
545
546(test '(u o i a b c d c e)
547      (lset-adjoin eq? '(a b c d c e) 'a 'e 'i 'o 'u))
548
549(test '(u o i a b c d e)
550      (lset-union eq? '(a b c d e) '(a e i o u)))
551
552(test '(x a a c)
553      (lset-union eq? '(a a c) '(x a x)))
554
555(test #t (null? (lset-union eq?)))
556
557(test '(a b c)
558      (lset-union eq? '(a b c)))
559
560(test '(a e)
561      (lset-intersection eq? '(a b c d e) '(a e i o u)))
562
563(test '(a x a)
564      (lset-intersection eq? '(a x y a) '(x a x z)))
565
566(test '(a b c)
567      (lset-intersection eq? '(a b c)))
568
569(test '(b c d)
570      (lset-difference eq? '(a b c d e) '(a e i o u)))
571
572(test '(a b c)
573      (lset-difference eq? '(a b c)))
574
575(test #t (lset= eq? '(d c b i o u) (lset-xor eq? '(a b c d e) '(a e i o u))))
576
577(test #t (lset= eq? '() (lset-xor eq?)))
578
579(test #t (lset= eq? '(a b c d e) (lset-xor eq? '(a b c d e))))
580
581(test #t (let-values (((d i) (lset-diff+intersection eq? '(a b c d e) '(c d f))))
582           (and (equal? d '(a b e))
583                (equal? i '(c d)))))
584
585; FIXME: For the following five procedures, need to check that cells
586; returned are from the arguments.
587
588(test '(u o i a b c d e)
589      (lset-union! eq? (list 'a 'b 'c 'd 'e) (list 'a 'e 'i 'o 'u)))
590
591(test '(x a a c)
592      (lset-union! eq? (list 'a 'a 'c) (list 'x 'a 'x)))
593
594(test #t (null? (lset-union! eq?)))
595
596(test '(a b c)
597      (lset-union! eq? (list 'a 'b 'c)))
598
599(test '(a e)
600      (lset-intersection! eq? (list 'a 'b 'c 'd 'e)
601                          (list 'a 'e 'i 'o 'u)))
602
603(test '(a x a)
604      (lset-intersection! eq? (list 'a 'x 'y 'a)
605                          (list 'x 'a 'x 'z)))
606
607(test '(a b c)
608      (lset-intersection! eq? (list 'a 'b 'c)))
609
610(test '(b c d)
611      (lset-difference! eq? (list 'a 'b 'c 'd 'e)
612                        (list 'a 'e 'i 'o 'u)))
613
614(test '(a b c)
615      (lset-difference! eq? (list 'a 'b 'c)))
616
617(test #t (lset= eq? '(d c b i o u)
618                     (lset-xor! eq? (list 'a 'b 'c 'd 'e)
619                                    (list 'a 'e 'i 'o 'u))))
620
621(test #t (lset= eq? '() (lset-xor! eq?)))
622
623(test #t (lset= eq? '(a b c d e) (lset-xor! eq? (list 'a 'b 'c 'd 'e))))
624
625(test #t (let-values (((d i) (lset-diff+intersection! eq? (list 'a 'b 'c 'd 'e)
626                                                      (list 'c 'd 'f))))
627           (and (equal? d '(a b e))
628                (equal? i '(c d)))))
629
630(test-end "srfi-1")
Note: See TracBrowser for help on using the repository browser.