Category : OS/2 Files
Archive   : KSH48.ZIP
Filename : TREE.C

 
Output of file : TREE.C contained in archive : KSH48.ZIP
/*
* command tree climbing
*/

#ifndef lint
static char *RCSid = "$Id: tree.c,v 1.2 1992/04/25 08:33:28 sjg Exp $";
#endif

#include "stdh.h"
#include
#include
#include

#ifdef __STDC__
# include
#else
# include
#endif
#include "sh.h"

#define FSTRING (FILE*)NULL

static int tputc ARGS((int c, FILE *f));
static void tputC ARGS((int c, FILE *f));
static void tputS ARGS((char *wp, FILE *f));
static struct ioword **iocopy ARGS((struct ioword **iow, Area *ap));
static void iofree ARGS((struct ioword **iow, Area *ap));

/*
* print a command tree
*/

void
ptree(t, f)
register struct op *t;
register FILE *f;
{
register char **w;
struct ioword **ioact;
struct op *t1;

Chain:
if (t == NULL)
return;
switch (t->type) {
case TCOM:
for (w = t->vars; *w != NULL; )
fptreef(f, "%S ", *w++);
for (w = t->args; *w != NULL; )
fptreef(f, "%S ", *w++);
break;

case TEXEC:
t = t->left;
goto Chain;
case TPAREN:
fptreef(f, "(%T)", t->left);
break;
case TPIPE:
fptreef(f, "%T| ", t->left);
t = t->right;
goto Chain;
case TLIST:
fptreef(f, "%T", t->left);
fptreef(f, "%;");
t = t->right;
goto Chain;
case TOR:
case TAND:
fptreef(f, "%T", t->left);
fptreef(f, "%s %T", (t->type==TOR) ? "||" : "&&", t->right);
break;
case TFOR:
fptreef(f, "for %s ", t->str);
if (t->vars != NULL) {
fptreef(f, "in ");
for (w = t->vars; *w; )
fptreef(f, "%S ", *w++);
fptreef(f, "%;");
}
fptreef(f, "do %T", t->left);
fptreef(f, "%;done ");
break;
case TCASE:
fptreef(f, "case %S in%;", t->str);
for (t1 = t->left; t1 != NULL; t1 = t1->right) {
fptreef(f, "(");
for (w = t1->vars; *w != NULL; w++) {
fptreef(f, "%S", *w);
fptreef(f, "%c", (w[1] != NULL) ? '|' : ')');
}
fptreef(f, " %T;;%;", t1->left);
}
fptreef(f, "esac ");
break;
case TIF:
fptreef(f, "if %T", t->left);
fptreef(f, "%;");
t = t->right;
if (t->left != NULL) {
fptreef(f, "then %T", t->left);
fptreef(f, "%;");
}
if (t->right != NULL) {
fptreef(f, "else %T", t->right);
fptreef(f, "%;");
}
fptreef(f, "fi ");
break;
case TWHILE:
case TUNTIL:
fptreef(f, "%s %T",
(t->type==TWHILE) ? "while" : "until",
t->left);
fptreef(f, "%;do %T", t->right);
fptreef(f, "%;done ");
break;
case TBRACE:
fptreef(f, "{%;%T", t->left);
fptreef(f, "%;} ");
break;
case TASYNC:
fptreef(f, "%T&", t->left);
break;
case TFUNCT:
fptreef(f, "function %s %T", t->str, t->left);
break;
case TTIME:
fptreef(f, "time %T", t->left);
break;
default:
fptreef(f, "");
break;
}
if ((ioact = t->ioact) != NULL)
while (*ioact != NULL)
pioact(f, *ioact++);
}

pioact(f, iop)
register FILE *f;
register struct ioword *iop;
{
register int flag = iop->flag;
if (iop->unit > 1)
fptreef(f, "%c", '0' + iop->unit );

switch(flag&IOTYPE) {
case IOREAD:
fptreef(f, "< ");
break;
case IOHERE:
if (flag&IOSKIP)
fptreef(f, "<<- ");
else
fptreef(f, "<< ");
if (!(flag&IOEVAL))
fptreef(f, "'");
break;
case IOCAT:
fptreef(f, ">> ");
break;
case IOWRITE:
if (flag&IOCLOB)
fptreef(f, ">! ");
else
fptreef(f, "> ");
break;
case IODUP: /* Needs help */
if (iop->unit == 0)
fptreef(f, "<&");
else
fptreef(f, ">&");
break;
}

if ((flag&IOTYPE) == IOHERE) {
if (flag&IOEVAL)
fptreef(f, "%s ", iop->name);
else
fptreef(f, "%s' ", iop->name);
} else {
fptreef(f, "%S ", iop->name);
}
}


