abort.c
/* Copyright 1989 Manx Software Systems, Inc. All rights reserved */

/*
 *	Synopsis
 *
 *	void abort(void);
 *
 *
 *	Description
 *
 *		The abort function causes abnormal program termination to occur, unless
 *	the signal SIGABRT is being caught and the signal handler does not return.
 *	Whether open output streams are flushed or open streams are closed or
 *	temporary files removed is implementation-defined. An implementation-
 *	defined form of the status unsuccessful termination is returned to the host
 *	environment by means of the function call raise(SIGABRT).
 *
 *
 *	Returns
 *
 *		The abort function cannot return to its caller.
 */

#include <stdlib.h>
#include <signal.h>

void
abort(void)
{
	raise(SIGABRT);
}

abs.a68
; Copyright 1989 Manx Software Systems, Inc. All rights reserved
; :ts=8

;	Synopsis
;
;	int abs(int j);
;
;
;	Description
;
;	    The abs function computes the absolute value of an integer j. If
;	the result cannot be represented, the behavior is undefined.
;
;
;	Returns
;
;	    The abs function returns the absolute value.

MOVE_X	macro
	IF INT32
	move.l	%1,%2
	ELSE
	move.w	%1,%2
	ENDC
	ENDM

NEG_X	macro
	IF INT32
	neg.l	%1
	ELSE
	neg.w	%1
	ENDC
	ENDM

	xdef	_abs
_abs:
	MOVE_X	4(sp),d0
	bpl	.1
	NEG_X	d0
.1
	rts

atexit.c
/* Copyright 1989 Manx Software Systems, Inc. All rights reserved */

/*
 *	Synopsis
 *
 *	int atexit(void (*func)(void));
 *
 *
 *	Description
 *
 *		The atexit function registers the function pointed to by func, to be
 *	called without arguments at normal program termination.
 *
 *
 *	Implementation Limits
 *
 *		The implementation shall support the registration of at least 32
 *	functions.
 *
 *
 *	Returns
 *
 *		The atexit function returns zero if the registration succeeds, nonzero
 *	if it fails.
 */

#include <stdlib.h>

typedef void (*PFV)(void);

struct _exfunc {
	struct _exfunc *next;
	PFV func;
};

extern struct _exfunc *_exit_funcs;

int
atexit(void (*func)(void))
{
	register struct _exfunc *ep;

	if ((ep = malloc(sizeof(struct _exfunc))) == 0)
		return(-1);
	ep->next = _exit_funcs;
	_exit_funcs = ep;
	ep->func = func;
	return(0);
}

atof.c
/* Copyright 1989 Manx Software Systems, Inc. All rights reserved */

/*
 *	Synopsis
 *
 *	double atof(const char *nptr);
 *
 *
 *	Description
 *
 *		The atof function converts the initial portion of the string pointed to
 *	by nptr to double representation. Except for the behavior on error, it is
 *	equivalent to 
 *
 *		strtod(nptr, (char **)NULL);
 *
 *
 *	Returns
 *
 *		The atof funciton returns the converted value.
 */

#include <stdlib.h>

double
atof(register const char *cp)
{
	return(strtod(cp, (char **)0));
}

atoi.c
/* Copyright 1989 Manx Software Systems, Inc. All rights reserved */

/*
 *	Synopsis
 *
 *	int atoi(const char *nptr);
 *
 *
 *	Description
 *
 *		The atoi function converts the initial portion of the string pointed
 *	to by nptr to int representation. Except for the behavior on error it is
 *	equivalent to
 *
 *		(int) strtol(nptr, (char **)NULL, 10)
 *
 *
 *	Returns
 *
 *		The atoi function returns the converted value.
 */

#include <stdlib.h>
#include <ctype.h>

int
atoi(register const char *cp)
{
	register unsigned i;
	register sign;

	while (*cp == ' ' || *cp == '\t')
		++cp;
	sign = 0;
	if ( *cp == '-' ) {
		sign = 1;
		++cp;
	} else if ( *cp == '+' )
		++cp;

	for ( i = 0 ; isdigit(*cp) ; )
		i = i*10 + *cp++ - '0';
	return(sign ? -i : i);
}

atol.c
/* Copyright 1989 Manx Software Systems, Inc. All rights reserved */

/*
 *	Synopsis
 *
 *	long int atol(const char *nptr);
 *
 *
 *	Description
 *
 *		The atol function converts the initial portion of the string pointed to
 *	by nptr to long int representation. Except for the behavior on error it is
 *	equivalent to
 *
 *		(int) strtol(nptr, (char **)NULL, 10)
 *
 *
 *	Returns
 *
 *		The atol function returns the converted value.
 */

#include <stdlib.h>
#include <ctype.h>

long int
atol(register const char *cp)
{
	register long n;
	register int sign;

	while (*cp == ' ' || *cp == '\t')
		++cp;
	sign = 0;
	if ( *cp == '-' ) {
		sign = 1;
		++cp;
	} else if ( *cp == '+' )
		++cp;

	for ( n = 0 ; isdigit(*cp) ; )
		n = n*10 + *cp++ - '0';
	return(sign ? -n : n);
}
bsearch.c
/* Copyright 1989 Manx Software Systems, Inc. All rights reserved */

/*
 *	Synopsis
 *
 *	void *bsearch(const void *key, const void *base, size_t nmemb, size_t size,
 *						int (*compar)(const void *, const void *));
 *
 *
 *	Description
 *
 *		The bsearch function searches an array of nmemb objects, the initial
 *	member of which is pointed to by base, for a member that matches the object
 *	pointed to by key. The size of each member of the array is specified by
 *	size.
 *
 *		The contents of the array shall be in ascending sorted order according
 *	to a comparison function pointed to by compar, which is called with two
 *	arguments that point to the key object and to an array member, in that
 *	order. The function shall return an integer less than, equal to, or greater
 *	than zero if the key object is considered, respectively, to be less than,
 *	to match, or to be greater than the array member.
 *
 *
 *	Returns
 *
 *		The bsearch function returns a pointer to a matching member of the
 *	array, or a null pointer if no match is found. If two members compare as
 *	equal, which member is matched is unspecified.
 */


#include <stdlib.h>

void *
bsearch(const void *key, const void *base, size_t nmemb, size_t size,
							register int (*compar)(const void *, const void *))
{
	register unsigned long first = 0;
	register unsigned long last = nmemb-1;
	register unsigned long n;
	register unsigned long lsize = size;

	if (last == ((unsigned long)0-(unsigned long)1))
		return(0);

	do {
		register int k;
		char *b;

		n = ((unsigned long)first+(unsigned long)last) >> 1;
		k = (*compar)(key, b = (char *)base + n * lsize);

		if (k == 0)
			return(b);
		if (k < 0)
			last = n - 1;
		else
			first = n + 1;
	} while (last >= first);

	return(0);
}

