Commit 63ad4cf6 authored by Ronny Wichers Schreur's avatar Ronny Wichers Schreur

initial import (version 1.1.2 with windows object files)

parent 473d1947
1.1.1
- Made Clean 2.0 compatible
- changed file size from BigInt to tuple of two integers
\ No newline at end of file
// version 1.1
#include <windows.h>
#include <direct.h>
#include <Clean.h>
// error codes:
#define NoDirError 0
#define OtherDirError -1
#define DoesntExist -2
#define BadName -3
#define NotEnoughSpace -4
#define AlreadyExists -5
#define NoPermission -6
#define MoveIntoOffspring -7
#define MoveAcrossDisks -8
#define NotYetRemovable -9
HANDLE ghSearch;
WIN32_FIND_DATA gWFD;
static int pc_error_to_clean_error(int pc_error)
{
switch(pc_error) {
case ERROR_SUCCESS: return NoDirError;
case ERROR_FILE_NOT_FOUND:
case ERROR_INVALID_DRIVE:
case ERROR_PATH_NOT_FOUND:
case ERROR_BAD_NET_NAME: return DoesntExist;
case ERROR_BAD_PATHNAME:
case ERROR_INVALID_NAME: return BadName;
case ERROR_DISK_FULL:
case ERROR_HANDLE_DISK_FULL: return NotEnoughSpace;
case ERROR_ALREADY_EXISTS:
case ERROR_FILE_EXISTS: return AlreadyExists;
case ERROR_DRIVE_LOCKED:
case ERROR_SHARING_VIOLATION:
case ERROR_ACCESS_DENIED:
case ERROR_WRITE_PROTECT:
case ERROR_LOCK_VIOLATION: return NoPermission;
case ERROR_DIR_NOT_EMPTY: return NotYetRemovable;
default: return OtherDirError;
};
}
// unhandled: NotADirectory, MoveIntoOffspring
int findFirstFileC(CleanString cs_path)
{
char *cPath;
int length,i,clean_err;
ghSearch = INVALID_HANDLE_VALUE;
length = CleanStringLength(cs_path);
if (CleanStringCharacters(cs_path)[length-1]=='\\')
length--;
cPath = GlobalAlloc(LMEM_FIXED, length+3); // +3 for adding "\\*\0"
if (!cPath)
return -1;
else { // make a C string with "\\*" appended
for(i=0; i<length; i++)
cPath[i] = CleanStringCharacters(cs_path)[i];
cPath[length ] = '\\';
cPath[length+1] = '*';
cPath[length+2] = '\0';
ghSearch = FindFirstFile(cPath,&gWFD);
clean_err = ghSearch==INVALID_HANDLE_VALUE ? pc_error_to_clean_error(GetLastError()) : NoDirError;
GlobalFree(cPath);
return clean_err;
};
}
void getCommonFileInfoC(int also_get_file_name,
CleanString *pFileName, int *pFileSizeLow, int *pFileSizeHigh,
int *pYear, int *pMonth, int *pDay, int *pDayNr,
int *pHours, int *pMinutes, int *pSeconds,
int *pIsDirectory, int *pIsReadOnly)
{
static int null=0;
FILETIME localFileTime;
SYSTEMTIME localSystemTime;
int i;
static CleanStringVariable(fileName,MAX_PATH);
static int nix = 0;
if (also_get_file_name) {
for(i=0; gWFD.cFileName[i]!='\0' && i<MAX_PATH; i++)
CleanStringCharacters(fileName)[i] = gWFD.cFileName[i];
CleanStringLength(fileName) = i;
*pFileName = (CleanString) fileName;
}
else
*pFileName = (CleanString) &nix;
*pFileSizeLow = gWFD.nFileSizeLow;
*pFileSizeHigh = gWFD.nFileSizeHigh;
FileTimeToLocalFileTime(&gWFD.ftLastWriteTime,&localFileTime);
FileTimeToSystemTime(&localFileTime,&localSystemTime);
*pYear = localSystemTime.wYear;
*pMonth = localSystemTime.wMonth;
*pDay = localSystemTime.wDay;
*pDayNr = localSystemTime.wDayOfWeek+1;
*pHours = localSystemTime.wHour;
*pMinutes = localSystemTime.wMinute;
*pSeconds = localSystemTime.wSecond;
*pIsDirectory = (gWFD.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
*pIsReadOnly = (gWFD.dwFileAttributes & FILE_ATTRIBUTE_READONLY) != 0;
}
#define ALT_LENGTH 14
void getWindowsFileInfoC(int *pFileAttributes,
int *pCYear, int *pCMonth, int *pCDay, int *pCDayNr, // creation time
int *pCHours, int *pCMinutes, int *pCSeconds, // dito
int *pLAYear, int *pLAMonth, int *pLADay, int *pLADayNr, // last access time
int *pLAHours, int *pLAMinutes, int *pLASeconds, // dito
CleanString *pDOSName, int *pIsHidden)
{
FILETIME localFileTime;
SYSTEMTIME localSystemTime;
int i;
CleanStringVariable(fileName,ALT_LENGTH);
*pFileAttributes = gWFD.dwFileAttributes;
FileTimeToLocalFileTime(&gWFD.ftCreationTime,&localFileTime);
FileTimeToSystemTime(&localFileTime,&localSystemTime);
*pCYear = localSystemTime.wYear;
*pCMonth = localSystemTime.wMonth;
*pCDay = localSystemTime.wDay;
*pCDayNr = localSystemTime.wDayOfWeek+1;
*pCHours = localSystemTime.wHour;
*pCMinutes = localSystemTime.wMinute;
*pCSeconds = localSystemTime.wSecond;
FileTimeToLocalFileTime(&gWFD.ftLastAccessTime,&localFileTime);
FileTimeToSystemTime(&localFileTime,&localSystemTime);
*pLAYear = localSystemTime.wYear;
*pLAMonth = localSystemTime.wMonth;
*pLADay = localSystemTime.wDay;
*pLADayNr = localSystemTime.wDayOfWeek+1;
*pLAHours = localSystemTime.wHour;
*pLAMinutes = localSystemTime.wMinute;
*pLASeconds = localSystemTime.wSecond;
for(i=0; gWFD.cAlternateFileName[i]!='\0' && i<ALT_LENGTH; i++)
CleanStringCharacters(fileName)[i] = gWFD.cAlternateFileName[i];
CleanStringLength(fileName) = i;
*pDOSName = (CleanString) fileName;
*pIsHidden = (gWFD.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) != 0;
}
int findNextFileC(int dummy)
{
return FindNextFile(ghSearch, &gWFD) ? 0 : 1;
}
int findSingleFileC(CleanString cs_path)
{
ghSearch = FindFirstFile(CleanStringCharacters(cs_path),&gWFD);
return ghSearch==INVALID_HANDLE_VALUE ? pc_error_to_clean_error(GetLastError()) : NoDirError;
}
void getMacFileInfoC()
{}
void getUnixFileInfoC()
{}
void closeSearchC()
{
FindClose(ghSearch);
}
void closeSingleSearchC()
{
FindClose(ghSearch);
}
int createDirectoryC(CleanString cs_path)
{
int ok;
ok = CreateDirectory(CleanStringCharacters(cs_path), NULL);
return ok ? NoDirError : pc_error_to_clean_error(GetLastError());
}
int fremoveC(CleanString cs_path)
{
int ok, errCode;
ok = DeleteFile(CleanStringCharacters(cs_path));
if (ok)
errCode = ERROR_SUCCESS;
else {
errCode = GetLastError();
if (errCode==ERROR_FILE_NOT_FOUND
|| errCode == ERROR_ACCESS_DENIED /*&& CleanStringCharacters(cs_path)[0]=='\\'*/)
// ERROR_ACCESS_DENIED happens when a folder in a network path is tried to be removed with
// DeleteFile()
{
ok = RemoveDirectory(CleanStringCharacters(cs_path));
if (ok)
errCode = ERROR_SUCCESS;
else
errCode = GetLastError();
};
};
return errCode==ERROR_ACCESS_DENIED ? NotYetRemovable : pc_error_to_clean_error(errCode);
}
#define OK 0
#define STRING_TOO_SMALL 1
#define FATAL_ERROR 2
int getCurrentDirectory_SE(CleanString cs)
{
unsigned int neededSize;
neededSize = GetCurrentDirectory(CleanStringLength(cs), CleanStringCharacters(cs));
if (neededSize==0)
return FATAL_ERROR;
else {
if (neededSize>CleanStringLength(cs))
return STRING_TOO_SMALL;
else {
CleanStringLength(cs) = neededSize;
return OK;
};
};
}
int setCurrentDirectoryC(CleanString csPath)
{
int ok;
ok = SetCurrentDirectory(CleanStringCharacters(csPath));
return ok ? NoDirError : pc_error_to_clean_error(GetLastError());
}
void get_mac_dir_parent_and_name_C()
{}
int getPlatformIdC(int dummy)
{
#define WindowsPlatform 1
return WindowsPlatform;
}
void getMacDiskNameC()
{}
int get_windows_disk_available_bits_C(int dummy)
{
return GetLogicalDrives();
}
int fmoveC(int overwrite, CleanString from, CleanString to)
{
int ok, last_error;
ok = MoveFile(CleanStringCharacters(from), CleanStringCharacters(to));
if (!ok && overwrite && GetLastError()==ERROR_ALREADY_EXISTS) {
if (!DeleteFile(CleanStringCharacters(to)))
return AlreadyExists;
else
ok = MoveFile(CleanStringCharacters(from), CleanStringCharacters(to));
};
if (ok)
return NoDirError;
else {
last_error = GetLastError();
return last_error==ERROR_ACCESS_DENIED ? MoveIntoOffspring : pc_error_to_clean_error(last_error);
};
}
void macMoveC()
{}
void macRenameC()
{}
kernel32.dll
CreateDirectoryA@8
RemoveDirectoryA@4
DeleteFileA@4
GetCurrentDirectoryA@8
SetCurrentDirectoryA@4
GetLogicalDrives@0
MoveFileA@8
definition module Directory
// version 1.1.1
//1.3
from StdFile import FileSystem
from StdOverloaded import toInt, ==
from StdLibMisc import Date, Time
//from BigInt import BigInt
//3.1
/*2.0
from StdFile import class FileSystem
from StdOverloaded import class toInt (..), class == (..)
from StdLibMisc import :: Date, :: Time
//from BigInt import :: BigInt
0.2*/
// shorthands: PI="platform independent", PD="platform dependent"
getDirectoryContents :: !Path !*env -> (!(!DirError, [DirEntry]), !*env) | FileSystem env
/* error codes: NoDirError, DoesntExist, BadName, NoPermission, OtherErro
The returned list is only valid, if the error code is NoDirError */
isHidden :: !DirEntry -> Bool
/* unix: whether the filename's first character is '.'
windows/mac: the win(mac)IsHidden flag from the pd_fileInfo field */
getFileInfo :: !Path !*env -> (!(!DirError, FileInfo), !*env) | FileSystem env
/* get information about a given file/directory.
error codes: NoDirError, DoesntExist, BadName, NoPermission, OtherDirError
The returned FileInfo is only valid, if the error code is NoDirError */
createDirectory :: !Path !*env -> (!DirError, !*env) | FileSystem env
/* error codes: NoDirError, DoesntExist, BadName, NotEnoughSpace, AlreadyExists, NoPermission,
OtherDirError */
fmove :: !MoveMode !Path !Path !*env -> (!DirError, !*env) | FileSystem env
/* (fmove mode src dest) moves a file or directory src to another location dst. dst also contains
the possibly new name of the moved object. Iff (dst already exists and dst is not a directory
and mode is OverwriteFile) then dst will be replaced by src.
error codes: NoDirError, DoesntExist, BadName, NotEnoughSpace, AlreadyExists, NoPermission,
MoveIntoOffspring, MoveAcrossDisks, OtherDirError */
fremove :: !Path !*env -> (!DirError, !*env) | FileSystem env
/* removes files and empty directories.
error codes: NoDirError, DoesntExist, BadName, NoPermission, NotYetRemovable, OtherDirError */
getCurrentDirectory :: !*env -> (!Path, !*env) | FileSystem env
setCurrentDirectory :: !Path !*env -> (!DirError, !*env) | FileSystem env
/* error codes: NoDirError, DoesntExist, BadName, NoPermission, OtherDirError */
getDiskNames :: !*env -> ([DiskName], !*env) | FileSystem env
pd_StringToPath :: !String !*env -> (!(!Bool, Path), !*env) | FileSystem env
/* converts a platform dependent string representation of a path into a Path which
is only valid, if the returned Bool is True */
pathToPD_String :: !Path !*env -> (!String, !*env) | FileSystem env
// converts a Path into a platform dependent string representation of a path
encodeUnixModeBits :: !UnixModeBitsField -> UnixAccessRights
instance == DirError
:: Path
= RelativePath [PathStep]
| AbsolutePath DiskName [PathStep]
:: PathStep = PathUp | PathDown String
:: DiskName :== String
/* on UNI//Name is ignored, on DOS/Windows/MacOS the ":" is omitted,
Windows network paths are specified as an AbsolutePath whose DiskName begins with two
backslashes (\\) */
:: DirError = NoDirError | DoesntExist | BadName | NotEnoughSpace | AlreadyExists | NoPermission
| MoveIntoOffspring | MoveAcrossDisks | NotYetRemovable | OtherDirError
/* NotYetRemovable: a file can't be removed because it has not been closed yet or
a directory can't be removed because it is not empty */
:: DirEntry
= { fileName :: !String
, fileInfo :: !FileInfo
}
:: FileInfo
= { pi_fileInfo :: !PI_FileInfo
, pd_fileInfo :: !PD_FileInfo
}
:: PI_FileInfo // platform independent information
= { fileSize :: !(!Int, !Int) // MdM
, lastModified :: !DateTime
, isDirectory :: !Bool
, isReadOnly :: !Bool
}
:: PD_FileInfo :== PlatformDependent UnixFileInfo WindowsFileInfo MacFileInfo
// platform dependent information
:: PlatformDependent unix windows mac
= Unix unix
| Windows windows
| Mac mac
:: UnixFileInfo
= { unixModeBitsField :: !UnixModeBitsField
, unixOwnerUserId :: Int
, unixOwnerGroupId :: Int
, unixLastAccessTime :: !DateTime
}
:: UnixModeBitsField :== Int
:: UnixAccessRights
= { ownerRight :: UnixRight
, groupRight :: UnixRight
, othersRight :: UnixRight
}
:: UnixRight
= { mayRead :: !Bool
, mayWrite :: !Bool
, mayExecute :: !Bool
}
:: WindowsFileInfo
= { winCreationTime :: !DateTime
, winLastAccessTime :: !DateTime
, winDOSName :: !String
, winIsHidden :: !Bool
, winIsArchiveFile :: !Bool
, winIsSystemFile :: !Bool
}
:: MacFileInfo
= { macCreationTime :: !DateTime
, macBackupTime :: !DateTime
, macIsHidden :: !Bool
, macFDFlags :: !Int // finder information from FInfo/DInfo record
, macFurtherInfo :: !ForFile MacFurtherInfo
}
:: MacFurtherInfo :== (!MacCreator, !MacFileType)
:: MacCreator :== String // always four characters
:: MacFileType :== String // always four characters
:: MoveMode = OverwriteFile | DontOverwrite
:: DateTime :== (!Date, !Time)
:: ForFile x
= File x
| Directory
This diff is collapsed.
Directory - a Clean module to access and manipulate directories
---------------------------------------------------------------
Version 1.1.1
Installation
------------
This module is based on two other libraries:
- "StdLib 1.0" (or higher) for the Date and Time types
- "ExtendedArith 1.0" (or higher) for the BigInt type
If you don't have these libraries already then download them from
the Clean homepage (www.cs.kun.nl/~clean), install them, and set
a path to each of these libraries. Also set a path to the Directory
module. See the CleanIDE's documentation about setting paths.
Use this module with Clean 1.3.3 or Clean 2.0 and the corresponding
CleanIDE.
mailto:clean@cs.kun.nl if a problem occurs.
Documentation
-------------
There is a brief description of the Directory module at the Clean
homepage (www.cs.kun.nl/~clean).
Differences to the previous version
-----------------------------------
This version also works with network path names.
The upgrade to version 1.1 is _not_ downward compatible. These are the
incompatible changes (there are no other changes in the dcl module):
- The Date` and Time` types of the previous version were replaced with
the Date and Time types of the StdLib. Now The Object I/O library
and the Directory module share the same types for date and type
information:
previous version:
:: Time` = { hours` :: !Int, minutes` :: !Int, seconds` :: !Int }
:: Date` = { year` :: !Int, month` :: !Int, day` :: !Int, dayNr` :: !Int }
this version:
:: Time = { hours :: !Int, minutes :: !Int, seconds :: !Int }
:: Date = { year :: !Int, month :: !Int, day :: !Int, dayNr :: !Int }
- The file size is now stored in an arbitrary size integer (BigInt) and not
in a 64 bit integer:
previous version:
:: PI_FileInfo = { fileSize :: !Integer64 ...
this version:
:: PI_FileInfo = { fileSize :: !BigInt ...
Sorry for that inconvenience.
Contents of the package
------------------------
Directory.dcl/icl - the module itself
Clean System Files\cDirectory.obj - necessary object file
Clean System Files\directory_library - necessary import library
README - this file
Clean System Files\cDirectory.c - C source used to build cDirectory.obj
(can be removed)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment