Public Domain Korn Shell - Part.06 of 7

USENET Administration netnews at netcom.UUCP
Wed Dec 12 22:38:51 AEST 1990


#!/bin/sh
# This is part 06 of ksh-pd
# ============= src/eval.c ==============
if test ! -d 'src'; then
    echo 'x - creating directory src'
    mkdir 'src'
fi
if test -f 'src/eval.c' -a X"$1" != X"-c"; then
	echo 'x - skipping src/eval.c (File already exists)'
else
echo 'x - extracting src/eval.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'src/eval.c' &&
X/*
X * Expansion - quoting, separation, substitution, globbing
X */
X
Xstatic char *RCSid = "$Header: /tmp/egisin/src/RCS/eval.c,v 3.3 88/12/17 20:59:47 egisin Exp $";
X
X#include <stddef.h>
X#include <stdio.h>
X#include <string.h>
X#include <errno.h>
X#include <setjmp.h>
X#include <unistd.h>
X#include <sys/types.h>
X#include <dirent.h>
X#include <pwd.h>
X#include "sh.h"
X#include "lex.h"
X#include "tree.h"
X#include "table.h"
X#include "expand.h"
X
X/*
X * string expansion
X *
X * first pass: quoting, IFS separation, ${} and $() substitution.
X * second pass: filename expansion (*?[]~).
X */
X
X/* expansion generator state */
Xtypedef struct Expand {
X	/* int  type; */	/* see expand() */
X	char   *str;		/* string */
X	union {
X		char  **strv;	/* string[] */
X		FILE   *file;	/* file */
X	} u;			/* source */
X	short	split;		/* split "$@"*/
X} Expand;
X
X#define	XBASE	0		/* scanning original */
X#define	XSUB	1		/* expanding ${} string */
X#define	XARGSEP	2		/* ifs0 between "$@" */
X#define	XARG	3		/* expanding $*, $@ */
X#define	XCOM	4		/* expanding $() */
X
Xstatic	void	expand ARGS((char *, XPtrV *, int));
Xstatic	int	comsub ARGS((Expand *, char *comm));
Xstatic	int	varsub ARGS((Expand *, char *name, int stype));
Xstatic	void	glob ARGS((char *cp, XPtrV *wp));
Xstatic	void	globit ARGS((char *ds, char *dp, char *sp, XPtrV *wp, int check));
Xstatic	char   *tilde ARGS((char *wp));
Xstatic	char   *trimsub ARGS((char *str, char *pat, int how));
X
Xint	ifs0 = ' ';		/* todo: first char of $IFS */
X
X/* compile and expand word */
Xchar *
Xsubstitute(cp, f)
X	char Const *cp;
X	int f;
X{
X	struct source *s, *sold;
X
X	sold = source;
X	s = pushs(SWSTR);
X	s->str = (char *) cp;
X	source = s;
X	if (yylex(ONEWORD) != LWORD)
X		errorf("eval:substitute error\n");
X	source = sold;
X	return evalstr(yylval.cp, f);
X}
X
X/*
X * expand arg-list
X */
Xchar **
Xeval(ap, f)
X	register char **ap;
X{
X	XPtrV w;
X
X	if (*ap == NULL)
X		return ap;
X	XPinit(w, 32);
X	XPput(w, NULL);		/* space for shell name */
X	while (*ap != NULL)
X		expand(*ap++, &w, f);
X	XPput(w, NULL);
X	return (char **) XPclose(w) + 1;
X}
X
X/*
X * expand string
X */
Xchar *
Xevalstr(cp, f)
X	register char *cp;
X	int f;
X{
X	XPtrV w;
X
X	XPinit(w, 1);
X	expand(cp, &w, f);
X	cp = (XPsize(w) == 0) ? "" : (char*) *XPptrv(w);
X	XPfree(w);
X	return cp;
X}
X
X/* for nested substitution: ${var:=$var2} */
Xtypedef struct SubType {
X	short	type;		/* [=+-?%#] action after expanded word */
X	short	base;		/* begin position of expanded word */
X	char   *name;		/* name for ${var=word} */
X} SubType;
X
Xstatic void
Xexpand(cp, wp, f)
X	char *cp;		/* input word */
X	register XPtrV *wp;	/* output words */
X	int f;			/* DO* flags */
X{
X	register int c;
X	register int type = XBASE; /* expansion type */
X	register int quote = 0;	/* quoted */
X	XString ds;		/* destination string */
X	register char *dp, *sp;	/* dest., source */
X	int fdo, word, combase;	/* second pass flags; have word */
X	Expand x;		/* expansion variables */
X	SubType subtype [10];	/* substitution type stack */
X	register SubType *st = subtype + 10;
X
X	if (cp == NULL)
X		errorf("eval:expand(NULL)\n");
X	if (flag[FNOGLOB])
X		f &= ~ DOGLOB;
X
X	Xinit(ds, dp, 128);	/* init dest. string */
X	type = XBASE;
X	sp = cp;
X	fdo = 0;
X	word = !(f&DOBLANK);
X
X	while (1) {
X		Xcheck(ds, dp);
X
X		switch (type) {
X		  case XBASE:	/* original prefixed string */
X			c = *sp++;
X			switch (c) {
X			  case EOS:
X				c = 0;
X				break;
X			  case CHAR:
X				c = *sp++;
X				break;
X			  case QCHAR:
X				quote |= 2; /* temporary quote */
X				c = *sp++;
X				break;
X			  case OQUOTE:
X				word = quote = 1;
X				continue;
X			  case CQUOTE:
X				quote = 0;
X				continue;
X			  case COMSUB:
X				type = comsub(&x, sp);
X				sp = strchr(sp, 0) + 1;
X				combase = Xsavepos(ds, dp);
X				continue;
X			  case OSUBST: /* ${var{:}[=+-?]word} */
X				cp = sp; 		/* variable */
X				sp = strchr(sp, 0) + 1;	/* skip variable */
X				c = (*sp == CSUBST) ? 0 : *sp++;
X				if ((c&0x7F) == '#' || (c&0x7F) == '%')
X					f |= DOPAT;
X				type = varsub(&x, cp, c);
X				if (type == XBASE) {	/* expand? */
X					if (st == subtype)
X						errorf("ridiculous ${} nesting\n");
X					--st;
X					st->type = c;
X					st->base = Xsavepos(ds, dp);
X					st->name = cp;
X				} else
X					/* todo: nested OSUBST/CSUBST */
X					sp = wdscan(sp, CSUBST); /* skip word */
X				continue;
X			  case CSUBST: /* only get here if expanding word */
X				*dp = 0;
X				if (f&DOGLOB)
X					f &= ~DOPAT;
X				switch (st->type&0x7F) {
X				  case '#':
X				  case '%':
X					*dp = 0;
X					dp = Xrestpos(ds, dp, st->base);
X					x.str = trimsub(x.str, dp, st->type);
X					type = XSUB;
X					continue;
X				  case '=':
X#if 0
X					if ((x.u.vp->flag&RDONLY))
X						errorf("cannot set readonly %s\n", cp);
X#endif
X					setstr(global(st->name), Xrestpos(ds, dp, st->base));
X					break;
X				  case '?':
X					if (dp == Xrestpos(ds, dp, st->base))
X						errorf("missing value for %s\n", cp);
X					else
X						errorf("%s\n", Xrestpos(ds, dp, st->base));
X				}
X				st++;
X				type = XBASE;
X				continue;
X			}
X			break;
X
X		  case XSUB:
X			if ((c = *x.str++) == 0) {
X				type = XBASE;
X				continue;
X			}
X			break;
X
X		  case XARGSEP:
X			type = XARG;
X			quote = 1;
X		  case XARG:
X			if ((c = *x.str++) == 0) {
X				if ((x.str = *x.u.strv++) == NULL) {
X					type = XBASE;
X					continue;
X				} else if (quote && x.split) {
X					/* terminate word for "$@" */
X					type = XARGSEP;
X					quote = 0;
X				}
X				c = ifs0;
X			}
X			break;
X
X		  case XCOM:
X			c = getc(x.u.file);
X			if (quote) {
X				if (c == EOF) {
X					cp = Xrestpos(ds, sp, combase);
X					for (dp--; dp >= cp && *dp == '\n'; dp--)
X						;
X					dp++;
X					fclose(x.u.file);
X					if (x.split)
X						waitlast();
X					type = XBASE;
X					continue;
X				}
X			} else {	/* this part is probably redundant */
X				if (c == EOF || c == '\n') {
X					while ((c = getc(x.u.file)) == '\n')
X						;
X					if (c == EOF) {
X						fclose(x.u.file);
X						if (x.split)
X							waitlast();
X						type = XBASE;
X						continue;
X					}
X					ungetc(c, x.u.file);
X					c = ifs0;
X				}
X			}
X			break;
X		}
X
X		/* check for end of word or IFS separation */
X		if (c == 0 || !quote && (f&DOBLANK) && ctype(c, C_IFS)) {
X			if (word) {
X				*dp++ = 0;
X				cp = Xclose(ds, dp);
X				if (fdo&DOTILDE)
X					cp = tilde(cp);
X				if (fdo&DOGLOB)
X					glob(cp, wp);
X				else
X					{XPput(*wp, cp);}
X				fdo = word = 0;
X				if (c != 0)
X					Xinit(ds, dp, 128);
X			} else
X				; /* ignore IFS */
X			if (c == 0)
X				return;
X		} else {
X			/* mark any special second pass chars */
X			if (!quote)
X				switch (c) {
X				  case '*':
X				  case '?':
X				  case '[':
X					if (f&(DOPAT|DOGLOB)) {
X						fdo |= (f&DOGLOB);
X						*dp++ = MAGIC;
X					}
X					break;
X				  case '~':
X					if ((f&DOTILDE) && dp == Xstring(ds, dp) ||
X					    !(f&DOBLANK) && 
X					    (dp[-1] == '=' || dp[-1] == ':')) {
X						fdo |= DOTILDE;
X						*dp++ = MAGIC;
X					}
X					break;
X				}
X			else
X				quote &= ~2; /* undo temporary */
X
X			word = 1;
X			*dp++ = c; /* save output char */
X		}
X	}
X}
X
X/*
X * Prepare to generate the string returned by ${} substitution.
X */
Xstatic int
Xvarsub(xp, sp, stype)
X	register Expand *xp;
X	register char *sp;
X	int stype;
X{
X	register int c;
X	int type;
X
X	/* ${#var}, string length or argc */
X	if (sp[0] == '#' && (c = sp[1]) != 0) {
X		c = (c == '*' || c == '@') ? e.loc->argc :
X			strlen(strval(global(sp+1)));
X		xp->str = strsave(ulton((unsigned long)c, 10), ATEMP);
X		return XSUB;
X	}
X
X	c = sp[0];
X	if (c == '*' || c == '@') {
X		if (e.loc->argc == 0) {
X			xp->str = null;
X			type = XSUB;
X		} else {
X			xp->u.strv = e.loc->argv + 1;
X			xp->str = *xp->u.strv++;
X			xp->split = c == '@'; /* $@ */
X			type = XARG;
X		}
X	} else {
X		xp->str = strval(global(sp));
X		type = XSUB;
X	}
X
X	c = stype&0x7F;
X	/* test the compiler's code generator */
X	if (c == '%' || c == '#' ||
X	    (((stype&0x80) ? *xp->str=='\0' : xp->str==null) ? /* undef? */
X	     c == '=' || c == '-' || c == '?' : c == '+'))
X		type = XBASE;	/* expand word instead of variable value */
X	if (type != XBASE && flag[FNOUNSET] && xp->str == null)
X		errorf("%s: unset variable\n", sp);
X	return type;
X}
X
X/*
X * Run the command in $(...) and read its output.
X */
Xstatic int
Xcomsub(xp, cp)
X	register Expand *xp;
X	char *cp;
X{
X	Source *s;
X	register struct op *t;
X	FILE *fi;
X
X	s = pushs(SSTRING);
X	s->str = cp;
X	t = compile(s);
X
X	if (t != NULL && t->type == TCOM && /* $(<file) */
X	    *t->args == NULL && *t->vars == NULL && t->ioact != NULL) {
X		register struct ioword *io = *t->ioact;
X
X		if ((io->flag&IOTYPE) != IOREAD)
X			errorf("funny $() command\n");
X		fi = fopen(evalstr(io->name, DOTILDE), "r");
X		if (fi != NULL)
X			fileno(fi) = savefd(fileno(fi));
X		xp->split = 0;	/* no waitlast() */
X	} else {
X		int ofd1, pv[2];
X		openpipe(pv);
X		fi = fdopen(pv[0], "r");
X		ofd1 = savefd(1);
X		dup2(pv[1], 1);
X		close(pv[1]);
X#if 0
X		exchild(t, XXCOM|XPIPEO);
X#else
X		execute(t, XFORK|XXCOM|XPIPEO);
X#endif
X		dup2(ofd1, 1);
X		xp->split = 1;	/* waitlast() */
X	}	
X
X	if (fi == NULL)
X		errorf("cannot open $() input\n");
X	setvbuf(fi, (char *)NULL, _IOFBF, BUFSIZ);
X	xp->u.file = fi;
X	return XCOM;
X}
X
X/*
X * perform #pattern and %pattern substitution in ${}
X */
X
Xstatic char *
Xtrimsub(str, pat, how)
X	register char *str;
X	char *pat;
X	int how;
X{
X	register char *end = strchr(str, 0);
X	register char *p, c;
X
X	switch (how) {
X	  case '#':		/* shortest at begin */
X		for (p = str; p <= end; p++) {
X			c = *p; *p = '\0';
X			if (gmatch(str, pat)) {
X				*p = c;
X				return p;
X			}
X			*p = c;
X		}
X		break;
X	case '#'|0x80:		/* longest match at begin */
X		for (p = end; p >= str; p--) {
X			c = *p; *p = '\0';
X			if (gmatch(str, pat)) {
X				*p = c;
X				return p;
X			}
X			*p = c;
X		}
X		break;
X	  case '%':		/* shortest match at end */
X		for (p = end; p >= str; p--) {
X			if (gmatch(p, pat)) {
X				*p = '\0';
X				return str;
X			}
X		}
X		break;
X	  case '%'|0x80:	/* longest match at end */
X		for (p = str; p <= end; p++) {
X			if (gmatch(p, pat)) {
X				*p = '\0';
X				return str;
X			}
X		}
X		break;
X	}
X
X	return str;		/* no match, return string */
X}
X
X/*
X * glob
X * Name derived from V6's /etc/glob, the program that expanded filenames.
X */
X
Xstatic	char   *debunk();
X
Xstatic void 
Xglob(cp, wp)
X	char *cp;
X	register XPtrV *wp;
X{
X	char path [PATH];
X	register char *sp = cp;
X	int oldsize;
X
X	oldsize = XPsize(*wp);
X	globit(path, path, sp, wp, 0);
X
X	if (XPsize(*wp) == oldsize)
X		{XPput(*wp, debunk(cp));}
X	else
X		qsortp(XPptrv(*wp) + oldsize, (size_t)(XPsize(*wp) - oldsize), xstrcmp);
X}
X
Xstatic void
Xglobit(ds, dp, sp, wp, check)
X	char *ds;		/* dest path */
X	char *dp;		/* dest end */
X	char *sp;		/* source path */
X	register XPtrV *wp;	/* output list */
X	int check;		/* check dest existence */
X{
X	register char *np;	/* next source component */
X	register char *tsp, *tdp;
X
X	if (sp == NULL) {	/* end of source path */
X		if (check && eaccess(ds, 0) < 0)
X			return;
X		XPput(*wp, strsave(ds, ATEMP));
X		return;
X	}
X
X	if (dp > ds)
X		*dp++ = '/';
X	while (*sp == '/')
X		*dp++ = *sp++;
X	np = strchr(sp, '/');
X	if (np != NULL)
X		*np++ = 0;
X
X	*dp = 0;
X	if (strchr(sp, MAGIC) == NULL) { /* contains no pattern? */
X		tdp = dp; tsp = sp;
X		while ((*tdp++ = *tsp++) != 0)
X			;
X		--tdp;
X		globit(ds, tdp, np, wp, check);
X	} else {
X		DIR *dirp;
X		struct dirent *d;
X
X		/* ToDo:
X		 * should not attemp to open() special files: /dev/ttyd0/*
X		 * opendir should do this check, but Doug Gwyn's does not.
X		 */
X		dirp = opendir((*ds == 0) ? "." : ds);
X		if (dirp == NULL)
X			goto Nodir;
X		while ((d = readdir(dirp)) != NULL) {
X			tsp = d->d_name;
X			if (tsp[0] == '.' &&
X			    (tsp[1] == 0 || tsp[1] == '.' && tsp[2] == 0))
X				continue; /* always ignore . and .. */
X			if (*tsp == '.' && *sp != '.' || !gmatch(tsp, sp))
X				continue;
X
X			tdp = dp;
X			while ((*tdp++ = *tsp++) != 0)
X				;
X			--tdp;
X			globit(ds, tdp, np, wp, np != NULL);
X		}
X		closedir(dirp);
X	  Nodir:;
X	}
X
X	if (np != NULL)
X		*--np = '/';
X}
X
X/* remove MAGIC from string */
Xstatic char *
Xdebunk(cp)
X	char *cp;
X{
X	register char *dp, *sp;
X
X	for (dp = sp = cp; *sp != 0; sp++)
X		if (*sp != MAGIC)
X			*dp++ = *sp;
X	*dp = 0;
X	return cp;
X}
X
X/*
X * tilde expansion
X *
X * based on a version by Arnold Robbins
X */
X
Xstatic char *homedir();
X
Xstatic char *
Xtilde(acp)
X	char *acp;
X{
X	register int c;
X	char path [PATH+1];
X	register char *cp = acp, *wp = path, *dp;
X	char userid [16+1];
X
X  Again:
X	while (1) {
X		if ((c = *cp++) == 0) {
X			*wp = 0;
X			afree((Void*)acp, ATEMP);
X			return strsave(path, ATEMP);
X		} else if (c == MAGIC && *cp == '~')
X			break;
X		else
X			*wp++ = c;
X	}
X
X	dp = NULL;	/* no output substitution */
X	if (cp[1] == 0 || cp[1] == '/' || cp[1] == ':') /* ~ or ~/ */
X		dp = strval(global("HOME")), cp += 1;
X	else if (cp[1] == '+' && (cp[2] == '/' || cp[2] == ':' || cp[2] == 0))
X		dp = strval(global("PWD")), cp += 2;
X	else if (cp[1] == '-' && (cp[2] == '/' || cp[2] == ':' || cp[2] == 0))
X		dp = strval(global("OLDPWD")), cp += 2;
X	else if (letter(cp[1])) {
X		char *save = cp;
X		for (dp = userid, cp++; letnum(*cp) && dp < userid+16; )
X			*dp++ = *cp++;
X		*dp = 0;
X		dp = homedir(userid);
X		if (dp == NULL)
X			cp = save;
X	}
X	/* substitute */
X	if (dp != NULL)
X		while (*dp != 0)
X			*wp++ = *dp++;
X	goto Again;
X}
X
X/*
X * map userid to user's home directory.
X * todo: implement a cache with the "homedirs" table.
X * note that 4.3's getpw adds more than 6K to the shell,
X * and the YP version probably adds much more.
X * we might consider our own version of getpwnam() to keep the size down.
X */
X
Xstatic char *
Xhomedir(name)
X	char *name;
X{
X	register struct tbl *ap;
X	register struct passwd *pw;
X
X	ap = tsearch(&homedirs, name, hash(name));
X	if ((ap != NULL && (ap->flag&ISSET)))
X		return ap->val.s;
X	pw = getpwnam(name);
X	if (pw == NULL)
X		return NULL;
X	return pw->pw_dir;
X}
X
SHAR_EOF
true || echo 'restore of src/eval.c failed'
fi
# ============= src/expr.c ==============
if test -f 'src/expr.c' -a X"$1" != X"-c"; then
	echo 'x - skipping src/expr.c (File already exists)'