calloc.c
/* Copyright 1989 Manx Software Systems, Inc. All rights reserved */

/*
 *	Synopsis
 *
 *	void *calloc(size_t nmemb, size_t size);
 *
 *
 *	Description
 *
 *		The calloc function allocates space for an array of nmemb objects, each
 *	of whose size is size. The space is initialized to all bits zero.
 *
 *
 *	Returns
 *
 *		The calloc function returns either a null pointer or a pointer to the
 *	allocated space.
 */

#include <stdlib.h>
#include <string.h>

void *
calloc(size_t nelem, size_t size)
{
	register size_t i = nelem*size;
	register void *cp;

	if ((cp = malloc(i)) != NULL)
		memset(cp, 0, i);
	return(cp);
}

div.c
/* Copyright 1989 Manx Software Systems, Inc. All rights reserved */

/*
 *	Synopsis
 *
 *	div_t div(int numer, int denom);
 *
 *
 *	Description
 *
 *		The div function computes the quotient and remainder of the division of
 *	the numerator numer by the demominator denom. If the division is inexact,
 *	the sign of the resulting quotient is that of the algebraic quotient, and
 *	the magnitude of the resulting quotient is the largest integer less than
 *	the magnitude of the algebraic quotient. If the result cannot be
 *	represented, the behavior is undefined; otherwise, quot * denom + rem shall
 *	equal numer.
 *
 *
 *	Returns
 *
 *		The div function returns a structure of type div_t, comprising both
 *	the quotient and the remainder. The structure shall contain the following
 *	members, in either order.
 *
 *		int quot;	quotient
 *		int rem;	remainder
 */

#include <stdlib.h>

div_t div(register int numer, register int denom)
{
	div_t d;

	d.quot = numer / denom;
	d.rem = numer % denom;
	return(d);
}

exit.c
/* Copyright 1989 Manx Software Systems, Inc. All rights reserved */

/*
 *	Synopsis
 *
 *	void exit(int status);
 *
 *
 *	Description
 *
 *		The exit function causes normal program termination to occur. If more
 *	than one call to the exit functions is executed by a program, the behavior
 *	is undefined.
 *
 *		First, all functions registered by the atexit function are called, in
 *	the reverse order of their registration.
 *
 *		Next, all open output streams are flushed, all open streams are closed,
 *	and all files created by the tmpfile function are removed.
 *
 *		Finally, control is returned to the host environment. If the value of
 *	status is zero or EXIT_SUCCESS, an implementation-defined form of the
 *	status "successful termination" is returned. If the value of the status is
 *	EXIT_FAILURE, an implementation-defined form of the status "unsuccessful
 *	termination" is returned. Otherwise the status returned is implementation-
 *	defined.
 *
 *
 *	Returns
 *
 *		The exit function cannot return to its caller.
 */

typedef void (*PFV)(void);

struct _exfunc {
	struct _exfunc *next;
	PFV func;
};

struct _exfunc *_exit_funcs;

PFV _close_stdio;
extern void _exit(int status);


void
exit(int status)
{
	while (_exit_funcs) {
		(*_exit_funcs->func)();
		_exit_funcs = _exit_funcs->next;
	}

	if (_close_stdio)
		(*_close_stdio)();

	_exit(status);
}

free.c
/* Copyright 1989 Manx Software Systems, Inc. All rights reserved */

/*
 *	Synopsis
 *
 *	void free(void *ptr);
 *
 *
 *	Description
 *
 *		The free function causes the space pointed to by ptr to be deallocated,
 *	that is, made available for further allocation. If ptr is a null pointer,
 *	action occurs. Otherwise, if the argument does not match a pointer earlier
 *	returned by the calloc, malloc or realloc function, or if the space has
 *	been deallocated by a call to free or realloc, the behavior is undefined.
 *
 *
 *	Returns
 *
 *		The free function returns no value.
 */

#include <stdlib.h>
#include <functions.h>

struct mem {
	struct mem *next;
	long size;
};

struct mem *_Free;

void free(void *blk)
{
	register struct mem *mp, *xp;

	xp = 0;
	for (mp=_Free;mp;mp=mp->next) {
		if (mp+1 == blk)
			goto found;
		xp = mp;
	}
	return;
found:
	if (xp)
		xp->next = mp->next;
	else
		_Free = mp->next;
	FreeMem(mp, mp->size+sizeof(struct mem));
}

ftoa.c
/* Copyright (C) 1984 by Manx Software Systems, Inc. */

#ifdef FP_FFP
static long lround[] = {
	0xa0000044L, 0x80000041L,
	0x80000040L, 0xcccccd3cL, 0xa3d70a39L, 0x83126e36L,
	0xd1b71632L, 0xa7c5ab2fL, 0x8637bc2cL, 0xd6bf9328L,
	0xabcc7625L, 0x89705e22L, 0xdbe6fd1eL, 0xafebfe1bL,
	0x8cbccb18L, 0xe12e1214L, 0xb424db11L, 0x901d7c0eL,
};
#else
static double round[] = { 10, 1,
	5e-1, 5e-2, 5e-3, 5e-4, 5e-5, 5e-6, 5e-7, 5e-8, 5e-9, 5e-10,
	5e-11, 5e-12, 5e-13, 5e-14, 5e-15, 5e-16 };
#endif

