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