else
echo 'x - extracting src/expr.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'src/expr.c' &&
X/*
X * Korn expression evaluation
X */
X
Xstatic char *RCSid = "$Header: /tmp/egisin/src/RCS/expr.c,v 3.1 88/11/03 09:15:55 egisin Exp $";
X
X#include <stddef.h>
X#include <errno.h>
X#include <setjmp.h>
X#include "sh.h"
X#include "table.h"
X
X#define	ef	else if		/* fashion statement */
X
X#define	VAR	0x01
X#define	LIT	0x02
X#define	LEQ	0x03
X#define	LNE	0x04
X#define	LLE	0x05
X#define	LGE	0x06
X
Xstatic void token();		/* read next token */
Xstatic Const char *expression;	/* expression being evaluated */
Xstatic Const char *tokp;	/* lexical position */
Xstatic int tok;			/* token from token() */
Xstatic struct tbl *val;		/* value from token() */
X
Xstatic struct tbl *tempvar(), *intvar();
Xstatic struct tbl *asn(), *e6(), *e5(), *e3(), *e2(), *e0();
X
X/*
X * parse and evalute expression
X */
Xvoid
Xevalerr(err)
X	char *err;
X{
X	errorf("%s: %s\n", expression, err);
X}
X
Xlong
Xevaluate(expr)
X	Const char *expr;
X{
X	struct tbl *v;
X
X	expression = tokp = expr;
X	token();
X	v = intvar(asn());
X	if (!(tok == 0))
X		evalerr("bad expression");
X	return v->val.i;
X}
X
Xstatic struct tbl *
Xasn()
X{
X	register struct tbl *vl, *vr;
X
X	vr = vl = e6();
X	if ((tok == '=')) {
X		Area * olastarea = lastarea;
X		token();
X		if ((vl->flag&RDONLY)) /* assign to rvalue */
X			evalerr("bad assignment");
X		vr = intvar(asn());
X		lastarea = olastarea;
X		setint(vl, vr->val.i);
X		if ((vl->flag&INTEGER) && vl->type == 0) /* default base? */
X			vl->type = vr->type;
X	}
X	return vr;
X}
X
Xstatic struct tbl *
Xe6()
X{
X	register struct tbl *vl, *vr;
X
X	vl = e5();
X	while ((tok == LEQ) || (tok == LNE)) {
X		int op = tok;
X		token();
X		vl = intvar(vl);
X		vr = intvar(e5());
X		vl->val.i = vl->val.i == vr->val.i;
X		if (op == LNE)
X			vl->val.i = ! vl->val.i;
X	}
X	return vl;
X}
X
Xstatic struct tbl *
Xe5()
X{
X	register struct tbl *vl, *vr;
X
X	vl = e3();
X	while ((tok == LLE) || (tok == '<') || (tok == '>') || (tok == LGE)) {
X		int op = tok;
X		token();
X		vl = intvar(vl);
X		vr = intvar(e3());
X		if (op == LLE)
X			vl->val.i = vl->val.i <= vr->val.i;
X		ef (op == '<')
X			vl->val.i = vl->val.i < vr->val.i;
X		ef (op == LGE)
X			vl->val.i = vl->val.i >= vr->val.i;
X		ef (op == '>')
X			vl->val.i = vl->val.i > vr->val.i;
X	}
X	return vl;
X}
X
Xstatic struct tbl *
Xe3()
X{
X	register struct tbl *vl, *vr;
X
X	vl = e2();
X	while ((tok == '+') || (tok == '-')) {
X		int op = tok;
X		token();
X		vl = intvar(vl);
X		vr = intvar(e2());
X		if (op == '+')
X			vl->val.i += vr->val.i;
X		ef (op == '-')
X			vl->val.i -= vr->val.i;
X	}
X	return vl;
X}
X
Xstatic struct tbl *
Xe2()
X{
X	register struct tbl *vl, *vr;
X
X	vl = e0();
X	while ((tok == '*') || (tok == '/') || (tok == '%')) {
X		int op = tok;
X		token();
X		vl = intvar(vl);
X		vr = intvar(e0());
X		if (op != '*' && vr->val.i == 0)
X			evalerr("zero divisor");
X		if (op == '*')
X			vl->val.i *= vr->val.i;
X		ef (op == '/')
X			vl->val.i /= vr->val.i;
X		ef (op == '%')
X			vl->val.i %= vr->val.i;
X	}
X	return vl;
X}
X
Xstatic struct tbl *
Xe0()
X{
X	register struct tbl *v;
X
X	if ((tok == '!') || (tok == '-')) {
X		int op = tok;
X		token();
X		v = intvar(e0());
X		if (op == '!')
X			v->val.i = !v->val.i;
X		ef (op == '-')
X			v->val.i = -v->val.i;
X	} else
X	if ((tok == '(')) {
X		token();
X		v = asn();
X		if (!(tok == ')'))
X			evalerr("missing )");
X		token();
X	} else
X	if ((tok == VAR) || (tok == LIT)) {
X		v = val;
X		token();
X	} else
X		evalerr("bad expression");
X	return v;
X}
X
Xstatic void
Xtoken()
X{
X	register char *cp = (char *) tokp;
X	register int c, c2;
X
X	/* skip white space */
X	do c = *cp++;	while (c != '\0' && (c == ' ' || c == '\t'));
X	tokp = cp-1;
X
X	if (letter(c)) {
X		for (; letnum(c); c = *cp++)
X			;
X		c = *--cp;
X		*cp = 0;
X		val = global(tokp);
X		*cp = c;
X		tok = VAR;
X	} else
X	if (digit(c)) {
X		for (; letnum(c) || c == '#'; c = *cp++)
X			;
X		c = *--cp;
X		*cp = 0;
X		val = tempvar();
X		setstr(val, tokp);
X		val->flag |= RDONLY;
X		*cp = c;
X		tok = LIT;
X	} else {
X		c2 = *cp++;
X		if (c == '=' && c2 == '=')
X			c = LEQ;
X		ef (c == '!' && c2 == '=')
X			c = LNE;
X		ef (c == '<' && c2 == '=')
X				c = LLE;
X		ef (c == '>' && c2 == '=')
X				c = LGE;
X		else
X			cp--;
X		tok = c;
X	}
X	tokp = cp;
X}
X
Xstatic struct tbl *
Xtempvar()
X{
X	register struct tbl *vp;
X
X	vp = alloc(sizeof(struct tbl), ATEMP);
X	lastarea = ATEMP;
X	vp->flag = ISSET|INTEGER;
X	vp->type = 0;
X	vp->name[0] = '\0';
X	return vp;
X}
X
X/* cast (string) variable to temporary integer variable */
Xstatic struct tbl *
Xintvar(vp)
X	register struct tbl *vp;
X{
X	register struct tbl *vq;
X
X	vq = tempvar();
X	vq->type = 10;
X	return strint(vq, vp);
X}
X
SHAR_EOF
true || echo 'restore of src/expr.c failed'
fi
# ============= ReadMe ==============
if test -f 'ReadMe' -a X"$1" != X"-c"; then
	echo 'x - skipping ReadMe (File already exists)'