void
ftoa(double number, register char *buffer, int maxwidth, int mode)
{
	register int i;
	register int exp, digit, decpos, ndig;
	register int flag;
#ifdef FP_FFP
	register float *round = (float *)lround;
#endif

#ifndef FP_FFP
	if ((*(short *)&number&0x7ff0) == 0x7ff0) {
		exp = (*(short *)&number&0x8000) ? '-' : '+';
		while (maxwidth--)
			*buffer++ = exp;
		*buffer = 0;
		return;
	}
#endif

	/*
	 *	Convert the number to a number between 1 and 10 or 0. Calculate the
	 *	exponent at the same time.
	 */

	exp = 0;
	if (number < 0.0) {
		number = -number;
		*buffer++ = '-';
	}
	if (number > 0.0) {
		while (number < round[1]) {
			number *= round[0];
			--exp;
		}
		while (number >= round[0]) {
			number /= round[0];
			++exp;
		}
	}


	/*
	 *	The number of digits to display is equal to the number of digits
	 *	following the decimal point (maxwidth) + digits to the left (exp) +
	 *	a guaranteed digit since the number 10 > x >= 1. For E format, the
	 *	exp digits are not counted, while G format works differently.
	 */

	flag = mode & 3;
	if (flag == 2) {						/* 'g' format */
		if (maxwidth == 0)
			maxwidth = 1;
		if (exp < -4 || exp >= maxwidth)
			flag = -1;						/* switch to 'e' format */
		ndig = maxwidth;
	} else if (flag == 1)					/* 'f' format */
		ndig = maxwidth + exp + 1;
	else									/* 'e' format */
		ndig = maxwidth + 1;

	/*
	 *	Round the number up using 5e-x where x is one more than the
	 *	precision of the number.
	 */

	if (ndig > 0) {
		if ((number += round[(ndig>16?16:ndig)+1]) >= round[0]) {
			number = round[1];
			++exp;
			if (flag > 0)
				++ndig;
		}
	}

	if (flag > 0) {
		if (exp < 0) {
			*buffer++ = '0';
			*buffer++ = '.';
			i = -exp - 1;
			if (ndig <= 0)
				i = maxwidth;
			while (i--)
				*buffer++ = '0';
			decpos = 0;
		} else {
			decpos = exp+1;
		}
	} else {
		decpos = 1;
	}

	if (ndig > 0) {
		for (i = 0 ; ; ++i) {
			if (i < 16) {
				digit = (int)number;
				*buffer++ = digit+'0';
				number = (number - digit) * round[0];
			} else
				*buffer++ = '0';
			if (--ndig == 0)
				break;
			if (decpos && --decpos == 0)
				*buffer++ = '.';
		}
	}

	if (decpos && (mode&0x20))
		*buffer++ = '.';
	if (flag <= 0) {
		*buffer++ = (mode&0x10)?'E':'e';
		if (exp < 0) {
			exp = -exp;
			*buffer++ = '-';
		} else
			*buffer++ = '+';
		*buffer++ = exp/100 + '0';
		exp %= 100;
		*buffer++ = exp/10 + '0';
		*buffer++ = exp%10 + '0';
	}
	if (decpos == 0 && (flag == 2 || flag == -1) && (mode&0x20) == 0) {
		while (*--buffer == '0')
			;
		if (*buffer != '.')
			++buffer;
	}
	*buffer = 0;
}

getenv.c
/* Copyright 1989 Manx Software Systems, Inc. All rights reserved */

/*
 *	Synopsis
 *
 *	char *getenv(const char *name);
 *
 *
 *	Description
 *
 *		The getenv function searches an "environment list", provided by the
 *	host environment, for a string that matches the string pointed to by name.
 *	The set of environment names and the method for altering the environment
 *	list are implementation-defined.
 *
 *		The implementation shall behave as if no library function calls the
 *	getenv function.
 *
 *
 *	Returns
 *
 *		The getenv function returns a pointer to a string asociated with the
 *	matched list member. Th array pointed to shall not be modified by the
 *	program, but may be overwritten by a subsequent call to the getenv
 *	function. If the specified name cannot be found, a null pointer is
 *	returned.
 */

#include <stdlib.h>
#include <string.h>
#include <functions.h>

struct lib {
	struct lib *succ, *prev;
	char type, priority;
	char *name;
	short flags;
	short negsize;
	short possize;
	short version;
	short revision;
	char *ID;
	long sum;
	short opencnt;
	char *env;
};

char *
getenv(const char *str)
{
	register struct lib *lp, *_OpenLibrary();
	register char *cp, *np;
	register size_t i;

	if ((lp = OpenLibrary("environment", 0L)) == 0)
		return(0);
	CloseLibrary(lp);
	Forbid();
	cp = lp->env;
	i = strlen(str);
	while (*cp) {
		if ((np = strchr(cp, '=')) && np-cp == i && strncmp(cp, str, i) == 0) {
			cp = malloc(strlen(++np)+1);
			strcpy(cp, np);
			Permit();
			return(cp);
		}
		cp += strlen(cp) + 1;
	}
	Permit();
	return(0);
}

labs.a68
; Copyright 1989 Manx Software Systems, Inc. All rights reserved
; :ts=8

;	Synopsis
;
;	long int labs(long int j);
;
;
;	Description
;
;	    The labs function computes the absolute value of a long integer j.
;	If the result cannot be represented, the behavior is undefined.
;
;
;	Returns
;
;	    The labs function returns the absolute value.

	xdef	_labs
_labs:
	move.l	4(sp),d0
	bpl	.1
	neg.l	d0
.1
	rts

ldiv.c
/* Copyright 1989 Manx Software Systems, Inc. All rights reserved */

/*
 *	Synopsis
 *
 *	ldiv_t ldiv(long int numer, long int denom);
 *
 *
 *	Description
 *
 *		The ldiv function computes the quotient and remainder of the division of
 *	the numerator numer by the demominator denom. If the division is inexact,
 *	the sign of the resulting quotient is that of the algebraic quotient, and
 *	the magnitude of the resulting quotient is the largest integer less than
 *	the magnitude of the algebraic quotient. If the result cannot be
 *	represented, the behavior is undefined; otherwise, quot * denom + rem shall
 *	equal numer.
 *
 *
 *	Returns
 *
 *		The ldiv function returns a structure of type ldiv_t, comprising both
 *	the quotient and the remainder. The structure shall contain the following
 *	members, in either order.
 *
 *		int quot;	quotient
 *		int rem;	remainder
 */

#include <stdlib.h>

ldiv_t ldiv(register long numer, register long denom)
{
	ldiv_t d;

	d.quot = numer / denom;
	d.rem = numer % denom;
	return(d);
}

makefile
CC=qcc
AS=as
CFLAGS=
AFLAGS=
O=oss

.c.$O:
	$(CC) -o $@ $(CFLAGS) $*.c
.a68.$O:
	$(AS) -o $@ $(AFLAGS) $*.a68

CLIB=\
	abs.$O atexit.$O atoi.$O atol.$O \
	bsearch.$O calloc.$O div.$O exit.$O free.$O \
	getenv.$O labs.$O malloc.$O mblen.$O mbtowc.$O \
	qsort.$O rand.$O realloc.$O strtol.$O \
	strtoul.$O system.$O wctomb.$O ldiv.$O abort.$O \
	wcstombs.$O mbstowcs.$O
MLIB=\
	atof.$O  ftoa.$O strtod.$O  strtold.$O 

clib:	$(CLIB)

mlib:	$(MLIB)

malloc.c
/* Copyright 1989 Manx Software Systems, Inc. All rights reserved */

/*
 *	Synopsis
 *
 *	void *malloc(size_t size);
 *
 *
 *	Description
 *
 *		The malloc function allocates space for an object whose size is
 *	specified by size and whose value is indeterminate.
 *
 *
 *	Returns
 *
 *		The malloc function returns either a null pointer or a pointer to the
 *	allocated space.
 */

#include <stdlib.h>
#include <functions.h>

struct mem {
	struct mem *next;
	long size;
};

struct mem *_Free;

