mirror of
git://git.code.sf.net/p/cdesktopenv/code
synced 2025-03-09 15:50:02 +00:00
266 lines
6.5 KiB
C
266 lines
6.5 KiB
C
/***********************************************************************
|
|
* *
|
|
* This software is part of the ast package *
|
|
* Copyright (c) 1982-2011 AT&T Intellectual Property *
|
|
* Copyright (c) 2020-2021 Contributors to ksh 93u+m *
|
|
* and is licensed under the *
|
|
* Eclipse Public License, Version 1.0 *
|
|
* by AT&T Intellectual Property *
|
|
* *
|
|
* A copy of the License is available at *
|
|
* http://www.eclipse.org/org/documents/epl-v10.html *
|
|
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
|
|
* *
|
|
* Information and Software Systems Research *
|
|
* AT&T Research *
|
|
* Florham Park NJ *
|
|
* *
|
|
* David Korn <dgk@research.att.com> *
|
|
* *
|
|
***********************************************************************/
|
|
#pragma prototyped
|
|
/*
|
|
* David Korn
|
|
* AT&T Labs
|
|
*
|
|
* shell parse tree dump
|
|
*
|
|
*/
|
|
|
|
#include "defs.h"
|
|
#include "shnodes.h"
|
|
#include "path.h"
|
|
#include "io.h"
|
|
#include <ccode.h>
|
|
|
|
static int p_comlist(const struct dolnod*);
|
|
static int p_arg(const struct argnod*);
|
|
static int p_comarg(const struct comnod*);
|
|
static int p_redirect(const struct ionod*);
|
|
static int p_switch(const struct regnod*);
|
|
static int p_tree(const Shnode_t*);
|
|
static int p_string(const char*);
|
|
|
|
static Sfio_t *outfile;
|
|
|
|
int sh_tdump(Sfio_t *out, const Shnode_t *t)
|
|
{
|
|
outfile = out;
|
|
return(p_tree(t));
|
|
}
|
|
|
|
/*
|
|
* convert to ASCII to write and back again if needed
|
|
*/
|
|
static int outstring(Sfio_t *out, const char *string, int n)
|
|
{
|
|
int r;
|
|
char *cp = (char*)string;
|
|
ccmaps(cp, n, CC_NATIVE, CC_ASCII);
|
|
r = sfwrite(out,cp,n);
|
|
ccmaps(cp, n, CC_ASCII, CC_NATIVE);
|
|
return(r);
|
|
}
|
|
|
|
/*
|
|
* print script corresponding to shell tree <t>
|
|
*/
|
|
static int p_tree(register const Shnode_t *t)
|
|
{
|
|
if(!t)
|
|
return(sfputl(outfile,-1));
|
|
if(sfputl(outfile,t->tre.tretyp)<0)
|
|
return(-1);
|
|
switch(t->tre.tretyp&COMMSK)
|
|
{
|
|
case TTIME:
|
|
case TPAR:
|
|
return(p_tree(t->par.partre));
|
|
case TCOM:
|
|
return(p_comarg((struct comnod*)t));
|
|
case TSETIO:
|
|
case TFORK:
|
|
if(sfputu(outfile,t->fork.forkline)<0)
|
|
return(-1);
|
|
if(p_tree(t->fork.forktre)<0)
|
|
return(-1);
|
|
return(p_redirect(t->fork.forkio));
|
|
case TIF:
|
|
if(p_tree(t->if_.iftre)<0)
|
|
return(-1);
|
|
if(p_tree(t->if_.thtre)<0)
|
|
return(-1);
|
|
return(p_tree(t->if_.eltre));
|
|
case TWH:
|
|
if(t->wh.whinc)
|
|
{
|
|
if(p_tree((Shnode_t*)(t->wh.whinc))<0)
|
|
return(-1);
|
|
}
|
|
else
|
|
{
|
|
if(sfputl(outfile,-1)<0)
|
|
return(-1);
|
|
}
|
|
if(p_tree(t->wh.whtre)<0)
|
|
return(-1);
|
|
return(p_tree(t->wh.dotre));
|
|
case TLST:
|
|
case TAND:
|
|
case TORF:
|
|
case TFIL:
|
|
if(p_tree(t->lst.lstlef)<0)
|
|
return(-1);
|
|
return(p_tree(t->lst.lstrit));
|
|
case TARITH:
|
|
if(sfputu(outfile,t->ar.arline)<0)
|
|
return(-1);
|
|
return(p_arg(t->ar.arexpr));
|
|
case TFOR:
|
|
if(sfputu(outfile,t->for_.forline)<0)
|
|
return(-1);
|
|
if(p_tree(t->for_.fortre)<0)
|
|
return(-1);
|
|
if(p_string(t->for_.fornam)<0)
|
|
return(-1);
|
|
return(p_tree((Shnode_t*)t->for_.forlst));
|
|
case TSW:
|
|
if(sfputu(outfile,t->sw.swline)<0)
|
|
return(-1);
|
|
if(p_arg(t->sw.swarg)<0)
|
|
return(-1);
|
|
return(p_switch(t->sw.swlst));
|
|
case TFUN:
|
|
if(sfputu(outfile,t->funct.functline)<0)
|
|
return(-1);
|
|
if(p_string(t->funct.functnam)<0)
|
|
return(-1);
|
|
if(p_tree(t->funct.functtre)<0)
|
|
return(-1);
|
|
return(p_tree((Shnode_t*)t->funct.functargs));
|
|
case TTST:
|
|
if(sfputu(outfile,t->tst.tstline)<0)
|
|
return(-1);
|
|
if((t->tre.tretyp&TPAREN)==TPAREN)
|
|
return(p_tree(t->lst.lstlef));
|
|
else
|
|
{
|
|
if(p_arg(&(t->lst.lstlef->arg))<0)
|
|
return(-1);
|
|
if((t->tre.tretyp&TBINARY))
|
|
return(p_arg(&(t->lst.lstrit->arg)));
|
|
return(0);
|
|
}
|
|
}
|
|
return(-1);
|
|
}
|
|
|
|
static int p_arg(register const struct argnod *arg)
|
|
{
|
|
register int n;
|
|
struct fornod *fp;
|
|
while(arg)
|
|
{
|
|
if((n = strlen(arg->argval)) || (arg->argflag&~(ARG_APPEND|ARG_MESSAGE|ARG_QUOTED)))
|
|
fp=0;
|
|
else
|
|
{
|
|
fp=(struct fornod*)arg->argchn.ap;
|
|
n = strlen(fp->fornam)+1;
|
|
}
|
|
sfputu(outfile,n+1);
|
|
if(fp)
|
|
{
|
|
sfputc(outfile,0);
|
|
outstring(outfile,fp->fornam,n-1);
|
|
}
|
|
else
|
|
outstring(outfile,arg->argval,n);
|
|
sfputc(outfile,arg->argflag);
|
|
if(fp)
|
|
{
|
|
sfputu(outfile,fp->fortyp);
|
|
p_tree(fp->fortre);
|
|
}
|
|
else if(n==0 && (arg->argflag&ARG_EXP) && arg->argchn.ap)
|
|
p_tree((Shnode_t*)arg->argchn.ap);
|
|
arg = arg->argnxt.ap;
|
|
}
|
|
return(sfputu(outfile,0));
|
|
}
|
|
|
|
static int p_redirect(register const struct ionod *iop)
|
|
{
|
|
while(iop)
|
|
{
|
|
if(iop->iovname)
|
|
sfputl(outfile,iop->iofile|IOVNM);
|
|
else
|
|
sfputl(outfile,iop->iofile);
|
|
if((iop->iofile & IOPROCSUB) && !(iop->iofile & IOLSEEK))
|
|
p_tree((Shnode_t*)iop->ioname); /* process substitution as file name to redirection */
|
|
else
|
|
p_string(iop->ioname); /* file name, descriptor, etc. */
|
|
if(iop->iodelim)
|
|
{
|
|
p_string(iop->iodelim);
|
|
sfputl(outfile,iop->iosize);
|
|
sfseek(sh.heredocs,iop->iooffset,SEEK_SET);
|
|
sfmove(sh.heredocs,outfile, iop->iosize,-1);
|
|
}
|
|
else
|
|
sfputu(outfile,0);
|
|
if(iop->iovname)
|
|
p_string(iop->iovname);
|
|
iop = iop->ionxt;
|
|
}
|
|
return(sfputl(outfile,-1));
|
|
}
|
|
|
|
static int p_comarg(register const struct comnod *com)
|
|
{
|
|
p_redirect(com->comio);
|
|
p_arg(com->comset);
|
|
if(!com->comarg)
|
|
sfputl(outfile,-1);
|
|
else if(com->comtyp&COMSCAN)
|
|
p_arg(com->comarg);
|
|
else
|
|
p_comlist((struct dolnod*)com->comarg);
|
|
return(sfputu(outfile,com->comline));
|
|
}
|
|
|
|
static int p_comlist(const struct dolnod *dol)
|
|
{
|
|
register char *cp, *const*argv;
|
|
register int n;
|
|
argv = dol->dolval+ARG_SPARE;
|
|
while(cp = *argv)
|
|
argv++;
|
|
n = argv - (dol->dolval+1);
|
|
sfputl(outfile,n);
|
|
argv = dol->dolval+ARG_SPARE;
|
|
while(cp = *argv++)
|
|
p_string(cp);
|
|
return(sfputu(outfile,0));
|
|
}
|
|
|
|
static int p_switch(register const struct regnod *reg)
|
|
{
|
|
while(reg)
|
|
{
|
|
sfputl(outfile,reg->regflag);
|
|
p_arg(reg->regptr);
|
|
p_tree(reg->regcom);
|
|
reg = reg->regnxt;
|
|
}
|
|
return(sfputl(outfile,-1));
|
|
}
|
|
|
|
static int p_string(register const char *string)
|
|
{
|
|
register size_t n=strlen(string);
|
|
if(sfputu(outfile,n+1)<0)
|
|
return(-1);
|
|
return(outstring(outfile,string,n));
|
|
}
|