diff options
author | johnvg | 2005-03-17 15:12:46 +0000 |
---|---|---|
committer | johnvg | 2005-03-17 15:12:46 +0000 |
commit | cdf0c13f4d2628030ccb4b96e2cc590e95aa3901 (patch) | |
tree | d70f0cfd09815a5a844d359c9ff8fb35495f787b /main/Mac cli | |
parent | handle \r as \n when scanning .abc files (diff) |
cli for MacOSX with MACH_O, same as unix, except : and , are used
in paths and object files generated by the c compiler have different
names
git-svn-id: https://svn.cs.ru.nl/repos/clean-compiler/trunk@1519 1f8540f1-abd5-4d5b-9d24-4c5ce8603e2d
Diffstat (limited to 'main/Mac cli')
-rw-r--r-- | main/Mac cli/Clean.h | 28 | ||||
-rw-r--r-- | main/Mac cli/CoclSystemDependent.dcl | 28 | ||||
-rw-r--r-- | main/Mac cli/CoclSystemDependent.icl | 122 | ||||
-rw-r--r-- | main/Mac cli/Makefile | 5 | ||||
-rw-r--r-- | main/Mac cli/cDirectory.c | 339 | ||||
-rw-r--r-- | main/Mac cli/ipc.c | 123 | ||||
-rw-r--r-- | main/Mac cli/ipc.dcl | 14 | ||||
-rw-r--r-- | main/Mac cli/ipc.h | 8 | ||||
-rw-r--r-- | main/Mac cli/ipc.icl | 30 | ||||
-rw-r--r-- | main/Mac cli/set_return_code.dcl | 9 | ||||
-rw-r--r-- | main/Mac cli/set_return_code.icl | 18 | ||||
-rw-r--r-- | main/Mac cli/set_return_code_c.c | 6 |
12 files changed, 730 insertions, 0 deletions
diff --git a/main/Mac cli/Clean.h b/main/Mac cli/Clean.h new file mode 100644 index 0000000..1508c1b --- /dev/null +++ b/main/Mac cli/Clean.h @@ -0,0 +1,28 @@ + +#define Clean(a) + +typedef struct clean_string *CleanString; + +/* a string in Clean is: + struct clean_string { + int clean_string_length; + char clean_string_characters[clean_string_length]; + }; + The string does not end with a '\0' ! +*/ + +/* CleanStringLength(clean_string) returns length of the clean_string in characters */ +#define CleanStringLength(clean_string) (*(unsigned int *)(clean_string)) + +/* CleanStringCharacters(clean_string) returns a pointer to the characters of the clean_string */ +#define CleanStringCharacters(clean_string) ((char*)(1+(unsigned int *)(clean_string))) + +/* CleanStringSizeInts(string_length) return size of CleanString in integers */ +#define CleanStringSizeInts(string_length) (1+(((unsigned int)(string_length)+3)>>2)) + +/* CleanStringVariable(clean_string,string_length) defines variable clean_string with length string_length, + before using the clean_string variable, cast to CleanString, except for the macros above */ +#define CleanStringVariable(clean_string,string_length) unsigned int clean_string[CleanStringSizeInts(string_length)] + +/* CleanStringSizeBytes(string_length) return size of CleanString in bytes */ +#define CleanStringSizeBytes(string_length) (4+(((unsigned int)(string_length)+3) & -4)) diff --git a/main/Mac cli/CoclSystemDependent.dcl b/main/Mac cli/CoclSystemDependent.dcl new file mode 100644 index 0000000..abe673f --- /dev/null +++ b/main/Mac cli/CoclSystemDependent.dcl @@ -0,0 +1,28 @@ +// this is for Windows +definition module CoclSystemDependent + +//1.3 +from StdString import String +from StdFile import Files +//3.1 +/*2.0 +from StdFile import ::Files +0.2*/ + +// RWS split +// from deltaIOSystem import DeviceSystem +// from deltaEventIO import InitialIO, IOState + +PathSeparator + :== ',' +DirectorySeparator + :== ':' + +SystemDependentDevices :: [a] +SystemDependentInitialIO :: [a] + +ensureCleanSystemFilesExists :: !String !*Files -> (!Bool, !*Files) +set_compiler_id :: Int -> Int + +compiler_loop :: ([{#Char}] *st -> *(Bool, *st)) *st -> (!Bool, !*st) + diff --git a/main/Mac cli/CoclSystemDependent.icl b/main/Mac cli/CoclSystemDependent.icl new file mode 100644 index 0000000..715b509 --- /dev/null +++ b/main/Mac cli/CoclSystemDependent.icl @@ -0,0 +1,122 @@ +// this is for Unix +implementation module CoclSystemDependent + +import StdEnv +import StdDebug +import ArgEnv +import ipc +from filesystem import ensureDirectoryExists + +import code from "cDirectory_c.o" +import code from "ipc_c.o" + +PathSeparator + :== ',' +DirectorySeparator + :== ':' + +SystemDependentDevices :: [a] +SystemDependentDevices + = [] + +SystemDependentInitialIO :: [a] +SystemDependentInitialIO + = [] + +set_compiler_id :: Int -> Int +set_compiler_id compiler_id = compiler_id + +ensureCleanSystemFilesExists :: !String !*Files -> (!Bool, !*Files) +// returned bool: now there is such a subfolder +ensureCleanSystemFilesExists path env + = ensureDirectoryExists path env + + +compiler_loop :: ([{#Char}] *st -> *(Bool, *st)) *st -> (!Bool, !*st) +compiler_loop compile compile_state + | length commandArgs==3 && commandArgs!!0=="--pipe" + # commands_name= (commandArgs!!1); + # results_name= (commandArgs!!2); + = (True,compile_loop compile commands_name results_name compile_state) + # (r,compile_state)=compile commandArgs compile_state + = (r,compile_state) + where + commandArgs + = tl [arg \\ arg <-: getCommandLine] +// ... Unix + +string_to_args string + = string_to_args 0; + where + l=size string; + + string_to_args i + # end_spaces_i=skip_spaces i; + | end_spaces_i==l + = [] + | string.[end_spaces_i]=='"' + # next_double_quote_i=skip_to_double_quote (end_spaces_i+1) + | next_double_quote_i>=l + = [string % (end_spaces_i,l-1)] + # arg=string % (end_spaces_i+1,next_double_quote_i-1); + = [arg : string_to_args (next_double_quote_i+1)]; + # space_i=skip_to_space (end_spaces_i+1) + | space_i>=l + = [string % (end_spaces_i,l-1)] + # arg=string % (end_spaces_i,space_i-1); + = [arg : string_to_args (space_i+1)]; + + skip_spaces i + | i>=l + = l; + # c=string.[i]; + | c==' ' || c=='\t' + = skip_spaces (i+1); + = i; + + skip_to_space i + | i>=l + = l; + # c=string.[i]; + | c==' ' || c=='\t' + = i; + = skip_to_space (i+1); + + skip_to_double_quote i + | i>=l + = l; + # c=string.[i]; + | c=='"' + = i; + = skip_to_double_quote (i+1); + + +compile_loop :: ([{#Char}] *st -> *(Bool, *st)) {#Char} {#Char} *st -> *st +compile_loop compile commands results compile_state + # r=open_pipes commands results; + | r<>0 + = abort ("compile_loop\n"); + = compile_files compile compile_state + +compile_files :: ([{#Char}] *st -> *(Bool, *st)) *st -> *st +compile_files compile compile_state + # n = get_command_length; + | n==(-1) + = abort "compile_files 1"; + # string=createArray n '\0'; + # r=get_command string; + | r<>0 + = abort ("compile_files 2 "); + # args=string_to_args (string % (0,size string-2)) + = case args of + ["cocl":cocl_args] + # (ok,compile_state)=compile cocl_args compile_state + # result=if ok 0(-1); + # r=send_result result + | r<>0 + -> abort "compile_files 3"; + -> compile_files compile compile_state + ["quit"] + -> /* trace_n "quiting" */ compile_state; + _ + -> abort "compile_files 4" diff --git a/main/Mac cli/Makefile b/main/Mac cli/Makefile new file mode 100644 index 0000000..f8ae7f3 --- /dev/null +++ b/main/Mac cli/Makefile @@ -0,0 +1,5 @@ +CC=gcc +CFLAGS=-pedantic -Wall -W -O +CPPFLAGS= + +all: cDirectory.o ipc.o set_return_code_c.o diff --git a/main/Mac cli/cDirectory.c b/main/Mac cli/cDirectory.c new file mode 100644 index 0000000..b95f19b --- /dev/null +++ b/main/Mac cli/cDirectory.c @@ -0,0 +1,339 @@ +#include <stdio.h> +#include <errno.h> +#include <fcntl.h> +#include <sys/stat.h> +#include <time.h> +#include <dirent.h> +#include <unistd.h> +#include <stdio.h> +#include "Clean.h" + +#ifndef NAME_MAX +#define NAME_MAX 500 +#endif + +#define FALSE 0 +#define TRUE (!FALSE) + +// 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 + +uid_t gUserId; +gid_t gGroupId; +struct DIR *gpDir; +struct dirent *gpDirent; +struct stat gFileStat; +char *gPath; +int gPathLength; +CleanStringVariable(gFileName,NAME_MAX+1); + +static int unix_error_to_clean_error(int errCode) +{ + switch(errCode) { + case ENOENT: + case ENOTDIR: return DoesntExist; + case ENAMETOOLONG: return BadName; + case EMLINK: + case ENOSPC: return NotEnoughSpace; + case EISDIR: + case EEXIST: return AlreadyExists; + case EPERM: + case EACCES: + case EROFS: return NoPermission; + case EINVAL: return MoveIntoOffspring; + case EXDEV: return MoveAcrossDisks; + case ENOTEMPTY: return NotYetRemovable; + default: return OtherDirError; + }; +} + +static int openSearch(const char *path, int length) +{ + int i; + + gPathLength = length; + gPath = (char*) malloc(gPathLength+NAME_MAX+2); + if (!gPath) { + gpDir = NULL; + return 0; + } + else { + memcpy(gPath, path, gPathLength); + gPath[gPathLength] = '\0'; + gpDir = (struct DIR*) opendir(gPath); + if (!gpDir) + return unix_error_to_clean_error(errno); + gPath[gPathLength] = '/'; // filename will be added later + gUserId = getuid(); + gGroupId = getgid(); + return NoDirError; + }; +} + +int findFirstFileC(CleanString cs_path) +{ + int errCode; + + errCode = openSearch(CleanStringCharacters(cs_path), CleanStringLength(cs_path)); + if (errCode) + return errCode; + else + return findNextFileC(0); +} + +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) +// requires gFileName and gFileStat to be initialized +{ + struct tm *pModificationTime; + int mask; + static int null = 0; + + *pFileName = also_get_file_name ? (CleanString) gFileName : (CleanString) &null; + *pFileSizeLow = gFileStat.st_size; + *pFileSizeHigh = 0; + pModificationTime= localtime(&gFileStat.st_mtime); + *pYear = pModificationTime->tm_year+1900; + *pMonth = pModificationTime->tm_mon+1; + *pDay = pModificationTime->tm_mday; + *pDayNr = pModificationTime->tm_wday+1; + *pHours = pModificationTime->tm_hour; + *pMinutes = pModificationTime->tm_min; + *pSeconds = pModificationTime->tm_sec % 60; + *pIsDirectory = (gFileStat.st_mode & S_IFDIR) != 0; + mask = gUserId==gFileStat.st_uid ? S_IWUSR + : gGroupId==gFileStat.st_gid ? S_IWGRP + : S_IWOTH; + *pIsReadOnly = (gFileStat.st_mode & mask) == 0; +} + +int findNextFileC(int dummy) +// return values: 0=ok, 1=no further files in directory +{ + int i; + + gpDirent = readdir((void*)gpDir); + if (!gpDirent) + return 1; + + for(i=0; gpDirent->d_name[i]!='\0' && i<NAME_MAX; i++) { + CleanStringCharacters(gFileName)[i] = gpDirent->d_name[i]; + gPath[gPathLength+1+i] = gpDirent->d_name[i]; + }; + CleanStringLength(gFileName)= i; + gPath[gPathLength+1+i] = '\0'; + gFileStat.st_size = 0; + gFileStat.st_mode = 0; + lstat(gPath,&gFileStat); + return 0; +} + +int getPlatformIdC(int dummy) +{ +#define UnixPlatform 0 + return UnixPlatform; +} + +void getWindowsFileInfoC() +{} + + +void getMacFileInfoC() +{} + +void getUnixFileInfoC(int *pModeBits, int *pOwnerUserId, int *pOwnerGroupId, + int *pLAYear, int *pLAMonth, int *pLADay, int *pLADayNr, // last access time + int *pLAHours, int *pLAMinutes, int *pLASeconds) // dito +{ + struct tm *pModificationTime; + + *pModeBits = gFileStat.st_mode; + *pOwnerUserId = gFileStat.st_uid; + *pOwnerGroupId = gFileStat.st_gid; + pModificationTime= localtime(&gFileStat.st_atime); + *pLAYear = pModificationTime->tm_year+1900; + *pLAMonth = pModificationTime->tm_mon+1; + *pLADay = pModificationTime->tm_mday; + *pLADayNr = pModificationTime->tm_wday+1; + *pLAHours = pModificationTime->tm_hour; + *pLAMinutes = pModificationTime->tm_min; + *pLASeconds = pModificationTime->tm_sec % 60; +} + + +void closeSearchC() +{ + free(gPath); + if (gpDir) + closedir((void*)gpDir); +} + +int findSingleFileC(CleanString cs_path) +{ + int err,i,length; + char *path_chars; + + gFileStat.st_size = 0; + gFileStat.st_mode = 0; + + path_chars = CleanStringCharacters(cs_path); + if (lstat(path_chars,&gFileStat)) + return unix_error_to_clean_error(errno); + + i = CleanStringLength(cs_path)-2; + while (i>=0 && path_chars[i]!='/') + i--; + // the last path element ranges from path_chars[i+1] to path_chars[CleanStringLength(cs_path)-2] + + length = CleanStringLength(cs_path)-2-i; + CleanStringLength(gFileName) = length; + memcpy(CleanStringCharacters(gFileName), path_chars+i+1, length); + + return NoDirError; +} + +void closeSingleSearchC() +{} + +int createDirectoryC(CleanString cs_path) +{ + int err; + + err = mkdir(CleanStringCharacters(cs_path), + S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); + // access rights for newly created directory: rwx--x--x + if (err) + return unix_error_to_clean_error(errno); + else + return NoDirError; +} + +int fremoveC(CleanString cs_path) +{ + int err; + + err = remove(CleanStringCharacters(cs_path)); + if (err) { + if (errno==EEXIST) + return NotYetRemovable; + else + return unix_error_to_clean_error(errno); + } + else + return NoDirError; +} + +// Try this code with slackware linux, if the testLinux program doesn't work +//int fremoveC(CleanString cs_path) +//{ +// int err; +// +// err = unlink(CleanStringCharacters(cs_path)); +// if (err) { +// if (errno==EPERM) { +// err = rmdir(CleanStringCharacters(cs_path)); +// if (err) +// return unix_error_to_clean_error(errno); +// else +// return NoDirError; +// } +// else +// return unix_error_to_clean_error(errno); +// } +// else +// return NoDirError; +//} + +#define OK 0 +#define STRING_TOO_SMALL 1 + +int getCurrentDirectory_SE(CleanString cs) +{ + if (getcwd(CleanStringCharacters(cs), CleanStringLength(cs))) { + // success. convert C String to Clean string + int i; + i = 0; + while(CleanStringCharacters(cs)[i]!='\0') + i++; + CleanStringLength(cs) = i; + return OK; + } + else { + // failure + if (errno==EACCES) { + // the permission to read the current directory was denied (how ever) + // return root directory + CleanStringLength(cs) = 1; + CleanStringCharacters(cs)[0] = '/'; + return OK; + } + else + return STRING_TOO_SMALL; + }; +} + +void get_mac_dir_parent_and_name_C() +{ +} + +int setCurrentDirectoryC(CleanString csPath) +{ + int err; + + err = chdir(CleanStringCharacters(csPath)); + if (err) + return unix_error_to_clean_error(errno); + else + return NoDirError; +} + +void getMacDiskNameC() +{} + +void get_windows_disk_available_bits_C() +{} + +void macRenameC() +{} + +void macMoveC() +{} + +int fmoveC(int overwrite, CleanString from, CleanString to) +{ + int err,clean_err; + + if (overwrite) { + err = rename(CleanStringCharacters(from), CleanStringCharacters(to)); + if (err && errno==ENOTDIR) { + // from is a directory and to a file + // try again after removing to + err = remove(CleanStringCharacters(to)); + if (!err) + err = rename(CleanStringCharacters(from), CleanStringCharacters(to)); + }; + clean_err = err ? unix_error_to_clean_error(errno) : NoDirError; + } + else { + struct stat fileStat; + if (stat(CleanStringCharacters(to),&fileStat)) { + err = rename(CleanStringCharacters(from), CleanStringCharacters(to)); + clean_err = err ? unix_error_to_clean_error(errno) : NoDirError; + } + else + clean_err = AlreadyExists; + }; + return clean_err; +} diff --git a/main/Mac cli/ipc.c b/main/Mac cli/ipc.c new file mode 100644 index 0000000..4ff823a --- /dev/null +++ b/main/Mac cli/ipc.c @@ -0,0 +1,123 @@ +/* + Unix clm/cocl interface + + Ronny Wichers Schreur + +*/ +# include <stdio.h> +# include <stdlib.h> +# include <stdarg.h> +# include <strings.h> + +/* + Clean string + ============ +*/ +typedef struct clean_string {int length; char chars [1]; } *CleanString; + +# define Clean(ignore) +# include "ipc.h" + +static void +log (char *format, ...) +{ +#ifdef DEBUG + va_list ap; + + va_start (ap, format); + (void) fputs(" cocl: ", stderr); + (void) vfprintf(stderr, format, ap); + va_end(ap); +#else /* ifndef DEBUG */ +#endif +} + +static char * +ConvertCleanString (CleanString string) +{ + int length; + char *copy; + + length = string->length; + copy = malloc (length+1); + strncpy (copy, string->chars, length); + copy [length] = '\0'; + + return (copy); +} /* ConvertCleanString */ + +static FILE *commands, *results; +# define COMMAND_BUFFER_SIZE 1024 +static char command_buffer[COMMAND_BUFFER_SIZE]; + +static void +crash (void) +{ + int *p; + + p = NULL; + log ("crashing\n"); + *p = 0; +} /* crash */ + +static void +hang (void) +{ + log ("hanging\n"); + for (;;) + ; +} /* hang */ + +int open_pipes (CleanString commands_clean, CleanString results_clean) +{ + char *commands_name, *results_name; + + commands_name = ConvertCleanString (commands_clean); + results_name = ConvertCleanString (results_clean); + + if ((commands = fopen(commands_name, "r")) == NULL) + { + log("commands = %s\n",commands_name); + perror("fopen commands"); + return -1; + } + if ((results = fopen(results_name, "w")) == NULL) + { + log("results = %s\n",results_name); + perror("fopen results"); + return -1; + } + return 0; +} + +int get_command_length (void) +{ + log ("reading command\n"); + if (fgets (command_buffer, COMMAND_BUFFER_SIZE, commands) == NULL) + return -1; + else + { + log ("command = %s", command_buffer); + return (strlen (command_buffer)); + } +} + +int get_command (CleanString cleanString) +{ + log ("%s\n", command_buffer); + strncpy (cleanString->chars, command_buffer, cleanString->length); + return (0); +} + +int send_result (int result) +{ + int r; + + if (fprintf (results, "%d\n", result) > 0) + r=0; + else + r=-1; + fflush (results); + + return r; +} diff --git a/main/Mac cli/ipc.dcl b/main/Mac cli/ipc.dcl new file mode 100644 index 0000000..ce686ae --- /dev/null +++ b/main/Mac cli/ipc.dcl @@ -0,0 +1,14 @@ +definition module ipc; + +//1.3 +from StdString import String; +//3.1 + +open_pipes :: !String !String -> Int; +// int open_pipes (CleanString commands_name,CleanString results_name); +get_command_length :: Int; +// int get_command_length (); +get_command :: !String -> Int; +// int get_command (CleanString cleanString); +send_result :: !Int -> Int; +// int send_result (int result); diff --git a/main/Mac cli/ipc.h b/main/Mac cli/ipc.h new file mode 100644 index 0000000..99a070e --- /dev/null +++ b/main/Mac cli/ipc.h @@ -0,0 +1,8 @@ +int open_pipes (CleanString commands_name, CleanString results_name); +Clean (open_pipes :: String String -> Int) +int get_command_length (void); +Clean (get_command_length :: Int) +int get_command (CleanString cleanString); +Clean (get_command :: String -> Int) +int send_result (int result); +Clean (send_result :: Int -> Int) diff --git a/main/Mac cli/ipc.icl b/main/Mac cli/ipc.icl new file mode 100644 index 0000000..55ca927 --- /dev/null +++ b/main/Mac cli/ipc.icl @@ -0,0 +1,30 @@ +implementation module ipc; + +//1.3 +from StdString import String; +//3.1 + + +open_pipes :: !String !String -> Int; +open_pipes a0 a1 = code { + ccall open_pipes "SS:I" +} +// int open_pipes (CleanString commands_name,CleanString results_name); + +get_command_length :: Int; +get_command_length = code { + ccall get_command_length ":I" +} +// int get_command_length (); + +get_command :: !String -> Int; +get_command a0 = code { + ccall get_command "S:I" +} +// int get_command (CleanString cleanString); + +send_result :: !Int -> Int; +send_result a0 = code { + ccall send_result "I:I" +} +// int send_result (int result); diff --git a/main/Mac cli/set_return_code.dcl b/main/Mac cli/set_return_code.dcl new file mode 100644 index 0000000..e8ed7f8 --- /dev/null +++ b/main/Mac cli/set_return_code.dcl @@ -0,0 +1,9 @@ +definition module set_return_code; + +//1.3 +from StdString import String; +//3.1 + +:: *UniqueWorld :== World; +set_return_code :: !Int !UniqueWorld -> UniqueWorld; +// void set_return_code (int return_code); diff --git a/main/Mac cli/set_return_code.icl b/main/Mac cli/set_return_code.icl new file mode 100644 index 0000000..b4028f7 --- /dev/null +++ b/main/Mac cli/set_return_code.icl @@ -0,0 +1,18 @@ +implementation module set_return_code; + +import code from "set_return_code_c.o"; + +import StdString; +import StdDebug; + +:: *UniqueWorld :== World; + +set_return_code :: !Int !UniqueWorld -> UniqueWorld; +set_return_code a0 a1 = code +{ + ccall set_return_code "I:V:A" + fill_a 0 1 + pop_a 1 +} + +// void set_return_code (int return_code); diff --git a/main/Mac cli/set_return_code_c.c b/main/Mac cli/set_return_code_c.c new file mode 100644 index 0000000..a09e1ab --- /dev/null +++ b/main/Mac cli/set_return_code_c.c @@ -0,0 +1,6 @@ +extern int return_code; + +void set_return_code (int code) +{ + return_code = code; +} |