static void
cleanup(void)
{
	register struct mem *mp, *xp;

	for (mp=_Free;mp;mp=xp) {
		xp = mp->next;
		FreeMem(mp, mp->size+sizeof(struct mem));
	}
	_Free = 0;
}

void *
malloc(size_t size)
{
	register struct mem *ptr;
	extern void (*_cln)(void);

	if (size == 0)
		return(0);
	if ((ptr = AllocMem(size+sizeof(struct mem), 0L)) == 0)
		return((void *)0);
	_cln = cleanup;
	ptr->next = _Free;
	ptr->size = size;
	_Free = ptr;
	return((char *)ptr + sizeof(struct mem));
}

mblen.c
/* Copyright 1989 Manx Software Systems, Inc. All rights reserved */

/*
 *	Synopsis
 *
 *	int mblen(const char *s, size_t n);
 *
 *
 *	Description
 *
 *		If s is not a null pointer, the mblen function determines the number of
 *	bytes comprising the multibyte character pointed to by s. Except that the
 *	shift state of the mbtowc function is not affected, it is equivalent to
 *
 *		mbtowc((wchar_t *)0, s, n);
 *
 *		The implementation shall behave as if no library function calls the
 *	mblen function.
 *
 *
 *	Returns
 *
 *		If s is a null pointer, the mblen function returns a nonzero or zero
 *	value, if multibyte character encodings, respectively, do or do not have
 *	state-dependent encodings. If s is not a null pointer, the mblen function
 *	either returns zero (if s points to the null character), or returns the
 *	number of bytes that comprise the multibyte character (if the next n or
 *	fewer bytes form a valid multibyte character), or returns -1 (if they do
 *	not form a valid multibyte character).
 */

#include <stdlib.h>

int mblen(const char *s, size_t n)
{
	if (s == 0 || *s == 0)
		return(0);
	if (n>=1)
		return(1);
	return(-1);
}

mbstowcs.c
/* Copyright 1989 Manx Software Systems, Inc. All rights reserved */

/*
 *	Synopsis
 *
 *	size_t mbstowcs(wchar_t *pwcs, const char *s, size_t n);
 *
 *
 *	Description
 *
 *		The mbstowcs function converts a sequence of multibyte characters that
 *	begins in the initial shift state from the array pointed to by s into a
 *	sequence of corresponding codes and stores not more than n codes into the
 *	array pointed to by pwcs. No multibyte characters that follow a null
 *	character (which is converted into a code with value zero) will be examined
 *	or converted. Each multibyte character is converted as if by a call to the
 *	mbtowc function, except that the shift state of the mbtowc function is not
 *	affected.
 *
 *		No more than n elements will be modified in the array pointed to by
 *	pwcs. If copying takes place between objects that overlap, the behavior is
 *	undefined.
 *
 *
 *	Returns
 *
 *		If an invalid multibyte character is encountered, the mbstowcs function
 *	returns (size_t)-1. Otherwise, the mbstowcs function returns the number of
 *	array elements modified, not including a terminating zero code, if any.
 */

#include <stdlib.h>

size_t
mbstowcs(wchar_t *pwcs, const char *s, size_t n)
{
	register size_t i = 0;

	while(i < n && (*pwcs++ = *s++))
		i++;
	return(i);
}

mbtowc.c
/* Copyright 1989 Manx Software Systems, Inc. All rights reserved */

/*
 *	Synopsis
 *
 *	int mbtowc(wchar_t *pwc, const char *s, size_t n);
 *
 *
 *	Description
 *
 *		If s is not a null pointer, the mbtowc function determines the number
 *	of bytes that comprise the multibyte character pointed to by s. It then
 *	determines the code for value of type wchar_t that corresponds to that
 *	multibyte character. (The value of the code corresponding to the null
 *	character is zero.) If the multibyte character is valid and pwc is not a
 *	null pointer, the mbtowc function stores the code in the object pointed to
 *	by pwc. At most n bytes of the array pointed to by s will be examined.
 *
 *		The implementation shall behave as if no library function calls the
 *	mbtowc function.
 *
 *
 *	Returns
 *
 *		If s is a null pointer, the mbtowc function returns a nonzero or zero
 *	value, if multibyte character encodings, respectively, do or do not have
 *	state-dependent encodings. If s is not a null pointer, the mbtowc function
 *	either returns zero (if s points to the null character), or returns the
 *	number of bytes that comprise the converted multibyte character (if the
 *	next n or fewer bytes form a valid multibyte character), or returns minus
 *	one (if they do not form a valid multibyte character).
 *
 *		In no case will the value returned be greater than n or the value of
 *	the MB_CUR_MAX macro.
 */

#include <stdlib.h>

int mbtowc(wchar_t *pwc, const char *s, size_t n)
{
	if (s == 0)
		return(0);
	if (n >= 1) {
		if (pwc != 0)
			*pwc = *s;
		if (*s == 0)
			return(0);
		return(1);
	}
	return(-1);
}

qsort.c
/* Copyright 1989 Manx Software Systems, Inc. All rights reserved */

/*
 *	Synopsis
 *
 *	void qsort(void *base, size_t nmemb, size_t size,
 *		 						int (*compar)(const void *, const void *));
 *
 *
 *	Description
 *
 *		The qsort function sorts an array of nmemb objects, the initial member
 *	of which is pointed to by base. The size of each object is specified by
 *	size.
 *
 *		The contents of the array are sorted in ascending order according to a
 *	comparison function pointed to by compar, which is called with two
 *	arguments that point to the objects being compared. The function shall
 *	return an integer less than, equal to, or greater than zero if the first
 *	argument is considered to be respectively less than, equal to, or greater
 *	than the second.
 *
 *		If two members compare as equal, their order in the sorted array is
 *	unspecified.
 *
 *
 *	Returns
 *
 *		The qsort function returns no value.
 */

#include <stdlib.h>
#include <string.h>

void
qsort(void *base, size_t nel, size_t size,
									int (*compar)(const void *, const void *))
{
	register char *i, *j, *x, *r, *bp;
	auto struct stk {
		char *l, *r;
	} stack[16];
	struct stk *sp;

	if (nel == 0)
		return;
	bp = base;
	sp = stack;
	r = bp + (nel-1)*size;
	for (;;) {
		do {
			x = bp + (r-bp)/size/2 * size;
			i = bp;
			j = r;
			do {
				while (i!=x && (*compar)(i,x) < 0)
					i += size;
				while (x!=j && (*compar)(x,j) < 0)
					j -= size;
				if (i < j) {
					swapmem(i, j, size);
					if (i == x)
						x = j;
					else if (j == x)
						x = i;
				}
				if (i <= j) {
					i += size;
					j -= size;
				}
			} while (i <= j);
			if (j-bp < r-i) {
				if (i < r) {	/* stack request for right partition */
					sp->l = i;
					sp->r = r;
					++sp;
				}
				r = j;			/* continue sorting left partition */
			} else {
				if (bp < j) {	/* stack request for left partition */
					sp->l = bp;
					sp->r = j;
					++sp;
				}
				bp = i;		/* continue sorting right partition */
			}
		} while (bp < r);

		if (sp <= stack)
			break;
		--sp;
		bp = sp->l;
		r = sp->r;
	}
}
rand.c
/* Copyright 1989 Manx Software Systems, Inc. All rights reserved */