else
echo 'x - extracting ReadMe (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'ReadMe' &&
X	Notes on the Standard C / POSIX P1003.1 package
X
XThis package contains header files and library routines
Xto provide a standard C (ANSI) and POSIX enviroment for portable programs.
XThis allows most OS dependcies to be removed from an application,
Xmaking it much more readable, and isolating them in a small,
Xstandardized library. It has the disadvantage that it only
Xworks with fairly stock UNIX versions, but a different approach
Xwill be used for other systems.
X
XThis package supplements the existing libraries and header files
Xof a AT&T-derived Unix system (System V and BSD in particular).
XIt also provides function prototypes when the compiler supports them,
Ximproving compile-time error checking and improving portability on
Xmachines where sizeof(int) == sizeof(size_t) == sizeof(void*) does not hold.
X
XA different approach will be used for the DOS, Atari St, Minix,
Xand possibly V7: a complete replacement standard C library will
Xbe provided as a separate package. This would not be practical
Xwith BSD or NFS systems because of the conflicts with the host
Xstdio and the replacement stdio in libc's getpwent().
X
XContents:
Xstdc/*:		The standard C header files and library.
Xposix/*:	The POSIX header files and library.
Xh/*, h/sys/*:	Links to the header files in stdc/ and posix/.
Xlibstdc.a:	The standard C library.
Xlibposix.a:	The POSIX emulation library.
X
XTo create the header files and libraries, perform the following
Xthree steps in the stdc and posix directories:
X	One of _BSD, _SYSV, or _V7 should be defined in the Makefile.
X	Do "rm stdc/stdio.h", it gets created by make.
X	Do "make link" first to set up the links from *.h to ../h.
X	Do "make" to create the library.
XCompile applications with -I$STD/h, link them with -L$STD ... -lstdc -lposix.
X
X	Notes on the standard C package
XThe files <locale.h>, <assert.h>, and <math.h> don't exist yet.
XMany standard C functions are not implemented yet.
XThese include strtol, strtoul, atexit, tempfile(?), etc.
XThe string routines are by Henry Spencer.
X
XKnown portability problems include:
Xsize_t or ptrdiff_t in <stddef.h> may need to be long.
XThe method of creating <stdio.h> from /usr/include/stdio.h and stdio.h_std
Xmay not work on some versions of UNIX.
XAlmost definitely not on Xenix, maybe not on merged BSD-SysV systems.
XThis package contains a correct version of setvbuf() which
Xdepends on the contents of FILE in the host stdio.h.
XThis will not work if FILE is neither stock System V or BSD.
XYou can safely "#if 0" out the body of setvbuf for PD ksh,
Xsetvbuf is used to decrease the size of buffers to speed up forks.
X
X	Notes on the POSIX package
XOnly headers and function required by the PD KornShell are implemented.
XI do not intend to develop this into a full POSIX emulation package.
XYou should install Doug Gwyn's <dirent> package if you do not have
X<dirent.h> nor <sys/dir>. If you do have <dirent.h>, unlink h/dirent.h
X(this should be configured automatically by the makefile).
X
SHAR_EOF
true || echo 'restore of ReadMe failed'
fi
# ============= posix/Makefile ==============
if test ! -d 'posix'; then
    echo 'x - creating directory posix'
    mkdir 'posix'
fi
if test -f 'posix/Makefile' -a X"$1" != X"-c"; then
	echo 'x - skipping posix/Makefile (File already exists)'
else
echo 'x - extracting posix/Makefile (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'posix/Makefile' &&
X# POSIX P1003.1 compatability
X# does not requires SVID/P1003.2-compatible "make"
X
X# $Header: Makefile,v 1.1 88/03/29 18:28:38 egisin Locked $
X
XSYSTEM=BSD
XCC = gcc -ansi -O -W 
XLN = ln
XPRINT = lpr -p -Plp26_3018
X
XCFLAGS = -I../h -D_$(SYSTEM) 
X
XMISC =	Makefile 
XHDRS =	wait.h times.h unistd.h fcntl.h dirent.h 
XSRCS =	unistd.c fcntl.c times.c 
XOBJS =	unistd.o fcntl.o times.o 
X#OBJS =	$(SRCS:.c=.o)
XLIB =	libposix.a
XINCL =	../h
X
Xall:	$(LIB)
X
Xlink:	$(HDRS)
X	[ -d $(INCL) ] || mkdir $(INCL)
X	[ -d $(INCL)/sys ] || mkdir $(INCL)/sys
X	$(LN) wait.h time.h times.h $(INCL)/sys
X	$(LN) unistd.h $(INCL)
X	if [ ! -r /usr/include/unistd.h ]; then $(LN) dirent.h $(INCL); fi
X
X$(LIB)(%.o): %.o
X
X%: RCS/%,v
X	co %@
X
X$(LIB):	$(OBJS)
X	ar r $@ $?
X	-ranlib $@
X
X#$(LIB): lib.a($OBJS)
X#	ar rv $@ $?
X#	-ranlib $@
X#	rm -f $?
X
Xstd_p.tar: $(MISC) $(SRCS)
X	tar cf std_p.tar $(MISC) $(HDRS) $(SRCS)
X
Xprint: $(MISC) $(HDRS) $(SRCS)
X	$(PRINT) $(MISC) $(HDRS) $(SRCS)
X
XIndex: $(SRCS)
X	ctags -x $(HDRS) $(SRCS) >Index
X
Xci:
X	ci -l $(MISC) $(HDRS) $(SRCS)
X
Xfcntl.o: fcntl.h 
X
Xtimes.o: times.h 
X
SHAR_EOF
true || echo 'restore of posix/Makefile failed'
fi
# ============= posix/dirent.C ==============
if test -f 'posix/dirent.C' -a X"$1" != X"-c"; then
	echo 'x - skipping posix/dirent.C (File already exists)'
else
echo 'x - extracting posix/dirent.C (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'posix/dirent.C' &&
X/*
X * simple implementation of directory(3) routines for V7 and Minix.
X * completly untested. not designed to be efficient.
X * missing telldir and seekdir.
X */
X
X#include <sys/types.h>
X#include <dirent.h>
X
Xchar	*malloc();
X
X#define	DIRSIZ	14
Xstruct	direct_v7
X{
X	unsigned short	d_ino;
X	char	d_name[DIRSIZ];
X};
X
XDIR *opendir(filename)
X	char *filename;
X{
X	DIR *dirp;
X
X	dirp = (DIR *) malloc(sizeof(DIR));
X	if (dirp == NULL)
X		return NULL;
X	dirp->fd = open(filename, 0);
X	if (dirp->fd < 0) {
X		free((char *) dirp);
X		return NULL;
X	}
X	return dirp;
X}
X
Xstruct dirent *readdir(dirp)
X	register DIR *dirp;
X{
X	static	struct direct_v7 ent;
X
X	while (read(dirp->fd, (char *)&ent, (int)sizeof(ent)) == sizeof(ent))
X		if (ent.d_ino != 0)
X			goto found;
X	return (struct dirent *) NULL;
X found:
X	dirp->ent.d_ino = ent.d_ino;
X	strncpy(dirp->ent.d_name, ent.d_name, DIRSIZ);
X	return &dirp->ent;
X}
X
Xvoid rewinddir(dirp)
X	DIR *dirp;
X{
X	lseek(dirp->fd, 0L, 0);
X}
X
Xclosedir(dirp)
X	DIR *dirp;
X{
X	close(dirp->fd);
X	dirp->fd = -1;
X	free((char *) dirp);
X	return 0;
X}
SHAR_EOF
true || echo 'restore of posix/dirent.C failed'
fi
# ============= posix/dirent.H ==============
if test -f 'posix/dirent.H' -a X"$1" != X"-c"; then
	echo 'x - skipping posix/dirent.H (File already exists)'
