source: trunk/ab5.0/ablib/src/Classes/System/String.ab@ 621

Last change on this file since 621 was 621, checked in by イグトランス (egtra), 16 years ago

GC_mallocがNULLを返さなくなったことへの対応

File size: 21.1 KB
Line 
1' Classes/System/String.ab
2
3Namespace System
4
5 Class String
6 Implements /*IComparable, ICloneable, IConvertible, IComparable<String>, IEnumerable, IEnumerable<Char>, IEquatable<String>*/
7
8 m_Length As Long
9 Chars As *Char
10
11 Sub validPointerCheck(p As VoidPtr, size = 1 As Long)
12 If p As ULONG_PTR < &h10000 Then
13 Throw New ArgumentException
14 ElseIf IsBadReadPtr(p, size As ULONG_PTR) Then
15 Throw New ArgumentException
16 End If
17 End Sub
18 Public
19 Static Const Empty = New String
20
21 Sub String()
22' Chars = 0
23' m_Length = 0
24 End Sub
25
26 Sub String(initStr As PCWSTR)
27 validPointerCheck(initStr)
28 Assign(initStr, lstrlenW(initStr))
29 End Sub
30
31 Sub String(initStr As PCWSTR, length As Long)
32 validPointerCheck(initStr, length)
33 Assign(initStr, length)
34 End Sub
35
36 Sub String(initStr As PCWSTR, start As Long, length As Long)
37 If start < 0 Or length Or start + length < 0 Then
38 Throw New ArgumentOutOfRangeException("String constractor: One or more arguments are out of range value.", "start or length or both")
39 End If
40 validPointerCheck(initStr + start, length)
41 Assign(initStr + start, length)
42 End Sub
43
44 Sub String(initStr As PCSTR)
45 validPointerCheck(initStr)
46 Assign(initStr, lstrlenA(initStr))
47 End Sub
48
49 Sub String(initStr As PCSTR, length As Long)
50 validPointerCheck(initStr, length)
51 Assign(initStr, length)
52 End Sub
53
54 Sub String(initStr As PCSTR, start As Long, length As Long)
55 If start < 0 Or length < 0 Then
56 Throw New ArgumentOutOfRangeException("String constructor: One or more arguments are out of range value.", "start or length or both")
57 End If
58 validPointerCheck(initStr + start, length)
59 Assign(initStr + start, length)
60 End Sub
61
62 Sub String(initStr As String)
63 If Not IsNullOrEmpty(initStr) Then
64 Assign(initStr.Chars, initStr.m_Length)
65 End If
66 End Sub
67
68 Sub String(initChar As Char, length As Long)
69 AllocStringBuffer(length)
70 ActiveBasic.Strings.ChrFill(Chars, length, initChar)
71 Chars[length] = 0
72 End Sub
73
74 Sub String(sb As Text.StringBuilder)
75 Chars = StrPtr(sb)
76 m_Length = sb.Length
77 sb.__Stringized()
78 End Sub
79
80 Const Function Length() As Long
81 Return m_Length
82 End Function
83
84 Function Operator() As *Char
85 Return Chars
86 End Function
87
88 Const Function Operator [] (n As Long) As Char
89 rangeCheck(n)
90 Return Chars[n]
91 End Function
92
93 Const Function Operator + (y As PCSTR) As String
94 If y = 0 Then
95 Return This
96 Else
97 Return Concat(y, lstrlenA(y))
98 End If
99 End Function
100
101 Const Function Operator + (y As PCWSTR) As String
102 If y = 0 Then
103 Return This
104 Else
105 Return Concat(y, lstrlenW(y))
106 End If
107 End Function
108
109 Const Function Operator + (y As String) As String
110 If ActiveBasic.IsNothing(y) Then
111 Return This
112 Else
113 Return Concat(y.Chars, y.m_Length)
114 End If
115 End Function
116
117 Const Function Operator & (y As PCSTR) As String
118 Return This + y
119 End Function
120
121 Const Function Operator & (y As PCWSTR) As String
122 Return This + y
123 End Function
124
125 Const Function Operator & (y As String) As String
126 Return This + y
127 End Function
128
129 Const Function Operator == (y As String) As Boolean
130 Return Compare(This, y) = 0
131 End Function
132
133 Const Function Operator == (y As *Char) As Boolean
134 Return Compare(This, y) = 0
135 End Function
136
137 Const Function Operator <> (y As String) As Boolean
138 Return Compare(This, y) <> 0
139 End Function
140
141 Const Function Operator <> (y As *Char) As Boolean
142 Return Compare(This, y) <> 0
143 End Function
144
145 Const Function Operator < (y As String) As Boolean
146 Return Compare(This, y) < 0
147 End Function
148
149 Const Function Operator < (y As *Char) As Boolean
150 Return Compare(This, y) < 0
151 End Function
152
153 Const Function Operator > (y As String) As Boolean
154 Return Compare(This, y) > 0
155 End Function
156
157 Const Function Operator > (y As *Char) As Boolean
158 Return Compare(This, y) > 0
159 End Function
160
161 Const Function Operator <= (y As String) As Boolean
162 Return Compare(This, y) <= 0
163 End Function
164
165 Const Function Operator <= (y As *Char) As Boolean
166 Return Compare(This, y) <= 0
167 End Function
168
169 Const Function Operator >= (y As String) As Boolean
170 Return Compare(This, y) >= 0
171 End Function
172
173 Const Function Operator >= (y As *Char) As Boolean
174 Return Compare(This, y) >= 0
175 End Function
176
177 Static Function Compare(x As String, y As String) As Long
178 Return CompareOrdinal(x, y)
179 End Function
180
181 Public
182 'Compareなどで、x.Charsではなく、StrPtr(x)と書く理由は、xがNothingの場合のため。
183
184 Static Function Compare(x As String, indexX As Long, y As String, indexY As Long, length As Long) As Long
185 Return CompareOrdinal(x, indexX, y, indexY, length)
186 End Function
187
188 Static Function CompareOrdinal(x As String, y As String) As Long
189 Return CompareOrdinal(StrPtr(x), StrPtr(y))
190 End Function
191
192 Static Function CompareOrdinal(x As String, indexX As Long, y As String, indexY As Long, length As Long) As Long
193 Return CompareOrdinal(StrPtr(x), indexX, StrPtr(y), indexY, length)
194 End Function
195 Private
196 Static Function Compare(x As String, y As *Char) As Long
197 Return CompareOrdinal(x, y)
198 End Function
199
200 Static Function CompareOrdinal(x As String, y As *Char) As Long
201 Return CompareOrdinal(StrPtr(x), y)
202 End Function
203
204 Static Function CompareOrdinal(x As *Char, y As *Char) As Long
205 If x = 0 Then
206 If y = 0 Then
207 Return 0
208 Else
209 Return -1
210 End If
211 ElseIf y = 0 Then
212 Return 1
213 End If
214 Return ActiveBasic.Strings.StrCmp(x, y)
215 End Function
216
217 Static Function CompareOrdinal(x As *Char, indexX As Long, y As *Char, indexY As Long, length As Long) As Long
218 If x = 0 Then
219 If y = 0 Then
220 Return 0
221 Else
222 Return -1
223 End If
224 ElseIf y = 0 Then
225 Return 1
226 End If
227 Return ActiveBasic.Strings.ChrCmp(VarPtr(x[indexX]), VarPtr(y[indexY]), length As SIZE_T)
228 End Function
229 Public
230 Function CompareTo(y As String) As Long
231 Return String.Compare(This, y)
232 End Function
233
234 Function CompareTo(y As Object) As Long
235 If Not Object.Equals(This.GetType(), y.GetType()) Then
236 Throw New ArgumentException("String.CompareTo: y is not String.", "y")
237 End If
238 Return CompareTo(y As String)
239 End Function
240
241 Function Equals(s As String) As Boolean
242 Return This = s
243 End Function
244
245 Override Function Equals(s As Object) As Boolean
246 If Not ActiveBasic.IsNothing(s) Then
247 If Object.Equals(This.GetType(), s.GetType()) Then
248 Return This.Equals(s As String)
249 End If
250 End If
251 Return False
252 End Function
253
254 Const Function StrPtr() As *Char
255 Return Chars
256 End Function
257Private
258
259 Sub Assign(text As PCSTR, textLengthA As Long)
260#ifdef UNICODE
261 Dim textLengthW = MultiByteToWideChar(CP_THREAD_ACP, 0, text, textLengthA, 0, 0)
262 AllocStringBuffer(textLengthW)
263 MultiByteToWideChar(CP_THREAD_ACP, 0, text, textLengthA, Chars, textLengthW)
264 Chars[textLengthW] = 0
265#else
266 AssignFromCharPtr(text, textLengthA)
267#endif
268 End Sub
269
270 Sub Assign(text As PCWSTR, textLengthW As Long)
271#ifdef UNICODE
272 AssignFromCharPtr(text, textLengthW)
273#else
274 Dim textLengthA = WideCharToMultiByte(CP_THREAD_ACP, 0, text, textLengthW, 0, 0, 0, 0)
275 AllocStringBuffer(textLengthA)
276 WideCharToMultiByte(CP_THREAD_ACP, 0, text, textLengthW, Chars, textLengthA, 0, 0)
277 Chars[textLengthA] = 0
278#endif
279 End Sub
280
281 Private
282 Static Function ConcatChar(text1 As *Char, text1Length As Long, text2 As *Char, text2Length As Long) As String
283 ConcatChar = New String()
284 With ConcatChar
285 .AllocStringBuffer(text1Length + text2Length)
286 ActiveBasic.Strings.ChrCopy(.Chars, text1, text1Length As SIZE_T)
287 ActiveBasic.Strings.ChrCopy(VarPtr(.Chars[text1Length]), text2, text2Length As SIZE_T)
288 .Chars[text1Length + text2Length] = 0
289 End With
290 End Function
291 Public
292 Const Function Concat(text As PCSTR, len As Long) As String
293#ifdef UNICODE
294 With Concat
295 Dim lenW = MultiByteToWideChar(CP_THREAD_ACP, 0, text, len, 0, 0)
296 Concat = New String
297 .AllocStringBuffer(m_Length + lenW)
298 ActiveBasic.Strings.ChrCopy(.Chars, This.Chars, m_Length As SIZE_T)
299 MultiByteToWideChar(CP_THREAD_ACP, 0, text, len, VarPtr(.Chars[m_Length]), lenW)
300 .Chars[m_Length + lenW] = 0
301 End With
302#else
303 Return ConcatChar(This.Chars, m_Length, text, len)
304#endif
305 End Function
306
307 Const Function Concat(text As PCWSTR, len As Long) As String
308#ifdef UNICODE
309 Return ConcatChar(This.Chars, m_Length, text, len)
310#else
311 With Concat
312 Concat = New String
313 Dim lenA = WideCharToMultiByte(CP_THREAD_ACP, 0, text, len, 0, 0, 0, 0)
314 .AllocStringBuffer(m_Length + lenA)
315 ActiveBasic.Strings.ChrCopy(.Chars, This.Chars, m_Length As SIZE_T)
316 WideCharToMultiByte(CP_THREAD_ACP, 0, text, len, VarPtr(.Chars[m_Length]), lenA, 0, 0)
317 .Chars[m_Length + lenA] = 0
318 End With
319#endif
320 End Function
321
322 Static Function Concat(x As String, y As String) As String
323 If IsNullOrEmpty(x) Then
324 Return y
325 Else
326 Return x.Concat(y.Chars, y.m_Length)
327 End If
328 End Function
329
330 Static Function Concat(x As String, y As String, z As String) As String
331 Dim sb = New Text.StringBuilder(removeNull(x).Length + removeNull(y).Length + removeNull(z).Length)
332 sb.Append(x).Append(y).Append(z)
333 Concat = sb.ToString
334 End Function
335
336 Static Function Concat(x As String, y As String, z As String, w As String) As String
337 Dim sb = New Text.StringBuilder(removeNull(x).Length + removeNull(y).Length + removeNull(z).Length + removeNull(w).Length)
338 sb.Append(x).Append(y).Append(z).Append(w)
339 Concat = sb.ToString
340 End Function
341
342 Static Function Concat(x As Object, y As Object) As String
343 Return Concat(x.ToString, y.ToString)
344 End Function
345
346 Static Function Concat(x As Object, y As Object, z As Object) As String
347 Return Concat(x.ToString, y.ToString, z.ToString)
348 End Function
349
350 Static Function Concat(x As Object, y As Object, z As Object, w As Object) As String
351 Return Concat(x.ToString, y.ToString, z.ToString, w.ToString)
352 End Function
353
354 Const Function Contains(c As Char) As Boolean
355 Return IndexOf(c) >= 0
356 End Function
357
358 Const Function Contains(s As String) As Boolean
359 If ActiveBasic.IsNothing(s) Then
360 Throw New ArgumentNullException("String.Contains: An argument is null value.", "s")
361 ElseIf s = "" Then
362 Return True
363 Else
364 Return IndexOf(s, 0, m_Length) >= 0
365 End If
366 End Function
367
368 Const Function IndexOf(c As Char) As Long
369 Return indexOfCore(c, 0, m_Length)
370 End Function
371
372 Const Function IndexOf(c As Char, start As Long) As Long
373 rangeCheck(start)
374 Return indexOfCore(c, start, m_Length - start)
375 End Function
376
377 Const Function IndexOf(c As Char, start As Long, count As Long) As Long
378 rangeCheck(start, count)
379 Return indexOfCore(c, start, count)
380 End Function
381 Private
382 Const Function indexOfCore(c As Char, start As Long, count As Long) As Long
383 indexOfCore = ActiveBasic.Strings.ChrFind(VarPtr(Chars[start]), count, c) As Long
384 If indexOfCore <> -1 Then
385 indexOfCore += start
386 End If
387 End Function
388 Public
389 Const Function IndexOf(s As String) As Long
390 Return IndexOf(s, 0, m_Length)
391 End Function
392
393 Const Function IndexOf(s As String, startIndex As Long) As Long
394 Return IndexOf(s, startIndex, m_Length - startIndex)
395 End Function
396
397 Const Function IndexOf(s As String, startIndex As Long, count As Long) As Long
398 rangeCheck(startIndex, count)
399 If ActiveBasic.IsNothing(s) Then
400 Throw New ArgumentNullException("String.IndexOf: An argument is out of range value.", "s")
401 End If
402
403 Dim length = s.Length
404 If length = 0 Then Return startIndex
405
406 Dim i As Long, j As Long
407 For i = startIndex To startIndex + count - 1
408 For j = 0 To length - 1
409 If Chars[i + j] = s[j] Then
410 If j = length - 1 Then Return i
411 Else
412 Exit For
413 End If
414 Next
415 Next
416 Return -1
417 End Function
418
419 Const Function LastIndexOf(c As Char) As Long
420 Return lastIndexOf(c, m_Length - 1, m_Length)
421 End Function
422
423 Const Function LastIndexOf(c As Char, start As Long) As Long
424 rangeCheck(start)
425 Return lastIndexOf(c, start, start + 1)
426 End Function
427
428 Const Function LastIndexOf(c As Char, start As Long, count As Long) As Long
429 rangeCheck(start)
430 Dim lastFindPos = start - (count - 1)
431 If Not (m_Length > lastFindPos And lastFindPos >= 0) Then
432 Throw New ArgumentOutOfRangeException("String.LastIndexOf: An argument is out of range value.", "count")
433 End If
434 Return lastIndexOf(c, start, count)
435 End Function
436 Private
437 Const Function lastIndexOf(c As Char, start As Long, count As Long) As Long
438 Dim lastFindPos = start - (count - 1)
439 Dim i As Long
440 For i = start To lastFindPos Step -1
441 If Chars[i] = c Then
442 Return i
443 End If
444 Next
445 Return -1
446 End Function
447
448 Public
449 Const Function LastIndexOf(s As String) As Long
450 Return LastIndexOf(s, m_Length - 1, m_Length)
451 End Function
452
453 Const Function LastIndexOf(s As String, startIndex As Long) As Long
454 Return LastIndexOf(s, startIndex, startIndex + 1)
455 End Function
456
457 Const Function LastIndexOf(s As String, start As Long, count As Long) As Long
458 If ActiveBasic.IsNothing(s) Then
459 Throw New ArgumentNullException("String.LastIndexOf: An argument is out of range value.", "s")
460 End If
461
462 If start < 0 Or start > m_Length - 1 Or _
463 count < 0 Or count > start + 2 Then
464 Throw New ArgumentOutOfRangeException("String.LastIndexOf: One or more arguments are out of range value.", "start or count or both")
465 End If
466 Dim length = s.m_Length
467 If length > m_Length Then Return -1
468 If length = 0 Then Return start
469
470 Dim i As Long, j As Long
471 For i = start To start - count + 1 Step -1
472 For j = length - 1 To 0 Step -1
473 If Chars[i + j] = s[j] Then
474 If j = 0 Then Return i
475 Else
476 Exit For
477 End If
478 Next
479 Next
480 Return -1
481 End Function
482
483 Const Function StartsWith(c As Char) As Boolean
484 Return IndexOf(c) = 0
485 End Function
486
487 Const Function StartsWith(s As String) As Boolean
488 Return IndexOf(s) = 0
489 End Function
490
491 Const Function EndsWith(c As Char) As Boolean
492 Return LastIndexOf(c) = m_Length - 1
493 End Function
494
495 Const Function EndsWith(s As String) As Boolean
496 Return LastIndexOf(s) = m_Length - s.Length
497 End Function
498
499 Const Function Insert(startIndex As Long, text As String) As String
500 Dim sb = New Text.StringBuilder(This)
501 sb.Insert(startIndex, text)
502 Return sb.ToString
503 End Function
504
505 Const Function Substring(startIndex As Long) As String
506 rangeCheck(startIndex)
507 Return Substring(startIndex, m_Length - startIndex)
508 End Function
509
510 Const Function Substring(startIndex As Long, length As Long) As String
511 rangeCheck(startIndex, length)
512 Return New String(Chars, startIndex, length)
513 End Function
514
515 Const Function Remove(startIndex As Long) As String
516 rangeCheck(startIndex)
517 Remove = Substring(0, startIndex)
518 End Function
519
520 Const Function Remove(startIndex As Long, count As Long) As String
521 Dim sb = New Text.StringBuilder(This)
522 sb.Remove(startIndex, count)
523 Remove = sb.ToString
524 End Function
525
526 Static Function IsNullOrEmpty(s As String) As Boolean
527 If Not Object.ReferenceEquals(s, Nothing) Then
528 If s.m_Length > 0 Then
529 Return False
530 End If
531 End If
532 Return True
533 End Function
534
535 Const Function Replace(oldChar As Char, newChar As Char) As String
536 Dim sb = New Text.StringBuilder(This)
537 sb.Replace(oldChar, newChar)
538 Replace = sb.ToString
539 End Function
540
541 Const Function Replace(oldStr As String, newStr As String) As String
542 Dim sb = New Text.StringBuilder(This)
543 sb.Replace(oldStr, newStr)
544 Return sb.ToString
545 End Function
546
547 Function Split(separator As System.Collections.Generic.List<String>) As System.Collections.Generic.List<String>
548 Return Split(separator, -1, StringSplitOptions.None)
549 End Function
550
551 Function Split(separator As System.Collections.Generic.List<String>, options As StringSplitOptions) As System.Collections.Generic.List<String>
552 Return Split(separator, -1, options)
553 End Function
554
555 Function Split(separator As System.Collections.Generic.List<String>, count As Long, options As StringSplitOptions) As System.Collections.Generic.List<String>
556 Dim split As System.Collections.Generic.List<String>
557 Dim index As Long, t1Index As Long, t2Index As Long
558 Dim s As String, substring As String
559 Dim flag As Boolean
560
561 Do
562 t1Index = Length
563 flag = True
564 Foreach s In separator
565 t2Index = IndexOf(s, index)
566 If t2Index > -1 Then
567 t1Index = Math.Min(t1Index, t2Index)
568 flag = False
569 End If
570 Next
571
572 substring = Substring(index, t1Index - index)
573 If Not ( IsNullOrEmpty(substring) and (options = StringSplitOptions.RemoveEmptyEntries) ) Then
574 split.Add(substring)
575 End If
576
577 If flag Then Return split
578 If split.Count = count Then Return split
579
580 index = t1Index + 1
581 Loop
582 End Function
583
584 Static Function Join(separator As String, strings As System.Collections.Generic.List<String>) As String
585 Return Join(separator, strings, 0, strings.Count)
586 End Function
587
588 Static Function Join(separator As String, strings As System.Collections.Generic.List<String>, startIndex As Long, count As Long) As String
589 If (startIndex+count > strings.Count) or (startIndex < 0) or (count < 1) Then
590 Throw New ArgumentOutOfRangeException("String.Join: One or more arguments are out of range value.", "startIndex or count")
591 End If
592
593 Dim string As String
594 Dim i As Long
595 For i = startIndex To startIndex + count - 2
596 string += strings[i] + separator
597 Next
598 Return string + strings[i]
599 End Function
600
601 Const Function ToLower() As String
602 Dim sb = New Text.StringBuilder(m_Length)
603 sb.Length = m_Length
604 Dim i As Long
605 For i = 0 To ELM(m_Length)
606 sb[i] = ActiveBasic.CType.ToLower(Chars[i])
607 Next
608 Return sb.ToString
609 End Function
610
611 Const Function ToUpper() As String
612 Dim sb = New Text.StringBuilder(m_Length)
613 sb.Length = m_Length
614 Dim i As Long
615 For i = 0 To ELM(m_Length)
616 sb[i] = ActiveBasic.CType.ToUpper(Chars[i])
617 Next
618 Return sb.ToString
619 End Function
620
621 Override Function ToString() As String
622 ToString = This
623 End Function
624
625 Const Function Clone() As String
626 Clone = This
627 End Function
628/*
629 Function Clone() As Object
630 Clone = This
631 End Function
632*/
633 Static Function Copy(s As String) As String
634 Copy = New String(s.Chars, s.m_Length)
635 End Function
636
637 Sub CopyTo(sourceIndex As Long, destination As *Char, destinationIndex As Long, count As Long)
638 ActiveBasic.Strings.ChrCopy(VarPtr(destination[destinationIndex]), VarPtr(Chars[sourceIndex]), count As SIZE_T)
639 End Sub
640
641 Override Function GetHashCode() As Long
642#ifdef UNICODE
643 Dim size = m_Length
644#else
645 Dim size = (m_Length + 1) >> 1
646#endif
647 Return _System_GetHashFromWordArray(Chars As *Word, size) Xor m_Length
648 End Function
649
650 Function PadLeft(total As Long) As String
651 PadLeft(total, &h30 As Char)
652 End Function
653
654 Function PadLeft(total As Long, c As Char) As String
655 If total < 0 Then
656 Throw New ArgumentOutOfRangeException("String.PadLeft: An arguments is out of range value.", "total")
657 End If
658 If total >= m_Length Then
659 Return This
660 End If
661 Dim sb = New Text.StringBuilder(total)
662 sb.Append(c, total - m_Length)
663 sb.Append(This)
664 Return sb.ToString
665 End Function
666
667 Function PadRight(total As Long) As String
668 PadRight(total, &h30 As Char)
669 End Function
670
671 Function PadRight(total As Long, c As Char) As String
672 If total < 0 Then
673 Throw New ArgumentOutOfRangeException("String.PadRight: An arguments is out of range value.", "total")
674 End If
675 If total >= m_Length Then
676 Return This
677 End If
678 Dim sb = New Text.StringBuilder(total)
679 sb.Append(This)
680 sb.Append(c, total - m_Length)
681 Return sb.ToString
682 End Function
683 Private
684 Sub AllocStringBuffer(textLength As Long)
685 If textLength < 0 Then
686 Throw New ArgumentException
687 End If
688 Chars = GC_malloc_atomic(SizeOf(Char) * (textLength + 1))
689 m_Length = textLength
690 End Sub
691
692 Sub AssignFromCharPtr(text As *Char, textLength As Long)
693 AllocStringBuffer(textLength)
694 ActiveBasic.Strings.ChrCopy(Chars, text, textLength As SIZE_T)
695 Chars[m_Length] = 0
696 End Sub
697
698 Const Sub rangeCheck(index As Long)
699 If index < 0 Or index > m_Length Then
700 Throw New ArgumentOutOfRangeException("String: An argument is out of range value.", "index")
701 End If
702 End Sub
703
704 Const Sub rangeCheck(start As Long, length As Long)
705 If start < 0 Or start > This.m_Length Or length < 0 Then
706 Throw New ArgumentOutOfRangeException("String: One or more arguments are out of range value.", "start or length or both")
707 End If
708 End Sub
709
710 Static Function removeNull(s As String) As String
711 If ActiveBasic.IsNothing(s) Then
712 removeNull = Empty
713 Else
714 removeNull = s
715 End If
716 End Function
717 End Class
718
719 Enum StringSplitOptions
720 None
721 RemoveEmptyEntries
722 End Enum
723
724End Namespace
Note: See TracBrowser for help on using the repository browser.