/*
 *	Synopsis
 *
 *	void srand(unsigned int seed);
 *
 *
 *	Description
 *
 *		The srand function uses the argument as a seed for a new sequence of
 *	pseudo-random numbers to be returned by subsequent calls to rand. If srand
 *	is then called with the same seed value, the sequence of pseudo-random
 *	numbers shall be repeated. If rand is called before any calls to srand have
 *	been made, the same sequence shall be generated as when srand is first
 *	called with a seed value of 1.
 *
 *		The implementation shall behave as if no library function calls the
 *	srand function.
 *
 *
 *	Returns
 *
 *		The srand function returns no value.
 */

#include <stdlib.h>

static unsigned long next = 1;

void
srand(unsigned int seed)
{
	next = seed;
}

/*
 *	Synopsis
 *
 *	int rand(void);
 *
 *
 *	Description
 *
 *		The rand function computes a sequence of pseudo-random integers in the
 *	range 0 to RAND_MAX.
 *
 *		The implementation shall behave as if no library function calls the
 *	rand function.
 *
 *
 *	Returns
 *
 *		The rand function returns a pseudo-random integer.
 *
 *
 *	Environmental limit
 *
 *		The value of the RAND_MAX macro shall be at least 32767.
 */

int
rand(void)
{
	next = next * 1103515245L + 12345L;
	return((next >> 16) % (RAND_MAX+1L));
}

realloc.c
/* Copyright 1989 Manx Software Systems, Inc. All rights reserved */

/*
 *	Synopsis
 *
 *	void *realloc(void *ptr, size_t size);
 *
 *
 *	Description
 *
 *		The realloc function changes the size of the object pointed to by ptr
 *	to the size specified by size. The contents of the object shall be
 *	unchanged up to the lesser of the new and old sizes. If the new size is
 *	larger, the value of the newly allocated portion of the object is
 *	indeterminate. If ptr is a null pointer, the realloc function behaves like
 *	the malloc function for the specified size. Otherwise, if ptr does not
 *	match a pointer earlier returned by the calloc, malloc, or realloc
 *	function, or if the space has been deallocated by a call to the free or
 *	realloc function, the behavior is undefined. If the space cannot be
 *	allocated, the object pointed to by ptr is unchanged. If size is zero and
 *	ptr is not a null pointer, the object it points to is freed.
 *
 *
 *	Returns
 *
 *		The realloc function returns either a null pointer or a pointer to the
 *	possibly moved allocated space.
 */

#include <stdlib.h>
#include <string.h>

struct mem {
	struct mem *next;
	long size;
};

struct mem *_Free;

void *realloc(register void *ptr, register size_t size)
{
	register struct mem *lp, *tp;
	register void *newptr = 0;

	if (ptr) {
		tp = (struct mem *)ptr - 1;
		for (lp=_Free; lp; lp=lp->next)
			if (lp == tp)
				break;
		if (lp == 0)
			return(0);
	}

	if (size && (newptr = malloc(size)) == 0)
		return(0);

	if (ptr) {
		if (size) {
			if (size > lp->size)
				size = lp->size;
			memmove(newptr, ptr, size);
		}
		free(ptr);
	}
    return(newptr);
}

strtod.c
/* Copyright 1989 Manx Software Systems, Inc. All rights reserved */

/*
 *	Synopsis
 *
 *	double strtod(const char *nptr, char **endptr);
 *
 *
 *	Description
 *
 *		The strtod function converts the intitial portion of the string pointed
 *	to by nptr to double representation. First it decomposes the input string
 *	into three parts: an initial, possibly empty, sequence of white-space
 *	characters (as specified by the isspace function), a subject
 *	sequence resembling a floating-point constant, and a final string
 *	of one or more unrecognized characters, including the terminating
 *	null character of the input string. Then it attempts to convert
 *	the subject sequence to a floating-point number, and returns the
 *	result.
 *
 *	  The expected form of the subject sequence is an optional plus or
 *	minus sign, then a nonempty sequence of digits optionally
 *	containing a decimal-point character, then an optional exponent
 *	part, but no floating suffix. The subject sequence is defined as
 *	the longest subsequence of the input string, starting with the
 *	first non-white space character, that is an initial subsequence of
 *	a sequence of the expected form. The subject sequence contains no
 *	characters if the input string is empty or consists entirely of
 *	white space, or if the first non-white-space character is other
 *	than a sign, a digit, or a decimal-point character.
 *
 *		If the subject sequence has the expected form, the sequence of
 *	characters starting with the first digit or the decimal-point
 *	character (whichever occurs first) is interpreted as a floating
 *	constant, except that the decimal-point character is used in place
 *	of a period, and that if neither an exponent part nor a
 *	decimal-point character appears, a decimal point is assumed to
 *	follow the last digit in the string. If the subject sequence
 *	begins with a minus sign, the value resulting from the conversion
 *	is negated. A pointer to the final string is stored in the object
 *	pointed to by endptr, provided that endptr is not a null pointer.
 *
 *		If the subject sequence is empty or does not have the expected
 *	form, no conversion is performed; the value of nptr is stored in
 *	the object pointed to by endptr, provided that endptr is not a
 *	null pointer.
 *
 *
 *	Returns
 *
 *		The strtod function returns the converted value, if any. If no
 *	conversion is performed, zero is returned. If the correct value would cause
 *	overflow, plus or minus HUGE_VAL is returned (according to the sign of the
 *	value), and the value of the macro ERANGE is stored in errno. If the
 *	correct value would cause underflow, zero is returned and the value
 *	of the macro ERANGE is stored in errno.
 */

#include <ctype.h>
#include <errno.h>
#include <stdlib.h>

static double dpower(int n);

