/* sys.h Copyright (C) 1992-2002 Codemist Ltd */ /* * This file should contain a list of all the functions in CSL that have * to be provided on a per-host basis. */ /* * This code may be used and modified, and redistributed in binary * or source form, subject to the "CCL Public License", which should * accompany it. This license is a variant on the BSD license, and thus * permits use of code derived from this in either open and commercial * projects: but it does require that updates to this code be made * available back to the originators of the package. * Before merging other code in with this or linking this code * with other packages or libraries please check that the license terms * of the other material are compatible with those of this. */ /* Signature: 5a249156 08-Apr-2002 */ #ifndef header_sys_h #define header_sys_h 1 #ifdef __cplusplus extern "C" { #endif /* * I provide a hook so that memory allocation can be passed not to the * usual C library malloc() function but to some other system-specific code. * This is achieved by putting the actual function that is to be called in * a variable. Ditto for free(). I have static initialisation that causes * use of the ordinary C library and so anybody who needs an alternative * must reset the pointers VERY early on. */ typedef void *malloc_function(size_t); extern malloc_function *malloc_hook; typedef void *realloc_function(void *, size_t); extern realloc_function *realloc_hook; typedef void free_function(void *); extern free_function *free_hook; /* * find_image_directory is handed the information that main() sees when * the application is started up, and it returns a string (in freshly * malloc'd space) that is the default name for the checkpoint image file * to be used for this run. */ extern char *find_image_directory(int argc, char *argv[]); /* * open_file accepts a vector of characters (old) and looks at the first * (n) of them. This is taken as a CSL filename - it is subject (possibly) * to adjustments, the expanded name is copied to the array (filename) and an * attempt is made to open a file. (mode) is a string (like "r", "w" or "r+b") * suitable for handing to the C "fopen" function to specify a mode, and * if (old_file) is non-NULL we should do an freopen() rather than fopen(). * The main intent in filename conversion as supported here is to allow * users on all machines to use Unix-like file-names to at least some * minimal extent, so names like "subdir/file.lsp" should be allowed, even * if in native mode the computer used uses some quite different way of * specifying sub-directories and file-extensions. */ extern FILE *open_file(char *filename, char *old, size_t n, char *mode, FILE *old_file); /* * find if a file exists, and if it does return (as 24 chars) the * change time for it. See open_file re args. */ extern CSLbool file_exists(char *filename, char *old, size_t n, char *tt); /* * The interfaces to create_directory and delete_file are similar * to that for open_file. They do what their names suggest! They return * zero on success, and non-zero on failure. Each does file-name * conversion so that Unix-style names can be used even with Windows. */ extern int create_directory(char *filename, char *old, size_t n); extern int delete_file(char *filename, char *old, size_t n); extern int rename_file(char *from_name, char *from_old, size_t from_size, char *to_name, char *to_old, size_t to_size); /* * The interfaces to file_readable and file_writable are also similar * to that for open_file. They return 1 if their argument can be opened * for reading or writing respectively, and 0 otherwise. directoryp tests * whether its argument is a directory. */ extern int file_readable(char *filename, char *old, size_t n); extern int file_writeable(char *filename, char *old, size_t n); extern int directoryp(char *filename, char *old, size_t n); /* * file_length returns the length of its argument (a file) in bytes. */ extern long file_length(char *filename, char *old, size_t n); /* * current_directory() places the name of the current directory in the buffer * which has the indicated size, and returns 0 for failure or otherwise * the length of data written. */ extern int current_directory(char *name, int len); /* * The next three are much-like the same... On some operating systems * they will be pretty meaningless! */ extern int get_current_directory(char *name, int len); extern int get_home_directory(char *name, int len); extern int get_users_home_directory(char *name, int len); extern int change_directory(char *filename, char *old, size_t n); /* * get_truename attempts to get a canonical name for a file or directory. * It returns a string. If unable to do anything useful it can just * return a copy of its input, but the result is expected to be a * freshly allocated block of memory and should be handed to free() after * it has been used. This interface using malloc() should be changed at * some stage so that the caller passes down a buffer for the result to * be placed in (what is arg1 for anyway). * This comment also needs to be expanded to explain in a little more detail * what a "canonical" name for a file or directory is - eg whether the * intent is to allow wildcard inputs or whether this function is * expected to convert from a relative file-name into a fully rooted one. */ extern char *get_truename(char *filename, char *old, size_t n); #ifdef NAG_VERSION /* * list_directory_members allocates (using malloc) both a vector * (of type char **) and a load of strings to go in there, and updates * filelist to point at it. The caller must free() the space at some * later stage. */ extern int list_directory_members(char *filename, char *old, char **filelist[], size_t n); #else /* * list_directory_members calls the given callback function handing it * the name of each file in given directory. */ typedef void directory_callback(char *, int, long int); extern void list_directory_members(char *filename, char *old, size_t n, directory_callback *fn); #endif /* * (f) is an open file - truncate it at position (where). */ extern int truncate_file(FILE *f, long int where); /* * If I am to process directories I need a set of routines that will * scan sub-directories for me. The specification I want is: * int scan_directory(char *dir, * void (*proc)(char *name, int why, int32 size)); * * This is called with a file- or directory-name as its first argument * and a function as its second. * It calls the function for every directory and every file that can be found * rooted from the given place. If the file to scan is specified as NULL * the current directory is processed. * When a simple file is found the procedure is called with the name of the * file, why=0, and the length (in bytes) of the file. For a directory * the function is called with why=1, then the contents of the directory are * processed. For directories the size information will be 0. There is no * guarantee of useful behaviour if some of the files to be scanned are * flagged as "invisible" or "not readable" or if they are otherwise special. * The value returned is the number of characters that should be removed * the start of file-names returned to get rid of any initial directory * specified. If dir is passed as NULL this will be zero and names will * come back plain, otherwise it will be 1+strlen(dir) */ #define SCAN_FILE 0 #define SCAN_STARTDIR 1 #define SCAN_ENDDIR 2 extern void scan_directory(char *dir, void (*proc)(char *name, int why, long int size)); /* * When scan_directory calls the procedure it has been passed, it will have * set scan_leafstart to the offset in the passed filename where the * original directory ended and the new information starts. Thus if the * input string was (say) "/usr/users/acn/xxx" and some particular sub-file * was reported as "/usr/users/acn/xxx/subdir/subfile.ext" then * (name+scan_leafstart) gives the relative name "subdir/subfile.ext". */ extern int scan_leafstart; /* * scan_files() is just like scan_directory() excepr that it does not * recurse into sub-directories. */ extern void scan_files(char *dir, void (*proc)(char *name, int why, long int size)); extern void unpack_date(unsigned long int r, int *year, int *mon, int *day, int *hour, int *min, int *sec); extern unsigned long int pack_date(int year, int mon, int day, int hour, int min, int sec); typedef struct date_and_type { unsigned long int date; unsigned long int type; } date_and_type; /* Reinstate date and filetype... */ extern void set_filedate(char *name, unsigned long int datestamp, unsigned long int ftype); extern void put_fileinfo(date_and_type *p, char *name); /* * my_getenv() is much like the ANSI getenv(), but exists because * it may be useful to perform mappings on the character string given * (e.g. to fold case) before calling the built-in getenv(). */ extern char *my_getenv(char *s); /* * my_system is just like the ANSI function system() - done this way to * allow for machines where this is not available or where more work is * needed. */ extern int my_system(char *s); #ifdef PIPES /* * my_popen() and my_pclose() are intended to be just like the Unix * popen() and pclose functions. */ extern FILE *my_popen(char *command_name, char *direction); extern void my_pclose(FILE *stream); #endif #ifdef SIMULATED_PIPES /* * For RISCOS (at least) I send characters to a pipe (possibly * only used to support the gnuplot package) through a separate * special function as documented here. */ extern int my_pipe_putc(int c, FILE *f); extern int my_pipe_flush(FILE *f); #else # define my_pipe_putc(c, f) putc(c, f) # define my_pipe_flush(f) fflush(f) #endif #ifdef PIPES_SOMETIMES /* * If I have an operating system where the presence of pipes is * conditional, this variable is used to keep track. */ extern int pipes_today; #endif /* * batchp() should return true if stdin is NOT from an interactive * terminal. */ extern int batchp(void); #ifdef UNIX_TIMES /* * The intent here is that if UNIX_TIMES is set then the CPU times * reported to the user will be "user time" and will not include * "system time", as in using the Unix "times" facility. If UNIX_TIMES * is not defined no special code in sysxxx.c is needed. */ extern clock_t read_clock(void); #else # define read_clock() clock() #endif #ifdef SHOW_COUNTS_AVAILABLE /* * show_counts() can be called via mapstore(), and would be expected to * display some information relating to how many times each chunk of * C code has been executed - possibly only when the C coded parts of CSL have * been compiled with some special profile option. write_profile is * similar in style, but sends output to a file. If you do not have * statistics gathering facilities you do not need these implemented. */ extern void show_counts(void); extern void write_profile(char *filename); #endif /* * Imultiply and Idivide are things that you may want to re-implement in * machine code - if so here are their signatures, and you should #define * IMULTIPLY/IDIVIDE in machine.h to say what you have done. See arithXX.c * for the portable versions. */ #ifdef _MSC_VER /* * Apologies here: For Microsoft VC++ I need to define these as __stdcall * (and certainly NOT as __fastcall) because Microsoft potentially change * which registers are used with __fastcall from release to release of * their compiler. */ #ifdef IMULTIPLY extern unsigned32 __stdcall Imultiply(unsigned32 *rlow, unsigned32 a, unsigned32 b, unsigned32 c); #endif #ifdef IDIVIDE extern unsigned32 __stdcall Idivide(unsigned32 *qp, unsigned32 a, unsigned32 b, unsigned32 c); extern unsigned32 __stdcall Idiv10_9(unsigned32 *qp, unsigned32 a, unsigned32 b); #endif #else #ifdef IMULTIPLY extern unsigned32 Imultiply(unsigned32 *rlow, unsigned32 a, unsigned32 b, unsigned32 c); #endif #ifdef IDIVIDE extern unsigned32 Idivide(unsigned32 *qp, unsigned32 a, unsigned32 b, unsigned32 c); extern unsigned32 Idiv10_9(unsigned32 *qp, unsigned32 a, unsigned32 b); #endif #endif #ifdef TICK_STREAM /* * add_ticker() starts a steady(-ish) stream of clock pulses going, * and causes (indirectly) accept_tick() to be called in a regular basis. * These are used to help me with interfaces to window systems, and to * make responses to keyboard interrupts more friendly and reliable. */ extern void add_ticker(void); /* * remove_ticker() switches tick-events off. Best if it is legal to * call remove_ticker even if ticks are not active. */ extern void MS_CDECL remove_ticker(void); extern void accept_tick(void); #endif #ifdef POLL_FOR_ATTN /* * Used by MSDOS system to check if ^C has been pressed - see gc.c * and read.c for the only calls. Arg decides if it waits until some * input is ready. */ extern void poll_for_attn(void); #endif /* * When the garbage collector observes that memory is tight it can attempt * to allocate more by going back to malloc(). This function is called with * an argument that indicates how many pages are in use at present, and it * is expected to return an indication of how many more might be worth * allocating. See the code in gc.c for details of usage. */ int32 ok_to_grab_memory(int32 current_pages); #ifdef WINDOW_SYSTEM /* * start_up_window_manager is called after command-line options have been * decoded - and hence after any flags that might influence the character * of windowed use of the system have been set. */ extern void start_up_window_manager(int use_wimp); /* * The next represents the only way in which characters will be * sent to the screen - in the case of WINDOW_SYSTEM it write to the * screen. Possibly this is more complicated than just writing to stdout. */ extern void putc_stdout(int c); /* * flush_screen() tries to make sure that the display is up to date. */ extern void flush_screen(void); /* * I may want to redirect stdout to a file, in which case the following * is the handle that I will use. See "--" decoding in csl.c */ extern FILE *alternative_stdout; /* * Ditto reading from stdin. Reads chars into buffer, returns count. */ extern int wimpget(char *buf); /* * The next two call-backs tell the window manager how much time has * been spent and how many garbage collections have been done. */ extern void report_time(int32 t, int32 gct); extern void report_space(int gccount, double percent); /* * pause_for_user() gets called right at the end to give a chance for the * system to delay before closing the main output window. */ extern void pause_for_user(void); #endif #ifdef WINDOWS_NT /* * Am I in Win32S rather than full Win32? * The values I will use will be * 0 Windows NT * 1 win32s on top of Windows 3.x * 2 Windows 95 */ extern int win32s; #endif #ifdef __cplusplus } #endif #endif /* header_sys_h */ /* end of sys.h */