else
echo 'x - extracting posix/dirent.H (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'posix/dirent.H' &&
X/*
X	<sys/dirent.h> -- file system independent directory entry (SVR3)
X
X	last edit:	25-Apr-1987	D A Gwyn
X	last hack:	14-Aug-1987	Eric Gisin
X
X	prerequisite:	<sys/types.h>
X*/
X
X#define	MAXNAMLEN	16		/* maximum filename length */
X
Xstruct dirent				/* data from getdents()/readdir() */
X	{
X	long		d_ino;		/* inode number of entry */
X	off_t		d_off;		/* offset of disk directory entry */
X	unsigned short	d_reclen;	/* length of this record */
X	char	d_name[MAXNAMLEN];	/* name of file */
X};
X
X#ifndef NAME_MAX
X#define	NAME_MAX	(MAXNAMLEN - 1)	/* DAG -- added for POSIX */
X#endif
X
Xtypedef struct {			/* returned by opendir() */
X	int	fd;
X	struct dirent ent;
X} DIR;
X
Xextern DIR		*opendir();
Xextern struct dirent	*readdir();
Xextern off_t		telldir();
Xextern void		seekdir();
Xextern void		rewinddir();
Xextern int		closedir();
X
X#ifndef NULL
X#define	NULL	0			/* DAG -- added for convenience */
X#endif
SHAR_EOF
true || echo 'restore of posix/dirent.H failed'
fi
# ============= posix/dirent.h ==============
if test -f 'posix/dirent.h' -a X"$1" != X"-c"; then
	echo 'x - skipping posix/dirent.h (File already exists)'