double strtod(register const char *str, register char **ep)
{
	register double val, oldval;
	register const char *bp, *x, *op;
	int exp, oexp;
	char mflg = 0;

	for (bp=str;isspace(*bp);bp++)			/* scan past leading spaces */
		;
	if (*bp == '\0') {						/* return(0) if unable */
empty:
		if (ep != 0)
			*ep = (char *)str;
		return(0.0);
	}
	
	switch (*bp) {							/* may be preceded by '+' or '-' */
		case '-':
			mflg = 1;
			/* fall through */
		case '+':
			bp++;
			break;
		default:
			if (!isdigit(*bp) && *bp != '.')
				goto empty;
	}

	val = 0;
	for (x=bp;isdigit(*x);x++)				/* scan to end of first part */
		;
	op = x;
	val = 0;	
	for (x--;x>=bp;x--) {					/* calculate left of dec. pt. */
		oldval = val;
		val += (*x-'0') * dpower((int)(op-x-1));
		if (val < oldval) {					/*check for overflow*/
error:
			errno = ERANGE;
			if (mflg)
				return(-HUGE_VAL);
			return(HUGE_VAL);
		}
	}
	if (*op == '.') {
		for (x=op+1;isdigit(*x);x++)		/*calculate right of dec. pt.*/
			val += (*x-'0')/dpower((int)(x-op));
		op = x;
	}
	else
		x = op;
	if (*x == 'e' || *x == 'E') {			/* scientific notation? */
		if (*(x+1) == '-' || *(x+1) == '+')
			x++;
		if (isdigit(*(op=x+1))) {
			exp = 0;
			while (isdigit(*op)) {
				oexp = exp;
				exp = exp*10+*op-'0';
				if (exp < oexp) {
					if (*x == '-') {
						val = 0;
						exp = 0;
						errno = ERANGE;
						break;
					}
					else
						goto error;
				}
				op++;
			}
			if (*x == '-') {
				oldval = val;
				val /= dpower(exp);
				if ((oldval != 0.0)&&(val == 0.0)) /*underflow?*/
					errno = ERANGE;
			}
			else {
				oldval = val;
				val *= dpower(exp);
				if (val < oldval)		/*overflow?*/
					goto error;
			}
		}
	}
	if (ep != NULL)
		*ep = (char *)op;
	if (mflg)
		val = -val;
	return(val);
}

static double
dpower(int n) 
{
	double p;
	int i;
	p = 1;
	for (i=1; i<=n; ++i)
		p *=10.0;
	return(p); /* 10 to the nth power */
}

strtol.c
/* Copyright 1989 Manx Software Systems, Inc. All rights reserved */

/*
 *	Synopsis
 *
 *	long int strtol(const char *nptr, char **endptr, int base);
 *
 *
 *	Description
 *
 *		The strtol function converts the initial portion of the string pointed
 *	to by nptr to long int representation. First it decomposes the input string
 *	into three parts: an initial, possibly empty, sequence of white-space
 *	characters (as specified by the issspace function), a subject sequence
 *	resembling an integer represented in some radix determined by the value of
 *	base, and a final string of one or more unrecognized characters, including
 *	the terminating null character of the input string. Then it attempts to
 *	convert the subject sequence to an integer and returns the result.
 *
 *		If the value of base is zero, the expected form of the subject sequence
 *	is that of an integer constant using normal C syntax to specify the base,
 *	optionally preceded by a plus or minus sign, but not including an integer
 *	suffix. If the value of base is between 2 and 36, the expected form of the
 *	subject sequence is a sequence of letters and digits representing an
 *	integer with the radix specified by base, optionally preceded by a plus or
 *	minus sign, but not including an integer suffix. The letters from a (or A)
 *	through z (or Z) are ascribed the values 10 to 35; only letters whose
 *	ascribed values are less than that of base are permitted. If the value of
 *	base is 16, the characters 0x or 0X may optionally precede the sequence of
 *	letters and digits, following the sign if present.
 *
 *		The subject sequence is defined as the longest subsequence of the input
 *	string, starting with the first non-white-space character, that is an
 *	initial subsequence of a sequence of the expected form. The subject
 *	sequence contains no characters if the input string is empty or consists
 *	entirely of white space, or if the first non-white-space character is other
 *	than a sign or a permissible letter or digit.
 *
 *		If the subject sequence has the expected form and the value of base is
 *	zero , the sequence of characters starting with the first digit is
 *	interpreted as an integer constant according to normal C syntax rules. If
 *	the subject sequence has the expected form and the value of base is between
 *	2 and 36, it is used as the base for conversion, ascribing to each letter
 *	its value as given above. If the subject sequence begins with a minus sign,
 *	the value resulting from the conversion is negated. A pointer to the final
 *	string is stored in the object pointed to by endptr, provided that endptr
 *	is not a null pointer.
 *
 *		In other than the "C" locale, additional implementation-defined subject
 *	sequence forms may be accepted.
 *
 *		If the subject sequence is empty or does not have the expected form, no
 *	conversion is performed; the value of nptr is stored in the object pointed
 *	to by endptr, provided that endptr is not a null pointer.
 *
 *
 *	Returns
 *
 *		The strtol function returns the converted value, if any. If no
 *	conversion could be performed, zero is returned. If the correct value would
 *	cause overflow, LONG_MAX or LONG_MIN is returned (according to the sign of
 *	the value), and the value of the macro ERANGE is stored in errno.
 */


#include <stdlib.h>
#include <ctype.h>
#include <errno.h>
#include <limits.h>

long int
strtol(const char *arg, char **ep, register int base)
{
	
	register const char *str = arg;
	register long val;
	register int c;
	register char enddigit, endchar, sign;
	register long oldval;
	const char *savstr;

	str--;
	while (isspace(*++str))						/* scan past leading spaces */
		;

	if (*str == 0 || base == 1 || base > 36) {		/* return(0) if unable */
		if (ep != 0)
			*ep = (char *)arg;
		return(0);
	}
	
	savstr = str;
	sign = 0;
	if (*str=='+' || *str=='-') {			/* may be preceded by '+' or '-' */
		if (*str++ == '-')
			sign = 1;
	}

											/* allow 0x or 0X if in base 16 */
	if (base == 16 && (*str == '0' && tolower((int)*(str+1)) == 'x'))
		str += 2;

	if (base == 0) {			/* determine base from first two characters */
		if (*str == '0') {
			if (tolower((int)*++str) == 'x') {
				str++;
				base = 16;
			}
			else
				base = 8;
		}
		else
			base = 10;
	}

	if (base < 10)
		enddigit = '9' - (10 - base);
	else
		enddigit = '9';

	if (base > 10)
		endchar = 'z' - (36 - base);

	val = 0;	
	for (;;) {
		if ((c=tolower((int)*str++)) >= '0' && c <= enddigit)
			c -= '0';
		else if (base > 10 && c >= 'a' && c <= endchar)
			c = c - 'a' + 10;
		else
			break;
		oldval = val;
		val = val * base + c;
		if (val < oldval) {							/*check for overflow*/
			errno = ERANGE;
			if (sign)
				return(LONG_MIN);
			return(LONG_MAX);
		}
	}

	if (ep != 0) {
		if (savstr == --str)
			*ep = (char *)arg;
		else
			*ep = (char *)str;		/* *ep points to excess string area */
	}

	if (sign)
		val = -val;
	return(val);
}

