DiffListUtility.st
changeset 8933 94e708e9f812
child 9346 4a0b3584f5aa
equal deleted inserted replaced
8932:bd3f49d77ecb 8933:94e708e9f812
       
     1 "{ Package: 'stx:libtool' }"
       
     2 
       
     3 Object subclass:#DiffListUtility
       
     4 	instanceVariableNames:''
       
     5 	classVariableNames:'DiffCommandTemplate'
       
     6 	poolDictionaries:''
       
     7 	category:'Views-Text'
       
     8 !
       
     9 
       
    10 !DiffListUtility class methodsFor:'documentation'!
       
    11 
       
    12 documentation
       
    13 "
       
    14     a utility to encapsulate access to the diff command
       
    15     (may be a facede to a smalltalk-diff algorithm, eventually)
       
    16 
       
    17     [author:]
       
    18         cg (cg@CG-PC)
       
    19 
       
    20     [instance variables:]
       
    21 
       
    22     [class variables:]
       
    23 
       
    24     [see also:]
       
    25 
       
    26 "
       
    27 ! !
       
    28 
       
    29 !DiffListUtility class methodsFor:'defaults'!
       
    30 
       
    31 diffCommand
       
    32     "return the diff-command (with argument placeHolders)"
       
    33 
       
    34     DiffCommandTemplate notNil ifTrue:[ ^ DiffCommandTemplate ].
       
    35 
       
    36     OperatingSystem isMSDOSlike ifTrue:[
       
    37         (OperatingSystem canExecuteCommand:'diff') ifFalse:[
       
    38             'DiffTextView [warning]: no diff command found (please download and unzip "UnxUtils.zip" from "unxutils.sourceforge.net")' infoPrintCR.
       
    39             ^ nil
       
    40         ].
       
    41         ^ 'diff %1 %2'
       
    42     ].
       
    43     ^ 'diff -b %1 %2'
       
    44 
       
    45     "Modified: / 30.1.1998 / 12:12:49 / cg"
       
    46 !
       
    47 
       
    48 diffCommandTemplate:aCommandTemplateString
       
    49     "set the diff-command template"
       
    50 
       
    51     DiffCommandTemplate := aCommandTemplateString
       
    52 ! !
       
    53 
       
    54 !DiffListUtility class methodsFor:'private'!
       
    55 
       
    56 saveForDiff:text as:filename
       
    57     |stream|
       
    58 
       
    59     [
       
    60         stream := filename writeStream.
       
    61         text do:[:line |
       
    62             |lOut i|
       
    63 
       
    64             line notEmptyOrNil ifTrue:[
       
    65                 lOut := line.
       
    66                 (line includes:Character return) ifTrue: [
       
    67                     (line endsWith:Character return) ifTrue:[
       
    68                         lOut := line copyWithoutLast:1.
       
    69                     ] ifFalse:[
       
    70                         i := line indexOf:Character return.
       
    71                         (line at:i+1) == Character nl ifTrue:[
       
    72                             "/ crnl endings
       
    73                             lOut := line copyReplaceString:(String crlf) withString:(String lf).
       
    74                         ] ifFalse:[
       
    75                             "/ cr endings
       
    76                             lOut := line copyReplaceAll:Character return with:Character nl.
       
    77                         ].
       
    78                     ]
       
    79                 ].
       
    80                 lOut bitsPerCharacter > 8 ifTrue:[
       
    81                     (lOut first = (Character value:16rFEFF)) ifTrue:[
       
    82                         lOut := (lOut copyFrom:2) asSingleByteStringIfPossible.
       
    83                     ].
       
    84                     lOut bitsPerCharacter > 8 ifTrue:[ 
       
    85                         lOut := lOut collect:[:ch | ch bitsPerCharacter > 8 
       
    86                                                         ifTrue:[ Character value:16rFF ]
       
    87                                                         ifFalse:[ ch ]].
       
    88                         lOut := lOut asSingleByteStringIfPossible.
       
    89                     ].
       
    90                 ].
       
    91                 stream nextPutAll:lOut.
       
    92             ].
       
    93             stream cr
       
    94         ].
       
    95     ] ensure:[
       
    96         stream close.
       
    97     ].
       
    98 
       
    99     "Modified: / 22-10-2008 / 17:52:52 / cg"
       
   100 ! !
       
   101 
       
   102 !DiffListUtility class methodsFor:'utilities'!
       
   103 
       
   104 diffListFor:text1 and:text2
       
   105     "execute DiffCommand to get a list of diffs."
       
   106 
       
   107     "
       
   108      The returned list is in raw-diff output format, such as:
       
   109         1 : '1c1'
       
   110         2 : '< hello world'
       
   111         3 : '---'
       
   112         4 : '> Hello World'
       
   113         5 : '2a3'
       
   114         6 : '> line2'
       
   115         7 : '4d4'
       
   116         8 : '< line4'
       
   117     "
       
   118 
       
   119     |tmpFile1 tmpFile2 stream line 
       
   120      diffList diffTemplate diffCmd|
       
   121 
       
   122     diffTemplate := self diffCommand.
       
   123     diffTemplate isNil ifTrue:[
       
   124         "/ self warn:'no diff command available'.
       
   125         ^ nil
       
   126     ].
       
   127 
       
   128     text1 = text2 ifTrue:[
       
   129         "no diff"
       
   130         ^ #()
       
   131     ].
       
   132 
       
   133     "
       
   134      save them texts in two temporary files ...
       
   135     "
       
   136     [
       
   137         self saveForDiff:text1 as:(tmpFile1 := Filename newTemporary).
       
   138         self saveForDiff:text2 as:(tmpFile2 := Filename newTemporary).
       
   139 
       
   140         "
       
   141          start diff on it ...
       
   142         "
       
   143         diffCmd := diffTemplate
       
   144                     bindWith:tmpFile1 asString
       
   145                     with:tmpFile2 asString.
       
   146 
       
   147         stream := PipeStream readingFrom:diffCmd.
       
   148         stream isNil ifTrue:[
       
   149             stream := PipeStream readingFrom:('support' , Filename separator , diffCmd).
       
   150             stream isNil ifTrue:[
       
   151                 self error:'cannot execute diff' mayProceed:true.
       
   152                 ^ nil.
       
   153             ]
       
   154         ].
       
   155 
       
   156         diffList := OrderedCollection new.
       
   157         (stream readWaitWithTimeout:10) ifTrue:[
       
   158             "/ timeout
       
   159             stream close.
       
   160             self error:'cannot execute diff (timeout)' mayProceed:true.
       
   161             ^ nil.
       
   162         ].
       
   163 
       
   164         [stream atEnd] whileFalse:[
       
   165             line := stream nextLine.
       
   166             line notNil ifTrue:[diffList add:line]
       
   167         ].
       
   168         stream close.
       
   169     ] ensure:[
       
   170         tmpFile1 notNil ifTrue:[ tmpFile1 delete ].
       
   171         tmpFile2 notNil ifTrue:[ tmpFile2 delete ].
       
   172     ].
       
   173     ^ diffList
       
   174 
       
   175     "
       
   176      self 
       
   177         diffListFor:#(
       
   178                         'hello world'
       
   179                         'line1'
       
   180                         'line3'
       
   181                         'line4'
       
   182                     )
       
   183         and:        #(
       
   184                         'Hello World'
       
   185                         'line1'
       
   186                         'line2'
       
   187                         'line3'
       
   188                     )
       
   189     "
       
   190 ! !
       
   191 
       
   192 !DiffListUtility class methodsFor:'documentation'!
       
   193 
       
   194 version_CVS
       
   195     ^ '$Header: /cvs/stx/stx/libtool/DiffListUtility.st,v 1.1 2009-10-10 10:08:51 cg Exp $'
       
   196 ! !