[net.sources] varargs for the Zilog ZEUS

john@physiol.OZ (John Mackin) (12/21/84)

# This is a shell archive.  Remove anything before this line, then
# unpack it by saving it in a file and typing "sh file".  (Files
# unpacked will be owned by you and have default permissions.)
#
# This archive contains:
# READ_ME varargs.c varargs.h
echo x - READ_ME
cat > "READ_ME" << '//E*O*F READ_ME//'
This is an implementation of varargs.h for the Zilog ZEUS system.  It is
in use in production software, and is believed bug-free.  I no longer
have access to a ZEUS, but I would still appreciate hearing about
problems with it.

To install, just copy varargs.h to /usr/include (the one supplied by
Zilog is for a PDP-11), and cc -O -c varargs.c and put the resulting .o
file into /lib/libc.a (or ensure by whatever other means you like
that it gets loaded with any program which #include's varargs.h).


John Mackin, Physiology Department, University of Sydney, Sydney, Australia
...!decvax!mulga!physiol.su.oz!john		[UUCP]
decvax!mulga!physiol.su.oz!john@Berkeley	[ARPA]
john:physiol.su					[ACSnet]
//E*O*F READ_ME//
echo x - varargs.c
cat > "varargs.c" << '//E*O*F varargs.c//'
#include "varargs.h"

int _va_ustk[6] = { 0, 0, 0, 0, 0, 0, };
int _va_initialized = 0;
int _va_left = 0;

va_list _va_arg(list, size, next)
register va_list *list;
register int size;
register va_list next;
{
    register int i;

    if (_va_left < 0) {
	_va_left = -_va_left;
	*list += sizeof (long);
    }
    if (size == sizeof (long) && _va_left <= _va_Regsiz && size <= _va_left) {
	if (_va_left >= _va_Regsiz - sizeof (long)) {
	    _va_left = -4;
	    *list = (va_list)&_va_ustk[2];
	}
	else {
	    _va_left = 0;
	    *list = (va_list)&_va_ustk[4];
	}
	i = *((int *)*list + 1);
	*((int *)*list + 1) = *(int *)*list;
	*(int *)*list = i;
	return (*list);
    }
    if (size > _va_left || size == sizeof (double)) {
	*list = next;
	_va_left = (unsigned)-1 >> 1;
    }
    
    _va_left -= size;
    *list += size;
    return (*list - size);
}
//E*O*F varargs.c//
echo x - varargs.h
cat > "varargs.h" << '//E*O*F varargs.h//'
/*
 * Rewritten: JJM, Tue Aug  2 00:04:30 1983
 * to support the silly args-in-registers plan
 */

#define	_va_Regsiz	12
#define	va_alist	_va_r7, _va_r6, _va_r5, _va_r4, _va_r3, _va_r2, _va_stk
typedef	char *		va_list;
#define	va_dcl		int _va_r7, _va_r6, _va_r5, _va_r4, _va_r3, _va_r2, _va_stk;
#define	va_start(list)	{						\
			    register int *_va_i;			\
									\
			    if (!_va_initialized) {			\
				_va_i = &_va_ustk[0];			\
				*_va_i++ = _va_r7;	*_va_i++ = _va_r6; \
				*_va_i++ = _va_r5;	*_va_i++ = _va_r4; \
				*_va_i++ = _va_r3;	*_va_i = _va_r2; \
			    }						\
			    _va_initialized = 1;			\
			    list = (va_list)&_va_ustk[0];		\
			    _va_left = _va_Regsiz;			\
			}
#define	va_end(list)	va_initialized = 0
#define	va_arg(list, mode) (*(mode *)_va_arg((va_list *)&list, sizeof (mode), (va_list)&_va_stk))

va_list _va_arg();
extern int _va_ustk[], _va_initialized, _va_left;
//E*O*F varargs.h//
exit 0