strtold.c
/* Copyright 1989 Manx Software Systems, Inc. All rights reserved */

/*
 *	Synopsis
 *
 *	long double strtold(const char *nptr, char **endptr);
 *
 *
 *	Description
 *
 *		The strtold function converts the intitial portion of the string
 *	pointed to by nptr to long double representation. First it decomposes the
 *	input string into three parts: an initial, possibly empty, sequence of
 *	white-space characters (as specified by the isspace function), a subject
 *	sequence resembling a floating-point constant, and a final string
 *	of one or more unrecognized characters, including the terminating
 *	null character of the input string. Then it attempts to convert
 *	the subject sequence to a floating-point number, and returns the
 *	result.
 *
 *	  The expected form of the subject sequence is an optional plus or
 *	minus sign, then a nonempty sequence of digits optionally
 *	containing a decimal-point character, then an optional exponent
 *	part, but no floating suffix. The subject sequence is defined as
 *	the longest subsequence of the input string, starting with the
 *	first non-white space character, that is an initial subsequence of
 *	a sequence of the expected form. The subject sequence contains no
 *	characters if the input string is empty or consists entirely of
 *	white space, or if the first non-white-space character is other
 *	than a sign, a digit, or a decimal-point character.
 *
 *		If the subject sequence has the expected form, the sequence of
 *	characters starting with the first digit or the decimal-point
 *	character (whichever occurs first) is interpreted as a floating
 *	constant, except that the decimal-point character is used in place
 *	of a period, and that if neither an exponent part nor a
 *	decimal-point character appears, a decimal point is assumed to
 *	follow the last digit in the string. If the subject sequence
 *	begins with a minus sign, the value resulting from the conversion
 *	is negated. A pointer to the final string is stored in the object
 *	pointed to by endptr, provided that endptr is not a null pointer.
 *
 *		If the subject sequence is empty or does not have the expected
 *	form, no conversion is performed; the value of nptr is stored in
 *	the object pointed to by endptr, provided that endptr is not a
 *	null pointer.
 *
 *
 *	Returns
 *
 *		The strtold function returns the converted value, if any. If no
 *	conversion is performed, zero is returned. If the correct value would cause
 *	overflow, plus or minus HUGE_VAL is returned (according to the sign of the
 *	value), and the value of the macro ERANGE is stored in errno. If the
 *	correct value would cause underflow, zero is returned and the value
 *	of the macro ERANGE is stored in errno.
 */

#include <ctype.h>
#include <errno.h>
#include <stdlib.h>

static long double dpower(int n);

long double strtold(register const char *str, register char **ep)
{
	register long double val, oldval;
	register const char *bp, *x, *op;
	int exp, oexp;
	char mflg = 0;

	for (bp=str;isspace(*bp);bp++)			/* scan past leading spaces */
		;
	if (*bp == '\0') {						/* return(0) if unable */
empty:
		if (ep != 0)
			*ep = (char *)str;
		return(0.0);
	}
	
	switch (*bp) {							/* may be preceded by '+' or '-' */
		case '-':
			mflg = 1;
			/* fall through */
		case '+':
			bp++;
			break;
		default:
			if (!isdigit(*bp) && *bp != '.')
				goto empty;
	}

	val = 0;
	for (x=bp;isdigit(*x);x++)				/* scan to end of first part */
		;
	op = x;
	val = 0;	
	for (x--;x>=bp;x--) {					/* calculate left of dec. pt. */
		oldval = val;
		val += (*x-'0') * dpower((int)(op-x-1));
		if (val < oldval) {					/*check for overflow*/
error:
			errno = ERANGE;
			if (mflg)
				return(-HUGE_VAL);
			return(HUGE_VAL);
		}
	}
	if (*op == '.') {
		for (x=op+1;isdigit(*x);x++)		/*calculate right of dec. pt.*/
			val += (*x-'0')/dpower((int)(x-op));
		op = x;
	}
	else
		x = op;
	if (*x == 'e' || *x == 'E') {			/* scientific notation? */
		if (*(x+1) == '-' || *(x+1) == '+')
			x++;
		if (isdigit(*(op=x+1))) {
			exp = 0;
			while (isdigit(*op)) {
				oexp = exp;
				exp = exp*10+*op-'0';
				if (exp < oexp) {
					if (*x == '-') {
						val = 0;
						exp = 0;
						errno = ERANGE;
						break;
					}
					else
						goto error;
				}
				op++;
			}
			if (*x == '-') {
				oldval = val;
				val /= dpower(exp);
				if ((oldval != 0.0)&&(val == 0.0)) /*underflow?*/
					errno = ERANGE;
			}
			else {
				oldval = val;
				val *= dpower(exp);
				if (val < oldval)		/*overflow?*/
					goto error;
			}
		}
	}
	if (ep != NULL)
		*ep = (char *)op;
	if (mflg)
		val = -val;
	return(val);
}

static long double
dpower(int n) 
{
	long double p;
	int i;
	p = 1;
	for (i=1; i<=n; ++i)
		p *=10.0;
	return(p); /* 10 to the nth power */
}

strtoul.c
/* Copyright 1989 Manx Software Systems, Inc. All rights reserved */

/*
 *	Synopsis
 *
 *	unsigned long int strtoul(const char *nptr, char **endptr, int base);
 *
 *
 *	Description
 *
 *		The strtoul function converts the initial portion of the string pointed
 *	to by nptr to unsigned long int representation. First it decomposes the
 *	input string into three parts: an initial, possibly empty, sequence of
 *	white-space characters (as specified by the issspace function), a subject
 *	sequence resembling an unsigned integer represented in some radix
 *	determined by the value of base, and a final string of one or more
 *	unrecognized characters, including the terminating null character of the
 *	input string. Then it attempts to convert the subject sequence to an
 *	integer and returns the result.
 *
 *		If the value of base is zero, the expected form of the subject sequence
 *	is that of an integer constant using normal C syntax to specify the base,
 *	optionally preceded by a plus or minus sign, but not including an integer
 *	suffix. If the value of base is between 2 and 36, the expected form of the
 *	subject sequence is a sequence of letters and digits representing an
 *	integer with the radix specified by base, optionally preceded by a plus or
 *	minus sign, but not including an integer suffix. The letters from a (or A)
 *	through z (or Z) are ascribed the values 10 to 35; only letters whose
 *	ascribed values are less than that of base are permitted. If the value of
 *	base is 16, the characters 0x or 0X may optionally precede the sequence of
 *	letters and digits, following the sign if present.
 *
 *		The subject sequence is defined as the longest subsequence of the input
 *	string, starting with the first non-white-space character, that is an
 *	initial subsequence of a sequence of the expected form. The subject
 *	sequence contains no characters if the input string is empty or consists
 *	entirely of white space, or if the first non-white-space character is other
 *	than a sign or a permissible letter or digit.
 *
 *		If the subject sequence has the expected form and the value of base is
 *	zero , the sequence of characters starting with the first digit is
 *	interpreted as an integer constant according to normal C syntax rules. If
 *	the subject sequence has the expected form and the value of base is between
 *	2 and 36, it is used as the base for conversion, ascribing to each letter
 *	its value as given above. If the subject sequence begins with a minus sign,
 *	the value resulting from the conversion is negated. A pointer to the final
 *	string is stored in the object pointed to by endptr, provided that endptr
 *	is not a null pointer.
 *
 *		In other than the "C" locale, additional implementation-defined subject
 *	sequence forms may be accepted.
 *
 *		If the subject sequence is empty or does not have the expected form, no
 *	conversion is performed; the value of nptr is stored in the object pointed
 *	to by endptr, provided that endptr is not a null pointer.
 *
 *
 *	Returns
 *
 *		The strtoul function returns the converted value, if any. If no
 *	conversion could be performed, zero is returned. If the correct value would
 *	cause overflow, ULONG_MAX is returned, and the value of the macro ERANGE is
 *	stored in errno.
 */

