new goodies (bells & whistles upon claus's request)
authorClaus Gittinger <cg@exept.de>
Thu, 29 Feb 1996 21:01:28 +0100
changeset 1049 6f7b6c18a748
parent 1048 c535c5a73cba
child 1050 2f14bbd792a9
new goodies (bells & whistles upon claus's request)
Filename.st
--- a/Filename.st	Thu Feb 29 18:29:46 1996 +0100
+++ b/Filename.st	Thu Feb 29 21:01:28 1996 +0100
@@ -216,6 +216,42 @@
     "
 !
 
+fromComponents:aCollectionOfDirectoryNames
+    "create & return a new filename from components given in
+     aCollectionOfDirectoryNames. If the first component is the name of the
+     root directory (i.e. '/') an absolute path-filename is returned."
+
+    |sep s|
+
+    sep := self separator asString.
+    s := ''.
+    aCollectionOfDirectoryNames keysAndValuesDo:[:index :component |
+        index == 1 ifTrue:[
+            (component ~= sep 
+            or:[aCollectionOfDirectoryNames size == 1]) ifTrue:[
+                s := s , component
+            ]
+        ] ifFalse:[
+            s := s , '/' , component
+        ].
+    ].
+    ^ self named:s
+
+    "
+     Filename fromComponents:#('/' 'foo' 'bar' 'baz')  
+     Filename fromComponents:#('foo' 'bar' 'baz')  
+     Filename fromComponents:#('/')  
+
+     Filename fromComponents:
+         (Filename components:('.' asFilename pathName))
+
+     Filename fromComponents:
+         (Filename components:('.' asFilename name)) 
+    "
+
+    "Modified: 29.2.1996 / 20:18:34 / cg"
+!
+
 fromUser
     "show a box to enter a filename. Return a filename instance or
      nil (if cancel was pressed)."
@@ -231,6 +267,26 @@
     "
 !
 
+homeDirectory
+    "return your homeDirectory.
+     Some OperatingSystems do not support this - on those, the defaultDirectory
+     (which is the currentDirectory) is returned."
+
+    |s|
+
+    s := OperatingSystem getHomeDirectory.
+    s isNil ifTrue:[
+        ^ self defaultDirectory
+    ].
+    ^ s asFilename
+
+    "
+     Filename homeDirectory        
+    "
+
+    "Modified: 29.2.1996 / 21:00:31 / cg"
+!
+
 named:aString
     "return a filename for a directory named aString.
      This is the same as 'aString asFilename'."
@@ -327,6 +383,30 @@
 
 !Filename class methodsFor:'queries'!
 
+components:aString
+    "separate the pathName given by aString into 
+     a collection containing the directory components and the files name as
+     the final component.
+     If the argument names an absolute path, the first component will be the
+     name of the root directory (i.e. '/')."
+
+    |components|
+
+    components := aString asCollectionOfSubstringsSeparatedBy:(self separator).
+    components first isEmpty ifTrue:[
+        components at:1 put:(self separator asString)
+    ].
+    ^ components
+
+
+    "
+     Filename components:'/foo/bar/baz' 
+     Filename components:'foo/bar/baz'  
+    "
+
+    "Modified: 29.2.1996 / 20:06:38 / cg"
+!
+
 defaultClass
     "ST-80 compatibility:
      in ST-80, different subclasses of Filename are used for different
@@ -445,6 +525,16 @@
     "Modified: 7.9.1995 / 10:44:56 / claus"
 !
 
+maxLength
+    "return the maximum number of characters a filename may be in size.
+     This depends on the OperatingSystem."
+
+    ^ OperatingSystem maxFileNameLength
+
+    "Created: 29.2.1996 / 20:57:11 / cg"
+    "Modified: 29.2.1996 / 20:57:46 / cg"
+!
+
 parentDirectoryName 
     "return the name used for the parent directory.
      This is '..' for unix and dos-like systems. 
@@ -1046,18 +1136,6 @@
 
 !Filename methodsFor:'file utilities'!
 
-contentsOfEntireFile
-    "return the contents of the file as a string"
-
-    |s contents|
-
-    s := self readStream.
-    [
-	contents := s contents
-    ] valueNowOrOnUnwindDo:[s close].
-    ^ contents
-!
-
 edit
     "start an editView on the file represented by the receiver"
 
@@ -1078,8 +1156,9 @@
 
 construct:subname
     "taking the receiver as a directory name, construct a new
-     filename for an entry within this directory (i.e. for a file
-     or a subdirectory in that directory)."
+     filename for an entry within this directory 
+     (i.e. for a file or a subdirectory in that directory).
+     See also: #withSuffix: (which is different, but often needed)"
 
     ^ (self constructString:subname) asFilename
 
@@ -1089,19 +1168,21 @@
      '/usr/tmp' asFilename construct:'foo'
      '/foo/bar' asFilename construct:'baz' 
     "
+
+    "Modified: 29.2.1996 / 20:55:06 / cg"
 !
 
 constructString:subname
     "taking the receiver as a directory name, construct a new
-     filenames string for an entry within this directory (i.e. for a file
-     or a subdirectory in that directory)."
+     filenames string for an entry within this directory 
+     (i.e. for a file or a subdirectory in that directory)."
 
     |sepString|
 
     sepString := self class separator asString.
     nameString = sepString ifTrue:[
-	"I am the root"
-	^ sepString  , subname
+        "I am the root"
+        ^ sepString  , subname
     ].
     ^ nameString , sepString , subname asString
 
@@ -1113,6 +1194,7 @@
     "
 
     "Modified: 7.9.1995 / 10:15:22 / claus"
+    "Modified: 29.2.1996 / 20:55:18 / cg"
 ! !
 
 !Filename methodsFor:'misc'!
@@ -1121,14 +1203,19 @@
     "this allows filenames to understand how names are concatenated.
      Returns a string consisting of the receivers name, concatenated
      by aString. Notice this is NOT the same as construct:, which inserts
-     a directory delimiter and returns a new fileName instance."
+     a directory delimiter and returns a new fileName instance.
+     See also: #withSuffix: which is new and better."
 
     ^ (nameString , aString asString)
 
     "
-     'Makefile' asFilename , '.bak' 
-     'Makefile' asFilename construct:'.bak' 
+     'Makefile' asFilename , '.bak'        
+     ('Makefile' asFilename , '.bak') asFilename  
+     'Makefile' asFilename withSuffix:'bak' 
+     'Makefile' asFilename construct:'.bak'     
     "
+
+    "Modified: 29.2.1996 / 20:54:12 / cg"
 ! !
 
 !Filename methodsFor:'printing & storing'!
@@ -1160,23 +1247,6 @@
 
 !Filename methodsFor:'queries'!
 
-baseName
-    "return my baseName as a string.
-     - thats the file/directory name without leading parent-dirs."
-
-    ^ OperatingSystem baseNameOf:nameString "/ (self pathName) 
-
-    "
-     '/foo/bar' asFilename baseName  
-     '.' asFilename baseName          
-     '..' asFilename baseName         
-     '../..' asFilename baseName        
-     '../../libbasic' asFilename baseName        
-     '../../libpr' asFilename baseName        
-     '../../libbasic/Object.st' asFilename baseName        
-    "
-!
-
 canBeWritten
     "same as isWritable - for ST-80 compatibility"
 
@@ -1189,72 +1259,6 @@
     "
 !
 
-directory
-    "return the directory name part of the file/directory as a filename.
-     - thats a filename for the directory where the file/dir represented by
-       the receiver is contained in."
-
-    ^ self directoryName asFilename
-
-    "
-     '/foo/bar' asFilename directory
-     '.' asFilename directory        
-     '..' asFilename directory       
-     '../..' asFilename directory     
-    "
-!
-
-directoryContents
-    "return the contents of the directory as a collection of strings"
-
-    ^ (FileDirectory directoryNamed:self asString) contents
-
-    "
-     '.' asFilename directoryContents
-    "
-!
-
-directoryName
-    "return the directory name part of the file/directory as a string.
-     - thats the name of the directory where the file/dir represented by
-       the receiver is contained in.
-     See also: #directoryPathName"
-
-    ^ OperatingSystem directoryNameOf:nameString "/ (self pathName)
-
-    "
-     '/foo/bar/' asFilename directoryName    
-     '/foo/bar' asFilename directoryName    
-     'bitmaps' asFilename directoryName        
-     'bitmaps' asFilename directoryPathName        
-     '.' asFilename directoryName        
-     '..' asFilename directoryName       
-     '../..' asFilename directoryName     
-     '../..' asFilename directoryPathName     
-    "
-
-    "Modified: 7.9.1995 / 10:42:03 / claus"
-!
-
-directoryPathName
-    "return the full directory pathname part of the file/directory as a string.
-     - thats the full pathname of the directory where the file/dir represented by
-       the receiver is contained in.
-     See also: directoryName"
-
-    ^ OperatingSystem directoryNameOf:(self pathName)
-
-    "
-     '/foo/bar/' asFilename directoryPathName    
-     '/foo/bar' asFilename directoryPathName    
-     '.' asFilename directoryPathName        
-     '..' asFilename directoryPathName       
-     '../..' asFilename directoryPathName     
-    "
-
-    "Modified: 7.9.1995 / 10:42:13 / claus"
-!
-
 exists
     "return true, if such a file exists."
 
@@ -1267,155 +1271,6 @@
     "
 !
 
-filenameCompletion
-    "try to complete the recevier filename.
-     This method has both a return value and a side effect on the receiver:
-       it returns a collection of matching filename objects,
-       and leaves changes the receivers filename-string to the longest common
-       match.
-     If none matches, the returned collection is empty and the recevier is unchanged.
-     If there is only one match, the size of the returned collection is exactly 1,
-     containing the fully expanded filename and the receivers name is changed to it."
-
-    ^ self filenameCompletionIn:nil
-
-    " 
-     'mak' asFilename filenameCompletion  
-     'Make' asFilename filenameCompletion 
-     'Makef' asFilename filenameCompletion;yourself  
-     '/u' asFilename filenameCompletion             
-     '../../libpr' asFilename inspect filenameCompletion    
-    "
-!
-
-filenameCompletionIn:aDirectory
-    "try to complete the recevier filename.
-     This method has both a return value and a side effect on the receiver:
-       it returns a collection of matching filename objects,
-       and leaves changes the receivers filename-string to the longest common
-       match.
-     If none matches, the returned collection is empty and the recevier is unchanged.
-     If there is only one match, the size of the returned collection is exactly 1,
-     containing the fully expanded filename and the receivers name is changed to it."
-
-    |dir baseName matching matchLen try allMatching 
-     sepString parentString prefix nMatch|
-
-    sepString := self class separator asString.
-    (nameString endsWith:sepString) ifTrue:[
-	^ #()
-    ].
-
-    parentString := self class parentDirectoryName.
-    baseName := self baseName.
-    baseName ~= nameString ifTrue:[
-	prefix := self directoryName.
-    ].
-
-    self isAbsolute ifTrue:[
-	dir := self directory
-    ] ifFalse:[
-	aDirectory isNil ifTrue:[
-	    dir := self directory
-	] ifFalse:[
-	    dir := (aDirectory construct:nameString) directory
-	]
-    ].
-
-    matching := OrderedCollection new.
-    dir directoryContents do:[:fileName |
-	((fileName ~= '.') and:[fileName ~= parentString]) ifTrue:[
-	    (fileName startsWith:baseName) ifTrue:[
-		matching add:fileName
-	    ]
-	]
-    ].
-    (nMatch := matching size) > 1 ifTrue:[
-	"
-	 find the longest common prefix
-	"
-	matchLen := baseName size.
-	matchLen > matching first size ifTrue:[
-	    try := baseName.
-	    allMatching := false
-	] ifFalse:[
-	    try := matching first copyTo:matchLen.
-	    allMatching := true.
-	].
-
-	[allMatching] whileTrue:[
-	    matching do:[:aName |
-		(aName startsWith:try) ifFalse:[
-		    allMatching := false
-		]
-	    ].
-	    allMatching ifTrue:[
-		matchLen <  matching first size ifTrue:[
-		    matchLen := matchLen + 1.
-		    try := matching first copyTo:matchLen.
-		] ifFalse:[
-		    allMatching := false
-		]
-	    ] ifFalse:[
-		try := matching first copyTo:matchLen - 1.
-	    ]
-	].
-	"
-	 and set my name to the last full match
-	"
-	nameString := try
-    ].
-
-    "
-     if I had a directory-prefix, change names in collection ...
-    "
-    prefix notNil ifTrue:[
-	prefix = '/' ifTrue:[
-	    "/ avoid introducing double slashes
-	    prefix := ''
-	].
-	matching := matching collect:[:n | prefix , '/' , n].
-	nMatch == 1 ifTrue:[
-	    nameString := matching first
-	] ifFalse:[
-	    nMatch > 1 ifTrue:[
-		nameString := prefix , '/' , nameString
-	    ]
-	]
-    ] ifFalse:[
-	nMatch == 1 ifTrue:[
-	    nameString := matching first
-	]
-    ].
-
-    "
-     return the match-set, so caller can decide what to do
-     (i.e. show the matches, output a warning etc ...)
-    "
-    ^ matching
-
-    " trivial cases:
-
-     '../' asFilename filenameCompletion    
-     '/' asFilename filenameCompletion      
-     '/usr/' asFilename filenameCompletion   
-
-     'mak' asFilename filenameCompletion   
-     'Make' asFilename filenameCompletion    
-     'Makef' asFilename filenameCompletion
-     '/u' asFilename filenameCompletion             
-     '../../libpr' asFilename filenameCompletion    
-    "
-!
-
-filesMatching:aPattern
-    ^ self directoryContents select:[:name | aPattern match:name]
-
-    "
-     Filename currentDirectory filesMatching:'M*' 
-    "
-!
-
 isAbsolute
     "return true, if the receiver represents an absolute pathname
      (in contrast to one relative to the current directory)."
@@ -1517,6 +1372,311 @@
     "
 !
 
+separator
+    "return the directory-separator character"
+
+    ^ self class separator
+
+    "Modified: 29.2.1996 / 20:52:01 / cg"
+! !
+
+!Filename methodsFor:'queries-contents'!
+
+contentsOfEntireFile
+    "return the contents of the file as a string"
+
+    |s contents|
+
+    s := self readStream.
+    [
+	contents := s contents
+    ] valueNowOrOnUnwindDo:[s close].
+    ^ contents
+!
+
+directoryContents
+    "return the contents of the directory as a collection of strings"
+
+    ^ (FileDirectory directoryNamed:self asString) contents
+
+    "
+     '.' asFilename directoryContents
+    "
+!
+
+filesMatching:aPattern
+    "given the receiver, representing a directory;
+     return a collection of files matching a pattern."
+
+    ^ self directoryContents select:[:name | aPattern match:name]
+
+    "
+     Filename currentDirectory filesMatching:'M*' 
+     '/etc' asFilename filesMatching:'[a-z]*' 
+     '../../libbasic' asFilename filesMatching:'[A-D]*.st'  
+    "
+
+    "Modified: 29.2.1996 / 20:30:31 / cg"
+! !
+
+!Filename methodsFor:'queries-path & name'!
+
+baseName
+    "return my baseName as a string.
+     - thats the file/directory name without leading parent-dirs."
+
+    ^ OperatingSystem baseNameOf:nameString "/ (self pathName) 
+
+    "
+     '/foo/bar' asFilename baseName  
+     '.' asFilename baseName          
+     '..' asFilename baseName         
+     '../..' asFilename baseName        
+     '../../libbasic' asFilename baseName        
+     '../../libpr' asFilename baseName        
+     '../../libbasic/Object.st' asFilename baseName        
+    "
+!
+
+directory
+    "return the directory name part of the file/directory as a new filename.
+     - thats a filename for the directory where the file/dir represented by
+       the receiver is contained in.
+     (this is almost equivalent to #directoryName or #head, but returns
+      a Filename instance instead of a string )."
+
+    ^ self directoryName asFilename
+
+    "
+     '/foo/bar' asFilename directory      
+     '/foo/bar' asFilename directoryName  
+     '/foo/bar' asFilename head  
+
+     '.' asFilename directory        
+     '..' asFilename directory       
+     '../..' asFilename directory     
+    "
+
+    "Modified: 29.2.1996 / 20:50:14 / cg"
+!
+
+directoryName
+    "return the directory name part of the file/directory as a string.
+     - thats the name of the directory where the file/dir represented by
+       the receiver is contained in.
+     (this is almost equivalent to #directory, but returns
+      a string instead of a Filename instance).
+     See also: #directoryPathName.
+     Compatibility note: use #head for ST-80 compatibility."
+
+    ^ OperatingSystem directoryNameOf:nameString "/ (self pathName)
+
+    "
+     '/foo/bar/' asFilename directoryName    
+     '/foo/bar/' asFilename directory     
+
+     '/foo/bar' asFilename directoryName    
+     'bitmaps' asFilename directoryName        
+     'bitmaps' asFilename directoryPathName        
+     '.' asFilename directoryName        
+     '..' asFilename directoryName       
+     '../..' asFilename directoryName     
+     '../..' asFilename directoryPathName     
+    "
+
+    "Modified: 7.9.1995 / 10:42:03 / claus"
+    "Modified: 29.2.1996 / 20:23:49 / cg"
+!
+
+directoryPathName
+    "return the full directory pathname part of the file/directory as a string.
+     - thats the full pathname of the directory where the file/dir represented by
+       the receiver is contained in.
+     See also: #directoryName, #directory"
+
+    ^ OperatingSystem directoryNameOf:(self pathName)
+
+    "
+     '/foo/bar/' asFilename directoryPathName    
+     '/foo/bar' asFilename directoryPathName    
+
+     '.' asFilename directoryPathName      
+     '.' asFilename directoryName     
+     '.' asFilename directory          
+
+     '..' asFilename directoryPathName       
+     '..' asFilename directoryName       
+     '..' asFilename directory
+
+     '../..' asFilename directoryPathName     
+    "
+
+    "Modified: 7.9.1995 / 10:42:13 / claus"
+    "Modified: 29.2.1996 / 20:24:44 / cg"
+!
+
+filenameCompletion
+    "try to complete the receiver filename.
+     This method has both a return value and a side effect on the receiver:
+       it returns a collection of matching filename objects,
+       and leaves changes the receivers filename-string to the longest common
+       match.
+     If none matches, the returned collection is empty and the recevier is unchanged.
+     If there is only one match, the size of the returned collection is exactly 1,
+     containing the fully expanded filename and the receivers name is changed to it."
+
+    ^ self filenameCompletionIn:nil
+
+    " 
+     'mak' asFilename filenameCompletion  
+     'Make' asFilename filenameCompletion 
+     'Makef' asFilename filenameCompletion;yourself  
+     '/u' asFilename filenameCompletion             
+     '../../libpr' asFilename inspect filenameCompletion    
+    "
+
+    "Modified: 29.2.1996 / 20:28:36 / cg"
+!
+
+filenameCompletionIn:aDirectory
+    "try to complete the receiver filename.
+     This method has both a return value and a side effect on the receiver:
+       it returns a collection of matching filename objects,
+       and leaves changes the receivers filename-string to the longest common
+       match.
+     If none matches, the returned collection is empty and the recevier is unchanged.
+     If there is only one match, the size of the returned collection is exactly 1,
+     containing the fully expanded filename and the receivers name is changed to it."
+
+    |dir baseName matching matchLen try allMatching 
+     sepString parentString prefix nMatch|
+
+    sepString := self class separator asString.
+    (nameString endsWith:sepString) ifTrue:[
+        ^ #()
+    ].
+
+    parentString := self class parentDirectoryName.
+    baseName := self baseName.
+    baseName ~= nameString ifTrue:[
+        prefix := self directoryName.
+    ].
+
+    self isAbsolute ifTrue:[
+        dir := self directory
+    ] ifFalse:[
+        aDirectory isNil ifTrue:[
+            dir := self directory
+        ] ifFalse:[
+            dir := (aDirectory construct:nameString) directory
+        ]
+    ].
+
+    matching := OrderedCollection new.
+    dir directoryContents do:[:fileName |
+        ((fileName ~= '.') and:[fileName ~= parentString]) ifTrue:[
+            (fileName startsWith:baseName) ifTrue:[
+                matching add:fileName
+            ]
+        ]
+    ].
+    (nMatch := matching size) > 1 ifTrue:[
+        "
+         find the longest common prefix
+        "
+        matchLen := baseName size.
+        matchLen > matching first size ifTrue:[
+            try := baseName.
+            allMatching := false
+        ] ifFalse:[
+            try := matching first copyTo:matchLen.
+            allMatching := true.
+        ].
+
+        [allMatching] whileTrue:[
+            matching do:[:aName |
+                (aName startsWith:try) ifFalse:[
+                    allMatching := false
+                ]
+            ].
+            allMatching ifTrue:[
+                matchLen <  matching first size ifTrue:[
+                    matchLen := matchLen + 1.
+                    try := matching first copyTo:matchLen.
+                ] ifFalse:[
+                    allMatching := false
+                ]
+            ] ifFalse:[
+                try := matching first copyTo:matchLen - 1.
+            ]
+        ].
+        "
+         and set my name to the last full match
+        "
+        nameString := try
+    ].
+
+    "
+     if I had a directory-prefix, change names in collection ...
+    "
+    prefix notNil ifTrue:[
+        prefix = '/' ifTrue:[
+            "/ avoid introducing double slashes
+            prefix := ''
+        ].
+        matching := matching collect:[:n | prefix , '/' , n].
+        nMatch == 1 ifTrue:[
+            nameString := matching first
+        ] ifFalse:[
+            nMatch > 1 ifTrue:[
+                nameString := prefix , '/' , nameString
+            ]
+        ]
+    ] ifFalse:[
+        nMatch == 1 ifTrue:[
+            nameString := matching first
+        ]
+    ].
+
+    "
+     return the match-set, so caller can decide what to do
+     (i.e. show the matches, output a warning etc ...)
+    "
+    ^ matching
+
+    " trivial cases:
+
+     '../' asFilename filenameCompletion    
+     '/' asFilename filenameCompletion      
+     '/usr/' asFilename filenameCompletion   
+
+     'mak' asFilename filenameCompletion   
+     'Make' asFilename filenameCompletion    
+     'Makef' asFilename filenameCompletion
+     '/u' asFilename filenameCompletion             
+     '../../libpr' asFilename filenameCompletion    
+    "
+
+    "Modified: 29.2.1996 / 20:28:45 / cg"
+!
+
+head 
+    "return the directory name as a string. 
+     An alias for directoryName, for ST-80 compatiblity.
+     (this is almost equivalent to #directory, but returns
+      a string instead of a Filename instance)"
+
+    ^ self directoryName
+
+    "
+     Filename currentDirectory head  
+     'Makefile' asFilename head    
+     '/foo/bar/baz.st' asFilename head  
+    "
+
+    "Modified: 29.2.1996 / 20:21:25 / cg"
+!
+
 name
     "return the name of the file represented by the receiver as a string.
      This may or may not be a relative name (i.e. include ..'s).
@@ -1571,46 +1731,6 @@
     "Modified: 18.1.1996 / 21:36:46 / cg"
 !
 
-prefixAndSuffix
-    "return an array consisting of my prefix and suffix.
-     The suffix is the namepart after the final period character,
-     the prefix everything before, except for the period.
-     (on some systems, the suffix-character may be different from a period).
-     For example, foo.bar.baz has a prefix of 'foo.bar' and a suffix of '.baz'.
-
-     Notice: there is currently no known system which uses other than
-     the period character as suffixCharacter."
-
-    |nm idx|
-
-    nm := self baseName.
-    idx := nm lastIndexOf:(self class suffixSeparator).
-    idx == 0 ifTrue:[
-	^ Array with:nm with:''
-    ].
-    ^ Array 
-	with:(nm copyTo:idx-1)
-	with:(nm copyFrom:idx+1)
-
-    "
-     'abc.st' asFilename prefixAndSuffix  
-     'abc' asFilename prefixAndSuffix  
-     'a.b.c' asFilename prefixAndSuffix 
-
-     |parts| 
-     parts := 'Object.st' asFilename prefixAndSuffix.
-     ((parts at:1) , '.o') asFilename
-    "
-
-    "Modified: 7.9.1995 / 11:15:42 / claus"
-!
-
-separator
-    "return the directory-separator character (or string)"
-
-    ^ self class separator
-!
-
 suffix
     "return my suffix.
      The suffix is the namepart after the final period character,
@@ -1632,10 +1752,98 @@
      An alias for baseName, for ST-80 compatiblity."
 
     ^ self baseName
+
+    "
+     Filename currentDirectory tail 
+     'Makefile' asFilename tail    
+     '/foo/bar/baz.st' asFilename tail  
+    "
+
+    "Modified: 29.2.1996 / 20:19:50 / cg"
+! !
+
+!Filename methodsFor:'suffixes'!
+
+prefixAndSuffix
+    "return an array consisting of my prefix and suffix.
+     The suffix is the namepart after the final period character,
+     the prefix everything before, except for the period.
+     (on some systems, the suffix-character may be different from a period).
+     For example, foo.bar.baz has a prefix of 'foo.bar' and a suffix of '.baz'.
+
+     Notice: there is currently no known system which uses other than
+     the period character as suffixCharacter."
+
+    |nm idx|
+
+    nm := self baseName.
+    idx := nm lastIndexOf:(self class suffixSeparator).
+    idx == 0 ifTrue:[
+        ^ Array with:nm with:''
+    ].
+    ^ Array 
+        with:(nm copyTo:idx-1)
+        with:(nm copyFrom:idx+1)
+
+    "
+     'abc.st' asFilename prefixAndSuffix  
+     'abc' asFilename prefixAndSuffix  
+     'a.b.c' asFilename prefixAndSuffix 
+
+     |parts| 
+     parts := 'Object.st' asFilename prefixAndSuffix.
+     ((parts at:1) , '.o') asFilename
+    "
+
+    "Modified: 7.9.1995 / 11:15:42 / claus"
+!
+
+withSuffix:aSuffix
+    "return a new filename for the receivers name with a suffix.
+     If the name already has a sufix, the new suffix replacaes it;
+     otherwise, the new suffix simply appended to the name."
+
+    ^ self class named:
+        (self withoutSuffix name 
+         , self class suffixSeparator asString 
+         , aSuffix asString)
+
+    "
+     'abc.st' asFilename withSuffix:'o'         
+     'abc' asFilename withSuffix:'o'             
+     'a.b.c' asFilename withSuffix:'o'            
+     '/foo/bar/baz.st' asFilename withSuffix:'c'   
+     '/foo/bar/baz.c' asFilename withSuffix:'st'   
+    "
+
+    "Modified: 7.9.1995 / 11:15:42 / claus"
+    "Modified: 29.2.1996 / 20:50:03 / cg"
+!
+
+withoutSuffix
+    "return a new filename for the receivers name without the suffix.
+     If the name has no suffix, the receiver is returned."
+
+    |idx|
+
+    idx := nameString lastIndexOf:(self class suffixSeparator).
+    idx == 0 ifTrue:[^ self].
+
+    ^ self class named:(nameString copyTo:(idx - 1))
+
+    "
+     'abc.st' asFilename withoutSuffix         
+     'abc' asFilename withoutSuffix            
+     'a.b.c' asFilename withoutSuffix           
+     '/foo/bar/baz.c' asFilename withoutSuffix   
+    "
+
+    "Modified: 7.9.1995 / 11:15:42 / claus"
+    "Modified: 29.2.1996 / 20:49:59 / cg"
 ! !
 
 !Filename class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic/Filename.st,v 1.50 1996-02-04 19:06:34 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic/Filename.st,v 1.51 1996-02-29 20:01:28 cg Exp $'
 ! !