/*
* variants of fputc, fputs for ptreef and snptreef
*/

static char *snpf_s; /* snptreef string */
static int snpf_n; /* snptreef length */

static int
tputc(c, f)
int c;
register FILE *f;
{
if (f != NULL)
putc(c, f);
else
if (--snpf_n >= 0)
*snpf_s++ = c;
return c;
}

static void
tputC(c, f)
register int c;
register FILE *f;
{
if ((c&0x60) == 0) { /* C0|C1 */
tputc((c&0x80) ? '$' : '^', f);
tputc(((c&0x7F)|0x40), f);
} else if ((c&0x7F) == 0x7F) { /* DEL */
tputc((c&0x80) ? '$' : '^', f);
tputc('?', f);
} else
tputc(c, f);
}

static void
tputS(wp, f)
register char *wp;
register FILE *f;
{
register int c, quoted=0;

while (1)
switch ((c = *wp++)) {
case EOS:
return;
case CHAR:
tputC(*wp++, f);
break;
case QCHAR:
if (!quoted)
tputc('\\', f);
tputC(*wp++, f);
break;
case OQUOTE:
quoted = 1;
tputc('"', f);
break;
case CQUOTE:
quoted = 0;
tputc('"', f);
break;
case OSUBST:
tputc('$', f);
tputc('{', f);
while ((c = *wp++) != 0)
tputc(c, f);
if (*wp != CSUBST)
tputC(*wp++, f);
break;
case CSUBST:
tputc('}', f);
break;
case COMSUB:
tputc('$', f);
tputc('(', f);
while (*wp != 0)
tputC(*wp++, f);
tputc(')', f);
break;
}
}