else
echo 'x - extracting posix/dirent.h (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'posix/dirent.h' &&
X/* <dirent.h> based on BSD <sys/dir.h> */
X
X#include <sys/dir.h>
X#define dirent direct
X
SHAR_EOF
true || echo 'restore of posix/dirent.h failed'
fi
# ============= posix/fcntl.c ==============
if test -f 'posix/fcntl.c' -a X"$1" != X"-c"; then
	echo 'x - skipping posix/fcntl.c (File already exists)'
else
echo 'x - extracting posix/fcntl.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'posix/fcntl.c' &&
X/* fcntl emulation */
X
X#include <errno.h>
X#include <sys/types.h>
X#include <unistd.h>
X#include <fcntl.h>
X
X#if _V7
X
X#include <sgtty.h>
X
Xint
Xfcntl(fd, cmd, arg)
X	int fd, cmd, arg;
X{
X	switch (cmd) {
X	  case F_SETFD:		/* set fd flags */
X		ioctl(fd, (arg&FD_CLEXEC) ? FIOCLEX : FIONCLEX, (char *)NULL);
X		break;
X	  case F_DUPFD:		/* dup fd */
X		/* this one is fun. find an unused fd >= arg and dup2 */
X		break;
X	}
X	return 0;
X}
X
X#endif
X
SHAR_EOF
true || echo 'restore of posix/fcntl.c failed'
fi
# ============= posix/fcntl.h ==============
if test -f 'posix/fcntl.h' -a X"$1" != X"-c"; then
	echo 'x - skipping posix/fcntl.h (File already exists)'
else
echo 'x - extracting posix/fcntl.h (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'posix/fcntl.h' &&
X/* P1003.1 fcntl/open definitions */
X/* Based on a version by Terrence W. Holm */
X
X/*  for fcntl(2)  */
X
X#define	F_DUPFD		0
X#define	F_GETFD		1
X#define	F_SETFD		2
X#define	F_GETFL		3
X#define	F_SETFL		4
X
X#define	FD_CLEXEC	1		/* fcntl F_SETFD close on exec mode */
X
X/*  for open(2)  */
X
X#define	O_RDONLY	0
X#define	O_WRONLY	1
X#define	O_RDWR		2
X
X#if _BSD
X#undef	O_RDONLY
X#undef	O_WRONLY
X#undef	O_RDWR
X#include "/usr/include/fcntl.h"
X#endif
X
SHAR_EOF
true || echo 'restore of posix/fcntl.h failed'
fi
# ============= posix/io.h ==============
if test -f 'posix/io.h' -a X"$1" != X"-c"; then
	echo 'x - skipping posix/io.h (File already exists)'
