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 * KornShell lexical analyzer
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Written by David Korn
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * AT&T Labs
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <ast.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <stak.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <fcin.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <nval.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "FEATURE/options"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if KSHELL
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# include "defs.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# include <shell.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define nv_getval(np) ((np)->nvalue)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Shell_t sh = {1};
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* KSHELL */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "argnod.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "test.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "lexstates.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "io.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define TEST_RE 3
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define SYNBAD 3 /* exit value for syntax errors */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define STACK_ARRAY 3 /* size of depth match stack growth */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if _lib_iswblank < 0 /* set in lexstates.h to enable this code */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinlocal_iswblank(wchar_t wc)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static int initialized;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static wctype_t wt;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!initialized)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin initialized = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin wt = wctype("blank");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(iswctype(wc, wt));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * This structure allows for arbitrary depth nesting of (...), {...}, [...]
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstruct lexstate
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char incase; /* 1 for case pattern, 2 after case */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char intest; /* 1 inside [[...]] */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char testop1; /* 1 when unary test op legal */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char testop2; /* 1 when binary test op legal */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char reservok; /* >0 for reserved word legal */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char skipword; /* next word can't be reserved */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char last_quote; /* last multi-line quote character */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin};
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstruct lexdata
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char nocopy;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char paren;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char dolparen;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char nest;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char docword;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *docend;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char noarg;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char balance;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char warn;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char message;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char arith;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *first;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int level;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int lastc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int lex_max;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int *lex_match;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int lex_state;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz int docextra;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_KIA
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin off_t kiaoff;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin};
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define _SHLEX_PRIVATE \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin struct lexdata lexd; \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin struct lexstate lex;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "shlex.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define pushlevel(lp,c,s) ((lp->lexd.level>=lp->lexd.lex_max?stack_grow(lp):1) &&\
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ((lp->lexd.lex_match[lp->lexd.level++]=lp->lexd.lastc),\
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lexd.lastc=(((s)<<CHAR_BIT)|(c))))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define oldmode(lp) (lp->lexd.lastc>>CHAR_BIT)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define endchar(lp) (lp->lexd.lastc&0xff)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define setchar(lp,c) (lp->lexd.lastc = ((lp->lexd.lastc&~0xff)|(c)))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define poplevel(lp) (lp->lexd.lastc=lp->lexd.lex_match[--lp->lexd.level])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char *fmttoken(Lex_t*, int, char*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef SF_BUFCONST
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static int alias_exceptf(Sfio_t*, int, void*, Sfdisc_t*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static int alias_exceptf(Sfio_t*, int, Sfdisc_t*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void setupalias(Lex_t*,const char*, Namval_t*);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic int comsub(Lex_t*,int);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void nested_here(Lex_t*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int here_copy(Lex_t*, struct ionod*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int stack_grow(Lex_t*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic const Sfdisc_t alias_disc = { NULL, NULL, NULL, alias_exceptf, NULL };
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_KIA
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic void refvar(Lex_t *lp, int type)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register Shell_t *shp = lp->sh;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register Stk_t *stkp = shp->stk;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin off_t off = (fcseek(0)-(type+1))-(lp->lexd.first?lp->lexd.first:fcfirst());
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned long r;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lp->lexd.first)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin off = (fcseek(0)-(type+1)) - lp->lexd.first;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin r=kiaentity(lp,lp->lexd.first+lp->lexd.kiaoff+type,off-lp->lexd.kiaoff,'v',-1,-1,lp->current,'v',0,"");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int n,offset = stktell(stkp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *savptr,*begin;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin off = offset + (fcseek(0)-(type+1)) - fcfirst();
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lp->lexd.kiaoff < offset)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* variable starts on stak, copy remainder */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(off>offset)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfwrite(stkp,fcfirst()+type,off-offset);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin n = stktell(stkp)-lp->lexd.kiaoff;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin begin = stkptr(stkp,lp->lexd.kiaoff);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* variable in data buffer */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin begin = fcfirst()+(type+lp->lexd.kiaoff-offset);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin n = off-lp->lexd.kiaoff;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin savptr = stkfreeze(stkp,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin r=kiaentity(lp,begin,n,'v',-1,-1,lp->current,'v',0,"");
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin stkset(stkp,savptr,offset);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfprintf(lp->kiatmp,"p;%..64d;v;%..64d;%d;%d;r;\n",lp->current,r,shp->inlineno,shp->inlineno);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_KIA */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * This routine gets called when reading across a buffer boundary
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If lexd.nocopy is off, then current token is saved on the stack
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic void lex_advance(Sfio_t *iop, const char *buff, register int size, void *context)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register Lex_t *lp = (Lex_t*)context;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register Shell_t *shp = lp->sh;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register Sfio_t *log= shp->funlog;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Stk_t *stkp = shp->stk;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if KSHELL
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* write to history file and to stderr if necessary */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(iop && !sfstacked(iop))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh_isstate(SH_HISTORY) && shp->hist_ptr)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin log = shp->hist_ptr->histfp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfwrite(log, (void*)buff, size);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh_isstate(SH_VERBOSE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfwrite(sfstderr, buff, size);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lp->lexd.nocopy)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(lp->lexd.dolparen && lp->lexd.docword)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz int n = size - (lp->lexd.docend-(char*)buff);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sfwrite(shp->strbuf,lp->lexd.docend,n);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz lp->lexd.docextra += n;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lp->lexd.first)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin size -= (lp->lexd.first-(char*)buff);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin buff = lp->lexd.first;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!lp->lexd.noarg)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->arg = (struct argnod*)stkseek(stkp,ARGVAL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_KIA
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lexd.kiaoff += ARGVAL;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_KIA */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(size>0 && (lp->arg||lp->lexd.noarg))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfwrite(stkp,buff,size);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lexd.first = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * fill up another input buffer
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * preserves lexical state
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic int lexfill(Lex_t *lp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Lex_t savelex;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct argnod *ap;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz int aok,docextra;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin savelex = *lp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ap = lp->arg;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = fcfill();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ap)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->arg = ap;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz docextra = lp->lexd.docextra;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lex = savelex.lex;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lexd = savelex.lexd;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(fcfile() || c)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lexd.first = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin aok= lp->aliasok;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ap = lp->arg;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin memcpy(lp, &savelex, offsetof(Lex_t,lexd));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->arg = ap;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->aliasok = aok;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(lp->lexd.docword && docextra)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz lp->lexd.docextra = docextra;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz lp->lexd.docend = fcseek(0)-1;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * mode=1 for reinitialization
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinLex_t *sh_lexopen(Lex_t *lp, Shell_t *sp, int mode)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!lp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin lp = (Lex_t*)newof(0,Lex_t,1,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->sh = sp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin fcnotify(lex_advance,lp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lex.intest = lp->lex.incase = lp->lex.skipword = lp->lexd.warn = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->comp_assign = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lex.reservok = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!sh_isoption(SH_DICTIONARY) && sh_isoption(SH_NOEXEC))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lexd.warn=1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!mode)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lexd.noarg = lp->lexd.level= lp->lexd.dolparen = lp->lexd.balance = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lexd.nocopy = lp->lexd.docword = lp->lexd.nest = lp->lexd.paren = 0;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner lp->lexd.lex_state = lp->lexd.lastc=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->comsub = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(lp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef DBUG
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinextern int lextoken(Lex_t*);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinint sh_lex(Lex_t *lp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Shell_t *shp = lp->sh;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int flag;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *quoted, *macro, *split, *expand;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char tokstr[3];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int tok = lextoken();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin quoted = macro = split = expand = "";
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(tok==0 && (flag=lp->arg->argflag))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flag&ARG_MAC)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin macro = "macro:";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flag&ARG_EXP)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin expand = "expand:";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flag&ARG_QUOTED)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin quoted = "quoted:";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sfstderr,"line %d: %o:%s%s%s%s %s\n",shp->inlineno,tok,quoted,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin macro, split, expand, fmttoken(lp,tok,tokstr));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(tok);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define sh_lex lextoken
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Get the next word and put it on the top of the stak
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * A pointer to the current word is stored in lp->arg
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Returns the token type
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinint sh_lex(Lex_t* lp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register Shell_t *shp = lp->sh;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register const char *state;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register int n, c, mode=ST_BEGIN, wordflags=0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Stk_t *stkp = shp->stk;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int inlevel=lp->lexd.level, assignment=0, ingrave=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfio_t *sp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_MULTIBYTE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin LEN=1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_MULTIBYTE */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lp->lexd.paren)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lexd.paren = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(lp->token=LPAREN);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lp->lex.incase)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->assignok = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->assignok |= lp->lex.reservok;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lp->comp_assign==2)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->comp_assign = lp->lex.reservok = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lexd.arith = (lp->lexd.nest==1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lp->lexd.nest)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin pushlevel(lp,lp->lexd.nest,ST_NONE);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lexd.nest = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin mode = lp->lexd.lex_state;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(lp->lexd.docword)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fcgetc(c)=='-' || c=='#')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lexd.docword++;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->digits=(c=='#'?3:1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(c=='<')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->digits=2;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lexd.docword=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(c>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcseek(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!lp->lexd.dolparen)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->arg = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode!=ST_BEGIN)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lexd.first = fcseek(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lexd.first = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lastline = lp->sh->inlineno;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* skip over characters in the current state */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin state = sh_lexstates[mode];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while((n=STATE(state,c))==0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch(n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_BREAK:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcseek(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto breakloop;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_EOF:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sp = fcfile();
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((n=lexfill(lp)) > 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcseek(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* check for zero byte in file */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n==0 && fcfile())
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(shp->readscript)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *cp = error_info.id;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errno = ENOEXEC;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error_info.id = shp->readscript;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_system(ERROR_NOEXEC),e_exec,cp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->token = -1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_syntax(lp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* end-of-file */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode==ST_BEGIN)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(lp->token=EOFSYM);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(mode >ST_NORM && lp->lexd.level>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin switch(c=endchar(lp))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '$':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode==ST_LIT)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = '\'';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin mode = oldmode(lp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin poplevel(lp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case RBRACT:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = LBRACT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 1: /* for ((...)) */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case RPAREN:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = LPAREN;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = LBRACE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '"': case '`': case '\'':
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lexd.balance = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sp && !(sfset(sp,0,0)&SF_STRING))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lasttok = c;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->token = EOFSYM;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_syntax(lp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lexd.balance = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto breakloop;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_COM:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* skip one or more comment line(s) */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lex.reservok = !lp->lex.intest;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((n=lp->lexd.nocopy) && lp->lexd.dolparen)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lexd.nocopy--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin do
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(fcgetc(c)>0 && c!='\n');
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(c<=0 || lp->heredoc)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(shp->inlineno++,fcpeek(0)=='\n')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcseek(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(state[c=fcpeek(0)]==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcseek(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(c=='#');
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lexd.nocopy = n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c<0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(lp->token=EOFSYM);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = S_NLTOK;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin shp->inlineno--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* FALL THRU */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_NLTOK:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* check for here-document */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lp->heredoc)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!lp->lexd.dolparen)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lexd.nocopy++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = shp->inlineno;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(here_copy(lp,lp->heredoc)<=0 && lp->lasttok)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lasttok = IODOCSYM;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->token = EOFSYM;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lastline = c;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_syntax(lp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!lp->lexd.dolparen)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lexd.nocopy--;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->heredoc = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lex.reservok = !lp->lex.intest;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lex.skipword = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* FALL THRU */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_NL:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* skip over new-lines */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lex.last_quote = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(shp->inlineno++,fcget()=='\n');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcseek(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n==S_NLTOK)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->comp_assign = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(lp->token='\n');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_BLNK:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lp->lex.incase<=TEST_RE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* implicit RPAREN for =~ test operator */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(inlevel+1==lp->lexd.level)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lp->lex.intest)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin fcseek(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = RPAREN;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto do_pop;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_OP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* return operator token */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c=='<' || c=='>')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lp->lex.testop2)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lex.testop2 = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->digits = (c=='>');
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lex.skipword = 1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->aliasok = lp->lex.reservok;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lex.reservok = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lex.reservok = !lp->lex.intest;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c==RPAREN)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!lp->lexd.dolparen)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lex.incase = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(lp->token=c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lex.testop1 = lp->lex.intest;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fcgetc(n)>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcseek(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(state[n]==S_OP || n=='#')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n==c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c=='<')
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lexd.docword=1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(n==LPAREN)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lexd.nest=1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lastline = shp->inlineno;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lexd.lex_state = ST_NESTED;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcseek(1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(sh_lex(lp));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c |= SYMREP;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(c=='(' || c==')')
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(lp->token=c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(c=='&')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(!sh_isoption(SH_POSIX) && n=='>' && (sh_isoption(SH_BASH) || sh_isstate(SH_PROFILE)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(!sh_isoption(SH_BASH) && !lp->nonstandard)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz lp->nonstandard = 1;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz errormsg(SH_DICT,ERROR_warn(0),e_lexnonstandard,shp->inlineno);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->digits = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = '>';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(n=='&')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c |= SYMAMP;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(c!='<' && c!='>')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(n==LPAREN)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c |= SYMLPAR;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lex.reservok = 1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lex.skipword = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(n=='|')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c |= SYMPIPE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(c=='<' && n=='>')
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz lp->digits = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = IORDWRSYM;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fcgetc(n);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(fcgetc(n)==';')
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz lp->token = c = IORDWRSYMT;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(lp->inexec)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sh_syntax(lp);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else if(n>0)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fcseek(-1);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz n= 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(n=='#' && (c=='<'||c=='>'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c |= SYMSHARP;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(n==';' && c=='>')
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin c |= SYMSEMI;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lp->inexec)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->token = c;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_syntax(lp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcseek(1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lex.incase = (c==BREAKCASESYM || c==FALLTHRUSYM);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(lp->lexd.warn && (n=fcpeek(0))!=RPAREN && n!=' ' && n!='\t')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_warn(0),e_lexspace,shp->inlineno,c,n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(c==LPAREN && lp->comp_assign && !lp->lex.intest && !lp->lex.incase)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->comp_assign = 2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->comp_assign = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(lp->token=c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_ESC:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* check for \<new-line> */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcgetc(n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c=2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_CRNL
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n=='\r')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fcgetc(n)=='\n')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c=3;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n='\r';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcseek(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_CRNL */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n=='\n')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfio_t *sp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct argnod *ap;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin shp->inlineno++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* synchronize */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(sp=fcfile()))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin state=fcseek(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcclose();
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ap = lp->arg;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcfopen(sp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcsopen((char*)state);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* remove \new-line */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin n = stktell(stkp)-c;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin stkseek(stkp,n);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->arg = ap;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n<=ARGVAL)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mode = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lexd.first = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin wordflags |= ARG_QUOTED;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode==ST_DOL)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto err;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifndef STR_MAXIMAL
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(mode==ST_NESTED && lp->lexd.warn &&
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin endchar(lp)==RBRACE &&
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_lexstates[ST_DOL][n]==S_DIG
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin )
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_warn(0),e_lexfuture,shp->inlineno,n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* STR_MAXIMAL */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_NAME:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!lp->lex.skipword)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lex.reservok *= 2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* FALL THRU */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_TILDE:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_RES:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!lp->lexd.dolparen)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lexd.first = fcseek(0)-LEN;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(lp->lexd.docword)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lexd.docend = fcseek(0)-LEN;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mode = ST_NAME;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c=='.')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcseek(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n!=S_TILDE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcgetc(n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n>0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(c=='~' && n==LPAREN && lp->lex.incase)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lex.incase = TEST_RE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcseek(-1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n==LPAREN)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto epat;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin wordflags = ARG_MAC;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mode = ST_NORM;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_REG:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode==ST_BEGIN)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin do_reg:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* skip new-line joining */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c=='\\' && fcpeek(0)=='\n')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin shp->inlineno++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcseek(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcseek(-1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!lp->lexd.dolparen)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lexd.first = fcseek(0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(lp->lexd.docword)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lexd.docend = fcseek(0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(c=='[' && lp->assignok>=SH_ASSIGN)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mode = ST_NAME;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mode = ST_NORM;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_LIT:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(oldmode(lp)==ST_NONE && !lp->lexd.noarg) /* in ((...)) */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((c=fcpeek(0))==LPAREN || c==RPAREN || c=='$' || c==LBRACE || c==RBRACE || c=='[' || c==']')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fcpeek(1)=='\'')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcseek(2);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin wordflags |= ARG_QUOTED;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode==ST_DOL)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(endchar(lp)!='$')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto err;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(oldmode(lp)==ST_QUOTE) /* $' within "" or `` */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lp->lexd.warn)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_warn(0),e_lexslash,shp->inlineno);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mode = ST_LIT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode!=ST_LIT)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lp->lexd.warn && lp->lex.last_quote && shp->inlineno > lp->lastline)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin errormsg(SH_DICT,ERROR_warn(0),e_lexlongquote,lp->lastline,lp->lex.last_quote);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lex.last_quote = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lastline = shp->inlineno;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode!=ST_DOL)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin pushlevel(lp,'\'',mode);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mode = ST_LIT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* check for multi-line single-quoted string */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(shp->inlineno > lp->lastline)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lex.last_quote = '\'';
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin mode = oldmode(lp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin poplevel(lp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_ESC2:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* \ inside '' */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(endchar(lp)=='$')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcgetc(n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n=='\n')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin shp->inlineno++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_GRAVE:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lp->lexd.warn && (mode!=ST_QUOTE || endchar(lp)!='`'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_warn(0),e_lexobsolete1,shp->inlineno);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin wordflags |=(ARG_MAC|ARG_EXP);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode==ST_QUOTE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ingrave = !ingrave;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* FALL THRU */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_QUOTE:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(oldmode(lp)==ST_NONE && lp->lexd.arith) /* in ((...)) */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(n!=S_GRAVE || fcpeek(0)=='\'')
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin continue;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n==S_QUOTE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin wordflags |=ARG_QUOTED;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode!=ST_QUOTE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c!='"' || mode!=ST_QNEST)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lp->lexd.warn && lp->lex.last_quote && shp->inlineno > lp->lastline)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin errormsg(SH_DICT,ERROR_warn(0),e_lexlongquote,lp->lastline,lp->lex.last_quote);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lex.last_quote=0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lastline = shp->inlineno;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin pushlevel(lp,c,mode);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz ingrave ^= (c=='`');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mode = ST_QUOTE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if((n=endchar(lp))==c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->inlineno > lp->lastline)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lex.last_quote = c;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin mode = oldmode(lp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin poplevel(lp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(c=='"' && n==RBRACE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mode = ST_QNEST;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_DOL:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* don't check syntax inside `` */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode==ST_QUOTE && ingrave)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_KIA
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lp->lexd.first)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lexd.kiaoff = fcseek(0)-lp->lexd.first;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lexd.kiaoff = stktell(stkp)+fcseek(0)-fcfirst();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_KIA */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin pushlevel(lp,'$',mode);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mode = ST_DOL;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_PAR:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin do_comsub:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin wordflags |= ARG_MAC;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin mode = oldmode(lp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin poplevel(lp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcseek(-1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin wordflags |= comsub(lp,c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_RBRA:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((n=endchar(lp)) == '$')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto err;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode!=ST_QUOTE || n==RBRACE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin mode = oldmode(lp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin poplevel(lp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_EDOL:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* end $identifier */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_KIA
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lp->kiafile)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin refvar(lp,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_KIA */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lp->lexd.warn && c==LBRACT && !lp->lex.intest && !lp->lexd.arith && oldmode(lp)!= ST_NESTED)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_warn(0),e_lexusebrace,shp->inlineno);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcseek(-1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin mode = oldmode(lp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin poplevel(lp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_DOT:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* make sure next character is alpha */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fcgetc(n)>0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(n=='.')
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin fcgetc(n);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(n>0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin fcseek(-1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(isaletter(n) || n==LBRACT)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode==ST_NAME)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n=='=')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(n==RBRACE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(isastchar(n))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto err;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_SPC1:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin wordflags |= ARG_MAC;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(endchar(lp)==RBRACE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin setchar(lp,c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* FALL THRU */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_ALP:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(c=='.' && endchar(lp)=='$')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto err;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_SPC2:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_DIG:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin wordflags |= ARG_MAC;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin switch(endchar(lp))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '$':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n==S_ALP) /* $identifier */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mode = ST_DOLNAME;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin mode = oldmode(lp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin poplevel(lp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_TYPEDEF
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '@':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_TYPEDEF */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '!':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n!=S_ALP)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto dolerr;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '#':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case RBRACE:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n==S_ALP)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin setchar(lp,RBRACE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c=='.')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcseek(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mode = ST_BRACE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fcgetc(c)>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcseek(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(state[c]==S_ALP)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto err;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n==S_DIG)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin setchar(lp,'0');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin setchar(lp,'!');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '0':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n==S_DIG)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto dolerr;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dolerr:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_ERR:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((n=endchar(lp)) == '$')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto err;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c=='*' || (n=sh_lexstates[ST_BRACE][c])!=S_MOD1 && n!=S_MOD2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* see whether inside `...` */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin mode = oldmode(lp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin poplevel(lp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((n = endchar(lp)) != '`')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto err;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin pushlevel(lp,RBRACE,mode);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin setchar(lp,RBRACE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mode = ST_NESTED;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_MOD1:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(oldmode(lp)==ST_QUOTE || oldmode(lp)==ST_NONE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* allow ' inside "${...}" */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c==':' && fcgetc(n)>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = state[n];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcseek(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n==S_MOD1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mode = ST_QUOTE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* FALL THRU */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_MOD2:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_KIA
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lp->kiafile)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin refvar(lp,1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_KIA */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c!=':' && fcgetc(n)>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n!=c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!c || (fcgetc(n)>0))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcseek(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n==LPAREN)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c!='%')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->token = n;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_syntax(lp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(lp->lexd.warn)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_warn(0),e_lexquote,shp->inlineno,'%');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mode = ST_NESTED;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_LBRA:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((c=endchar(lp)) == '$')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fcgetc(c)>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcseek(-1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin setchar(lp,RBRACE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(state[c]!=S_ERR && c!=RBRACE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((n=sh_lexstates[ST_BEGIN][c])==0 || n==S_OP || n==S_NLTOK)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin c = LBRACE;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin goto do_comsub;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin err:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin n = endchar(lp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin mode = oldmode(lp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin poplevel(lp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n!='$')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->token = c;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_syntax(lp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lp->lexd.warn && c!='/' && sh_lexstates[ST_NORM][c]!=S_BREAK && (c!='"' || mode==ST_QUOTE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_warn(0),e_lexslash,shp->inlineno);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else if(c=='"' && mode!=ST_QUOTE && !ingrave)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin wordflags |= ARG_MESSAGE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcseek(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_META:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lp->lexd.warn && endchar(lp)==RBRACE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_warn(0),e_lexusequote,shp->inlineno,c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_PUSH:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin pushlevel(lp,RPAREN,mode);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mode = ST_NESTED;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_POP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin do_pop:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lp->lexd.level <= inlevel)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lp->lexd.level==inlevel+1 && lp->lex.incase>=TEST_RE && !lp->lex.intest)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin fcseek(-1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin goto breakloop;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin n = endchar(lp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c==RBRACT && !(n==RBRACT || n==RPAREN))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((c==RBRACE||c==RPAREN) && n==RPAREN)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fcgetc(n)==LPAREN)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c!=RPAREN)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcseek(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcseek(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = RPAREN;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c==';' && n!=';')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lp->lexd.warn && n==RBRACE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_warn(0),e_lexusequote,shp->inlineno,c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode==ST_QNEST)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lp->lexd.warn)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_warn(0),e_lexescape,shp->inlineno,c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin mode = oldmode(lp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin poplevel(lp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* quotes in subscript need expansion */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode==ST_NAME && (wordflags&ARG_QUOTED))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin wordflags |= ARG_MAC;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* check for ((...)) */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n==1 && c==RPAREN)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fcgetc(n)==RPAREN)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(mode==ST_NONE && !lp->lexd.dolparen)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto breakloop;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lex.reservok = 1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lex.skipword = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(lp->token=EXPRSYM);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* backward compatibility */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lp->lexd.warn)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_warn(0),e_lexnested,shp->inlineno);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!(state=lp->lexd.first))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin state = fcfirst();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcseek(state-fcseek(0));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lp->arg)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->arg = (struct argnod*)stkfreeze(stkp,1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin setupalias(lp,lp->arg->argval,NIL(Namval_t*));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lexd.paren = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(lp->token=LPAREN);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode==ST_NONE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c!=n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->token = c;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_syntax(lp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c==RBRACE && (mode==ST_NAME||mode==ST_NORM))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto epat;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_EQ:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin assignment = lp->assignok;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* FALL THRU */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_COLON:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(assignment)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((c=fcget())=='~')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin wordflags |= ARG_MAC;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(c!=LPAREN && assignment==SH_COMPASSIGN)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin assignment = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcseek(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_LABEL:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lp->lex.reservok && !lp->lex.incase)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = fcget();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcseek(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(state[c]==S_BREAK)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin assignment = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto breakloop;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_BRACT:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* check for possible subscript */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((n=endchar(lp))==RBRACT || n==RPAREN ||
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (mode==ST_BRACE) ||
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin (oldmode(lp)==ST_NONE) ||
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin (mode==ST_NAME && (lp->assignok||lp->lexd.level)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(mode==ST_NAME)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fcgetc(n);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(n>0)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(n==']')
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz errormsg(SH_DICT,ERROR_exit(SYNBAD),e_lexsyntax1, shp->inlineno, "[]", "empty subscript");
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fcseek(-1);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin pushlevel(lp,RBRACT,mode);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin wordflags |= ARG_QUOTED;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mode = ST_NESTED;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin wordflags |= ARG_EXP;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_BRACE:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int isfirst;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lp->lexd.dolparen)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(mode==ST_BEGIN && (lp->lex.reservok||lp->comsub))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin fcgetc(n);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(n>0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin fcseek(-1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin n = '\n';
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(n==RBRACT || sh_lexstates[ST_NORM][n])
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(lp->token=c);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(mode==ST_BEGIN)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lp->comsub && c==RBRACE)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(lp->token=c);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin goto do_reg;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin isfirst = (lp->lexd.first&&fcseek(0)==lp->lexd.first+1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcgetc(n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* check for {} */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c==LBRACE && n==RBRACE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcseek(-1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(lp->lex.reservok)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* check for reserved word { or } */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lp->lex.reservok && state[n]==S_BREAK && isfirst)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh_isoption(SH_BRACEEXPAND) && c==LBRACE && !assignment && state[n]!=S_BREAK
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin && !lp->lex.incase && !lp->lex.intest
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin && !lp->lex.skipword)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin wordflags |= ARG_EXP;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c==RBRACE && n==LPAREN)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto epat;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_PAT:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin wordflags |= ARG_EXP;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* FALL THRU */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_EPAT:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin epat:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fcgetc(n)==LPAREN)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lp->lex.incase==TEST_RE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lex.incase++;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin pushlevel(lp,RPAREN,ST_NORM);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mode = ST_NESTED;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin wordflags |= ARG_EXP;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin pushlevel(lp,RPAREN,mode);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mode = ST_NESTED;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcseek(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n=='=' && c=='+' && mode==ST_NAME)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->comp_assign = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode==ST_NAME)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mode = ST_NORM;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(mode==ST_NONE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinbreakloop:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lp->lexd.nocopy)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lexd.balance = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lp->lexd.dolparen)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lexd.balance = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lp->lexd.docword)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nested_here(lp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lexd.message = (wordflags&ARG_MESSAGE);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(lp->token=0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!(state=lp->lexd.first))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin state = fcfirst();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = fcseek(0)-(char*)state;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!lp->arg)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->arg = (struct argnod*)stkseek(stkp,ARGVAL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n>0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfwrite(stkp,state,n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* add balancing character if necessary */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lp->lexd.balance)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfputc(stkp,lp->lexd.balance);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lexd.balance = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfputc(stkp,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin stkseek(stkp,stktell(stkp)-1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin state = stkptr(stkp,ARGVAL);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin n = stktell(stkp)-ARGVAL;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lexd.first=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n==1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* check for numbered redirection */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = state[0];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((c=='<' || c=='>') && isadigit(n))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin c = sh_lex(lp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->digits = (n-'0');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n==LBRACT)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(n==RBRACE && lp->comsub)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(lp->token=n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(n=='~')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = ARG_MAC;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = (wordflags&ARG_EXP);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(n>2 && state[0]=='{' && state[n-1]=='}' && !lp->lex.intest && !lp->lex.incase && (c=='<' || c== '>') && sh_isoption(SH_BRACEEXPAND))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!strchr(state,','))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin stkseek(stkp,stktell(stkp)-1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->arg = (struct argnod*)stkfreeze(stkp,1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(lp->token=IOVNAME);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = wordflags;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = wordflags;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(assignment<0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin stkseek(stkp,stktell(stkp)-1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->arg = (struct argnod*)stkfreeze(stkp,1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lex.reservok = 1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(lp->token=LABLSYM);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(assignment || (lp->lex.intest&&!lp->lex.incase) || mode==ST_NONE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c &= ~ARG_EXP;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((c&ARG_EXP) && (c&ARG_QUOTED))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c |= ARG_MAC;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode==ST_NONE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* eliminate trailing )) */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin stkseek(stkp,stktell(stkp)-2);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c&ARG_MESSAGE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh_isoption(SH_DICTIONARY))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->arg = sh_endword(shp,2);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!sh_isoption(SH_NOEXEC))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->arg = sh_endword(shp,1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c &= ~ARG_MESSAGE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(c==0 || (c&(ARG_MAC|ARG_EXP)) || (lp->lexd.warn && !lp->lexd.docword))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->arg = (struct argnod*)stkfreeze(stkp,1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->arg->argflag = (c?c:ARG_RAW);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(mode==ST_NONE)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->arg = sh_endword(shp,-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->arg = sh_endword(shp,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin state = lp->arg->argval;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->comp_assign = assignment;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(assignment)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->arg->argflag |= ARG_ASSIGN;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(!lp->lex.skipword)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->assignok = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->arg->argchn.cp = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->arg->argnxt.ap = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode==ST_NONE)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(lp->token=EXPRSYM);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lp->lex.intest)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lp->lex.testop1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lex.testop1 = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n==2 && state[0]=='-' && state[2]==0 &&
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin strchr(test_opchars,state[1]))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lp->lexd.warn && state[1]=='a')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_warn(0),e_lexobsolete2,shp->inlineno);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->digits = state[1];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->token = TESTUNOP;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(n==1 && state[0]=='!' && state[1]==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lex.testop1 = 1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->token = '!';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lex.testop2 = 1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->token = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(lp->token);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lex.incase = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = sh_lookup(state,shtab_testops);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch(c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case TEST_END:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lex.testop2 = lp->lex.intest = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lex.reservok = 1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->token = ETESTSYM;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(lp->token);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case TEST_SEQ:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lp->lexd.warn && state[1]==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_warn(0),e_lexobsolete3,shp->inlineno);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* FALL THRU */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lp->lex.testop2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lp->lexd.warn && (c&TEST_ARITH))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_warn(0),e_lexobsolete4,shp->inlineno,state);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c&TEST_PATTERN)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lex.incase = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(c==TEST_REP)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lex.incase = TEST_RE;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lex.testop2 = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->digits = c;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->token = TESTBINOP;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(lp->token);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case TEST_OR: case TEST_AND:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 0:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(lp->token=0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lp->lex.reservok /* && !lp->lex.incase*/ && n<=2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* check for {, }, ! */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = state[0];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n==1 && (c=='{' || c=='}' || c=='!'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lp->lexd.warn && c=='{' && lp->lex.incase==2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_warn(0),e_lexobsolete6,shp->inlineno);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lp->lex.incase==1 && c==RBRACE)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lex.incase = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(lp->token=c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(!lp->lex.incase && c==LBRACT && state[1]==LBRACT)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lex.intest = lp->lex.testop1 = 1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lex.testop2 = lp->lex.reservok = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(lp->token=BTESTSYM);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!lp->lex.skipword)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(n>1 && lp->lex.reservok==1 && mode==ST_NAME &&
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (c=sh_lookup(state,shtab_reserved)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lp->lex.incase)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lp->lex.incase >1)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lex.incase = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(c==ESACSYM)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lex.incase = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(c==FORSYM || c==CASESYM || c==SELECTSYM || c==FUNCTSYM || c==NSPACESYM)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lex.skipword = 1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lex.incase = 2*(c==CASESYM);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lex.skipword = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c==INSYM)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lex.reservok = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(c==TIMESYM)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* yech - POSIX requires time -p */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(fcgetc(n)==' ' || n=='\t');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcseek(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n=='-')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(lp->token=c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!(wordflags&ARG_QUOTED) && (lp->lex.reservok||lp->aliasok))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* check for aliases */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Namval_t* np;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!lp->lex.incase && !assignment && fcpeek(0)!=LPAREN &&
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (np=nv_search(state,shp->alias_tree,HASH_SCOPE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin && !nv_isattr(np,NV_NOEXPAND)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if KSHELL
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin && (!sh_isstate(SH_NOALIAS) || nv_isattr(np,NV_NOFREE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* KSHELL */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin && (state=nv_getval(np)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin setupalias(lp,state,np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_onattr(np,NV_NOEXPAND);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lex.reservok = 1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->assignok |= lp->lex.reservok;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(sh_lex(lp));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lex.reservok = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lex.skipword = lp->lexd.docword = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(lp->token=c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * read to end of command substitution
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic int comsub(register Lex_t *lp, int endtok)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int n,c,count=1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register int line=lp->sh->inlineno;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char word[5];
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner int off, messages=0, assignok=lp->assignok, csub;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct lexstate save;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin save = lp->lex;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin csub = lp->comsub;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_lexopen(lp,lp->sh,1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lexd.dolparen++;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lex.incase=0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin pushlevel(lp,0,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->comsub = (endtok==LBRACE);
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner off = fcseek(0) - lp->lexd.first;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(sh_lex(lp)==endtok)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if(endtok==LPAREN && fcseek(0)==lp->lexd.first)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner {
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner count++;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner lp->lexd.paren = 0;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner fcseek(off+2);
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* look for case and esac */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcgetc(c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* skip leading white space */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n==0 && !sh_lexstates[ST_BEGIN][c])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n==4)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh_lexstates[ST_NAME][c])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto skip;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin word[n++] = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh_lexstates[ST_NAME][c]==S_BREAK)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(memcmp(word,"case",4)==0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lex.incase=1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(memcmp(word,"esac",4)==0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lex.incase=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin skip:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c && (c!='#' || n==0))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcseek(-1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(c==RBRACE && lp->lex.incase)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lex.incase=0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin switch(c=sh_lex(lp))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin case LBRACE:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(endtok==LBRACE && !lp->lex.incase)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->comsub = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin count++;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin break;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin case RBRACE:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin rbrace:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(endtok==LBRACE && --count<=0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin goto done;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->comsub = (count==1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin break;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin case IPROCSYM: case OPROCSYM:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin case LPAREN:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(endtok==LPAREN && !lp->lex.incase)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin count++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case RPAREN:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lp->lex.incase)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lex.incase=0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(endtok==LPAREN && --count<=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto done;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case EOFSYM:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lastline = line;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lasttok = endtok;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_syntax(lp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case IOSEEKSYM:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fcgetc(c)!='#' && c>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcseek(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case IODOCSYM:
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz lp->lexd.docextra = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_lex(lp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 0:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lex.reservok = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin messages |= lp->lexd.message;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin break;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin case ';':
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin fcgetc(c);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(c==RBRACE && endtok==LBRACE)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin goto rbrace;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(c>0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin fcseek(-1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* fall through*/
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin default:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lex.reservok = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chindone:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin poplevel(lp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->comsub = csub;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lastline = line;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lexd.dolparen--;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lex = save;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->assignok = (endchar(lp)==RBRACT?assignok:0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(messages);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * here-doc nested in $(...)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * allocate ionode with delimiter filled in without disturbing stak
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void nested_here(register Lex_t *lp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register struct ionod *iop;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register int n,offset;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin struct argnod *arg = lp->arg;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Stk_t *stkp = lp->sh->stk;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin char *base;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(offset=stktell(stkp))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin base = stkfreeze(stkp,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin n = fcseek(0)-lp->lexd.docend;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz iop = newof(0,struct ionod,1,lp->lexd.docextra+n+ARGVAL);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin iop->iolst = lp->heredoc;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin stkseek(stkp,ARGVAL);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(lp->lexd.docextra)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sfseek(lp->sh->strbuf,(Sfoff_t)0, SEEK_SET);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sfmove(lp->sh->strbuf,stkp,lp->lexd.docextra,-1);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfwrite(stkp,lp->lexd.docend,n);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->arg = sh_endword(lp->sh,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin iop->ioname = (char*)(iop+1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin strcpy(iop->ioname,lp->arg->argval);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin iop->iofile = (IODOC|IORAW);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lp->lexd.docword>1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin iop->iofile |= IOSTRIP;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->heredoc = iop;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->arg = arg;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lexd.docword = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(offset)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin stkset(stkp,base,offset);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin stkseek(stkp,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * skip to <close> character
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * if <copy> is non,zero, then the characters are copied to the stack
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * <state> is the initial lexical state
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinvoid sh_lexskip(Lex_t *lp,int close, register int copy, int state)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *cp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lexd.nest = close;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lexd.lex_state = state;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lexd.noarg = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(copy)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin fcnotify(lex_advance,lp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lexd.nocopy++;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_lex(lp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lexd.noarg = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(copy)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin fcnotify(0,lp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!(cp=lp->lexd.first))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = fcfirst();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((copy = fcseek(0)-cp) > 0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfwrite(lp->sh->stk,cp,copy);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lexd.nocopy--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_CRNL
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ssize_t _sfwrite(Sfio_t *sp, const Void_t *buff, size_t n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin const char *cp = (const char*)buff, *next=cp, *ep = cp + n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int m=0,k;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(next = (const char*)memchr(next,'\r',ep-next))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*++next=='\n')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(k=next-cp-1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((k=sfwrite(sp,cp,k)) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(m>0?m:-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin m += k;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((k=sfwrite(sp,cp,ep-cp)) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(m>0?m:-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(m+k);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define sfwrite _sfwrite
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_CRNL */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * read in here-document from script
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * quoted here documents, and here-documents without special chars are
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * noted with the IOQUOTE flag
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * returns 1 for complete here-doc, 0 for EOF
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int here_copy(Lex_t *lp,register struct ionod *iop)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register const char *state;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c,n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *bufp,*cp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register Sfio_t *sp=lp->sh->heredocs, *funlog;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int stripcol=0,stripflg, nsave, special=0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(funlog=lp->sh->funlog)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fcfill()>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcseek(-1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->sh->funlog = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(iop->iolst)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin here_copy(lp,iop->iolst);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin iop->iooffset = sfseek(sp,(off_t)0,SEEK_END);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin iop->iosize = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin iop->iodelim=iop->ioname;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* check for and strip quoted characters in delimiter string */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(stripflg=iop->iofile&IOSTRIP)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(*iop->iodelim=='\t')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin iop->iodelim++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* skip over leading tabs in document */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(iop->iofile&IOLSEEK)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin iop->iofile &= ~IOLSEEK;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(fcgetc(c)=='\t' || c==' ')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c==' ')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stripcol++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stripcol += 8 - stripcol%8;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(fcgetc(c)=='\t');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcseek(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(iop->iofile&IOQUOTE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin state = sh_lexstates[ST_LIT];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin state = sh_lexstates[ST_QUOTE];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin bufp = fcseek(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = S_NL;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n!=S_NL)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* skip over regular characters */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while((n=STATE(state,c))==0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n==S_EOF || !(c=fcget()))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!lp->lexd.dolparen && (c=(fcseek(0)-1)-bufp))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n==S_ESC)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((c=sfwrite(sp,bufp,c))>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin iop->iosize += c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((c=lexfill(lp))<=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n==S_ESC)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_CRNL
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c=='\r' && (c=fcget())!=NL)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcseek(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_CRNL */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c==NL)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcseek(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputc(sp,'\\');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin bufp = fcseek(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcseek(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch(n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_NL:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->sh->inlineno++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((stripcol && c==' ') || (stripflg && c=='\t'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!lp->lexd.dolparen)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* write out line */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = fcseek(0)-bufp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((n=sfwrite(sp,bufp,n))>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin iop->iosize += n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* skip over tabs */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(stripcol)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int col=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin do
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcgetc(c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c==' ')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin col++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin col += 8 - col%8;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(col>stripcol)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (c==' ' || c=='\t');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else while(c=='\t')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcgetc(c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c<=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto done;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin bufp = fcseek(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c!=iop->iodelim[0])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = fcseek(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nsave = n = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(c=fcget()))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!lp->lexd.dolparen && (c=cp-bufp))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((c=sfwrite(sp,cp=bufp,c))>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin iop->iosize+=c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nsave = n;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((c=lexfill(lp))<=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = iop->iodelim[n]==0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto done;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_CRNL
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c=='\r' && (c=fcget())!=NL)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcseek(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c='\r';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_CRNL */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c==NL)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->sh->inlineno++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(iop->iodelim[n]==0 && (c==NL||c==RPAREN))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!lp->lexd.dolparen && (n=cp-bufp))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((n=sfwrite(sp,bufp,n))>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin iop->iosize += n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->sh->inlineno--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c==RPAREN)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcseek(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto done;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(iop->iodelim[n++]!=c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * The match for delimiter failed.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * nsave>0 only when a buffer boundary
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * was crossed while checking the
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * delimiter
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!lp->lexd.dolparen && nsave>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((n=sfwrite(sp,bufp,nsave))>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin iop->iosize += n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin bufp = fcfirst();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c==NL)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcseek(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_ESC:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n=1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_CRNL
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c=='\r')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcseek(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c=fcget())
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcseek(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c==NL)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n=2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin special++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_CRNL */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c==NL)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* new-line joining */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->sh->inlineno++;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(!lp->lexd.dolparen && (n=(fcseek(0)-bufp)-n)>=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(n && (n=sfwrite(sp,bufp,n))>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin iop->iosize += n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin bufp = fcseek(0)+1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin special++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcget();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_GRAVE:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_DOL:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin special++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chindone:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->sh->funlog = funlog;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lp->lexd.dolparen)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free((void*)iop);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(!special)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin iop->iofile |= IOQUOTE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * generates string for given token
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char *fmttoken(Lex_t *lp, register int sym, char *tok)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz int n=1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sym < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return((char*)sh_translate(e_lexzerobyte));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sym==0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(lp->arg?lp->arg->argval:"?");
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lp->lex.intest && lp->arg && *lp->arg->argval)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(lp->arg->argval);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sym&SYMRES)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register const Shtable_t *tp=shtab_reserved;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(tp->sh_number && tp->sh_number!=sym)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tp++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return((char*)tp->sh_name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sym==EOFSYM)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return((char*)sh_translate(e_endoffile));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sym==NL)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return((char*)sh_translate(e_newline));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tok[0] = sym;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sym&SYMREP)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz tok[n++] = sym;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch(sym&SYMMASK)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case SYMAMP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sym = '&';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case SYMPIPE:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sym = '|';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case SYMGT:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sym = '>';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case SYMLPAR:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sym = LPAREN;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case SYMSHARP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sym = '#';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin case SYMSEMI:
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(tok[0]=='<')
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz tok[n++] = '>';
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sym = ';';
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sym = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz tok[n++] = sym;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz tok[n] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(tok);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * print a bad syntax message
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinvoid sh_syntax(Lex_t *lp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register Shell_t *shp = lp->sh;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register const char *cp = sh_translate(e_unexpected);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *tokstr;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register int tok = lp->token;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char tokbuf[3];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfio_t *sp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((tok==EOFSYM) && lp->lasttok)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin tok = lp->lasttok;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = sh_translate(e_unmatched);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lastline = shp->inlineno;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tokstr = fmttoken(lp,tok,tokbuf);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((sp=fcfile()) || (shp->infd>=0 && (sp=shp->sftable[shp->infd])))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* clear out any pending input */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Sfio_t *top;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(fcget()>0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcclose();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(top=sfstack(sp,SF_POPSTACK))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfclose(top);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcclose();
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->inlineno = lp->inlineno;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->st.firstline = lp->firstline;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if KSHELL
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!sh_isstate(SH_INTERACTIVE) && !sh_isstate(SH_PROFILE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(shp->inlineno!=1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin errormsg(SH_DICT,ERROR_exit(SYNBAD),e_lexsyntax1,lp->lastline,tokstr,cp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_exit(SYNBAD),e_lexsyntax2,tokstr,cp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic char *stack_shift(Stk_t *stkp, register char *sp,char *dp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *ep;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register int offset = stktell(stkp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register int left = offset-(sp-stkptr(stkp,0));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int shift = (dp+1-sp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin offset += shift;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin stkseek(stkp,offset);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sp = stkptr(stkp,offset);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep = sp - shift;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(left--)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *--sp = *--ep;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(sp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Assumes that current word is unfrozen on top of the stak
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If <mode> is zero, gets rid of quoting and consider argument as string
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * and returns pointer to frozen arg
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If mode==1, just replace $"..." strings with international strings
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * The result is left on the stak
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If mode==2, the each $"" string is printed on standard output
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstruct argnod *sh_endword(Shell_t *shp,int mode)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register const char *state = sh_lexstates[ST_NESTED];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *sp,*dp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int inquote=0, inlit=0; /* set within quoted strings */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct argnod* argp=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *ep=0, *xp=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int bracket=0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Stk_t *stkp=shp->stk;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfputc(stkp,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sp = stkptr(stkp,ARGVAL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_MULTIBYTE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mbwide())
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin do
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int len;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch(len = mbsize(sp))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case -1: /* illegal multi-byte char */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 0:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 1:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n=state[*sp++];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * None of the state tables contain
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * entries for multibyte characters,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * however, they should be treated
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * the same as any other alph
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * character. Therefore, we'll use
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * the state of the 'a' character.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n=state['a'];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sp += len;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(n == 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_MULTIBYTE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while((n=state[*sp++])==0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp = sp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode<0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin inquote = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch(n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_EOF:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin stkseek(stkp,dp-stkptr(stkp,0));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode<=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin argp = (struct argnod*)stkfreeze(stkp,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argp->argflag = ARG_RAW|ARG_QUOTED;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(argp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_LIT:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(inquote&1))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin inlit = !inlit;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode==0 || (mode<0 && bracket))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ep)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *dp = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp = ep+stresc(ep);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_QUOTE:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode<0 && !bracket)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!inlit)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode<=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin inquote = inquote^1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ep)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *msg;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode==2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sfstdout,"%.*s\n",dp-ep,ep);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *--dp = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if ERROR_VERSION >= 20000317L
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin msg = ERROR_translate(0,error_info.id,0,ep);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# if ERROR_VERSION >= 20000101L
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin msg = ERROR_translate(error_info.id,ep);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin msg = ERROR_translate(ep,2);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = strlen(msg);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp = ep+n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sp-dp <= 1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sp = stack_shift(stkp,sp,dp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp = sp-1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep = dp-n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memmove(ep,msg,n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *dp++ = '"';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_DOL: /* check for $'...' and $"..." */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(inlit)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*sp==LPAREN || *sp==LBRACE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin inquote <<= 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(inquote&1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*sp=='\'' || *sp=='"')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*sp=='"')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin inquote |= 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin inlit = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sp++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((mode==0||(mode<0&&bracket)) || (inquote&1))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode==2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep = dp++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(mode==1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (ep=dp)[-1] = '"';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep = --dp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_ESC:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_CRNL
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*sp=='\r' && sp[1]=='\n')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sp++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_CRNL */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(inlit || mode>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode<0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(dp>=sp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sp = stack_shift(stkp,sp,dp+1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp = sp-2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *dp++ = '\\';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ep)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *dp++ = *sp++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = *sp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_DOS
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(inquote&1) && sh_lexstates[ST_NORM][n]==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_DOS */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(inquote&1) || (sh_lexstates[ST_QUOTE][n] && n!=RBRACE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n=='\n')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp[-1] = n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sp++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_POP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sp[-1]!=RBRACT)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!inlit && !(inquote&1))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin inquote >>= 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(xp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp = sh_checkid(xp,dp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin xp = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(--bracket<=0 && mode<0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin inquote = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if((inlit||inquote) && mode<0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp[-1] = '\\';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(dp>=sp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sp = stack_shift(stkp,sp,dp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp = sp-1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *dp++ = ']';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case S_BRACT:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(dp[-2]=='.')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin xp = dp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode<0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(inlit || (bracket&&inquote))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp[-1] = '\\';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(dp>=sp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sp = stack_shift(stkp,sp,dp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp = sp-1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *dp++ = '[';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(bracket++==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin inquote = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_MULTIBYTE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mbwide())
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin do
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int len;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch(len = mbsize(sp))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case -1: /* illegal multi-byte char */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 0:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 1:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n=state[*dp++ = *sp++];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * None of the state tables contain
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * entries for multibyte characters,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * however, they should be treated
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * the same as any other alph
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * character. Therefore, we'll use
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * the state of the 'a' character.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(len--)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *dp++ = *sp++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n=state['a'];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(n == 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_MULTIBYTE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while((n=state[*dp++ = *sp++])==0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstruct alias
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfdisc_t disc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Namval_t *np;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int nextc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int line;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char buf[2];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Lex_t *lp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin};
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * This code gets called whenever an end of string is found with alias
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifndef SF_ATEXIT
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define SF_ATEXIT 0
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * This code gets called whenever an end of string is found with alias
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef SF_BUFCONST
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int alias_exceptf(Sfio_t *iop,int type,void *data, Sfdisc_t *handle)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int alias_exceptf(Sfio_t *iop,int type,Sfdisc_t *handle)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct alias *ap = (struct alias*)handle;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Namval_t *np;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Lex_t *lp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(type==0 || type==SF_ATEXIT || !ap)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin lp = ap->lp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np = ap->np;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(type!=SF_READ)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(type==SF_CLOSING)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Sfdisc_t *dp = sfdisc(iop,SF_POPDISC);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(dp!=handle)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfdisc(iop,dp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(type==SF_FINAL)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free((void*)ap);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto done;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ap->nextc)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* if last character is a blank, then next work can be alias */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c = fcpeek(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(isblank(c))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->aliasok = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *ap->buf = ap->nextc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ap->nextc = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfsetbuf(iop,ap->buf,1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chindone:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(np)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_offattr(np,NV_NOEXPAND);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void setupalias(Lex_t *lp, const char *string,Namval_t *np)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Sfio_t *iop, *base;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct alias *ap = (struct alias*)malloc(sizeof(struct alias));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ap->disc = alias_disc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ap->lp = lp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ap->buf[1] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ap->np = np)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_KIA
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lp->kiafile)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned long r;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin r=kiaentity(lp,nv_name(np),-1,'p',0,0,lp->current,'a',0,"");
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfprintf(lp->kiatmp,"p;%..64d;p;%..64d;%d;%d;e;\n",lp->current,r,lp->sh->inlineno,lp->sh->inlineno);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_KIA */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((ap->nextc=fcget())==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ap->nextc = ' ';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ap->nextc = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin iop = sfopen(NIL(Sfio_t*),(char*)string,"s");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfdisc(iop, &ap->disc);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lexd.nocopy++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(base=fcfile()))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin base = sfopen(NIL(Sfio_t*),fcseek(0),"s");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcclose();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfstack(base,iop);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcfopen(base);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lexd.nocopy--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * grow storage stack for nested constructs by STACK_ARRAY
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int stack_grow(Lex_t *lp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lexd.lex_max += STACK_ARRAY;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lp->lexd.lex_match)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lexd.lex_match = (int*)realloc((char*)lp->lexd.lex_match,sizeof(int)*lp->lexd.lex_max);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->lexd.lex_match = (int*)malloc(sizeof(int)*STACK_ARRAY);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(lp->lexd.lex_match!=0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin