h&@x>      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLM Safe-Inferred6 easy-file=If the operating system has a notion of current directories,  returns an absolute path to the current directory of the calling process.The operation may fail with: HardwareFault$ A physical I/O error has occurred. [EIO]isDoesNotExistError /  NoSuchThing6 There is no path referring to the current directory. [EPERM, ENOENT, ESTALE...]isPermissionError / PermissionDenied The process has insufficient privileges to perform the operation. [EACCES]ResourceExhausted? Insufficient resources are available to perform the operation.UnsupportedOperation9 The operating system has no notion of current directory. easy-file*Returns the current user's home directory.The directory returned is expected to be writable by the current user, but note that it isn't generally considered good practice to store application-specific data here; use  instead. On Unix,  returns the value of the HOME environment variable. On Windows, the system is queried for a suitable path; a typical path might be C:Documents And Settingsuser.The operation may fail with:UnsupportedOperation6 The operating system has no notion of home directory.isDoesNotExistError The home directory for the current user does not exist, or cannot be found. easy-file3Returns the current user's home directory from the HOME environment variable. easy-fileReturns the pathname of a directory in which application-specific data for the current user can be stored. The result of 9 for a given application is specific to the current user.The argument should be the name of the application, which will be used to construct the pathname (so avoid using unusual characters that might result in an invalid pathname).Note: the directory may not actually exist, and may need to be created first. It is expected that the parent directory exists and is writable.On Unix, this function returns $HOME/.appName&. On Windows, a typical path might be 7C:/Documents And Settings/user/Application Data/appNameThe operation may fail with:UnsupportedOperation The operating system has no notion of application-specific data directory.isDoesNotExistError The home directory for the current user does not exist, or cannot be found. easy-file.Returns the current user's document directory.The directory returned is expected to be writable by the current user, but note that it isn't generally considered good practice to store application-specific data here; use  instead. On Unix,  returns the value of the HOME environment variable. On Windows, the system is queried for a suitable path; a typical path might be +C:/Documents and Settings/user/My Documents.The operation may fail with:UnsupportedOperation: The operating system has no notion of document directory.isDoesNotExistError The document directory for the current user does not exist, or cannot be found. easy-file2Returns the current directory for temporary files. On Unix,  returns the value of the TMPDIR environment variable or "/tmp" if the variable isn't defined. On Windows, the function checks for the existence of environment variables in the following order and uses the first path found:TMP environment variable.TEMP environment variable.!USERPROFILE environment variable.The Windows directoryThe operation may fail with:UnsupportedOperation; The operating system has no notion of temporary directory.4The function doesn't verify whether the path exists. easy-fileThis function copy the permission of the first file to the second. N Safe-Inferred9s.O easy-file*Is the operating system Unix or Linux likeP easy-file$Is the operating system Windows like easy-file)The character that separates directories. 3pathSeparator == '/' isPathSeparator pathSeparator easy-file$The list of all possible separators. Windows: pathSeparators == ['\\', '/'] Posix: pathSeparators == ['/'] pathSeparator `elem` pathSeparators easy-fileRather than using (== )5, use this. Test if something is a path separator. .isPathSeparator a == (a `elem` pathSeparators) easy-fileFile extension character extSeparator == '.'  easy-file(Is the character an extension character? 'isExtSeparator a == (a == extSeparator)! easy-fileSplit on the extension. & is the inverse. uncurry (++) (splitExtension x) == x uncurry addExtension (splitExtension x) == x splitExtension "file.txt" == ("file",".txt") splitExtension "file" == ("file","") splitExtension "file/file.txt" == ("file/file",".txt") splitExtension "file.txt/boris" == ("file.txt/boris","") splitExtension "file.txt/boris.ext" == ("file.txt/boris",".ext") splitExtension "file/path.txt.bob.fred" == ("file/path.txt.bob",".fred") splitExtension "file/path.txt/" == ("file/path.txt/","")" easy-file%Get the extension of a file, returns "" for no extension, .ext otherwise. takeExtension x == snd (splitExtension x) Valid x => takeExtension (addExtension x "ext") == ".ext" Valid x => takeExtension (replaceExtension x "ext") == ".ext"# easy-fileSet the extension of a file, overwriting one if already present. replaceExtension "file.txt" ".bob" == "file.bob" replaceExtension "file.txt" "bob" == "file.bob" replaceExtension "file" ".bob" == "file.bob" replaceExtension "file.txt" "" == "file" replaceExtension "file.fred.bob" "txt" == "file.fred.txt"$ easy-file Alias to &), for people who like that sort of thing.% easy-file0Remove last extension, and the "." preceding it. )dropExtension x == fst (splitExtension x)& easy-file>Add an extension, even if there is already one there. E.g. -addExtension "foo.txt" "bat" -> "foo.txt.bat". addExtension "file.txt" "bib" == "file.txt.bib" addExtension "file." ".bib" == "file..bib" addExtension "file" ".bib" == "file.bib" addExtension "/" "x" == "/.x" Valid x => takeFileName (addExtension (addTrailingPathSeparator x) "ext") == ".ext" Windows: addExtension "\\\\share" ".txt" == "\\\\share\\.txt"' easy-file*Does the given filename have an extension? .null (takeExtension x) == not (hasExtension x)( easy-fileSplit on all extensions 3splitExtensions "file.tar.gz" == ("file",".tar.gz")) easy-fileDrop all extensions %not $ hasExtension (dropExtensions x)* easy-fileGet all extensions )takeExtensions "file.tar.gz" == ".tar.gz"Q easy-fileIs the given character a valid drive letter? only a-z and A-Z are letters, not isAlpha which is more unicodey+ easy-file?Split a path into a drive and a path. On Unix, / is a Drive. uncurry (++) (splitDrive x) == x Windows: splitDrive "file" == ("","file") Windows: splitDrive "c:/file" == ("c:/","file") Windows: splitDrive "\\\\shared\\test" == ("\\\\shared\\","test") Windows: splitDrive "\\\\shared" == ("\\\\shared","") Windows: splitDrive "\\\\?\\UNC\\shared\\file" == ("\\\\?\\UNC\\shared\\","file") Windows: splitDrive "\\\\?\\UNCshared\\file" == ("\\\\?\\","UNCshared\\file") Windows: splitDrive "\\\\?\\d:\\file" == ("\\\\?\\d:\\","file") Windows: splitDrive "/d" == ("","/d") -- xxx Posix: splitDrive "/test" == ("/","test") -- xxx Posix: splitDrive "//test" == ("//","test") Posix: splitDrive "test/file" == ("","test/file") Posix: splitDrive "file" == ("","file"), easy-file&Join a drive and the rest of the path.  uncurry joinDrive (splitDrive x) == x Windows: joinDrive "C:" "foo" == "C:foo" Windows: joinDrive "C:/" "bar" == "C:/bar" Windows: joinDrive "\\\\share" "foo" == "\\\\share/foo" -- xxx Windows: joinDrive "/:" "foo" == "/:/foo" -- xxx- easy-fileGet the drive from a filepath. !takeDrive x == fst (splitDrive x). easy-fileDelete the drive, if it exists. !dropDrive x == snd (splitDrive x)/ easy-fileDoes a path have a drive. ¬ (hasDrive x) == null (takeDrive x)0 easy-fileIs an element a drive1 easy-file*Split a filename into directory and file. < is the inverse. uncurry (++) (splitFileName x) == x Valid x => uncurry combine (splitFileName x) == x splitFileName "file/bob.txt" == ("file/", "bob.txt") splitFileName "file/" == ("file/", "") splitFileName "bob" == ("", "bob") Posix: splitFileName "/" == ("/","") Windows: splitFileName "c:" == ("c:","")2 easy-fileSet the filename. 2Valid x => replaceFileName x (takeFileName x) == x3 easy-fileDrop the filename. 'dropFileName x == fst (splitFileName x)4 easy-fileGet the file name. takeFileName "test/" == "" takeFileName x `isSuffixOf` x takeFileName x == snd (splitFileName x) Valid x => takeFileName (replaceFileName x "fred") == "fred" Valid x => takeFileName (x "fred") == "fred" Valid x => isRelative (takeFileName x)5 easy-file0Get the base name, without an extension or path. takeBaseName "file/test.txt" == "test" takeBaseName "dave.ext" == "dave" takeBaseName "" == "" takeBaseName "test" == "test" takeBaseName (addTrailingPathSeparator x) == "" takeBaseName "file/file.tar.gz" == "file.tar"6 easy-fileSet the base name. replaceBaseName "file/test.txt" "bob" == "file/bob.txt" replaceBaseName "fred" "bill" == "bill" replaceBaseName "/dave/fred/bob.gz.tar" "new" == "/dave/fred/new.tar" replaceBaseName x (takeBaseName x) == x7 easy-fileIs an item either a directory or the last character a path separator? hasTrailingPathSeparator "test" == False hasTrailingPathSeparator "test/" == True8 easy-fileAdd a trailing file path separator if one is not already present. hasTrailingPathSeparator (addTrailingPathSeparator x) hasTrailingPathSeparator x ==> addTrailingPathSeparator x == x addTrailingPathSeparator "test/rest" == "test/rest/"9 easy-file#Remove any trailing path separators dropTrailingPathSeparator "file/test/" == "file/test" not (hasTrailingPathSeparator (dropTrailingPathSeparator x)) || isDrive x dropTrailingPathSeparator "/" == "/": easy-file*Get the directory name, move up one level.  takeDirectory x `isPrefixOf` x takeDirectory "foo" == "" takeDirectory "/foo/bar/baz" == "/foo/bar" takeDirectory "/foo/bar/baz/" == "/foo/bar/baz" takeDirectory "foo/bar/baz" == "foo/bar" Windows: takeDirectory "foo\\bar\\\\" == "foo\\bar" -- xxx Windows: takeDirectory "C:/" == "C:/"; easy-file1Set the directory, keeping the filename the same. 6replaceDirectory x (takeDirectory x) `equalFilePath` x< easy-file&Combine two paths, if the second path E, then it returns the second. Valid x => combine (takeDirectory x) (takeFileName x) `equalFilePath` x combine "/" "test" == "/test" combine "home" "bob" == "home/bob"R easy-file0Combine two paths, assuming rhs is NOT absolute.= easy-fileA nice alias for <.> easy-file(Split a path by the directory separator. concat (splitPath x) == x splitPath "test//item/" == ["test//","item/"] splitPath "test/item/file" == ["test/","item/","file"] splitPath "" == [] Windows: splitPath "c:/test/path" == ["c:/","test/","path"] Posix: splitPath "/file/test" == ["/","file/","test"]? easy-fileJust as >5, but don't add the trailing slashes to each element. splitDirectories "test/file" == ["test","file"] splitDirectories "/test/file" == ["/","test","file"] Valid x => joinPath (splitDirectories x) `equalFilePath` x splitDirectories "" == []@ easy-file!Join path elements back together. Valid x => joinPath (splitPath x) == x joinPath [] == "" Posix: joinPath ["test","file","path"] == "test/file/path"A easy-fileEquality of two s. If you call !System.Directory.canonicalizePath first this has a much better chance of working. Note that this doesn't follow symlinks or DOSNAM~1s.  x == y ==> equalFilePath x y normalise x == normalise y ==> equalFilePath x y Posix: equalFilePath "foo" "foo/" Posix: not (equalFilePath "foo" "/foo") Posix: not (equalFilePath "foo" "FOO") Windows: equalFilePath "foo" "FOO"B easy-file.Contract a filename, based on a relative path.There is no corresponding  makeAbsolute function, instead use !System.Directory.canonicalizePath which has the same effect.  Valid y => equalFilePath x y || (isRelative x && makeRelative y x == x) || equalFilePath (y makeRelative y x) x makeRelative x x == "." null y || equalFilePath (makeRelative x (x y)) y || null (takeFileName x) Windows: makeRelative "C:/Home" "c:/home/bob" == "bob" Windows: makeRelative "C:/Home" "D:/Home/Bob" == "D:/Home/Bob" Windows: makeRelative "C:/Home" "C:Home/Bob" == "C:Home/Bob" Windows: makeRelative "/Home" "/home/bob" == "bob" Posix: makeRelative "/Home" "/home/bob" == "/home/bob" Posix: makeRelative "/home/" "/home/bob/foo/bar" == "bob/foo/bar" Posix: makeRelative "/fred" "bob" == "bob" Posix: makeRelative "/file/test" "/file/test/fred" == "fred" Posix: makeRelative "/file/test" "/file/test/fred/" == "fred/" Posix: makeRelative "some/path" "some/path/a/b/c" == "a/b/c"C easy-fileNormalise a file)// outside of the drive can be made blank/ -> ./ -> "" Posix: normalise "/file/\\test////" == "/file/\\test/" Posix: normalise "/file/./test" == "/file/test" Posix: normalise "/test/file/../bob/fred/" == "/test/file/../bob/fred/" Posix: normalise "../bob/fred/" == "../bob/fred/" Posix: normalise "./bob/fred/" == "bob/fred/" Windows: normalise "c:\\file/bob\\" == "C:/file/bob/" Windows: normalise "c:/" == "C:/" Windows: normalise "\\\\server\\test" == "\\\\server\\test" -- xxx Windows: normalise "." == "." Posix: normalise "./" == "./"D easy-file/Is a path relative, or is it fixed to the root? Windows: isRelative "path\\test" == True Windows: isRelative "c:\\test" == False Windows: isRelative "c:test" == True Windows: isRelative "c:" == True Windows: isRelative "\\\\foo" == False Windows: isRelative "/foo" == True Posix: isRelative "test/path" == True Posix: isRelative "/test" == FalseE easy-file not . D "isAbsolute x == not (isRelative x)+ !"#$%&'()*+,-./0123456789:;<=>?@ABCDE$7=5 Safe-Inferred>F easy-fileThis function tells whether or not a file/directory is symbolic link.G easy-file;This function returns the link counter of a file/directory.H easy-fileThis function returns whether or not a directory has sub-directories.I easy-fileThe I operation returns the UTC time at which the file or directory was created. The time is only available on Windows.J easy-fileThe J operation returns the UTC time at which the file or directory was changed. The time is only available on Unix and Mac. Note that Unix's rename() does not change ctime but MacOS's rename() does.K easy-fileThe K operation returns the UTC time at which the file or directory was last modified.The operation may fail with:isPermissionError if the user is not permitted to access the modification time; orisDoesNotExistError) if the file or directory does not exist.L easy-fileThe K operation returns the UTC time at which the file or directory was last accessed.M easy-fileGetting the size of the file. FGHIJKLSM Safe-Inferred>0  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLM   IJKLMFGH !"#%&'$()*+,-/.0142356:;<=>@?789CABDE                !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]&easy-file-0.2.3-Ki4wcbJa7714iHRWJXCQ15System.EasyFileSystem.EasyFile.DirectorySystem.EasyFile.FilePathSystem.EasyFile.MissingbaseGHC.IOFilePathdirectory-1.3.6.2System.DirectorysetPermissionssetCurrentDirectory renameFilerenameDirectory removeFileremoveDirectoryRecursiveremoveDirectorygetPermissionsgetDirectoryContents doesFileExistdoesDirectoryExistcreateDirectoryIfMissingcreateDirectorycopyFilecanonicalizePath System.Directory.Internal.Commonwritable searchablereadable executable PermissionsgetCurrentDirectorygetHomeDirectorygetHomeDirectory2getAppUserDataDirectorygetUserDocumentsDirectorygetTemporaryDirectorycopyPermissions pathSeparatorpathSeparatorsisPathSeparator extSeparatorisExtSeparatorsplitExtension takeExtensionreplaceExtension<.> dropExtension addExtension hasExtensionsplitExtensionsdropExtensionstakeExtensions splitDrive joinDrive takeDrive dropDrivehasDriveisDrive splitFileNamereplaceFileName dropFileName takeFileName takeBaseNamereplaceBaseNamehasTrailingPathSeparatoraddTrailingPathSeparatordropTrailingPathSeparator takeDirectoryreplaceDirectorycombine splitPathsplitDirectoriesjoinPath equalFilePath makeRelative normalise isRelative isAbsolute isSymlink getLinkCounthasSubDirectoriesgetCreationTime getChangeTimegetModificationTime getAccessTime getFileSizefixPathisPosix isWindowsisLetter combineAlwaysepochTimeToUTCTime