#include <stdlib.h>
#include <ctype.h>
#include <errno.h>
#include <limits.h>

unsigned long int
strtoul(const char *arg, char **ep, register int base)
{
	
	register const char *str = arg;
	register unsigned long val;
	register int c;
	register char enddigit, endchar, sign;
	register unsigned long oldval;
	const char *savstr;

	str--;
	while (isspace(*++str))						/* scan past leading spaces */
		;

	if (*str == 0 || base == 1 || base > 36) {		/* return(0) if unable */
		if (ep != 0)
			*ep = (char *)arg;
		return(0);
	}
	
	savstr = str;
	sign = 0;
	if (*str=='+' || *str=='-') {			/* may be preceded by '+' or '-' */
		if (*str++ == '-')
			sign = 1;
	}

											/* allow 0x or 0X if in base 16 */
	if (base == 16 && (*str == '0' && tolower((int)*(str+1)) == 'x'))
		str += 2;

	if (base == 0) {			/* determine base from first two characters */
		if (*str == '0') {
			if (tolower((int)*++str) == 'x') {
				str++;
				base = 16;
			}
			else
				base = 8;
		}
		else
			base = 10;
	}

	if (base < 10)
		enddigit = '9' - (10 - base);
	else
		enddigit = '9';

	if (base > 10)
		endchar = 'z' - (36 - base);

	val = 0;	
	for (;;) {
		if ((c=tolower((int)*str++)) >= '0' && c <= enddigit)
			c -= '0';
		else if (base > 10 && c >= 'a' && c <= endchar)
			c = c - 'a' + 10;
		else
			break;
		oldval = val;
		val = val * base + c;
		if (val < oldval) {							/*check for overflow*/
			errno = ERANGE;
			return(ULONG_MAX);
		}
	}

	if (ep != 0) {
		if (savstr == --str)
			*ep = (char *)arg;
		else
			*ep = (char *)str;		/* *ep points to excess string area */
	}

	if (sign)
		val = -val;
	return(val);
}

system.c
/* Copyright 1989 Manx Software Systems, Inc. All rights reserved */

/*
 *	Synopsis
 *
 *	int system(const char *string);
 *
 *
 *	Description
 *
 *		The system function passes the string pointed to by string to the host
 *	environment to be executed by a "command processor" in an implementation-
 *	defined manner. A null pointer may be used for string to inquire whether a
 *	command processor exists.
 *
 *
 *	Returns
 *
 *		If the argument is a null pointer, the system function returns nonzero
 *	only if a command processor is available. If the argument is not a null
 *	pointer, the system function returns an implementation-defined value.
 */

int system(const char *string)
{
	return(0);
}

wcstombs.c
/* Copyright 1989 Manx Software Systems, Inc. All rights reserved */

/*
 *	Synopsis
 *
 *	size_t wcstombs(char *s, const wchar_t *pwcs, size_t n);
 *
 *
 *	Description
 *
 *		The wcstombs function converts a sequence of codes that correspond to
 *	multibyte characters from the array pointed to by pwcs into a sequence of
 *	multibyte characters that begins in the initial shift state and stores
 *	these multibyte characters into the array pointed to by s, stopping if a
 *	multibyte character would exceed the limit of n total bytes or if a null
 *	character is stored. Each code is converted as if by a call to the wctomb
 *	function, except that the shift state of the wctomb function is not
 *	affected.
 *
 *		No more than n bytes will be modified in the array pointed to by s. If
 *	copying takes place between objects that overlap, the behavior is
 *	undefined.
 *
 *
 *	Returns
 *
 *		If a code is encountered that does not correspond to a valid multibyte
 *	character, the wcstombs function returns (size_t)-1. Otherwise, the
 *	wcstombs function returns the number of bytes modified, not including a
 *	terminatin null character, if any.
 */

#include <stdlib.h>

size_t
wcstombs(char *s, const wchar_t *pwcs, size_t n)
{
	register size_t i = 0;

	while(i < n && (*s++ = *pwcs++))
		i++;
	return(i);
}

wctomb.c
/* Copyright 1989 Manx Software Systems, Inc. All rights reserved */

/*
 *	Synopsis
 *
 *	int wctomb(char *s, wchar_t wchar);
 *
 *
 *	Description
 *
 *		The wctomb function determines the number of bytes needed to represent
 *	the multibyte character corresponding to the code whose value is wchar
 *	(including any change in shift state). It stores the multibyte character
 *	representation in the array object pointed to by s (if s is not a null
 *	pointer).  At most MB_CUR_MAX characters are stored. If the value of wchar
 *	is zero, the wctomb function is left in the initial shift state.
 *
 *		The implementation shall behave as if no library functions calls the
 *	wctomb function.
 *
 *
 *	Returns
 *
 *		If s is a null pointer, the wctomb function returns a nonzero or zero
 *	value, if multibyte character encodings, respectively, do or do not have
 *	state-dependent encodings. If s is not a null pointer, the wctomb function
 *	returns -1 if the value of wchar does not correspond to a valid multibyte
 *	character, or returns the number of bytes that comprise the multibyte
 *	character corresponding to the value of wchar.
 *
 *		In no case will the value returned be greater than the value of the
 *	MB_CUR_MAX macro.
 */

#include <stdlib.h>

int wctomb(char *s, wchar_t wchar)
{
	if (s == 0)
		return(0);
	if (wchar <= 0xff) {
		*s = wchar;
		return(1);
	}
	return(-1);
}