else
echo 'x - extracting posix/io.h (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'posix/io.h' &&
X/* POSIX IO functions */
X
X/* include <unistd.h> to get this */
X
X#if ! _IO_H
X#define	_IO_H	1
X
X#include <unistd.h>
X
X#if _ST				/* dLibs hack */
X#define	unlink	remove
X#endif
X
Xstruct stat;			/* create global incompletely-typed structure */
X
Xint chdir ARGS ((const char *path));
Xint umask ARGS ((int mode));
X
Xint open ARGS ((const char *path, int flags, ... /*mode*/));
Xint creat ARGS ((const char *path, int mode));
Xint pipe ARGS ((int pv[2]));
Xint close ARGS ((int fd));
X
Xint fcntl ARGS ((int fd, int cmd, int arg));
Xint dup ARGS ((int fd));
Xint dup2 ARGS ((int ofd, int nfd));
X
Xint link ARGS ((const char *opath, const char *npath));
Xint unlink ARGS ((const char *path));
Xint rename ARGS ((const char *opath, const char *npath));
Xint mkdir ARGS ((const char *path, int mode));
X
Xlong lseek ARGS ((int fd, long off, int how));
Xint read ARGS ((int fd, char *buf, unsigned len));
Xint write ARGS ((int fd, char *buf, unsigned len));
X
Xint access ARGS ((const char *path, int mode));
Xint stat ARGS ((const char *path, struct stat *sp));
Xint fstat ARGS ((int fd, struct stat *sp));
X
Xint chmod ARGS ((const char *path, int mode));
Xint chown ARGS ((const char *path, int uid));
Xint chgrp ARGS ((const char *path, int gid));
Xint utime ARGS ((const char *path, long tv[2]));
X
X#if _BSD || _V7
Xint ioctl ARGS ((int fd, int cmd, void *argp)); /* BSD is "uns long cmd" */
X#endif
X
X#endif
SHAR_EOF
true || echo 'restore of posix/io.h failed'
fi
# ============= posix/times.c ==============
if test -f 'posix/times.c' -a X"$1" != X"-c"; then
	echo 'x - skipping posix/times.c (File already exists)'
else
echo 'x - extracting posix/times.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'posix/times.c' &&
X/* P1003.1 times emulation */
X
X#include <sys/times.h>
X
X#if _BSD
X
X#include <sys/time.h>
X#include <sys/resource.h>
X
Xstatic	long base_tv_sec = 0;
X
Xclock_t
Xtimes(tmsp)
X	register struct tms *tmsp;
X{
X	struct timeval tv;
X	struct rusage ru;
X
X	getrusage(RUSAGE_SELF, &ru);
X	tmsp->tms_utime = ru.ru_utime.tv_sec*CLK_TCK
X		+ (long)ru.ru_utime.tv_usec*CLK_TCK/1000000;
X	tmsp->tms_stime = ru.ru_stime.tv_sec*CLK_TCK
X		+ (long)ru.ru_stime.tv_usec*CLK_TCK/1000000;
X	getrusage(RUSAGE_CHILDREN, &ru);
X	tmsp->tms_cutime = ru.ru_utime.tv_sec*CLK_TCK
X		+ (long)ru.ru_utime.tv_usec*CLK_TCK/1000000;
X	tmsp->tms_cstime = ru.ru_stime.tv_sec*CLK_TCK
X		+ (long)ru.ru_stime.tv_usec*CLK_TCK/1000000;
X
X	gettimeofday(&tv, (struct timezone *)NULL);
X	if (base_tv_sec == 0)
X		base_tv_sec = tv.tv_sec;
X	tv.tv_sec -= base_tv_sec; /*  prevent clock_t overflow */
X	return tv.tv_sec*CLK_TCK + (long)tv.tv_usec*CLK_TCK/1000000;
X}
X
X#endif
X
X#if _V7
X
Xclock_t
Xtimes(tmsp)
X	struct tms *tmsp;
X{
X	struct timeb tb;
X
X#undef times			/* access real times() */
X	times(tmsp);
X#define times times_
X	ftime(&tb);
X	return tb.time*CLK_TCK + (long)tb.millitm*CLK_TCK/1000;
X}
X
X#endif
X
SHAR_EOF
true || echo 'restore of posix/times.c failed'
fi
# ============= posix/unistd.c ==============
if test -f 'posix/unistd.c' -a X"$1" != X"-c"; then
	echo 'x - skipping posix/unistd.c (File already exists)'
else
echo 'x - extracting posix/unistd.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'posix/unistd.c' &&
X/* misc. POSIX emulation */
X
X/* $Header$ */
X
X#include <string.h>
X#include <errno.h>
X#include <sys/types.h>
X#include <unistd.h>
X
X#if _V7 || _BSD
X
Xchar *
Xgetcwd(buf, len)
X	char *buf;
X	size_t len;
X{
X	char cwd [1024];
X	extern char *getwd();
X	if (getwd(cwd) == NULL)
X		return NULL;
X	if (strlen(cwd)+1 >= len) {
X		errno = ERANGE;
X		return NULL;
X	}
X	return strcpy(buf, cwd);
X}
X
X#endif
X
X#if _V7
X
Xlong
Xulimit(cmd, limit)
X	int cmd;
X	long limit;
X{
X	return 0;
X}
X
X#endif
X
SHAR_EOF
true || echo 'restore of posix/unistd.c failed'
fi
# ============= posix/unistd.h ==============
if test -f 'posix/unistd.h' -a X"$1" != X"-c"; then
	echo 'x - skipping posix/unistd.h (File already exists)'
else
echo 'x - extracting posix/unistd.h (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'posix/unistd.h' &&
X/* unistd.h: misc. P1003.1 definitions */
X/* Based on a version by Terrence W. Holm */
X
X#if ! _UNISTD_H
X#define	_UNISTD_H 1
X
X#include <stddef.h>
X
X/* doesn't really belong here, but the library function need it */
X/* todo: use _ARGS, _Void, _Const */
X#if __STDC__
X#define	ARGS(args)	args
X#define Void	void
X#define	Const	const
X#else
X#define	ARGS(args)	()
X#define	Void	char
X#define	Const
X#endif
X
X#include <io.h>			/* POSIX IO functions */
X
X/*  for access(2)  */
X
X#define	R_OK	4
X#define	W_OK	2
X#define	X_OK	1
X#define	F_OK	0
X
X/*  for lockf(2)  */
X
X#define	F_ULOCK	0
X#define	F_LOCK	1
X#define	F_TLOCK	2
X#define	F_TEST	3
X
X/*  for lseek(2)  */
X
X#define	SEEK_SET	0
X#define	SEEK_CUR	1
X#define	SEEK_END	2
X
X#define	IN_PATH	"/usr/include"
X
Xchar   *getcwd ARGS ((char *buf, size_t len));
X
X#endif
X
SHAR_EOF
true || echo 'restore of posix/unistd.h failed'
fi
# ============= posix/time.h ==============
if test -f 'posix/time.h' -a X"$1" != X"-c"; then
	echo 'x - skipping posix/time.h (File already exists)'
else
echo 'x - extracting posix/time.h (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'posix/time.h' &&
X/*
X * Replacement for BSD <sys/time.h>
X * because Ultrix screws it up.
X */
X
Xstruct timeval {
X	long tv_sec;		/* time_t */
X	long tv_usec;		/* microsex */
X};
X
Xstruct timezone {
X	int tz_minuteswest;	/* of Greenwinch */
X	int tz_dsttime;		/* type of dst correction to apply */
X};
SHAR_EOF
true || echo 'restore of posix/time.h failed'
fi
# ============= posix/times.h ==============
if test -f 'posix/times.h' -a X"$1" != X"-c"; then
	echo 'x - skipping posix/times.h (File already exists)'
else
echo 'x - extracting posix/times.h (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'posix/times.h' &&
X/*
X * sys/times.h: POSIX times()
X */
X
X#if ! _TIMES_H
X#define	_TIMES_H 1
X
X#include <time.h>		/* defines CLK_TCK */
X
X#if __STDC__
X#define	ARGS(args)	args
X#else
X#define	ARGS(args)	()
X#endif
X
Xstruct tms {
X	clock_t	tms_utime, tms_stime;
X	clock_t	tms_cutime, tms_cstime;
X};
X
X#if _V7
X#define times times_
X#endif
X
Xclock_t	times ARGS((struct tms *tmsp));
X
X#endif
X
SHAR_EOF
true || echo 'restore of posix/times.h failed'
fi
# ============= posix/wait.h ==============
if test -f 'posix/wait.h' -a X"$1" != X"-c"; then
	echo 'x - skipping posix/wait.h (File already exists)'
