/****************************************************************************** #### # # #### ##### ###### # # # # # # # # # # ## ## # # #### # #### # ##### # ## # ###### # # # # # # # ### # # # # # # # # # # # ### # # #### # #### # ###### # # ### # # ******************************************************************************/ /* This file is part of MAPMAKER, Copyright 1987-1992 Whitehead Institute. See the READ.ME file for license agreement and non-warranty information. */ /*************************************************************************** This file, along with the syscode.c file, is used to provide most, if not all system specific, definitions allowing our library files to port from one system to another. Note that these declarations are provided for the shell library code, NOT NECESSARILY FOR THE APPLICATION CODE! See the apropriate ...lib.h file for a list of the functions you should use. With the increasing encroachment of ANSI C, we can now get away with only only one system.h files (with #ifdefs, of course) for all systems. An ANSI compiler doesn't help too much, because Sun/DEC (and others) include files are just not ANSI. At present, fixes are in place for: * SunOS 4.1.x with the bundled cc (ANSI-C, just say no) * DEC Ultrix 4.2 on the nice but now obsolete DECStation line (cc, not acc) * Apple's A/UX 3.0 on high end Macintoshes * WATCOM C/386 9.0 on MicroSloth's MS-DOG, optionally with M$-Windoze 3.1 Previous versions of this library have been ported in various flavors to Mac ThinkC and VMS as well as other flavors of Unix - hopefully these ports will happen again for this version soon. If you port this code, we suggest you use the following flags: _SYS_SUNOS Specifics for SunOS 4.1.x (only tried SPARC) _SYS_SOLARIS Specifics for Solaris 2.x (SPARC and Intel versions identical?) _SYS_AUX Specifics for Apple's A/UX 3.0 _SYS_MACHTEN Specifics for Tennon's MachTen on Macintosh (tried & failed!) _SYS_ULTRIX Specifics for DEC RISC/ULTRIX 4.x (for MIPS based DECStations) _SYS_OSF Specifics for OSF/1 for DEC Alpha (like, if it ever ships) _SYS_AIX Specifics for the inferior but marketable AIX (RISC or other?) _SYS_HPUX Specifics for HP-UX (8.x?) for HP 9000/700 series. _SYS_UNIX Basic Unix semantics, defined if any one of the above is _SYS_WATCOM Specifics for WATCOM C/386 9.0 with apropriate libraries _SYS_DOS Basic DOS semantics, defined if the above is _SYS_THINKC Specifics for ThinkC (5.0?) _SYS_MPW Specifics for MPW C (ver???) _SYS_MAC Basic MAC semantics, should be defined if one of the above is Things I'm not quite sure what to do with... _SYS_NT Windoze/NT (Not There) on Intel (what about Alpha/MIPS/etc?) _SYS_OS2 OS/2 2.x (gives me the willies just to think about it) _SYS_NEXT NeXTStep 3.0, wiTh ThE fUNkey CaPItaLizAtION (040 or Intel?) _SYS_VMS Basic VMS semantics (what options are there?) Of course most of these flags are not handled yet. Happy porting :-) Among other things ,this is the only file which understands which of the system's #include files need to be used, as well as what order they should be included in! (This is handled at the end of this file). You should include standard files by #defining one or more of the following and then #including "system.h": INC_IO File and TTY I/O routines, including stdio. INC_MATH Simple math routines. INC_MSG Message sending and trapping routines. INC_MEM Memory allocation/free routines. INC_STR String functions, including C's and this library's. INC_LIB All five of the above. INC_MISC Misc. functions (time, subshells, array dumps, sorting, etc). INC_SHELL The ubiquitous MAPMAKERish shell. INC_TABLE A useful data struct, used by the shell and other things. *************************************************************************/ #ifdef _SYS_SUNOS #define _SYS_UNIX #else #ifdef _SYS_ULTRIX #define _SYS_UNIX #else #ifdef _SYS_AUX #define _SYS_UNIX /* Note: NOT _SYS_MAC */ #endif #endif #endif #ifdef _SYS_WATCOM #define _SYS_DOS #endif /************************ File name syntax **************************** Setup the following for the OS's path types (these are used by the make_filename() procedure in iolib.c). Note that the lengths of various elements of a path are not checked, only its total length. *************************************************************************/ #define PATH_LENGTH 200 #ifndef _SYS_DOS /* e.g. _SYS_UNIX or some POSIX like thing */ #define HELP_EXT ".help" #define ARG_CHAR '-' /* Usual char for command line switches */ #define PATH_REQUIRE_EXTENSION FALSE #define PATH_SINGLE_EXTENSION FALSE #define PATH_UPPERCASE FALSE #define PATH_DIR_SEPARATORS "/" /* rightmost separating char */ #define PATH_DIR_FILE_INSERT "/" /* insert between a dir and filename */ #define PATH_OK_CHARS \ "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~#/" #define PATH_DIR_CHARS \ "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~#/" #else /* is _SYS_DOS */ #define HELP_EXT ".hlp" #define ARG_CHAR '/' /* Usual char for command line switches */ #define PATH_REQUIRE_EXTENSION TRUE #define PATH_SINGLE_EXTENSION TRUE #define PATH_UPPERCASE TRUE #define PATH_DIR_SEPARATORS "\\" /* rightmost separating char */ #define PATH_DIR_FILE_INSERT "\\" /* insert between a dir and filename */ #define PATH_OK_CHARS \ "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.$#/\\" #define PATH_DIR_CHARS \ "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.$#/\\" #endif /**************************** Subshells ********************************* To help portability, we use the system() function to spawn subshells on all operating systems. (However, system specific code may be placed in syscode.c to do it another way). Under Unix, if TRY_SHELL_VAR is TRUE, getenv() will be used to get the value of SHELL to run by calling system(getenv("SHELL")). If the SHELL variable is not set we try calling system(TRY_SHELL_CMD). Naturally, these presume HAVE_GETENV is defined. On MS-DOS we will first try system(getenv("COMSPEC")). Otherwise, TRY_SHELL_CMD should be "command.com". System() is not supported on the Mac, and on VMS, SHELL_CMD should be "SPAWN". **************************************************************************/ /* #define NO_SYSTEM_FUNC *//* ANSI/POSIX - All should have system() now */ #ifdef _SYS_DOS #define TRY_COMSPEC_VAR #define TRY_SHELL_CMD "command.com" #define SHELL_MESSAGE "Running DOS prompt: Type 'exit' to return...\n" #else /* _SYS_UNIX */ #define TRY_SHELL_VAR #define TRY_SHELL_CMD "/bin/csh" /* csh is the default on Sun, DEC, A/UX */ #define SHELL_MESSAGE \ "Running Unix shell: Type 'exit' or hit Control-D to return...\n" #endif /************************ Error handling routines ************************* Errno lookups: strerror(), which is allegedly ANSI standard, should return an error message (char*) when given a correct system errno (generally from ferror()). Don't use perror(). For systems without strerror(), use sys_errlist[] and sys_nerr (this includes Lightspeed, System V, HP-UX, and SunOS). If sys_nerr does not exist, we ignore it and hope that sysnerr[errno] is valid... On some systems (Sun) sys_errlist does not appear in any #include file, although errno (extern int) is defined (usu. in math.h?). Also, define HAVE_MATHERR if matherr() trapping is supported, as it is on System V (See msglib.h). SIGHANDLE should be the return value type of a signal handling function used as an argument to signal(). ***************************************************************************/ #define HAVE_MATHERR /* Doesn't hurt to not define it... */ #ifdef _SYS_WATCOM /* strerror is defined, as it should be */ #define SIGHANDLE int #define SIGQUIT SIGABRT /* bizzare */ #endif #ifdef _SYS_SUNOS /* the @#!$% map pages lie */ #define SIGHANDLE int #define strerror(num) (num=0 or 0 indicating "no error" int getc(FILE *fp) returns c or EOF ungetc(int c; FILE *fp) it can't fail FILE *fopen(char *nam,*mode) NULL if fail fseek(FILE *fp; long num; int dir) it can't fail if fp is OK int fgets(FILE *fp; char *s; int n) may return EOF char Note that functions listed without return types here may or may not be of type void: on many systems they are of type int! However, the fuction's return value is always (and should always be) discarded, if it exists. We provide a workaround for fseek(), which seems to have bugs on VMS. ***************************************************************************/ #define xputc(c,fp) (putc(c,fp)!= EOF) #define xclose(fp) (fclose(fp)!= EOF) #define file_seek(fp,char_num) fseek(fp,((long)(char_num)),0) /* #define REPLACE_FSEEK *//* Needed on VMS? */ /**************** GLOBAL DECLARATIONS FOR USERS OF LIB ***************** Good working assumptions about data types, etc: * Doubles are big (say e+/-30, at least): avoid single precision (float) or other floating point types like the plauge. * A short is 2 bytes and a long is 4 bytes, both are signed. * An int is either a short or a long. On everything we use now, its long. * A char can take 7 (NOT 8) bits (0-127), positive values only. * unsigned ints exist, but there are a number of reasons not to use them (it is easy for arguments to get passed incorrectly). * Never-ever assume that shifts wrap around correctly (or don't wrap correctly), or that overflow/underflow ever produces predictable results * God knows what a pointer is. Always cast pointer types correctly, and avoid recasting pointers in general. * Always make sure that arguments passed=arguments declared EXACTLY! Many bugs arrise if you don't. Never assume that parameters in a function call will be automaticly be cast correctly. Be explicit. * Pass structs/unions/arrays as args by pointer ONLY. Passing by value is not even close to portable. Variable length argument lists are not portable. Returning structs/unions/arrays by value is also unportable. * Never-ever-ever try to side-effect constants. The biggest culprit here is passing a string argument to a function which then try to change characters in the string. This causes bus errors on most systems. * void exists, but void* doesn't, nor does enum. Use void, not int, for procedures that return nothing * Really avoid other implicit int declarations (ex arguments w/o a type are assumed to be ints - YUK!) * Only assume that the result of a boolean expression (ex x #ifndef _SYS_WATCOM #include /* not quite sure why we need this */ #endif #ifdef INC_IO #include #include "iolib.h" #endif #ifdef INC_MATH #ifdef _SYS_WATCOM #undef real #endif #include /* WATCOM has problems with this if "real" is a macro */ #ifdef _SYS_WATCOM #define real double #endif #include "mathlib.h" #endif #ifdef INC_MSG #include #include "msglib.h" #endif #ifdef INC_MEM #include "memlib.h" #endif #ifdef INC_STR #include #include #include "strlib.h" #endif /* The following are NOT included by INC_LIB */ #ifdef INC_MISC #include "misclib.h" #endif #ifdef INC_SHELL #include "shell.h" #endif #ifdef INC_TABLE #include "table.h" #endif #ifdef INC_EQN #include "eqn.h" #endif #ifdef INC_HISTO void make_histo(); /* that's all? */ #endif #ifdef INC_STATS #include "stats.h" #endif /********************* Defs internal to the library ********************* Here are definitions needed ONLY to compile the helpers files themselves. None of this stuff should be used by the user code: much better (that is, robust and portable) interfaces are provided by the library. */ /*************************************************************************/ #ifdef INC_HELP_DEFS #include #include #include /* for ctime() def - Who does not have this file? */ #include #include #ifdef TRY_WINSIZE #include #endif /* The BSD random number functions... seemingly not declared anywhere */ #ifdef USE_RANDOM long random(); int srandom(); #endif /* The HPUX (and System V?) random number functions... ditto */ #ifdef USE_DRAND48 double drand48(); void srand48(); #endif /* Library declarations only to be used by the helpers library code itself */ extern char *ps_, *ln_; /* defined in iolib.c */ void dummy_math_calls(); #endif /* for #ifdef INC_HELP_DEFS */ #undef fflush /* a special version is used by the application code */ /*************************************************************************/