File: oldcrtl.c

package info (click to toggle)
glhack 1.2-3
  • links: PTS
  • area: main
  • in suites: stretch
  • size: 26,744 kB
  • ctags: 21,239
  • sloc: ansic: 208,571; cpp: 13,139; yacc: 2,005; makefile: 1,155; lex: 377; sh: 121; awk: 89; sed: 11
file content (192 lines) | stat: -rw-r--r-- 5,573 bytes parent folder | download | duplicates (24)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
/*	SCCS Id: @(#)oldcrtl.c	3.4	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
 * <varargs.h> 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 <errno.h>
#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*/