da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/***********************************************************************
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* This software is part of the ast package *
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner* Copyright (c) 1982-2010 AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* and is licensed under the *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Common Public License, Version 1.0 *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* by AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* A copy of the License is available at *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* http://www.opensource.org/licenses/cpl1.0.txt *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Information and Software Systems Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* AT&T Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Florham Park NJ *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* David Korn <dgk@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin***********************************************************************/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#pragma prototyped
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Shell macro expander
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * expands ~
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * expands ${...}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * expands $(...)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * expands $((...))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * expands `...`
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * David Korn
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * AT&T Labs
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "defs.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <fcin.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <pwd.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "name.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "variables.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "shlex.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "io.h"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#include "jobs.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "shnodes.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "path.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "national.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "streval.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#undef STR_GROUP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifndef STR_GROUP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define STR_GROUP 0
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if !SHOPT_MULTIBYTE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define mbchar(p) (*(unsigned char*)p++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int _c_;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chintypedef struct _mac_
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Shell_t *shp; /* pointer to shell interpreter */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfio_t *sp; /* stream pointer for here-document */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct argnod **arghead; /* address of head of argument list */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *ifsp; /* pointer to IFS value */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int fields; /* number of fields */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin short quoted; /* set when word has quotes */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned char ifs; /* first char of IFS */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char quote; /* set within double quoted contexts */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char lit; /* set within single quotes */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char split; /* set when word splittin is possible */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char pattern; /* set when file expansion follows */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char patfound; /* set if pattern character found */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char assign; /* set for assignments */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char arith; /* set for ((...)) */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char let; /* set when expanding let arguments */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char zeros; /* strip leading zeros when set */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin char arrayok; /* $x[] ok for arrays */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin char subcopy; /* set when copying subscript */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int dotdot; /* set for .. in subscript */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin void *nvwalk; /* for name space walking*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin} Mac_t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#undef ESCAPE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define ESCAPE '\\'
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define isescchar(s) ((s)>S_QUOTE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define isqescchar(s) ((s)>=S_QUOTE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define isbracechar(c) ((c)==RBRACE || (_c_=sh_lexstates[ST_BRACE][c])==S_MOD1 ||_c_==S_MOD2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define ltos(x) fmtbase((long)(x),0,0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/* type of macro expansions */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define M_BRACE 1 /* ${var} */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define M_TREE 2 /* ${var.} */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define M_SIZE 3 /* ${#var} */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define M_VNAME 4 /* ${!var} */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define M_SUBNAME 5 /* ${!var[sub]} */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define M_NAMESCAN 6 /* ${!var*} */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define M_NAMECOUNT 7 /* ${#var*} */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define M_TYPE 8 /* ${@var} */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int substring(const char*, const char*, int[], int);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void copyto(Mac_t*, int, int);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic void comsubst(Mac_t*, Shnode_t*, int);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int varsub(Mac_t*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void mac_copy(Mac_t*,const char*, int);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic void tilde_expand2(Shell_t*,int);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic char *sh_tilde(Shell_t*,const char*);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic char *special(Shell_t *,int);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void endfield(Mac_t*,int);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void mac_error(Namval_t*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char *mac_getstring(char*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int charlen(const char*,int);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_MULTIBYTE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static char *lastchar(const char*,const char*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_MULTIBYTE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid *sh_macopen(Shell_t *shp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin void *addr = newof(0,Mac_t,1,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Mac_t *mp = (Mac_t*)addr;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->shp = shp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(addr);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * perform only parameter substitution and catch failures
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinchar *sh_mactry(Shell_t *shp,register char *string)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(string)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int jmp_val;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int savexit = shp->savexit;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct checkpt buff;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_pushcontext(&buff,SH_JMPSUB);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin jmp_val = sigsetjmp(buff.buff,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(jmp_val == 0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin string = sh_mactrim(shp,string,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_popcontext(&buff);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->savexit = savexit;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(string);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return("");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Perform parameter expansion, command substitution, and arithmetic
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * expansion on <str>.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If <mode> greater than 1 file expansion is performed if the result
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * yields a single pathname.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If <mode> negative, than expansion rules for assignment are applied.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinchar *sh_mactrim(Shell_t *shp, char *str, register int mode)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register Mac_t *mp = (Mac_t*)shp->mac_context;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Stk_t *stkp = shp->stk;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Mac_t savemac;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin savemac = *mp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin stkseek(stkp,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->arith = (mode==3);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->let = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->argaddr = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->pattern = (mode==1||mode==2);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->patfound = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin mp->assign = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(mode<0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin mp->assign = -mode;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->quoted = mp->lit = mp->split = mp->quote = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->sp = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(mp->ifsp=nv_getval(sh_scoped(shp,IFSNOD)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->ifs = *mp->ifsp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->ifs = ' ';
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin stkseek(stkp,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcsopen(str);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin copyto(mp,0,mp->arith);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin str = stkfreeze(stkp,1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode==2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* expand only if unique */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct argnod *arglist=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((mode=path_expand(str,&arglist))==1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin str = arglist->argval;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(mode>1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_exit(1),e_ambiguous,str);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_trim(str);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *mp = savemac;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(str);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Perform all the expansions on the argument <argp>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinint sh_macexpand(Shell_t* shp, register struct argnod *argp, struct argnod **arghead,int flag)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register int flags = argp->argflag;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register char *str = argp->argval;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register Mac_t *mp = (Mac_t*)shp->mac_context;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin char **saveargaddr = shp->argaddr;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Mac_t savemac;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Stk_t *stkp = shp->stk;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin savemac = *mp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->sp = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(mp->ifsp=nv_getval(sh_scoped(shp,IFSNOD)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->ifs = *mp->ifsp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->ifs = ' ';
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((flag&ARG_OPTIMIZE) && !shp->indebug)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->argaddr = (char**)&argp->argchn.ap;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->argaddr = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->arghead = arghead;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->quoted = mp->lit = mp->quote = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->arith = ((flag&ARG_ARITH)!=0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->let = ((flag&ARG_LET)!=0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->split = !(flag&ARG_ASSIGN);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->assign = !mp->split;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->pattern = mp->split && !(flag&ARG_NOGLOB) && !sh_isoption(SH_NOGLOB);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin mp->arrayok = mp->arith || (flag&ARG_ARRAYOK);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin str = argp->argval;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcsopen(str);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->fields = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!arghead)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->split = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->pattern = ((flag&ARG_EXP)!=0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin stkseek(stkp,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin stkseek(stkp,ARGVAL);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin *stkptr(stkp,ARGVAL-1) = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->patfound = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(mp->pattern)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin mp->arrayok = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin copyto(mp,0,mp->arith);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!arghead)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin argp->argchn.cp = stkfreeze(stkp,1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->argaddr)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argp->argflag |= ARG_MAKE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin endfield(mp,mp->quoted);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flags = mp->fields;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(flags==1 && shp->argaddr)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argp->argchn.ap = *arghead;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->argaddr = saveargaddr;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *mp = savemac;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(flags);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Expand here document which is stored in <infile> or <string>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * The result is written to <outfile>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinvoid sh_machere(Shell_t *shp,Sfio_t *infile, Sfio_t *outfile, char *string)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c,n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register const char *state = sh_lexstates[ST_QUOTE];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *cp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register Mac_t *mp = (Mac_t*)shp->mac_context;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Lex_t *lp = (Lex_t*)mp->shp->lex_context;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Fcin_t save;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Mac_t savemac;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Stk_t *stkp = shp->stk;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin savemac = *mp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin stkseek(stkp,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->argaddr = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->sp = outfile;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->split = mp->assign = mp->pattern = mp->patfound = mp->lit = mp->arith = mp->let = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->quote = 1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin mp->ifsp = nv_getval(sh_scoped(shp,IFSNOD));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->ifs = ' ';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcsave(&save);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(infile)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcfopen(infile);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcsopen(string);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin fcnotify(0,lp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = fcseek(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_MULTIBYTE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mbwide())
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin do
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ssize_t len;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch(len = mbsize(cp))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case -1: /* illegal multi-byte char */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 0:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 1:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n=state[*(unsigned char*)cp++];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* use state of alpha character */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n=state['a'];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp += len;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(n == 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_MULTIBYTE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while((n=state[*(unsigned char*)cp++])==0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n==S_NL || n==S_QUOTE || n==S_RBRA)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c=(cp-1)-fcseek(0))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfwrite(outfile,fcseek(0),c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = fcseek(c+1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch(n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_EOF:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((n=fcfill()) <=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* ignore 0 byte when reading from file */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n==0 && fcfile())
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcrestore(&save);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *mp = savemac;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = fcseek(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_ESC:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcgetc(c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp=fcseek(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!isescchar(state[c]))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputc(outfile,ESCAPE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_GRAVE:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin comsubst(mp,(Shnode_t*)0,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_DOL:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = fcget();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c=='.')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto regular;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin again:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch(n=sh_lexstates[ST_DOL][c])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_ALP: case S_SPC1: case S_SPC2:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_DIG: case S_LBRA:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Fcin_t save2;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int offset = stktell(stkp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int offset2;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfputc(stkp,c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n==S_LBRA)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin c = fcget();
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin fcseek(-1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(sh_lexstates[ST_NORM][c]==S_BREAK)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin comsubst(mp,(Shnode_t*)0,2);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin break;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_lexskip(lp,RBRACE,1,ST_BRACE);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(n==S_ALP)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(fcgetc(c),isaname(c))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfputc(stkp,c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcseek(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfputc(stkp,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin offset2 = stktell(stkp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcsave(&save2);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin fcsopen(stkptr(stkp,offset));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin varsub(mp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(c=stktell(stkp)-offset2)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfwrite(outfile,(char*)stkptr(stkp,offset2),c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcrestore(&save2);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin stkseek(stkp,offset);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_PAR:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin comsubst(mp,(Shnode_t*)0,1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_EOF:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((c=fcfill()) > 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto again;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* FALL THRU */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin regular:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputc(outfile,'$');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcseek(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = fcseek(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * expand argument but do not trim pattern characters
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinchar *sh_macpat(Shell_t *shp,register struct argnod *arg, int flags)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *sp = arg->argval;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((arg->argflag&ARG_RAW))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(sp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_stats(STAT_ARGEXPAND);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flags&ARG_OPTIMIZE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin arg->argchn.ap=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(sp=arg->argchn.cp))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_macexpand(shp,arg,NIL(struct argnod**),flags|ARG_ARRAYOK);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sp = arg->argchn.cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(flags&ARG_OPTIMIZE) || !(arg->argflag&ARG_MAKE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin arg->argchn.cp = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin arg->argflag &= ~ARG_MAKE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_stats(STAT_ARGHITS);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(sp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Process the characters up to <endch> or end of input string
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void copyto(register Mac_t *mp,int endch, int newquote)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c,n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register const char *state = sh_lexstates[ST_MACRO];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *cp,*first;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Lex_t *lp = (Lex_t*)mp->shp->lex_context;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int tilde = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int oldquote = mp->quote;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int ansi_c = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int paren = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int ere = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int brace = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfio_t *sp = mp->sp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Stk_t *stkp = mp->shp->stk;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->sp = NIL(Sfio_t*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->quote = newquote;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin first = cp = fcseek(0);
9a6f360e750e0b14fc9b9bf8347e0ebad3959e3fCasper H.S. Dik if(!mp->quote && *cp=='~' && cp[1]!=LPAREN)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin tilde = stktell(stkp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* handle // operator specially */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mp->pattern==2 && *cp=='/')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_MULTIBYTE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mbwide())
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ssize_t len;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin do
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch(len = mbsize(cp))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case -1: /* illegal multi-byte char */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 0:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin len = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 1:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = state[*(unsigned char*)cp++];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* treat as if alpha */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp += len;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n=state['a'];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(n == 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = (cp-len) - first;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_MULTIBYTE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while((n=state[*(unsigned char*)cp++])==0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = (cp-1) - first;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch(n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_ESC:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ansi_c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* process ANSI-C escape character */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *addr= --cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfwrite(stkp,first,c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = chresc(cp,&addr);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = addr;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin first = fcseek(cp-first);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_MULTIBYTE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c > UCHAR_MAX && mbwide())
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int i;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned char mb[8];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = wctomb((char*)mb, c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(i=0;i<n;i++)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfputc(stkp,mb[i]);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_MULTIBYTE */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfputc(stkp,c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c==ESCAPE && mp->pattern)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfputc(stkp,ESCAPE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(sh_isoption(SH_BRACEEXPAND) && mp->pattern==4 && (*cp==',' || *cp==LBRACE || *cp==RBRACE || *cp=='.'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(mp->split && endch && !mp->quote && !mp->lit)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mac_copy(mp,first,c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = fcseek(c+2);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c= cp[-1])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfputc(stkp,c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c==ESCAPE)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfputc(stkp,ESCAPE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin first = cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = state[*(unsigned char*)cp];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n==S_ENDCH && *cp!=endch)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = S_PAT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mp->pattern)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* preserve \digit for pattern matching */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* also \alpha for extended patterns */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(!mp->lit && !mp->quote)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if((n==S_DIG || ((paren+ere) && sh_lexstates[ST_DOL][*(unsigned char*)cp]==S_ALP)))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz break;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(ere && mp->pattern==1 && strchr(".[()*+?{|^$&!",*cp))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz break;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* followed by file expansion */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!mp->lit && (n==S_ESC || (!mp->quote &&
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (n==S_PAT||n==S_ENDCH||n==S_SLASH||n==S_BRACT||*cp=='-'))))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp += (n!=S_EOF);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(ere && n==S_ESC && *cp =='\\' && cp[1]=='$')
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* convert \\\$ into \$' */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfwrite(stkp,first,c+1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin cp = first = fcseek(c+3);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!(ere && *cp=='$') && (mp->lit || (mp->quote && !isqescchar(n) && n!=S_ENDCH)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* add \ for file expansion */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfwrite(stkp,first,c+1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin first = fcseek(c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mp->lit)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!mp->quote || isqescchar(n) || n==S_ENDCH)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* eliminate \ */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfwrite(stkp,first,c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* check new-line joining */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin first = fcseek(c+1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp += (n!=S_EOF);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_GRAVE: case S_DOL:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mp->lit)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mp->split && !mp->quote && endch)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mac_copy(mp,first,c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfwrite(stkp,first,c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin first = fcseek(c+1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = mp->pattern;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n==S_GRAVE)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin comsubst(mp,(Shnode_t*)0,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if((n= *cp)==0 || !varsub(mp))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n=='\'' && !mp->quote)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ansi_c = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(mp->quote || n!='"')
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfputc(stkp,'$');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = first = fcseek(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*cp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->pattern = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_ENDCH:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((mp->lit || cp[-1]!=endch || mp->quote!=newquote))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto pattern;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(endch==RBRACE && *cp==LPAREN && mp->pattern && brace)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto pattern;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_EOF:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mp->split && !mp->quote && !mp->lit && endch)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mac_copy(mp,first,c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfwrite(stkp,first,c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c += (n!=S_EOF);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin first = fcseek(c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(tilde>=0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin tilde_expand2(mp->shp,tilde);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto done;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_QUOTE:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mp->lit || mp->arith)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_LIT:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mp->arith)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((*cp=='`' || *cp=='[') && cp[1]=='\'')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp +=2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n==S_LIT && mp->quote)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mp->split && endch && !mp->quote && !mp->lit)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mac_copy(mp,first,c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfwrite(stkp,first,c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin first = fcseek(c+1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n==S_LIT)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mp->quote)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mp->lit)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->lit = ansi_c = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->lit = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->quote = !mp->quote;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->quoted++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_BRACT:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(mp->arith || (((mp->assign&1) || endch==RBRACT) &&
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin !(mp->quote || mp->lit)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int offset=0,oldpat = mp->pattern;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int oldarith = mp->arith, oldsub=mp->subcopy;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfwrite(stkp,first,++c);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(mp->assign&1)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(first[c-2]=='.')
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz offset = stktell(stkp);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(isastchar(*cp) && cp[1]==']')
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz errormsg(SH_DICT,ERROR_exit(1),
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainze_badsubscript,*cp);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin first = fcseek(c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->pattern = 4;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->arith = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin mp->subcopy = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin copyto(mp,RBRACT,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin mp->subcopy = oldsub;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->arith = oldarith;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->pattern = oldpat;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfputc(stkp,RBRACT);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(offset)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin cp = stkptr(stkp,stktell(stkp));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(sh_checkid(stkptr(stkp,offset),cp)!=cp)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin stkseek(stkp,stktell(stkp)-2);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = first = fcseek(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_PAT:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mp->pattern && !(mp->quote || mp->lit))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->patfound = mp->pattern;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((n=cp[-1])==LPAREN)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin paren++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((cp-first)>1 && cp[-2]=='~')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *p = cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while((c=mbchar(p)) && c!=RPAREN && c!='E');
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz ere = (c=='E'||c=='A');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(n==RPAREN)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin --paren;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto pattern;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin case S_COM:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(mp->pattern==4 && (mp->quote || mp->lit))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(c)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfwrite(stkp,first,c);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin first = fcseek(c);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfputc(stkp,ESCAPE);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_BRACE:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(mp->quote || mp->lit))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->patfound = mp->split && sh_isoption(SH_BRACEEXPAND);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin brace = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pattern:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!mp->pattern || !(mp->quote || mp->lit))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* mark beginning of {a,b} */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n==S_BRACE && endch==0 && mp->pattern)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->pattern=4;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n==S_SLASH && mp->pattern==2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->pattern=3;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mp->pattern==3)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfwrite(stkp,first,c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin first = fcseek(c);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfputc(stkp,ESCAPE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_EQ:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mp->assign==1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*cp=='~' && !endch && !mp->quote && !mp->lit)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin tilde = stktell(stkp)+(c+1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->assign = 2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_SLASH:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_COLON:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(tilde >=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfwrite(stkp,first,c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin first = fcseek(c);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin tilde_expand2(mp->shp,tilde);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tilde = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n==S_COLON && mp->assign==2 && *cp=='~' && endch==0 && !mp->quote &&!mp->lit)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin tilde = stktell(stkp)+(c+1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(n==S_SLASH && mp->pattern==2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if 0
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto pattern;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mp->quote || mp->lit)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto pattern;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfwrite(stkp,first,c+1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin first = fcseek(c+1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin c = stktell(stkp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_lexskip(lp,RBRACE,0,ST_NESTED);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin stkseek(stkp,c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = fcseek(-1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfwrite(stkp,first,cp-first);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin first=cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin case S_DOT:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(*cp=='.' && mp->subcopy==1)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfwrite(stkp,first,c);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfputc(stkp,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin mp->dotdot = stktell(stkp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin cp = first = fcseek(c+2);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chindone:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->sp = sp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->quote = oldquote;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * copy <str> to stack performing sub-expression substitutions
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void mac_substitute(Mac_t *mp, register char *cp,char *str,register int subexp[],int subsize)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register int c,n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *first=fcseek(0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin char *ptr;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Mac_t savemac;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Stk_t *stkp = mp->shp->stk;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin n = stktell(stkp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin savemac = *mp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->pattern = 3;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->split = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcsopen(cp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin copyto(mp,0,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfputc(stkp,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ptr = cp = strdup(stkptr(stkp,n));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin stkseek(stkp,n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *mp = savemac;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcsopen(first);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin first = cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while((c= *cp++) && c!=ESCAPE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((n= *cp++)=='\\' || n==RBRACE || (n>='0' && n<='9' && (n-='0')<subsize))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = cp-first-2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mac_copy(mp,first,c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin first=cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n=='\\' || n==RBRACE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin first--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((c=subexp[2*n])>=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((n=subexp[2*n+1]-c)>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mac_copy(mp,str+c,n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(n==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n=cp-first-1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mac_copy(mp,first,n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free(ptr);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_FILESCAN
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define MAX_OFFSETS (sizeof(shp->offsets)/sizeof(shp->offsets[0]))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define MAX_ARGN (32*1024)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * compute the arguments $1 ... $n and $# from the current line as needed
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * save line offsets in the offsets array.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char *getdolarg(Shell_t *shp, int n, int *size)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c=S_DELIM, d=shp->ifstable['\\'];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register unsigned char *first,*last,*cp = (unsigned char*)shp->cur_line;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int m=shp->offsets[0],delim=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(m==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(m<0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin m = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(n<=m)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin m = n-1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin m--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(m >= MAX_OFFSETS-1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin m = MAX_OFFSETS-2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp += shp->offsets[m+1];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n -= m;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin shp->ifstable['\\'] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin shp->ifstable[0] = S_EOF;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c==S_DELIM)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(shp->ifstable[*cp++]==S_SPACE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin first = --cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(++m < MAX_OFFSETS)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin shp->offsets[m] = (first-(unsigned char*)shp->cur_line);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while((c=shp->ifstable[*cp++])==0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin last = cp-1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c==S_SPACE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while((c=shp->ifstable[*cp++])==S_SPACE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(--n==0 || c==S_EOF)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(last==first && c==S_EOF && (!delim || (m>1)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin m--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin delim = (c==S_DELIM);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin shp->ifstable['\\'] = d;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(m > shp->offsets[0])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin shp->offsets[0] = m;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin first = last = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(size)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *size = last-first;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return((char*)first);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_FILESCAN */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * get the prefix after name reference resolution
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic char *prefix(Shell_t *shp, char *id)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Namval_t *np;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz register char *sub=0, *cp = strchr(id,'.');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(cp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *cp = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin np = nv_search(id, shp->var_tree,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *cp = '.';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(isastchar(cp[1]))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp[1] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(np && nv_isref(np))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *sp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->argaddr = 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz while(nv_isref(np) && np->nvalue.cp)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sub = nv_refsub(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np = nv_refnode(np);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(sub)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz nv_putsub(np,sub,0L);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz id = (char*)malloc(strlen(cp)+1+(n=strlen(sp=nv_name(np)))+ (sub?strlen(sub)+3:1));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memcpy(id,sp,n);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(sub)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz id[n++] = '[';
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz strcpy(&id[n],sub);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz n+= strlen(sub)+1;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz id[n-1] = ']';
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz strcpy(&id[n],cp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(id);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(strdup(id));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * copy to ']' onto the stack and return offset to it
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int subcopy(Mac_t *mp, int flag)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int split = mp->split;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int xpattern = mp->pattern;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int loc = stktell(mp->shp->stk);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int xarith = mp->arith;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int arrayok = mp->arrayok;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->split = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->arith = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->pattern = flag?4:0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin mp->arrayok=1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin mp->subcopy++;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin mp->dotdot = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin copyto(mp,RBRACT,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin mp->subcopy = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->pattern = xpattern;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->split = split;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->arith = xarith;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin mp->arrayok = arrayok;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(loc);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin/*
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * if name is a discipline function, run the function and put the results
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * on the stack so that ${x.foo} behaves like ${ x.foo;}
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinint sh_macfun(Shell_t *shp, const char *name, int offset)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Namval_t *np, *nq;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin np = nv_bfsearch(name,shp->fun_tree,&nq,(char**)0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(np)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* treat ${x.foo} as ${x.foo;} */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Shnode_t *tp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin char buff[sizeof(struct dolnod)+sizeof(char*)];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin struct comnod node;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin struct dolnod *dp = (struct dolnod*)buff;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin memset(&node,0,sizeof(node));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin memset(&buff,0,sizeof(buff));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin tp = (Shnode_t*)&node;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin tp->com.comarg = (struct argnod*)dp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin tp->com.comline = shp->inlineno;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz dp->dolnum = 1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin dp->dolval[0] = strdup(name);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin stkseek(shp->stk,offset);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin comsubst((Mac_t*)shp->mac_context,tp,2);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin free(dp->dolval[0]);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin}
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int namecount(Mac_t *mp,const char *prefix)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int count = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin mp->nvwalk = nv_diropen((Namval_t*)0,prefix);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(nv_dirnext(mp->nvwalk))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin count++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_dirclose(mp->nvwalk);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(count);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char *nextname(Mac_t *mp,const char *prefix, int len)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(len==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin mp->nvwalk = nv_diropen((Namval_t*)0,prefix);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return((char*)mp->nvwalk);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(cp=nv_dirnext(mp->nvwalk)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_dirclose(mp->nvwalk);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(cp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * This routine handles $param, ${parm}, and ${param op word}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * The input stream is assumed to be a string
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int varsub(Mac_t *mp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int type=0; /* M_xxx */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *v,*argp=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Namval_t *np = NIL(Namval_t*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int dolg=0, mode=0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Lex_t *lp = (Lex_t*)mp->shp->lex_context;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Namarr_t *ap=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int dolmax=0, vsize= -1, offset= -1, nulflg, replen=0, bysub=0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin char idbuff[3], *id = idbuff, *pattern=0, *repstr, *arrmax=0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz int var=1,addsub=0,oldpat=mp->pattern,idnum=0,flag=0,d;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Stk_t *stkp = mp->shp->stk;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinretry1:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->zeros = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin idbuff[0] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin idbuff[1] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = fcget();
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz switch(isascii(c)?sh_lexstates[ST_DOL][c]:S_ALP)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_RBRA:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(type<M_SIZE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto nosub;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* This code handles ${#} */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = mode;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mode = type = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* FALL THRU */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_SPC1:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(type==M_BRACE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(isaletter(mode=fcpeek(0)) || mode=='.')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c=='#')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin type = M_SIZE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef SHOPT_TYPEDEF
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(c=='@')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin type = M_TYPE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto retry1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_TYPEDEF */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin type = M_VNAME;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mode = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto retry1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(c=='#' && (isadigit(mode)||fcpeek(1)==RBRACE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin type = M_SIZE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mode = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto retry1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* FALL THRU */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_SPC2:
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz var = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *id = c;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin v = special(mp->shp,c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(isastchar(c))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mode = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_FILESCAN
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(mp->shp->cur_line)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin v = getdolarg(&sh,1,(int*)0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dolmax = MAX_ARGN;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_FILESCAN */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin dolmax = mp->shp->st.dolc+1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dolg = (v!=0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_LBRA:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(type)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto nosub;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin type = M_BRACE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto retry1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_PAR:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(type)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto nosub;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin comsubst(mp,(Shnode_t*)0,1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_DIG:
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz var = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c -= '0';
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin mp->shp->argaddr = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(type)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int d;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while((d=fcget()),isadigit(d))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = 10*c + (d-'0');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcseek(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin idnum = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c==0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin v = special(mp->shp,c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_FILESCAN
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(mp->shp->cur_line)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin mp->shp->used_pos = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin v = getdolarg(&sh,c,&vsize);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_FILESCAN */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(c <= mp->shp->st.dolc)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin mp->shp->used_pos = 1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin v = mp->shp->st.dolv[c];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin v = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_ALP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c=='.' && type==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto nosub;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin offset = stktell(stkp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin do
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin do
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfputc(stkp,c);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz while(((c=fcget()),(!isascii(c)||isaname(c)))||type && c=='.');
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin while(c==LBRACT && (type||mp->arrayok))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin mp->shp->argaddr=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((c=fcget(),isastchar(c)) && fcpeek(0)==RBRACT)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(type==M_VNAME)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin type = M_SUBNAME;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin idbuff[0] = mode = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcget();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = fcget();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c=='.' || c==LBRACT)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfputc(stkp,LBRACT);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfputc(stkp,mode);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfputc(stkp,RBRACT);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flag = NV_ARRAY;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcseek(-1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin c = stktell(stkp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfputc(stkp,LBRACT);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin v = stkptr(stkp,subcopy(mp,1));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(type && mp->dotdot)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin mode = '@';
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin v[-1] = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(type==M_VNAME)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin type = M_SUBNAME;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(type==M_SIZE)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin goto nosub;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfputc(stkp,RBRACT);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = fcget();
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(c==0 && type==M_VNAME)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin type = M_SUBNAME;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(type && c=='.');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c==RBRACE && type && fcpeek(-2)=='.')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* ${x.} or ${x..} */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(fcpeek(-3) == '.')
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin stkseek(stkp,stktell(stkp)-2);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_local = 1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin stkseek(stkp,stktell(stkp)-1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin type = M_TREE;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfputc(stkp,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin id=stkptr(stkp,offset);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(isastchar(c) && type)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(type==M_VNAME || type==M_SIZE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin idbuff[0] = mode = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((d=fcpeek(0))==c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin idbuff[1] = fcget();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(type==M_VNAME)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin type = M_NAMESCAN;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin type = M_NAMECOUNT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto nosub;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flag |= NV_NOASSIGN|NV_VARNAME|NV_NOADD;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c=='=' || c=='?' || (c==':' && ((d=fcpeek(0))=='=' || d=='?')))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flag &= ~NV_NOADD;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_FILESCAN
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(mp->shp->cur_line && *id=='R' && strcmp(id,"REPLY")==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin mp->shp->argaddr=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np = REPLYNOD;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_FILESCAN */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(mp->shp->argaddr)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz flag &= ~NV_NOADD;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz np = nv_open(id,mp->shp->var_tree,flag|NV_NOFAIL);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(isastchar(mode))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz var = 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if((!np || nv_isnull(np)) && type==M_BRACE && c==RBRACE && !(flag&NV_ARRAY) && strchr(id,'.'))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(sh_macfun(mp->shp,id,offset))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin fcget();
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(np && (flag&NV_NOADD) && nv_isnull(np))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(nv_isattr(np,NV_NOFREE))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz nv_offattr(np,NV_NOFREE);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz np = 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ap = np?nv_arrayptr(np):0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(type)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(mp->dotdot)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(ap)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_putsub(np,v,ARRAY_SCAN);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin v = stkptr(stkp,mp->dotdot);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin dolmax =1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(array_assoc(ap))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin arrmax = strdup(v);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if((dolmax = (int)sh_arith(v))<0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin dolmax += array_maxindex(np);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(type==M_SUBNAME)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin bysub = 1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((int)sh_arith(v))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin np = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(ap && (isastchar(mode)||type==M_TREE) && !(ap->nelem&ARRAY_SCAN) && type!=M_SIZE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_putsub(np,NIL(char*),ARRAY_SCAN);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!isbracechar(c))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto nosub;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcseek(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcseek(-1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(type<=1 && np && nv_isvtree(np) && mp->pattern==1 && !mp->split)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int peek=1,cc=fcget();
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(type && cc=='}')
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin cc = fcget();
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin peek = 2;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(mp->quote && cc=='"')
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin cc = fcget();
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin peek++;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin fcseek(-peek);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(cc==0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin mp->assign = 1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((type==M_VNAME||type==M_SUBNAME) && mp->shp->argaddr && strcmp(nv_name(np),id))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin mp->shp->argaddr = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = (type>M_BRACE && isastchar(mode));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(np && (type==M_TREE || !c || !ap))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin char *savptr;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin c = *((unsigned char*)stkptr(stkp,offset-1));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin savptr = stkfreeze(stkp,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(type==M_VNAME || (type==M_SUBNAME && ap))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin type = M_BRACE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin v = nv_name(np);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(ap && !mp->dotdot && !(ap->nelem&ARRAY_UNDEF))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin addsub = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef SHOPT_TYPEDEF
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(type==M_TYPE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Namval_t *nq = nv_type(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin type = M_BRACE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nq)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_typename(nq,mp->shp->strbuf);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_attribute(np,mp->shp->strbuf,"typeset",1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin v = sfstruse(mp->shp->strbuf);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_TYPEDEF */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_FILESCAN
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(mp->shp->cur_line && np==REPLYNOD)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin v = mp->shp->cur_line;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_FILESCAN */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(type==M_TREE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin v = nv_getvtree(np,(Namfun_t*)0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(type && fcpeek(0)=='+')
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(ap)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz v = nv_arrayisset(np,ap)?(char*)"x":0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz v = nv_isnull(np)?0:(char*)"x";
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz v = nv_getval(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* special case --- ignore leading zeros */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if( (mp->arith||mp->let) && (np->nvfun || nv_isattr(np,(NV_LJUST|NV_RJUST|NV_ZFILL))) && (offset==0 || !isalnum(c)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->zeros = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(savptr==stakptr(0))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin stkseek(stkp,offset);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin stkset(stkp,savptr,offset);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin v = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(type==M_VNAME)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin v = id;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin type = M_BRACE;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(type==M_TYPE)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin type = M_BRACE;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin stkseek(stkp,offset);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ap)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_OPTIMIZE
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(mp->shp->argaddr)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_optimize(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(isastchar(mode) && array_elem(ap)> !c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dolg = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dolg = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_EOF:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcseek(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto nosub;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = fcget();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(type>M_TREE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c!=RBRACE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mac_error(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(type==M_NAMESCAN || type==M_NAMECOUNT)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz mp->shp->last_root = mp->shp->var_tree;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin id = prefix(mp->shp,id);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin stkseek(stkp,offset);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(type==M_NAMECOUNT)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = namecount(mp,id);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin v = ltos(c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dolmax = strlen(id);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dolg = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nextname(mp,id,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin v = nextname(mp,id,dolmax);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(type==M_SUBNAME)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(dolg<0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin v = nv_getsub(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin bysub=1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(v)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!ap || isastchar(mode))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin v = "0";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin v = nv_getsub(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!isastchar(mode))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = charlen(v,vsize);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(dolg>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_FILESCAN
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(mp->shp->cur_line)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin getdolarg(&sh,MAX_ARGN,(int*)0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin c = mp->shp->offsets[0];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_FILESCAN */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin c = mp->shp->st.dolc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(dolg<0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = array_elem(ap);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = (v!=0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dolg = dolmax = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin v = ltos(c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = RBRACE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nulflg = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(type && c==':')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = fcget();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh_lexstates[ST_BRACE][c]==S_MOD1 && c!='*' && c!= ':')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nulflg=1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(c!='%' && c!='#')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcseek(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = ':';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(type)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!isbracechar(c))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!nulflg)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mac_error(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcseek(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = ':';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c!=RBRACE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int newops = (c=='#' || c == '%' || c=='/');
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin offset = stktell(stkp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c=='/' ||c==':' || ((!v || (nulflg && *v==0)) ^ (c=='+'||c=='#'||c=='%')))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int newquote = mp->quote;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int split = mp->split;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int quoted = mp->quoted;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int arith = mp->arith;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int zeros = mp->zeros;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz int assign = mp->assign;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(newops)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin type = fcget();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(type=='%' || type=='#')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int d = fcget();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcseek(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(d=='(')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin type = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcseek(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->pattern = 1+(c=='/');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->split = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->quoted = 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz mp->assign &= ~1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->arith = mp->zeros = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin newquote = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(c=='?' || c=='=')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->split = mp->pattern = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin copyto(mp,RBRACE,newquote);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!oldpat)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->patfound = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->pattern = oldpat;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->split = split;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->quoted = quoted;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->arith = arith;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->zeros = zeros;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz mp->assign = assign;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* add null byte */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfputc(stkp,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin stkseek(stkp,stktell(stkp)-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_lexskip(lp,RBRACE,0,(!newops&&mp->quote)?ST_QUOTE:ST_NESTED);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin stkseek(stkp,offset);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin argp=stkptr(stkp,offset);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcseek(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c==':') /* ${name:expr1[:expr2]} */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *ptr;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin type = (int)sh_strnum(argp,&ptr,1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(isastchar(mode))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(id==idbuff) /* ${@} or ${*} */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(type<0 && (type+= dolmax)<0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin type = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(type==0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin v = special(mp->shp,dolg=0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_FILESCAN
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(mp->shp->cur_line)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin v = getdolarg(&sh,dolg=type,&vsize);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!v)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dolmax = type;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_FILESCAN */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(type < dolmax)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin v = mp->shp->st.dolv[dolg=type];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin v = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(ap)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(type<0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(array_assoc(ap))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin type = -type;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin type += array_maxindex(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(array_assoc(ap))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(type-- >0 && (v=0,nv_nextsub(np)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin v = nv_getval(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(type > 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nv_putsub(np,NIL(char*),type|ARRAY_SCAN))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin v = nv_getval(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin v = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(type>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin v = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(v)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin vsize = charlen(v,vsize);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(type<0 && (type += vsize)<0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin type = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(vsize < type)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin v = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_MULTIBYTE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(mbwide())
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mbinit();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(type-->0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((c=mbsize(v))<1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin v += c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = ':';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_MULTIBYTE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin v += type;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin vsize -= type;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*ptr==':')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((type = (int)sh_strnum(ptr+1,&ptr,1)) <=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin v = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(isastchar(mode))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(dolg>=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(dolg+type < dolmax)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dolmax = dolg+type;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dolmax = type;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(type < vsize)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_MULTIBYTE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mbwide())
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *vp = v;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mbinit();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(type-->0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((c=mbsize(vp))<1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin vp += c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin type = vp-v;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = ':';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_MULTIBYTE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin vsize = type;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*ptr)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mac_error(np);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin stkseek(stkp,offset);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argp = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* check for substring operations */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(c == '#' || c == '%' || c=='/')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c=='/')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(type=='/' || type=='#' || type=='%')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = type;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin type = '/';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argp++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin type = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(type==c) /* ## or %% */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argp++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin type = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pattern = strdup(argp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((type=='/' || c=='/') && (repstr = mac_getstring(pattern)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin replen = strlen(repstr);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(v || c=='/' && offset>=0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin stkseek(stkp,offset);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* check for quoted @ */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode=='@' && mp->quote && !v && c!='-')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->quoted-=2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinretry2:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(v && (!nulflg || *v ) && c!='+')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int d = (mode=='@'?' ':mp->ifs);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int match[2*(MATCH_MAX+1)], nmatch, nmatch_prev, vsize_last;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *vlast;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!v)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin v= "";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c=='/' || c=='#' || c== '%')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin flag = (type || c=='/')?(STR_GROUP|STR_MAXIMAL):STR_GROUP;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c!='/')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flag |= STR_LEFT;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nmatch = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin vsize = strlen(v);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nmatch_prev = nmatch;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c=='%')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nmatch=substring(v,pattern,match,flag&STR_MAXIMAL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nmatch=strgrpmatch(v,pattern,match,elementsof(match)/2,flag);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(replen>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_setmatch(v,vsize,nmatch,match);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nmatch)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin vlast = v;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin vsize_last = vsize;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin vsize = match[0];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(c=='#')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin vsize = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(vsize)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mac_copy(mp,v,vsize);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(nmatch && replen>0 && (match[1] || !nmatch_prev))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mac_substitute(mp,repstr,v,match,nmatch);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nmatch==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin v += vsize;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin v += match[1];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*v && c=='/' && type)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* avoid infinite loop */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nmatch && match[1]==0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nmatch = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin mac_copy(mp,v,1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin v++;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin vsize = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(replen==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_setmatch(vlast,vsize_last,nmatch,match);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(vsize)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mac_copy(mp,v,vsize>0?vsize:strlen(v));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(addsub)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfprintf(mp->shp->strbuf,"[%s]",nv_getsub(np));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin v = sfstruse(mp->shp->strbuf);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin mac_copy(mp, v, strlen(v));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(dolg==0 && dolmax==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(mp->dotdot)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(nv_nextsub(np) == 0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin break;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(bysub)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin v = nv_getsub(np);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin v = nv_getval(np);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(array_assoc(ap))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(strcmp(bysub?v:nv_getsub(np),arrmax)>0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin break;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(nv_aindex(np) > dolmax)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin break;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(dolg>=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(++dolg >= dolmax)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_FILESCAN
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(mp->shp->cur_line)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(dolmax==MAX_ARGN && isastchar(mode))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(v=getdolarg(&sh,dolg,&vsize)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dolmax = dolg;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_FILESCAN */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin v = mp->shp->st.dolv[dolg];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(!np)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(v = nextname(mp,id,dolmax)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(dolmax && --dolmax <=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_putsub(np,NIL(char*),ARRAY_UNDEF);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(ap)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ap->nelem |= ARRAY_SCAN;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nv_nextsub(np) == 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(bysub)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin v = nv_getsub(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin v = nv_getval(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mp->split && (!mp->quote || mode=='@'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!np)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->pattern = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin endfield(mp,mp->quoted);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->pattern = oldpat;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(d)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mp->sp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputc(mp->sp,d);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfputc(stkp,d);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(arrmax)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin free((void*)arrmax);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(pattern)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free((void*)pattern);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(argp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c=='/' && replen>0 && pattern && strmatch("",pattern))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mac_substitute(mp,repstr,v,0,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c=='?')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(np)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin id = nv_name(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(idnum)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin id = ltos(idnum);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*argp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfputc(stkp,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_exit(1),"%s: %s",id,argp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(v)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_exit(1),e_nullset,id);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_exit(1),e_notset,id);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(c=='=')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(np)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(mp->shp->subshell)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np = sh_assignok(np,1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_putval(np,argp,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin v = nv_getval(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nulflg = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin stkseek(stkp,offset);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto retry2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mac_error(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner else if(var && sh_isoption(SH_NOUNSET) && type<=M_TREE && (!np || nv_isnull(np) || (nv_isarray(np) && !np->nvalue.cp)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(np)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nv_isarray(np))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfprintf(mp->shp->strbuf,"%s[%s]\0",nv_name(np),nv_getsub(np));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin id = sfstruse(mp->shp->strbuf);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin id = nv_name(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_close(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_exit(1),e_notset,id);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(np)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_close(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinnosub:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(type==M_BRACE && sh_lexstates[ST_NORM][c]==S_BREAK)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin fcseek(-1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin comsubst(mp,(Shnode_t*)0,2);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(type)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mac_error(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcseek(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_close(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * This routine handles command substitution
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * <type> is 0 for older `...` version
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic void comsubst(Mac_t *mp,register Shnode_t* t, int type)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfdouble_t num;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *str;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfio_t *sp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Stk_t *stkp = mp->shp->stk;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Fcin_t save;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin struct slnod *saveslp = mp->shp->st.staklist;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct _mac_ savemac;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int savtop = stktell(stkp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin char lastc, *savptr = stkfreeze(stkp,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int was_history = sh_isstate(SH_HISTORY);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int was_verbose = sh_isstate(SH_VERBOSE);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int was_interactive = sh_isstate(SH_INTERACTIVE);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int newlines,bufsize,nextnewlines;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Namval_t *np;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin mp->shp->argaddr = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin savemac = *mp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin mp->shp->st.staklist=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(type)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sp = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcseek(-1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!t)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin t = sh_dolparen((Lex_t*)mp->shp->lex_context);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(t && t->tre.tretyp==TARITH)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcsave(&save);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((t->ar.arexpr->argflag&ARG_RAW))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin num = arith_exec(t->ar.arcomp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin num = sh_arith(sh_mactrim(mp->shp,t->ar.arexpr->argval,3));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin out_offset:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin stkset(stkp,savptr,savtop);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *mp = savemac;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((Sflong_t)num!=num)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfprintf(mp->shp->strbuf,"%.*Lg",LDBL_DIG,num);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(num)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfprintf(mp->shp->strbuf,"%lld",(Sflong_t)num);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfprintf(mp->shp->strbuf,"%Lg",num);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin str = sfstruse(mp->shp->strbuf);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mac_copy(mp,str,strlen(str));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin mp->shp->st.staklist = saveslp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcrestore(&save);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(fcgetc(c)!='`' && c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c==ESCAPE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcgetc(c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(isescchar(sh_lexstates[ST_QUOTE][c]) ||
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin (c=='"' && mp->quote)))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfputc(stkp,ESCAPE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfputc(stkp,c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin c = stktell(stkp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin str=stkfreeze(stkp,1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* disable verbose and don't save in history file */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_offstate(SH_HISTORY);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_offstate(SH_VERBOSE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mp->sp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfsync(mp->sp); /* flush before executing command */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sp = sfnew(NIL(Sfio_t*),str,c,-1,SF_STRING|SF_READ);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin c = mp->shp->inlineno;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin mp->shp->inlineno = error_info.line+mp->shp->st.firstline;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t = (Shnode_t*)sh_parse(mp->shp, sp,SH_EOF|SH_NL);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin mp->shp->inlineno = c;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin type = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if KSHELL
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(t)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcsave(&save);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfclose(sp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(t->tre.tretyp==0 && !t->com.comarg && !t->com.comset)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* special case $(<file) and $(<#file) */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int fd;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int r;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct checkpt buff;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct ionod *ip=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_pushcontext(&buff,SH_JMPIO);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((ip=t->tre.treio) &&
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ((ip->iofile&IOLSEEK) || !(ip->iofile&IOUFD)) &&
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (r=sigsetjmp(buff.buff,0))==0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin fd = sh_redirect(mp->shp,ip,3);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fd = sh_chkopen(e_devnull);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_popcontext(&buff);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(r==0 && ip && (ip->iofile&IOLSEEK))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(sp=mp->shp->sftable[fd])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin num = sftell(sp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin num = lseek(fd, (off_t)0, SEEK_CUR);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto out_offset;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sp = sfnew(NIL(Sfio_t*),(char*)malloc(IOBSIZE+1),IOBSIZE,fd,SF_READ|SF_MALLOC);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin type = 3;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sp = sh_subshell(t,sh_isstate(SH_ERREXIT),type);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcrestore(&save);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sp = sfopen(NIL(Sfio_t*),"","sr");
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_freeup(mp->shp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin mp->shp->st.staklist = saveslp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(was_history)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_onstate(SH_HISTORY);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(was_verbose)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_onstate(SH_VERBOSE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sp = sfpopen(NIL(Sfio_t*),str,"r");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *mp = savemac;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin np = sh_scoped(mp->shp,IFSNOD);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_putval(np,mp->ifsp,NV_RDONLY);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->ifsp = nv_getval(np);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin stkset(stkp,savptr,savtop);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin newlines = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin lastc = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfsetbuf(sp,(void*)sp,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin bufsize = sfvalue(sp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* read command substitution output and put on stack or here-doc */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfpool(sp, NIL(Sfio_t*), SF_WRITE);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_offstate(SH_INTERACTIVE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while((str=(char*)sfreserve(sp,SF_UNBOUND,0)) && (c = sfvalue(sp))>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_CRNL
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* eliminate <cr> */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *dp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *buff = str;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(c>1 && (*str !='\r'|| str[1]!='\n'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin str++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp = str;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(c>1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin str++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(c>1 && (*str!='\r' || str[1]!='\n'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *dp++ = *str++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *dp++ = *str++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin str = buff;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = dp-str;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_CRNL */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* delay appending trailing new-lines */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin for(nextnewlines=0; c-->0 && str[c]=='\n'; nextnewlines++);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(c < 0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin newlines += nextnewlines;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin continue;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(newlines >0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mp->sp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfnputc(mp->sp,'\n',newlines);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(!mp->quote && mp->split && mp->shp->ifstable['\n'])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin endfield(mp,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfnputc(stkp,'\n',newlines);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(lastc)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mac_copy(mp,&lastc,1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin lastc = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin newlines = nextnewlines;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(++c < bufsize)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin str[c] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* can't write past buffer so save last character */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin lastc = str[--c];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin str[c] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mac_copy(mp,str,c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(was_interactive)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_onstate(SH_INTERACTIVE);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(mp->shp->spid)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin job_wait(mp->shp->spid);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(--newlines>0 && mp->shp->ifstable['\n']==S_DELIM)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mp->sp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfnputc(mp->sp,'\n',newlines);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(!mp->quote && mp->split)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin while(newlines--)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin endfield(mp,1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfnputc(stkp,'\n',newlines);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(lastc)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mac_copy(mp,&lastc,1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfclose(sp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * copy <str> onto the stack
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void mac_copy(register Mac_t *mp,register const char *str, register int size)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *state;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register const char *cp=str;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register int c,n,nopat,len;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Stk_t *stkp=mp->shp->stk;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nopat = (mp->quote||mp->assign==1||mp->arith);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mp->zeros)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* prevent leading 0's from becomming octal constants */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(size>1 && *str=='0')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin str++,size--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->zeros = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = str;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mp->sp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfwrite(mp->sp,str,size);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(mp->pattern>=2 || (mp->pattern && nopat))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin state = sh_lexstates[ST_MACRO];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* insert \ before file expansion characters */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(size-->0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#if SHOPT_MULTIBYTE
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(mbwide() && (len=mbsize(cp))>1)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin cp += len;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin size -= (len-1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin continue;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = state[n= *(unsigned char*)cp++];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nopat&&(c==S_PAT||c==S_ESC||c==S_BRACT||c==S_ENDCH) && mp->pattern!=3)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c=1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(mp->pattern==4 && (c==S_ESC||c==S_BRACT||c==S_ENDCH || isastchar(n)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c=1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(mp->pattern==2 && c==S_SLASH)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c=1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(mp->pattern==3 && c==S_ESC && (state[*(unsigned char*)cp]==S_DIG||(*cp==ESCAPE)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(c=mp->quote))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c = (cp-1) - str)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfwrite(stkp,str,c);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfputc(stkp,ESCAPE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin str = cp-1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c = cp-str)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfwrite(stkp,str,c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(!mp->quote && mp->split && (mp->ifs||mp->pattern))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* split words at ifs characters */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin state = mp->shp->ifstable;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mp->pattern)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *sp = "&|()";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(c = *sp++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(state[c]==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin state[c] = S_EPAT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sp = "*?[{";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(c = *sp++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(state[c]==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin state[c] = S_PAT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(state[ESCAPE]==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin state[ESCAPE] = S_ESC;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(size-->0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin n=state[c= *(unsigned char*)cp++];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#if SHOPT_MULTIBYTE
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(mbwide() && n!=S_MBYTE && (len=mbsize(cp-1))>1)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfwrite(stkp,cp-1, len);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin cp += --len;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin size -= len;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin continue;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(n==S_ESC || n==S_EPAT)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* don't allow extended patterns in this case */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->patfound = mp->pattern;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfputc(stkp,ESCAPE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(n==S_PAT)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->patfound = mp->pattern;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(n && mp->ifs)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_MULTIBYTE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n==S_MBYTE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh_strchr(mp->ifsp,cp-1)<0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = mbsize(cp-1) - 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n==-2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp += n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size -= n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n= S_DELIM;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_MULTIBYTE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n==S_SPACE || n==S_NL)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(size>0 && ((n=state[c= *(unsigned char*)cp++])==S_SPACE||n==S_NL))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_MULTIBYTE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n==S_MBYTE && sh_strchr(mp->ifsp,cp-1)>=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = mbsize(cp-1) - 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n==-2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp += n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size -= n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n=S_DELIM;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_MULTIBYTE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n==S_DELIM)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin endfield(mp,n==S_DELIM||mp->quoted);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->patfound = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n==S_DELIM)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(size>0 && ((n=state[c= *(unsigned char*)cp++])==S_SPACE||n==S_NL))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(size<=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfputc(stkp,c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mp->pattern)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = "&|()";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(c = *cp++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(state[c]==S_EPAT)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin state[c] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = "*?[{";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(c = *cp++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(state[c]==S_PAT)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin state[c] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(mp->shp->ifstable[ESCAPE]==S_ESC)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin mp->shp->ifstable[ESCAPE] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfwrite(stkp,str,size);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Terminate field.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If field is null count field if <split> is non-zero
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Do filename expansion of required
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void endfield(register Mac_t *mp,int split)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register struct argnod *argp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register int count=0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Stk_t *stkp = mp->shp->stk;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(stktell(stkp) > ARGVAL || split)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin argp = (struct argnod*)stkfreeze(stkp,1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argp->argnxt.cp = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argp->argflag = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mp->patfound)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin mp->shp->argaddr = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_BRACEPAT
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin count = path_generate(argp,mp->arghead);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin count = path_expand(argp->argval,mp->arghead);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_BRACEPAT */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(count)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->fields += count;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(split) /* pattern is null string */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *argp->argval = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else /* pattern expands to nothing */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin count = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(count==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argp->argchn.ap = *mp->arghead;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *mp->arghead = argp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->fields++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(count>=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*mp->arghead)->argflag |= ARG_MAKE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mp->assign || sh_isoption(SH_NOGLOB))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argp->argflag |= ARG_RAW|ARG_EXP;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin stkseek(stkp,ARGVAL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->quoted = mp->quote;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Finds the right substring of STRING using the expression PAT
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * the longest substring is found when FLAG is set.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int substring(register const char *string,const char *pat,int match[], int flag)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register const char *sp=string;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int size,len,nmatch,n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int smatch[2*(MATCH_MAX+1)];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flag)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n=strgrpmatch(sp,pat,smatch,elementsof(smatch)/2,STR_RIGHT|STR_MAXIMAL))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memcpy(match,smatch,n*2*sizeof(smatch[0]));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size = len = strlen(sp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sp += size;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(sp>=string)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_MULTIBYTE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mbwide())
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sp = lastchar(string,sp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_MULTIBYTE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n=strgrpmatch(sp,pat,smatch,elementsof(smatch)/2,STR_RIGHT|STR_LEFT|STR_MAXIMAL))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nmatch = n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memcpy(match,smatch,n*2*sizeof(smatch[0]));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size = sp-string;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sp--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(size==len)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nmatch)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nmatch *=2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(--nmatch>=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin match[nmatch] += size;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_MULTIBYTE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static char *lastchar(const char *string, const char *endstring)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *str = (char*)string;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mbinit();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(*str)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((c=mbsize(str))<0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(str+c > endstring)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin str += c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(str);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_MULTIBYTE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int charlen(const char *string,int len)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!string)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_MULTIBYTE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mbwide())
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register const char *str = string, *strmax=string+len;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int n=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mbinit();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(len>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(str<strmax && mbchar(str))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else while(mbchar(str))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_MULTIBYTE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(len<0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(strlen(string));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(len);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * This is the default tilde discipline function
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int sh_btilde(int argc, char *argv[], void *context)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Shell_t *shp = ((Shbltin_t*)context)->shp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin char *cp = sh_tilde(shp,argv[1]);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin NOT_USED(argc);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!cp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = argv[1];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputr(sfstdout, cp, '\n');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * <offset> is byte offset for beginning of tilde string
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic void tilde_expand2(Shell_t *shp, register int offset)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin char shtilde[10], *av[3], *ptr=stkfreeze(shp->stk,1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfio_t *iop, *save=sfstdout;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Namval_t *np;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static int beenhere=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin strcpy(shtilde,".sh.tilde");
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin np = nv_open(shtilde,shp->fun_tree, NV_VARNAME|NV_NOARRAY|NV_NOASSIGN|NV_NOFAIL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(np && !beenhere)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin beenhere = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_addbuiltin(shtilde,sh_btilde,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_onattr(np,NV_EXPORT);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin av[0] = ".sh.tilde";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin av[1] = &ptr[offset];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin av[2] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin iop = sftmp(IOBSIZE+1);;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfset(iop,SF_READ,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfstdout = iop;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(np)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_fun(np, (Namval_t*)0, av);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_btilde(2, av, &sh);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfstdout = save;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin stkset(shp->stk,ptr, offset);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfseek(iop,(Sfoff_t)0,SEEK_SET);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfset(iop,SF_READ,1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ptr = sfreserve(iop, SF_UNBOUND, -1))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfoff_t n = sfvalue(iop);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(ptr[n-1]=='\n')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n==1 && fcpeek(0)=='/' && ptr[n-1])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfwrite(shp->stk,ptr,n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfputr(shp->stk,av[1],0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfclose(iop);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * This routine is used to resolve ~ expansion.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * A ~ by itself is replaced with the users login directory.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * A ~- is replaced by the previous working directory in shell.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * A ~+ is replaced by the present working directory in shell.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If ~name is replaced with login directory of name.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If string doesn't start with ~ or ~... not found then 0 returned.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic char *sh_tilde(Shell_t *shp,register const char *string)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct passwd *pw;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Namval_t *np=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static Dt_t *logins_tree;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*string++!='~')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(NIL(char*));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((c = *string)==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!(cp=nv_getval(sh_scoped(shp,HOME))))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = getlogin();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(cp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((c=='-' || c=='+') && string[1]==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c=='+')
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin cp = nv_getval(sh_scoped(shp,PWDNOD));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin cp = nv_getval(sh_scoped(shp,OLDPWDNOD));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(cp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(logins_tree && (np=nv_search(string,logins_tree,0)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(nv_getval(np));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(pw = getpwnam(string)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(NIL(char*));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!logins_tree)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin logins_tree = dtopen(&_Nvdisc,Dtbag);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(np=nv_search(string,logins_tree,NV_ADD))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_putval(np, pw->pw_dir,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(pw->pw_dir);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * return values for special macros
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic char *special(Shell_t *shp,register int c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c!='$')
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->argaddr = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch(c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '@':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '*':
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(shp->st.dolc>0?shp->st.dolv[1]:NIL(char*));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '#':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_FILESCAN
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->cur_line)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin getdolarg(shp,MAX_ARGN,(int*)0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(ltos(shp->offsets[0]));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_FILESCAN */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(ltos(shp->st.dolc));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '!':
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->bckpid)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(ltos(shp->bckpid));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '$':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nv_isnull(SH_DOLLARNOD))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(ltos(shp->pid));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(nv_getval(SH_DOLLARNOD));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '-':
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(sh_argdolminus(shp->arg_context));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '?':
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(ltos(shp->savexit));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 0:
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(sh_isstate(SH_PROFILE) || shp->fn_depth==0 || !shp->st.cmdname)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(shp->shname);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz return(shp->st.cmdname);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(NIL(char*));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Handle macro expansion errors
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void mac_error(Namval_t *np)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(np)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_close(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_exit(1),e_subst,fcfirst());
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Given pattern/string, replace / with 0 and return pointer to string
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * \ characters are stripped from string. The \ are stripped in the
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * replacement string unless followed by a digit or \.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char *mac_getstring(char *pattern)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register char *cp=pattern, *rep=0, *dp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(c = *cp++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(c==ESCAPE && (!rep || (*cp && strchr("&|()[]*?",*cp))))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin c = *cp++;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(!rep && c=='/')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp[-1] = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin rep = dp = cp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(rep)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin *dp++ = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(rep)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin *dp = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(rep);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}