else
echo 'x - extracting posix/wait.h (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'posix/wait.h' &&
X/*
X * POSIX <sys/wait.h>
X */
X
X#if __STDC__
X#define	ARGS(args)	args
X#else
X#define	ARGS(args)	()
X#endif
X
X#if 1
Xtypedef int pid_t;		/* belong in sys/types.h */
X#endif
X
X/* waitpid options */
X#define WNOHANG		1	/* don't hang in wait */
X#define WUNTRACED	2	/* tell about stopped, untraced children */
X
X#define	WSTOPPED	0x7F	/* process is stopped */
X
X#define WIFSTOPPED(x)	(((x)&0xFF) == 0x7F)
X#define WIFSIGNALED(x)	(((x)&0xFF) != 0x7F && ((x)&0x7F) != 0)
X#define WIFEXITED(x)	(((x)&0xFF) != 0x7F && ((x)&0x7F) == 0)
X#define	WIFCORED(x)	(!!((x)&0x80)) /* non-standard */
X#define	WEXITSTATUS(x)	((x)>>8&0xFF)
X#define	WTERMSIG(x)	((x)&0x7F)
X#define	WSTOPSIG(x)	((x)>>8&0xFF)
X
Xpid_t wait ARGS((int *statp));
X#if _BSD
Xpid_t wait3 ARGS((int *statp, int options, Void *));
X/* todo: does not emulate pid argument */
X#define	waitpid(pid, sp, opts)	wait3(sp, opts, (Void*)NULL)
X#else
Xpid_t waitpid ARGS((pid_t pid, int *statp, int options));
X#endif
X
SHAR_EOF
true || echo 'restore of posix/wait.h failed'
fi
# ============= posix/fixincludes ==============
if test -f 'posix/fixincludes' -a X"$1" != X"-c"; then
	echo 'x - skipping posix/fixincludes (File already exists)'