/*
* this is the _only_ way to reliably handle
* variable args with an ANSI compiler
*/
#ifdef __STDC__
/* VARARGS */ int
fptreef(FILE *f, char *fmt, ...)
{
#else
fptreef(va_alist)
va_dcl
{
FILE *f;
char *fmt;
#endif
va_list va;

#ifdef __STDC__
va_start(va, fmt);
#else
va_start(va);
f = va_arg(va, FILE *);
fmt = va_arg(va, char *);
#endif

vfptreef(f, fmt, va);
va_end(va);
return 0;
}

/* VARARGS */ int
#ifdef __STDC__
snptreef(char *s, int n, char *fmt, ...)
{
#else
snptreef(va_alist)
va_dcl
{
char *s;
int n;
char *fmt;
#endif
va_list va;

#ifdef __STDC__
va_start(va, fmt);
#else
va_start(va);
s = va_arg(va, char *);
n = va_arg(va, int);
fmt = va_arg(va, char *);
#endif

snpf_s = s;
snpf_n = n;
vfptreef(FSTRING, fmt, va);
tputc('\0', FSTRING);
va_end(va);
return 0;
}


vfptreef(f, fmt, va)
register FILE *f;
register char *fmt;
register va_list va;
{
register int c;

while ((c = *fmt++))
if (c == '%') {
register long n;
register char *p;
int neg;

switch ((c = *fmt++)) {
case 'c':
tputc(va_arg(va, int), f);
break;
case 's':
p = va_arg(va, char *);
while (*p)
tputc(*p++, f);
break;
case 'S': /* word */
p = va_arg(va, char *);
tputS(p, f);
break;
case 'd': case 'u': /* decimal */
n = (c == 'd') ? va_arg(va, int) : va_arg(va, unsigned int);
neg = c=='d' && n<0;
p = ulton((neg) ? -n : n, 10);
if (neg)
*--p = '-';
while (*p)
tputc(*p++, f);
break;
case 'T': /* format tree */
ptree(va_arg(va, struct op *), f);
break;
case ';': /* newline or ; */
p = (f == FSTRING) ? "; " : "\n";
while (*p)
tputc(*p++, f);
break;
default:
tputc(c, f);
break;
}
} else
tputc(c, f);
}

/*
* copy tree (for function definition)
*/

static struct ioword **iocopy();

struct op *
tcopy(t, ap)
register struct op *t;
Area *ap;
{
register struct op *r;
register char **tw, **rw;

if (t == NULL)
return NULL;

r = (struct op *) alloc(sizeof(struct op), ap);

r->type = t->type;

/* this will copy function and for identifiers quite accidently */
r->str = (t->str == NULL) ? NULL : wdcopy(t->str, ap);

if (t->vars == NULL)
r->vars = NULL;
else {
for (tw = t->vars; *tw++ != NULL; )
;
rw = r->vars = (char **)
alloc((int)(tw - t->vars) * sizeof(*tw), ap);
for (tw = t->vars; *tw != NULL; )
*rw++ = wdcopy(*tw++, ap);
*rw = NULL;
}

if (t->args == NULL)
r->args = NULL;
else {
for (tw = t->args; *tw++ != NULL; )
;
rw = r->args = (char **)
alloc((int)(tw - t->args) * sizeof(*tw), ap);
for (tw = t->args; *tw != NULL; )
*rw++ = wdcopy(*tw++, ap);
*rw = NULL;
}

r->ioact = (t->ioact == NULL) ? NULL : iocopy(t->ioact, ap);

r->left = tcopy(t->left, ap);
r->right = tcopy(t->right, ap);

return r;
}

char *
wdcopy(wp, ap)
char *wp;
Area *ap;
{
size_t len = wdscan(wp, EOS) - wp;
return memcpy(alloc(len, ap), wp, len);
}

/* return the position of prefix c in wp plus 1 */
char *
wdscan(wp, c)
register char *wp;
register int c;
{
register int nest = 0;

while (1)
switch (*wp++) {
case EOS:
return wp;
case CHAR:
case QCHAR:
wp++;
break;
case OQUOTE:
case CQUOTE:
break;
case OSUBST:
nest++;
while (*wp++ != 0)
;
if (*wp != CSUBST)
wp++;
break;
case CSUBST:
if (c == CSUBST && nest == 0)
return wp;
nest--;
break;
case COMSUB:
while (*wp++ != 0)
;
break;
}
}

static struct ioword **
iocopy(iow, ap)
register struct ioword **iow;
Area *ap;
{
register struct ioword **ior;
register int i;

for (ior = iow; *ior++ != NULL; )
;
ior = (struct ioword **) alloc((int)(ior - iow) * sizeof(*ior), ap);

for (i = 0; iow[i] != NULL; i++) {
register struct ioword *p, *q;

p = iow[i];
q = (struct ioword *) alloc(sizeof(*p), ap);
ior[i] = q;
*q = *p;
if (p->name != NULL)
q->name = wdcopy(p->name, ap);
}
ior[i] = NULL;

return ior;
}

/*
* free tree (for function definition)
*/

static void iofree();

void
tfree(t, ap)
register struct op *t;
Area *ap;
{
register char **w;

if (t == NULL)
return;

if (t->str != NULL)
afree((void*)t->str, ap);

if (t->vars != NULL) {
for (w = t->vars; *w != NULL; w++)
afree((void*)*w, ap);
afree((void*)t->vars, ap);
}

if (t->args != NULL) {
for (w = t->args; *w != NULL; w++)
afree((void*)*w, ap);
afree((void*)t->args, ap);
}

if (t->ioact != NULL)
iofree(t->ioact, ap);

tfree(t->left, ap);
tfree(t->right, ap);

afree((void*)t, ap);
}

static void
iofree(iow, ap)
struct ioword **iow;
Area *ap;
{
register struct ioword **iop;
register struct ioword *p;

for (iop = iow; (p = *iop++) != NULL; ) {
if (p->name != NULL)
afree((void*)p->name, ap);
afree((void*)p, ap);
}
}



  3 Responses to “Category : OS/2 Files
Archive   : KSH48.ZIP
Filename : TREE.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/