VersionDiffBrowser.st
changeset 2695 6cf8801118a3
parent 2694 a19deafda6b0
child 2697 b4f4e431b71e
equal deleted inserted replaced
2694:a19deafda6b0 2695:6cf8801118a3
    19 	poolDictionaries:''
    19 	poolDictionaries:''
    20 	category:'Interface-Browsers'
    20 	category:'Interface-Browsers'
    21 !
    21 !
    22 
    22 
    23 HierarchicalItem subclass:#ClassChangeSet
    23 HierarchicalItem subclass:#ClassChangeSet
    24 	instanceVariableNames:'classBeingCompared labelA labelB changeSet onlyInA onlyInB
    24 	instanceVariableNames:'classBeingCompared labelA labelB diffSet onlyInA onlyInB
    25 		changedMethods'
    25 		changedMethods'
    26 	classVariableNames:''
    26 	classVariableNames:''
    27 	poolDictionaries:''
    27 	poolDictionaries:''
    28 	privateIn:VersionDiffBrowser
    28 	privateIn:VersionDiffBrowser
    29 !
    29 !
    90        #(#WindowSpec
    90        #(#WindowSpec
    91           #label: 'Version DiffBrowser'
    91           #label: 'Version DiffBrowser'
    92           #name: 'Version DiffBrowser'
    92           #name: 'Version DiffBrowser'
    93           #min: #(#Point 10 10)
    93           #min: #(#Point 10 10)
    94           #max: #(#Point nil nil)
    94           #max: #(#Point nil nil)
    95           #bounds: #(#Rectangle 294 23 1159 527)
    95           #bounds: #(#Rectangle 12 22 877 526)
    96           #menu: #mainMenu
    96           #menu: #mainMenu
    97         )
    97         )
    98         #component: 
    98         #component: 
    99        #(#SpecCollection
    99        #(#SpecCollection
   100           #collection: #(
   100           #collection: #(
   450         nil
   450         nil
   451         nil
   451         nil
   452       )
   452       )
   453 ! !
   453 ! !
   454 
   454 
       
   455 !VersionDiffBrowser class methodsFor:'plugIn spec'!
       
   456 
       
   457 aspectSelectors
       
   458     "This resource specification was automatically generated
       
   459      by the UIPainter of ST/X."
       
   460 
       
   461     "Do not manually edit this. If it is corrupted,
       
   462      the UIPainter may not be able to read the specification."
       
   463 
       
   464     "Return a description of exported aspects;
       
   465      these can be connected to aspects of an embedding application
       
   466      (if this app is embedded in a subCanvas)."
       
   467 
       
   468     ^ #(
       
   469         #changedLabelHolder
       
   470         #onlyInALabelHolder
       
   471         #onlyInBLabelHolder
       
   472       ).
       
   473 
       
   474 ! !
       
   475 
   455 !VersionDiffBrowser class methodsFor:'startup'!
   476 !VersionDiffBrowser class methodsFor:'startup'!
   456 
   477 
   457 openOnClass:aClass labelA:aLabelA sourceA:aSourceA labelB:aLabelB sourceB:aSourceB 
   478 openOnClass:aClass againstVersion:aVersionA 
   458 "
   479 "
   459 create an VersionDiffBrowser instance and set the class change set of the
   480 create an VersionDiffBrowser instance and set the class change set of the
   460 broswer. The class change set is generated from two source files.
   481 browser. The class diff set is generated from classes current against some version
       
   482 via the source code manager .
   461 
   483 
   462 <return: VersionDiffBrowser>
   484 <return: VersionDiffBrowser>
   463 "
   485 "
   464     |theBrowser|
   486     |theBrowser|
   465 
   487 
   466     theBrowser := self new.
   488     theBrowser := self new.
   467     theBrowser allButOpen.
   489     theBrowser allButOpen.
   468     theBrowser classChangeSet:(ClassChangeSet newForClass:aClass labelA:aLabelA sourceA:aSourceA labelB:aLabelB sourceB:aSourceB).
   490     theBrowser setupForClass:aClass againstVersion:aVersionA.
   469     theBrowser openWindow.
   491     theBrowser openWindow.
   470     ^ theBrowser.
   492     ^ theBrowser.
   471 
   493 
   472 !
   494     "
   473 
   495      self openOnClass:Array againstVersion:'1.116'
   474 openOnClass:aClass versionA:aVersionA versionB:aVersionB
   496      self openOnClass:Array againstVersion:nil            - against the version on which Array is based upon
       
   497      self openOnClass:Array againstVersion:#newest        - against the newest repository version
       
   498 
       
   499      self openOnClass:VersionDiffBrowser againstVersion:nil
       
   500      self openOnClass:VersionDiffBrowser againstVersion:#newest
       
   501     "
       
   502 !
       
   503 
       
   504 openOnClass:aClass labelA:aLabelA sourceA:aSourceA labelB:aLabelB sourceB:aSourceB 
   475 "
   505 "
   476 create an VersionDiffBrowser instance and set the class change set of the
   506 create an VersionDiffBrowser instance and set the class change set of the
   477 broswer. The class change set is generated from two class versions via
   507 browser. The class diff set is generated from two source files.
   478 the source code manager .
       
   479 
   508 
   480 <return: VersionDiffBrowser>
   509 <return: VersionDiffBrowser>
   481 "
   510 "
   482     |theBrowser|
   511     |theBrowser|
   483 
   512 
   484     theBrowser := self new.
   513     theBrowser := self new.
   485     theBrowser allButOpen.
   514     theBrowser allButOpen.
   486     theBrowser classChangeSet:(ClassChangeSet newForClass:aClass versionA:aVersionA versionB:aVersionB).
   515     theBrowser setupForClass:aClass labelA:aLabelA sourceA:aSourceA labelB:aLabelB sourceB:aSourceB.
       
   516     theBrowser openWindow.
       
   517     ^ theBrowser.
       
   518 
       
   519 
       
   520 !
       
   521 
       
   522 openOnClass:aClass versionA:aVersionA versionB:aVersionB
       
   523 "
       
   524 create an VersionDiffBrowser instance and set the class change set of the
       
   525 browser. The class diff set is generated from two class versions via
       
   526 the source code manager .
       
   527 
       
   528 <return: VersionDiffBrowser>
       
   529 "
       
   530     |theBrowser|
       
   531 
       
   532     theBrowser := self new.
       
   533     theBrowser allButOpen.
       
   534     theBrowser setupForClass:aClass versionA:aVersionA versionB:aVersionB.
   487     theBrowser openWindow.
   535     theBrowser openWindow.
   488     ^ theBrowser.
   536     ^ theBrowser.
   489 
   537 
   490     "
   538     "
   491      self openOnClass:Array versionA:'1.116' versionB:'1.113'
   539      self openOnClass:Array versionA:'1.116' versionB:'1.113'
   625 the selection in the list of the 'changed methods' changed.
   673 the selection in the list of the 'changed methods' changed.
   626 Reset the selection of the two other lists and calc the method change.
   674 Reset the selection of the two other lists and calc the method change.
   627 
   675 
   628 <return: self>
   676 <return: self>
   629 "
   677 "
   630     |sel idxA idxB changeA changeB|
   678     |sel idxA idxB changeA changeB methodsChanged|
   631 
   679 
   632     sel := self methodsChangedSelection value.
   680     sel := self methodsChangedSelection value.
   633     sel notNil ifTrue:[
   681     sel notNil ifTrue:[
   634         self methodsOnlyInASelection value:nil.
   682         self methodsOnlyInASelection value:nil.
   635         self methodsOnlyInBSelection value:nil.
   683         self methodsOnlyInBSelection value:nil.
   636         changeA := (self classChangeSet methodsChanged at:sel) first.
   684         methodsChanged := self classChangeSet methodsChanged.
   637         changeB := (self classChangeSet methodsChanged at:sel) second.
   685         changeA := (methodsChanged at:sel) first.
       
   686         changeB := (methodsChanged at:sel) second.
   638         self withReadCursorDo:[
   687         self withReadCursorDo:[
   639             self diffTextView text1:changeA source text2:changeB source.
   688             self diffTextView text1:changeA source text2:changeB source.
   640             self diffTextView moveToNextChanged
   689             self diffTextView moveToNextChanged
   641         ].
   690         ].
   642         self showDiffTextView.
   691         self showDiffTextView.
   903 
   952 
   904     (holder := builder bindingAt:#onlyInBLabelHolder) isNil ifTrue:[
   953     (holder := builder bindingAt:#onlyInBLabelHolder) isNil ifTrue:[
   905         builder aspectAt:#onlyInBLabelHolder put:(holder :=  ValueHolder new).
   954         builder aspectAt:#onlyInBLabelHolder put:(holder :=  ValueHolder new).
   906     ].
   955     ].
   907     ^ holder.
   956     ^ holder.
       
   957 ! !
       
   958 
       
   959 !VersionDiffBrowser methodsFor:'aspects - exported'!
       
   960 
       
   961 changedLabelHolder:aValueHolder
       
   962     builder aspectAt:#changedLabelHolder put:aValueHolder.
       
   963 
       
   964 !
       
   965 
       
   966 classHolder:aValueHolder
       
   967     |holder|
       
   968 
       
   969     (holder := builder bindingAt:#classHolder) notNil ifTrue:[
       
   970         holder removeDependent:self
       
   971     ].
       
   972     builder aspectAt:#classHolder put:aValueHolder.
       
   973     aValueHolder notNil ifTrue:[
       
   974         aValueHolder addDependent:self
       
   975     ]
       
   976 !
       
   977 
       
   978 onlyInALabelHolder:aValueHolder
       
   979     builder aspectAt:#onlyInALabelHolder put:aValueHolder.
       
   980 !
       
   981 
       
   982 onlyInBLabelHolder:aValueHolder
       
   983     builder aspectAt:#onlyInBLabelHolder put:aValueHolder.
       
   984 !
       
   985 
       
   986 versionAHolder:aValueHolder
       
   987     |holder|
       
   988 
       
   989     (holder := builder bindingAt:#versionAHolder) notNil ifTrue:[
       
   990         holder removeDependent:self
       
   991     ].
       
   992     builder aspectAt:#versionAHolder put:aValueHolder.
       
   993     aValueHolder notNil ifTrue:[
       
   994         aValueHolder addDependent:self
       
   995     ]
       
   996 !
       
   997 
       
   998 versionBHolder:aValueHolder
       
   999     |holder|
       
  1000 
       
  1001     (holder := builder bindingAt:#versionBHolder) notNil ifTrue:[
       
  1002         holder removeDependent:self
       
  1003     ].
       
  1004     builder aspectAt:#versionBHolder put:aValueHolder.
       
  1005     aValueHolder notNil ifTrue:[
       
  1006         aValueHolder addDependent:self
       
  1007     ]
       
  1008 ! !
       
  1009 
       
  1010 !VersionDiffBrowser methodsFor:'change & update'!
       
  1011 
       
  1012 update:something with:parameter from:changedObject
       
  1013     |classHolder versionAHolder versionBHolder|
       
  1014 
       
  1015     classHolder := self classHolder.
       
  1016     versionAHolder := self versionAHolder.
       
  1017     versionBHolder := self versionBHolder.
       
  1018 
       
  1019     (changedObject == classHolder 
       
  1020     or:[changedObject == versionAHolder
       
  1021     or:[changedObject == versionBHolder]]) ifTrue:[
       
  1022         self setupForClass:(classHolder value) versionA:(versionAHolder value) versionB:(versionBHolder value)
       
  1023 .        ^ self
       
  1024     ].
       
  1025     super update:something with:parameter from:changedObject
   908 ! !
  1026 ! !
   909 
  1027 
   910 !VersionDiffBrowser methodsFor:'initialization & release'!
  1028 !VersionDiffBrowser methodsFor:'initialization & release'!
   911 
  1029 
   912 postBuildWith:aBuilder
  1030 postBuildWith:aBuilder
  1213                                   or:[self methodsOnlyInB notEmpty])]) not.
  1331                                   or:[self methodsOnlyInB notEmpty])]) not.
  1214 ! !
  1332 ! !
  1215 
  1333 
  1216 !VersionDiffBrowser methodsFor:'setup'!
  1334 !VersionDiffBrowser methodsFor:'setup'!
  1217 
  1335 
       
  1336 setupForClass:aClass againstVersion:aVersionA
       
  1337 "
       
  1338 compute the class change set for the class aClass of its current version against the repository version A.
       
  1339 When setting the class change set, the labels, list etc. of the receiver
       
  1340 are updated.
       
  1341 
       
  1342 <return: self>
       
  1343 "
       
  1344     self classChangeSet:(ClassChangeSet newForClass:aClass againstVersion:aVersionA)
       
  1345 !
       
  1346 
  1218 setupForClass:aClass labelA:aLabelA sourceA:aSourceA labelB:aLabelB sourceB:aSourceB
  1347 setupForClass:aClass labelA:aLabelA sourceA:aSourceA labelB:aLabelB sourceB:aSourceB
  1219 "
  1348 "
  1220 generate the class change set from the two source files A and B.
  1349 generate the class change set from the two source files A and B.
  1221 When setting the class change set, the labels, list etc. of the receiver
  1350 When setting the class change set, the labels, list etc. of the receiver
  1222 are updated.
  1351 are updated.
  1297     ]
  1426     ]
  1298 ! !
  1427 ! !
  1299 
  1428 
  1300 !VersionDiffBrowser::ClassChangeSet class methodsFor:'instance creation'!
  1429 !VersionDiffBrowser::ClassChangeSet class methodsFor:'instance creation'!
  1301 
  1430 
       
  1431 changeSetForClass:aClass 
       
  1432 "return a ChangeSet for the class aClass and its current source.
       
  1433 The source is generated into a stream and then the change set is generated
       
  1434 from the source stream.
       
  1435 
       
  1436 <return: ChangeSet|nil>
       
  1437 "
       
  1438     |theChangeSet source s|
       
  1439 
       
  1440     s := '' writeStream.
       
  1441     aClass fileOutOn:s.
       
  1442     source := s contents.
       
  1443 
       
  1444     theChangeSet := ChangeSet fromStream:(source readStream).
       
  1445     ^theChangeSet
       
  1446 !
       
  1447 
  1302 changeSetForClass:aClass andRevision:aVersion
  1448 changeSetForClass:aClass andRevision:aVersion
  1303 "return a ChangeSet for the class aClass and version aVersion.
  1449 "return a ChangeSet for the class aClass and version aVersion.
  1304 The version from the class source stream is checked out from the repositiory
  1450 The version from the class source stream is checked out from the repositiory
  1305 into a source stream. Then the change set is generated from the source stream.
  1451 into a source stream. Then the change set is generated from the source stream.
  1306 
  1452 
  1330         ifTrue:[theChangeSet:=ChangeSet fromStream:(theSourceStream := aSource readStream)]]
  1476         ifTrue:[theChangeSet:=ChangeSet fromStream:(theSourceStream := aSource readStream)]]
  1331     valueNowOrOnUnwindDo:
  1477     valueNowOrOnUnwindDo:
  1332         [theSourceStream notNil
  1478         [theSourceStream notNil
  1333             ifTrue:[theSourceStream close]].
  1479             ifTrue:[theSourceStream close]].
  1334     ^theChangeSet
  1480     ^theChangeSet
       
  1481 !
       
  1482 
       
  1483 newForClass:aClass againstVersion:aVersionA
       
  1484 "return a ClassChangeSet for the class aClass against some verison in the repository.
       
  1485 A new instance of ClassChangeSet is generated containing 
       
  1486 the correspondenting changes.
       
  1487 
       
  1488 <return: ClassChangeSet>
       
  1489 "
       
  1490     |theChangeSetA theChangeSetB theClassChangeSet versionCompared|
       
  1491 
       
  1492     theClassChangeSet := self new.
       
  1493     theClassChangeSet classBeingCompared:aClass.
       
  1494     versionCompared := aVersionA.
       
  1495     aVersionA isNil ifTrue:[
       
  1496         theClassChangeSet labelA:(versionCompared := aClass revision).
       
  1497     ] ifFalse:[
       
  1498         aVersionA == #newest ifTrue:[
       
  1499             theClassChangeSet labelA:'newest'.
       
  1500         ] ifFalse:[
       
  1501             theClassChangeSet labelA:versionCompared.
       
  1502         ]
       
  1503     ].
       
  1504     theClassChangeSet labelB:'current'.
       
  1505     theChangeSetA := self changeSetForClass: aClass andRevision: versionCompared.
       
  1506     theChangeSetB := self changeSetForClass: aClass.
       
  1507     theChangeSetA isNil
       
  1508         ifTrue: [theChangeSetA := ChangeSet new].
       
  1509     theChangeSetB isNil
       
  1510         ifTrue: [theChangeSetB := ChangeSet new].
       
  1511     ^theClassChangeSet diffSet:(theChangeSetA diffSetsAgainst:theChangeSetB)
       
  1512 
  1335 !
  1513 !
  1336 
  1514 
  1337 newForClass:aClass labelA:aLabelA sourceA:aSourceA labelB:aLabelB sourceB:aSourceB
  1515 newForClass:aClass labelA:aLabelA sourceA:aSourceA labelB:aLabelB sourceB:aSourceB
  1338 "return a ClassChangeSet for the class aClass and the two sources.
  1516 "return a ClassChangeSet for the class aClass and the two sources.
  1339 The two classes are compared via the source files. A new instance of 
  1517 The two classes are compared via the source files. A new instance of 
  1351     theChangeSetB:=self changeSetForClass:aClass andSource:aSourceB.
  1529     theChangeSetB:=self changeSetForClass:aClass andSource:aSourceB.
  1352     theChangeSetA isNil
  1530     theChangeSetA isNil
  1353         ifTrue: [theChangeSetA := ChangeSet new].
  1531         ifTrue: [theChangeSetA := ChangeSet new].
  1354     theChangeSetB isNil
  1532     theChangeSetB isNil
  1355         ifTrue: [theChangeSetB := ChangeSet new].
  1533         ifTrue: [theChangeSetB := ChangeSet new].
  1356     ^theClassChangeSet changeSet:(theChangeSetA diffSetsAgainst:theChangeSetB)
  1534     ^theClassChangeSet diffSet:(theChangeSetA diffSetsAgainst:theChangeSetB)
  1357 !
  1535 !
  1358 
  1536 
  1359 newForClass:aClass versionA:aVersionA versionB:aVersionB
  1537 newForClass:aClass versionA:aVersionA versionB:aVersionB
  1360 "return a ClassChangeSet for the class aClass and the two versions.
  1538 "return a ClassChangeSet for the class aClass and the two versions.
  1361 The two class version are checked out from the repository and then being
  1539 The two class version are checked out from the repository and then being
  1374     theChangeSetB := self changeSetForClass: aClass andRevision: aVersionB.
  1552     theChangeSetB := self changeSetForClass: aClass andRevision: aVersionB.
  1375     theChangeSetA isNil
  1553     theChangeSetA isNil
  1376         ifTrue: [theChangeSetA := ChangeSet new].
  1554         ifTrue: [theChangeSetA := ChangeSet new].
  1377     theChangeSetB isNil
  1555     theChangeSetB isNil
  1378         ifTrue: [theChangeSetB := ChangeSet new].
  1556         ifTrue: [theChangeSetB := ChangeSet new].
  1379     ^theClassChangeSet changeSet:(theChangeSetA diffSetsAgainst:theChangeSetB)
  1557     ^theClassChangeSet diffSet:(theChangeSetA diffSetsAgainst:theChangeSetB)
  1380 
  1558 
  1381 ! !
  1559 ! !
  1382 
  1560 
  1383 !VersionDiffBrowser::ClassChangeSet methodsFor:'accessing'!
  1561 !VersionDiffBrowser::ClassChangeSet methodsFor:'accessing'!
  1384 
  1562 
  1385 changeSet
  1563 classBeingCompared
       
  1564 "returns the value of the class which is compared
       
  1565 
       
  1566 <return: Behavior>
       
  1567 "
       
  1568 
       
  1569     ^ classBeingCompared
       
  1570 !
       
  1571 
       
  1572 classBeingCompared:something
       
  1573 "set the value of the class which is compared
       
  1574 
       
  1575 <return: self>"
       
  1576 
       
  1577     classBeingCompared := something.
       
  1578 !
       
  1579 
       
  1580 diffSet
  1386 "returns a identity dictionary containing the different changes.
  1581 "returns a identity dictionary containing the different changes.
  1387 key:            value:
  1582 key:            value:
  1388 #changed        OrderedCollection of arrays containing ChangeSets for methods 
  1583 #changed        OrderedCollection of arrays containing ChangeSets for methods 
  1389                 which are changed and exists in the class versionA and versionB
  1584                 which are changed and exists in the class versionA and versionB
  1390 #onlyInArg      ChangeSet for the methods which exists only in the class versionB
  1585 #onlyInArg      ChangeSet for the methods which exists only in the class versionB
  1391 #onlyInReceiver ChangeSet for the methods which exists only in the class versionA
  1586 #onlyInReceiver ChangeSet for the methods which exists only in the class versionA
  1392 
  1587 
  1393 <return: IdentityDictionary>
  1588 <return: IdentityDictionary>
  1394 "  
  1589 "  
  1395     ^ changeSet
  1590     ^ diffSet
  1396 !
  1591 !
  1397 
  1592 
  1398 changeSet:something
  1593 diffSet:something
  1399 "sets a identity dictionary containing the different changes.
  1594 "sets a identity dictionary containing the different changes.
  1400 key:            value:
  1595 key:            value:
  1401 #changed        OrderedCollection of arrays containing ChangeSets for methods 
  1596 #changed        OrderedCollection of arrays containing ChangeSets for methods 
  1402                 which are changed and exists in the class versionA and versionB
  1597                 which are changed and exists in the class versionA and versionB
  1403 #onlyInArg      ChangeSet for the methods which exists only in the class versionB
  1598 #onlyInArg      ChangeSet for the methods which exists only in the class versionB
  1404 #onlyInReceiver ChangeSet for the methods which exists only in the class versionA
  1599 #onlyInReceiver ChangeSet for the methods which exists only in the class versionA
  1405 
  1600 
  1406 <return: self>
  1601 <return: self>
  1407 "  
  1602 "  
  1408 
  1603 
  1409     changeSet := something.
  1604     diffSet := something.
  1410 !
       
  1411 
       
  1412 classBeingCompared
       
  1413 "returns the value of the class which is compared
       
  1414 
       
  1415 <return: Behavior>
       
  1416 "
       
  1417 
       
  1418     ^ classBeingCompared
       
  1419 !
       
  1420 
       
  1421 classBeingCompared:something
       
  1422 "set the value of the class which is compared
       
  1423 
       
  1424 <return: self>"
       
  1425 
       
  1426     classBeingCompared := something.
       
  1427 !
  1605 !
  1428 
  1606 
  1429 labelA
  1607 labelA
  1430 "returns the label for the class versionA
  1608 "returns the label for the class versionA
  1431 
  1609 
  1463 "returns a  OrderedCollection of arrays containing ChangeSets for methods 
  1641 "returns a  OrderedCollection of arrays containing ChangeSets for methods 
  1464 which are changed and exists in the class versionA and versionB
  1642 which are changed and exists in the class versionA and versionB
  1465 
  1643 
  1466 <return: OrderedCollection>
  1644 <return: OrderedCollection>
  1467 "
  1645 "
  1468     ^ self changeSet at:#changed
  1646     ^ self diffSet at:#changed
  1469 !
  1647 !
  1470 
  1648 
  1471 methodsOnlyInA
  1649 methodsOnlyInA
  1472 "returns a ChangeSet for the methods which exists only in the class versionA
  1650 "returns a ChangeSet for the methods which exists only in the class versionA
  1473 
  1651 
  1474 <return: ChangeSet>
  1652 <return: ChangeSet>
  1475 "  
  1653 "  
  1476 
  1654 
  1477     ^ self changeSet at:#onlyInReceiver
  1655     ^ self diffSet at:#onlyInReceiver
  1478 !
  1656 !
  1479 
  1657 
  1480 methodsOnlyInB
  1658 methodsOnlyInB
  1481 "returns a ChangeSet for the methods which exists only in the class versionB
  1659 "returns a ChangeSet for the methods which exists only in the class versionB
  1482 
  1660 
  1483 <return: ChangeSet>
  1661 <return: ChangeSet>
  1484 "  
  1662 "  
  1485 
  1663 
  1486     ^ self changeSet at:#onlyInArg
  1664     ^ self diffSet at:#onlyInArg
  1487 ! !
  1665 ! !
  1488 
  1666 
  1489 !VersionDiffBrowser class methodsFor:'documentation'!
  1667 !VersionDiffBrowser class methodsFor:'documentation'!
  1490 
  1668 
  1491 version
  1669 version
  1492     ^ '$Header: /cvs/stx/stx/libtool/VersionDiffBrowser.st,v 1.23 2000-08-10 09:50:49 cg Exp $'
  1670     ^ '$Header: /cvs/stx/stx/libtool/VersionDiffBrowser.st,v 1.24 2000-08-11 17:35:06 cg Exp $'
  1493 ! !
  1671 ! !