From: jwalz Date: Sat, 5 Jan 2002 21:06:00 +0000 (+0000) Subject: *** empty log message *** X-Git-Tag: MOVE2GIT~3630 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6f4f2d3947d1f38a39e9e93fa7604f48d04f9e8e;p=nethack *** empty log message *** --- diff --git a/sys/vms/oldcrtl.c b/sys/vms/oldcrtl.c new file mode 100644 index 000000000..586f69793 --- /dev/null +++ b/sys/vms/oldcrtl.c @@ -0,0 +1,192 @@ +/* SCCS Id: @(#)oldcrtl.c 3.3 1995/06/01 */ +/* Pat Rankin May'90 */ +/* VMS NetHack support, not needed for vms 4.6,4.7,5.x,or later */ + +#ifdef VERYOLD_VMS +/* + * The following routines are used by NetHack but were not available + * from the C Run-Time Library (VAXCRTL) prior to VMS V4.6. + * + * atexit, memcmp, memcpy, qsort, rename, vprintf, vsprintf + * + * Most of them are implemented here, but others will have to be worked + * around in another fashion [such as '#define USE_OLDARGS' (even though + * is available) to avoid the need for vprintf & vsprintf]. + * + */ +#define REG register +#define const + +#ifndef SUPPRESS_MEM_FUNCS +/* note: hand optimized for VAX (hardware pre-decrement & post-increment) */ + +/* void *memset(void *, int, size_t) -- fill chunk of memory. +*/ +char *memset( dst, fil, cnt ) +REG char *dst; +REG char fil; +REG int cnt; +{ + char *dst_p = dst; + while ( --cnt >= 0 ) + *dst++ = fil; + return dst_p; +} + +/* void *memcpy(void *, const void *, size_t) -- copy chunk of memory. +*/ +char *memcpy( dst, src, cnt ) +REG char *dst; +REG const char *src; +REG int cnt; +{ + char *dst_p = dst; + while ( --cnt >= 0 ) + *dst++ = *src++; + return dst_p; +} + +/* void *memmove(void *, const void *, size_t) -- copy possibly overlapping mem. +*/ +char *memmove( dst, src, cnt ) +REG char *dst; +REG const char *src; +REG int cnt; +{ + char *dst_p = dst; + if ( src == dst || cnt <= 0 ) { + ; /* do nothing */ + } else if ( dst < src || dst >= src + cnt ) { + while ( --cnt >= 0 ) + *dst++ = *src++; + } else { /* work backwards */ + dst += cnt, src += cnt; + while ( --cnt >= 0 ) + *--dst = *--src; + } + return dst_p; +} + +/* void *memchr(const void *, int, size_t) -- search for a byte. +*/ +char *memchr( buf, byt, len ) +REG const char *buf; +REG char byt; +REG int len; +{ + while ( --len >= 0 ) + if ( *buf++ == byt ) /* found */ + return (char *)--buf; + return (char *)0; /* not found */ +} + +/* int memcmp(const void *, const void *, size_t) -- compare two chunks. +*/ +int memcmp( buf1, buf2, len ) +REG const char *buf1; +REG const char *buf2; +REG int len; +{ + while ( --len >= 0 ) + if ( *buf1++ != *buf2++ ) + return (*--buf1 - *--buf2); + return 0; /* buffers matched */ +} +#endif /*!SUPPRESS_MEM_FUNCS*/ + + +#ifndef SUPPRESS_ATEXIT +/* int atexit(void (*)(void)) -- register an exit handler. +*/ +#define MAX_EXIT_FUNCS 32 /* arbitrary (32 matches VAX C v3.x docs) */ +struct ex_hndlr { long reserved, (*routine)(), arg_count, *arg1_addr; }; +static int ex_cnt = 0; /* number of handlers registered so far */ +static struct { long dummy_arg; struct ex_hndlr handler; /*(black box)*/ + } ex_data[MAX_EXIT_FUNCS]; /* static handler data */ +extern unsigned long sys$dclexh(); + +int atexit( function ) + void (*function)(); /* note: actually gets called with 1 arg */ +{ + if ( ex_cnt < MAX_EXIT_FUNCS ) { + ex_data[ex_cnt].dummy_arg = 0; /* ultimately receives exit reason */ + ex_data[ex_cnt].handler.reserved = 0; + ex_data[ex_cnt].handler.routine = (long (*)()) function; + ex_data[ex_cnt].handler.arg_count = 1; /*(required)*/ + ex_data[ex_cnt].handler.arg1_addr = &ex_data[ex_cnt].dummy_arg; + (void)sys$dclexh(&ex_data[ex_cnt].handler); /* declare exit handler */ + return ++ex_cnt; /*(non-zero)*/ + } else + return 0; +} +#endif /*!SUPPRESS_ATEXIT*/ + + +#ifndef SUPPRESS_RENAME +/* int rename(const char *, const char *) -- rename a file (on same device). +*/ +#ifndef EVMSERR +#include +#define C$$TRANSLATE(status) (errno = EVMSERR, vaxc$errno = (status)) +#endif +extern unsigned long lib$rename_file(); + +int rename( old_name, new_name ) + const char *old_name; + const char *new_name; +{ + struct dsc { unsigned short len, mbz; const char *adr; } old_dsc, new_dsc; + unsigned long status; + + /* put strings into descriptors and call run-time library routine */ + new_dsc.mbz = old_dsc.mbz = 0; /* type and class unspecified */ + old_dsc.len = strlen( old_dsc.adr = old_name ); + new_dsc.len = strlen( new_dsc.adr = new_name ); + status = lib$rename_file(&old_dsc, &new_dsc); /* omit optional args */ + if ( !(status & 1) ) { /* even => failure */ + C$$TRANSLATE(status); + return -1; + } else /* odd => success */ + return 0; +} +#endif /*!SUPPRESS_RENAME*/ + + +#ifndef SUPPRESS_QSORT +/* void qsort(void *, size_t, size_t, int (*)()) -- sort arbitrary collection. +*/ +extern char *malloc(); /* assume no alloca() available */ +extern void free(); + +void qsort( base, count, size, compare ) + char *base; + int count; +REG int size; + int (*compare)(); +{ +REG int i, cmp; +REG char *next, *prev, *tmp = 0; + char wrk_buf[512]; + + /* just use a shuffle sort (tradeoff between efficiency & simplicity) */ + /* [Optimal if already sorted; worst case when initially reversed.] */ + for ( next = base, i = 1; i < count; i++ ) { + prev = next, next += size; /* increment front pointer */ + if ( (cmp = (*compare)( next, prev)) < 0 ) { + /* found element out of order; move other(s) up then re-insert it */ + if ( !tmp ) tmp = size > (int)(sizeof wrk_buf) ? malloc(size) : wrk_buf; + memcpy( tmp, next, size); /* save smaller element */ + while ( cmp < 0 ) { + memcpy( prev + size, prev, size); /* move larger elem. up */ + prev -= size; /* decrement back pointer */ + cmp = (prev >= base ? (*compare)( tmp, prev) : 0); + } + memcpy( prev + size, tmp, size); /* restore small element */ + } + } + if ( tmp != 0 && tmp != wrk_buf ) free(tmp); + return; +} +#endif /*!SUPPRESS_QSORT*/ + +#endif /*VERYOLD_VMS*/