else
echo 'x - extracting posix/fixincludes (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'posix/fixincludes' &&
X# Install modified versions of certain ANSI-incompatible system header files
X# which are fixed to work correctly with ANSI C
X# and placed in a directory that GNU C will search.
X# This works properly on a Sun in system version 3.4;
X# for other versions, you had better check.
X
Xmkdir /usr/local/lib/gcc-include
Xmkdir /usr/local/lib/gcc-include/sys
Xcp /usr/include/sys/ioctl.h /usr/local/lib/gcc-include/sys/ioctl.h
Xchmod +w /usr/local/lib/gcc-include/sys/ioctl.h
Xex /usr/local/lib/gcc-include/sys/ioctl.h <<\EOF
Xg/_IO/s/(\(.\),/('\1',/
Xg/#define._IO/s/'x'/x/g
Xwq
XEOF
X
Xcp /usr/include/sys/ttychars.h /usr/local/lib/gcc-include/sys/ttychars.h
Xchmod +w /usr/local/lib/gcc-include/sys/ttychars.h
Xex /usr/local/lib/gcc-include/sys/ttychars.h <<\EOF
Xg/CTRL/s/(\(.\))/('\1')/
Xg/#define.CTRL/s/'c'/c/g
Xwq
XEOF
SHAR_EOF
true || echo 'restore of posix/fixincludes failed'
fi
# ============= stdc/Makefile ==============
if test ! -d 'stdc'; then
    echo 'x - creating directory stdc'
    mkdir 'stdc'
fi
if test -f 'stdc/Makefile' -a X"$1" != X"-c"; then
	echo 'x - skipping stdc/Makefile (File already exists)'
else
echo 'x - extracting stdc/Makefile (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'stdc/Makefile' &&
X# Standard C (ANSI) compatabilaty
X# does not requires SVID/P1003.2-compatible "make"
X
X# $Header: Makefile,v 1.1 88/03/29 18:28:38 egisin Locked $
X
XSYSTEM=BSD
XCC = gcc -ansi -O -W 
XLN = ln
XPRINT = lpr -p -Plp26_3018
X
XCFLAGS = -I../h -D_$(SYSTEM)
X
XMISC =	Makefile stdio.h_std
XHDRS =	limits.h stddef.h stdlib.h string.h time.h stdarg.h 
XSRCS =	clock.c stdio.c setvbuf.c vprintf.c fprintf.c sprintf.c \
X	strstr.c \
X	memmove.c memcpy.c memset.c memcmp.c memchr.c 
XOBJS =	clock.o stdio.o setvbuf.o vprintf.o fprintf.o sprintf.o \
X	strstr.o \
X	memmove.o memcpy.o memset.o memcmp.o memchr.o 
X#OBJS =	$(SRCS:.c=.o)
XLIB =	libstdc.a
XINCL =	../h
X
Xall:	$(LIB)
X
Xlink:	$(HDRS) stdio.h 
X	[ -d $(INCL) ] || mkdir $(INCL)
X	[ -d $(INCL)/sys ] || mkdir $(INCL)/sys
X	$(LN) types.h $(INCL)/sys
X	$(LN) limits.h stddef.h stdlib.h stdio.h string.h time.h stdarg.h $(INCL)
X
X$(LIB)(%.o): %.o
X
X%: RCS/%,v
X	co %@
X
X$(LIB):	$(OBJS)
X	ar r $@ $?
X	-ranlib $@
X
X#$(LIB): lib.a($OBJS)
X#	ar rv $@ $?
X#	-ranlib $@
X#	rm -f $?
X
Xstdio.h: stdio.h_std /usr/include/stdio.h 
X	sed </usr/include/stdio.h >stdio.hacked \
X		-e '/^# *include/ d' -e '/char..sprintf/ d' -e '/# *define.NULL./ d'
X	sed <stdio.h_std >stdio.h -e '/%%%/ r stdio.hacked'
X	rm stdio.hacked
X
Xstd_c.tar: $(MISC) $(HDRS) $(SRCS)
X	tar cf std_c.tar $(MISC) $(HDRS) $(SRCS)
X
Xprint: $(MISC) $(HDRS) $(SRCS)
X	$(PRINT) $(MISC) $(HDRS) $(SRCS)
X
Xstring.h: stddef.h
X
Xstdlib.h: stddef.h
X
Xstdio.h: stddef.h 
X
Xtime.h: stddef.h
X
Xstdio.o: stdio.h
X
Xsetvbuf.o: stdlib.h stdio.h
X
Xfprintf.o: stdarg.h stdio.h
X
Xsprintf.o: stdarg.h stdio.h
X
Xvprintf.o: stdarg.h stdio.h
X
Xstrstr.o: string.h 
X
SHAR_EOF
true || echo 'restore of stdc/Makefile failed'
fi
# ============= stdc/vprintf.c ==============
if test -f 'stdc/vprintf.c' -a X"$1" != X"-c"; then
	echo 'x - skipping stdc/vprintf.c (File already exists)'
else
echo 'x - extracting stdc/vprintf.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'stdc/vprintf.c' &&
X#if __STDC__
X#include <stdarg.h>
X#else
X#include <varargs.h>
X#endif
X#include <stdio.h>
X
X#define	BUF	40		/* buffer for int -> string conversion */
X
Xint
X#if __STDC__
Xvprintf(Const char *fmt, va_list va) {
X#else
Xvprintf(fmt, va) char *fmt; va_list va; {
X#endif
X	return vfprintf(stdout, fmt, va);
X}
X
Xint
X#if __STDC__
Xvfprintf(register FILE *f, register Const char *fmt, register va_list va) {
X#else
Xvfprintf(f, fmt, va) register FILE *f; register char *fmt; register va_list va; {
X#endif
X	register int c;
X	int pos = 0;			/* todo: implement */
X
X	while ((c = *fmt++))
X	    if (c == '%') {
X		long n;
X		register unsigned long u;
X		char buf [BUF+1];
X		register char *p = buf + BUF;
X		register enum {
X			FF_ALT = 0x01, /* #, alternate format */
X			FF_SHORT = 0x02, /* h, short arg */
X			FF_LONG = 0x04,	/* l, long arg */
X			FF_ZERO = 0x08,	/* 0, zero fill */
X			FF_LEFT = 0x10,	/* -, left adjust */
X			FF_PREC = 0x20,	/* .*, precision */
X			FF_NEG = 0x40,	/* signed arg */
X			FF_PUTS = 0x80,	/* fputs(p, f) */
X			FF_DEFAULT = 0
X		} flags = FF_DEFAULT;
X		int sign = '-';	/* sign: [ +-] */
X		int width = 0, prec = 0; /* width, precision */
X
X		*p = 0;
X
X		/* scan flag characters */
X		for (c = *fmt++; ; c = *fmt++) switch (c) {
X		  case '0':
X			flags |= FF_ZERO;
X			break;
X
X		  case '#':		/* alternate format */
X			flags |= FF_ALT;
X			break;
X
X		  case ' ':		/* blank sign */
X			sign = ' ';
X			break;
X		  case '+':		/* +/- sign */
X			sign = '+';
X			break;
X
X		  case '-':		/* left just. */
X			flags |= FF_LEFT;
X			break;
X
X		  default:
X			goto Frogs;
X		}
X	  Frogs:
X
X		/* scan width */
X	  	if (c == '*') {		/* width from arg list */
X			width = va_arg(va, int);
X			c = *fmt++;
X		} else
X			while ('0' <= c && c <= '9') {
X				width = width*10 + (c-'0');
X				c = *fmt++;
X			}
X
X		if (c == '.') {		/* scan precision */
X			flags |= FF_PREC;
X			c = *fmt++;
X			if (c == '*') {	/* precision from arg list */
X				prec = va_arg(va, int);
X				c = *fmt++;
X			} else
X				while ('0' <= c && c <= '9') {
X					prec = prec*10 + (c-'0');
X					c = *fmt++;
X				}
X		}
X
X		/* length modifiers */
X		if (c == 'h') {
X			flags |= FF_SHORT;
X			c = *fmt++;
X		} else if (c == 'l') {
X			flags |= FF_LONG;
X			c = *fmt++;
X		}
X
X		/* do conversion */
X		switch (c) {
X		  case '%':		/* %% -> % */
X			putc(c, f);
X			pos ++;
X			break;
X
X		  case 'p':		/* pointer */
X			*--p = '}';
X			u = (unsigned long) va_arg(va, Void*);
X			do {
X				*--p = "0123456789ABCDEF"[u%16];
X				u /= 16;
X			} while (u != 0);
X			*--p = '{';
X			flags |= FF_PUTS;
X			break;
X
X		  case 'n':		/* save position */
X			*va_arg(va, int*) = pos;
X			break;
X
X		  case 'c':		/* character */
X			u = (flags&FF_SHORT) ? va_arg(va, unsigned short)
X			  : (flags&&FF_LONG) ? va_arg(va, unsigned long)
X			  : va_arg(va, unsigned int);
X			*--p = u;
X			flags |= FF_PUTS;
X			break;
X
X		  case 's':		/* string */
X			p = va_arg(va, char *);
X			if ((flags&FF_PREC) && strlen(p) > prec) {
X				pos += prec;
X				while (--prec >= 0)
X					putc(*p++, f);
X				break;
X			}
X			flags |= FF_PUTS;
X			break;
X
X		  case 'i': case 'd': case 'u': /* decimal */
X			if (c != 'u') {	/* signed */
X				n = (flags&FF_SHORT) ? va_arg(va, short)
X				  : (flags&&FF_LONG) ? va_arg(va, long)
X				  : va_arg(va, int);
X				if (n < 0)
X					flags |= FF_NEG;
X				u = (n < 0) ? -n : n;
X			} else
X				u = (flags&FF_SHORT) ? va_arg(va, unsigned short)
X				  : (flags&&FF_LONG) ? va_arg(va, unsigned long)
X				  : va_arg(va, unsigned int);
X			do {
X				*--p = '0' + u%10;
X				u /= 10;
X			} while (u != 0);
X			prec -= buf+BUF - p;
X			while (--prec >= 0)
X				*--p = '0';
X			if (flags&FF_NEG)
X				*--p = '-';
X			else
X				if (sign != '-')
X					*--p = (sign == '+') ? '+' : ' ';
X			flags |= FF_PUTS;
X			break;
X
X		  case 'x': case 'X':	/* hex, Hex */
X			u = (flags&FF_SHORT) ? va_arg(va, unsigned short)
X			  : (flags&&FF_LONG) ? va_arg(va, unsigned long)
X			  : va_arg(va, unsigned int);
X			do {
X				*--p = "0123456789ABCDEF"[u%16];
X				u /= 16;
X			} while (u != 0);
X			prec -= buf+BUF - p;
X			while (--prec >= 0)
X				*--p = '0';
X			if (flags&&FF_ALT)
X				*--p = 'x', *--p = '0';
X			flags |= FF_PUTS;
X			break;
X
X		  case 'o':		/* octal */
X			u = (flags&FF_SHORT) ? va_arg(va, unsigned short)
X			  : (flags&&FF_LONG) ? va_arg(va, unsigned long)
X			  : va_arg(va, unsigned int);
X			do {
X				*--p = '0' + u%8;
X				u /= 8;
X			} while (u != 0);
X			prec -= buf+BUF - p;
X			while (--prec >= 0)
X				*--p = '0';
X			if (flags&&FF_ALT && *p != '0')
X				*--p = '0';
X			flags |= FF_PUTS;
X			break;
X
X		  default:		/* todo: error */
X			putc('%', f);
X			putc(c, f);
X			pos += 2;
X			break;
X		}
X
X		/* copy adjusted string "p" to output */
X		if (flags&FF_PUTS) {
X			int len = strlen(p);
X			int pad = width - len;
X			if (!(flags&FF_LEFT))
X				while (--pad >= 0)
X					putc(' ', f);
X			while (*p)
X				putc(*p++, f);
X			if ((flags&FF_LEFT))
X				while (--pad >= 0)
X					putc(' ', f);
X			pos += (len < width) ? width : len;
X		}
X	    } else {			/* ordinary character */
X		putc(c, f);
X		pos ++;
X	    }
X	return pos;
X}
X
SHAR_EOF
true || echo 'restore of stdc/vprintf.c failed'
fi
# ============= stdc/stddef.h ==============
if test -f 'stdc/stddef.h' -a X"$1" != X"-c"; then
	echo 'x - skipping stdc/stddef.h (File already exists)'
else
echo 'x - extracting stdc/stddef.h (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'stdc/stddef.h' &&
X/* ANSI common definitions */
X
X/* $Header$ */
X
X#ifndef NULL
X#if __STDC__
X#define	NULL	(void*)0
X#else
X#define	NULL	0
X#endif
X#endif
X
X#if ! _STDDEF_H
X#define	_STDDEF_H 1
X
X/* doesn't really belong here, but the library function need it */
X#if __STDC__
X#define	ARGS(args)	args
X#define Void	void
X#define	Const	const
X#else
X#define	ARGS(args)	()
X#define	Void	char
X#define	Const
X#endif
X
Xtypedef unsigned size_t;		/* may need long */
Xtypedef int ptrdiff_t;
X
X#define	offsetof(type,id) ((size_t)&((type*)NULL)->id)
X
Xextern	int errno;		/* really belongs in <errno.h> */
X
X#endif
X
SHAR_EOF
true || echo 'restore of stdc/stddef.h failed'
fi
# ============= stdc/stdio.c ==============
if test -f 'stdc/stdio.c' -a X"$1" != X"-c"; then
	echo 'x - skipping stdc/stdio.c (File already exists)'
else
echo 'x - extracting stdc/stdio.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'stdc/stdio.c' &&
X/*
X * Emulation of misc. ANSI C stdio functions
X */
X
X/* $Header */
X
X#include <stdio.h>
X
X#if 1
Xint
Xremove(name)
X	Const char *name;
X{
X	return unlink(name);
X}
X#endif
X
X#if _V7
Xint
Xrename(oname, name)
X	Const char *oname, *nname;
X{
X	return link(oname, nname) == 0 && unlink(oname) == 0 ? 0 : -1;
X}
X#endif
X
SHAR_EOF
true || echo 'restore of stdc/stdio.c failed'
fi
true || echo 'restore of stdc/stdio.h failed'
echo End of part 6, continue with part 7
exit 0



More information about the Alt.sources mailing list