1 /***********************************************************************
3 * This software is part of the ast package *
4 * Copyright (c) 1982-2010 AT&T Intellectual Property *
5 * and is licensed under the *
6 * Common Public License, Version 1.0 *
7 * by AT&T Intellectual Property *
9 * A copy of the License is available at *
10 * http://www.opensource.org/licenses/cpl1.0.txt *
11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
13 * Information and Software Systems Research *
17 * David Korn <dgk@research.att.com> *
19 ***********************************************************************/
22 * KornShell lexical analyzer
24 * Written by David Korn
33 #include "FEATURE/options"
39 # define nv_getval(np) ((np)->nvalue)
45 #include "lexstates.h"
49 #define SYNBAD 3 /* exit value for syntax errors */
50 #define STACK_ARRAY 3 /* size of depth match stack growth */
52 #if _lib_iswblank < 0 /* set in lexstates.h to enable this code */
55 local_iswblank(wchar_t wc
)
57 static int initialized
;
65 return(iswctype(wc
, wt
));
71 * This structure allows for arbitrary depth nesting of (...), {...}, [...]
75 char incase
; /* 1 for case pattern, 2 after case */
76 char intest
; /* 1 inside [[...]] */
77 char testop1
; /* 1 when unary test op legal */
78 char testop2
; /* 1 when binary test op legal */
79 char reservok
; /* >0 for reserved word legal */
80 char skipword
; /* next word can't be reserved */
81 char last_quote
; /* last multi-line quote character */
109 #define _SHLEX_PRIVATE \
110 struct lexdata lexd; \
116 #define pushlevel(lp,c,s) ((lp->lexd.level>=lp->lexd.lex_max?stack_grow(lp):1) &&\
117 ((lp->lexd.lex_match[lp->lexd.level++]=lp->lexd.lastc),\
118 lp->lexd.lastc=(((s)<<CHAR_BIT)|(c))))
119 #define oldmode(lp) (lp->lexd.lastc>>CHAR_BIT)
120 #define endchar(lp) (lp->lexd.lastc&0xff)
121 #define setchar(lp,c) (lp->lexd.lastc = ((lp->lexd.lastc&~0xff)|(c)))
122 #define poplevel(lp) (lp->lexd.lastc=lp->lexd.lex_match[--lp->lexd.level])
124 static char *fmttoken(Lex_t
*, int, char*);
126 static int alias_exceptf(Sfio_t
*, int, void*, Sfdisc_t
*);
128 static int alias_exceptf(Sfio_t
*, int, Sfdisc_t
*);
130 static void setupalias(Lex_t
*,const char*, Namval_t
*);
131 static int comsub(Lex_t
*,int);
132 static void nested_here(Lex_t
*);
133 static int here_copy(Lex_t
*, struct ionod
*);
134 static int stack_grow(Lex_t
*);
135 static const Sfdisc_t alias_disc
= { NULL
, NULL
, NULL
, alias_exceptf
, NULL
};
139 static void refvar(Lex_t
*lp
, int type
)
141 register Shell_t
*shp
= lp
->sh
;
142 register Stk_t
*stkp
= shp
->stk
;
143 off_t off
= (fcseek(0)-(type
+1))-(lp
->lexd
.first
?lp
->lexd
.first
:fcfirst());
147 off
= (fcseek(0)-(type
+1)) - lp
->lexd
.first
;
148 r
=kiaentity(lp
,lp
->lexd
.first
+lp
->lexd
.kiaoff
+type
,off
-lp
->lexd
.kiaoff
,'v',-1,-1,lp
->current
,'v',0,"");
152 int n
,offset
= stktell(stkp
);
154 off
= offset
+ (fcseek(0)-(type
+1)) - fcfirst();
155 if(lp
->lexd
.kiaoff
< offset
)
157 /* variable starts on stak, copy remainder */
159 sfwrite(stkp
,fcfirst()+type
,off
-offset
);
160 n
= stktell(stkp
)-lp
->lexd
.kiaoff
;
161 begin
= stkptr(stkp
,lp
->lexd
.kiaoff
);
165 /* variable in data buffer */
166 begin
= fcfirst()+(type
+lp
->lexd
.kiaoff
-offset
);
167 n
= off
-lp
->lexd
.kiaoff
;
169 savptr
= stkfreeze(stkp
,0);
170 r
=kiaentity(lp
,begin
,n
,'v',-1,-1,lp
->current
,'v',0,"");
171 stkset(stkp
,savptr
,offset
);
173 sfprintf(lp
->kiatmp
,"p;%..64d;v;%..64d;%d;%d;r;\n",lp
->current
,r
,shp
->inlineno
,shp
->inlineno
);
175 #endif /* SHOPT_KIA */
178 * This routine gets called when reading across a buffer boundary
179 * If lexd.nocopy is off, then current token is saved on the stack
181 static void lex_advance(Sfio_t
*iop
, const char *buff
, register int size
, void *context
)
183 register Lex_t
*lp
= (Lex_t
*)context
;
184 register Shell_t
*shp
= lp
->sh
;
185 register Sfio_t
*log
= shp
->funlog
;
186 Stk_t
*stkp
= shp
->stk
;
188 /* write to history file and to stderr if necessary */
189 if(iop
&& !sfstacked(iop
))
191 if(sh_isstate(SH_HISTORY
) && shp
->hist_ptr
)
192 log
= shp
->hist_ptr
->histfp
;
193 sfwrite(log
, (void*)buff
, size
);
194 if(sh_isstate(SH_VERBOSE
))
195 sfwrite(sfstderr
, buff
, size
);
200 if(lp
->lexd
.dolparen
&& lp
->lexd
.docword
)
202 int n
= size
- (lp
->lexd
.docend
-(char*)buff
);
203 sfwrite(shp
->strbuf
,lp
->lexd
.docend
,n
);
204 lp
->lexd
.docextra
+= n
;
208 size
-= (lp
->lexd
.first
-(char*)buff
);
209 buff
= lp
->lexd
.first
;
211 lp
->arg
= (struct argnod
*)stkseek(stkp
,ARGVAL
);
213 lp
->lexd
.kiaoff
+= ARGVAL
;
214 #endif /* SHOPT_KIA */
216 if(size
>0 && (lp
->arg
||lp
->lexd
.noarg
))
218 sfwrite(stkp
,buff
,size
);
224 * fill up another input buffer
225 * preserves lexical state
227 static int lexfill(Lex_t
*lp
)
238 docextra
= lp
->lexd
.docextra
;
239 lp
->lex
= savelex
.lex
;
240 lp
->lexd
= savelex
.lexd
;
245 memcpy(lp
, &savelex
, offsetof(Lex_t
,lexd
));
248 if(lp
->lexd
.docword
&& docextra
)
250 lp
->lexd
.docextra
= docextra
;
251 lp
->lexd
.docend
= fcseek(0)-1;
257 * mode=1 for reinitialization
259 Lex_t
*sh_lexopen(Lex_t
*lp
, Shell_t
*sp
, int mode
)
263 lp
= (Lex_t
*)newof(0,Lex_t
,1,0);
266 fcnotify(lex_advance
,lp
);
267 lp
->lex
.intest
= lp
->lex
.incase
= lp
->lex
.skipword
= lp
->lexd
.warn
= 0;
269 lp
->lex
.reservok
= 1;
270 if(!sh_isoption(SH_DICTIONARY
) && sh_isoption(SH_NOEXEC
))
274 lp
->lexd
.noarg
= lp
->lexd
.level
= lp
->lexd
.dolparen
= lp
->lexd
.balance
= 0;
275 lp
->lexd
.nocopy
= lp
->lexd
.docword
= lp
->lexd
.nest
= lp
->lexd
.paren
= 0;
276 lp
->lexd
.lex_state
= lp
->lexd
.lastc
=0;
283 extern int lextoken(Lex_t
*);
284 int sh_lex(Lex_t
*lp
)
286 Shell_t
*shp
= lp
->sh
;
288 char *quoted
, *macro
, *split
, *expand
;
290 register int tok
= lextoken();
291 quoted
= macro
= split
= expand
= "";
292 if(tok
==0 && (flag
=lp
->arg
->argflag
))
301 sfprintf(sfstderr
,"line %d: %o:%s%s%s%s %s\n",shp
->inlineno
,tok
,quoted
,
302 macro
, split
, expand
, fmttoken(lp
,tok
,tokstr
));
305 #define sh_lex lextoken
309 * Get the next word and put it on the top of the stak
310 * A pointer to the current word is stored in lp->arg
311 * Returns the token type
313 int sh_lex(Lex_t
* lp
)
315 register Shell_t
*shp
= lp
->sh
;
316 register const char *state
;
317 register int n
, c
, mode
=ST_BEGIN
, wordflags
=0;
318 Stk_t
*stkp
= shp
->stk
;
319 int inlevel
=lp
->lexd
.level
, assignment
=0, ingrave
=0;
323 #endif /* SHOPT_MULTIBYTE */
327 return(lp
->token
=LPAREN
);
332 lp
->assignok
|= lp
->lex
.reservok
;
333 if(lp
->comp_assign
==2)
334 lp
->comp_assign
= lp
->lex
.reservok
= 0;
335 lp
->lexd
.arith
= (lp
->lexd
.nest
==1);
338 pushlevel(lp
,lp
->lexd
.nest
,ST_NONE
);
340 mode
= lp
->lexd
.lex_state
;
342 else if(lp
->lexd
.docword
)
344 if(fcgetc(c
)=='-' || c
=='#')
347 lp
->digits
=(c
=='#'?3:1);
357 if(!lp
->lexd
.dolparen
)
361 lp
->lexd
.first
= fcseek(0);
365 lp
->lastline
= lp
->sh
->inlineno
;
368 /* skip over characters in the current state */
369 state
= sh_lexstates
[mode
];
370 while((n
=STATE(state
,c
))==0);
378 if((n
=lexfill(lp
)) > 0)
383 /* check for zero byte in file */
388 char *cp
= error_info
.id
;
390 error_info
.id
= shp
->readscript
;
391 errormsg(SH_DICT
,ERROR_system(ERROR_NOEXEC
),e_exec
,cp
);
401 return(lp
->token
=EOFSYM
);
402 if(mode
>ST_NORM
&& lp
->lexd
.level
>0)
404 switch(c
=endchar(lp
))
418 case 1: /* for ((...)) */
425 case '"': case '`': case '\'':
426 lp
->lexd
.balance
= c
;
429 if(sp
&& !(sfset(sp
,0,0)&SF_STRING
))
435 lp
->lexd
.balance
= c
;
439 /* skip one or more comment line(s) */
440 lp
->lex
.reservok
= !lp
->lex
.intest
;
441 if((n
=lp
->lexd
.nocopy
) && lp
->lexd
.dolparen
)
445 while(fcgetc(c
)>0 && c
!='\n');
446 if(c
<=0 || lp
->heredoc
)
448 while(shp
->inlineno
++,fcpeek(0)=='\n')
450 while(state
[c
=fcpeek(0)]==0)
456 return(lp
->token
=EOFSYM
);
461 /* check for here-document */
464 if(!lp
->lexd
.dolparen
)
467 if(here_copy(lp
,lp
->heredoc
)<=0 && lp
->lasttok
)
469 lp
->lasttok
= IODOCSYM
;
474 if(!lp
->lexd
.dolparen
)
478 lp
->lex
.reservok
= !lp
->lex
.intest
;
479 lp
->lex
.skipword
= 0;
482 /* skip over new-lines */
483 lp
->lex
.last_quote
= 0;
484 while(shp
->inlineno
++,fcget()=='\n');
489 return(lp
->token
='\n');
492 if(lp
->lex
.incase
<=TEST_RE
)
494 /* implicit RPAREN for =~ test operator */
495 if(inlevel
+1==lp
->lexd
.level
)
504 /* return operator token */
511 lp
->digits
= (c
=='>');
512 lp
->lex
.skipword
= 1;
513 lp
->aliasok
= lp
->lex
.reservok
;
514 lp
->lex
.reservok
= 0;
519 lp
->lex
.reservok
= !lp
->lex
.intest
;
522 if(!lp
->lexd
.dolparen
)
526 lp
->lex
.testop1
= lp
->lex
.intest
;
530 if(state
[n
]==S_OP
|| n
=='#')
539 lp
->lastline
= shp
->inlineno
;
540 lp
->lexd
.lex_state
= ST_NESTED
;
546 else if(c
=='(' || c
==')')
550 if(!sh_isoption(SH_POSIX
) && n
=='>' && (sh_isoption(SH_BASH
) || sh_isstate(SH_PROFILE
)))
552 if(!sh_isoption(SH_BASH
) && !lp
->nonstandard
)
555 errormsg(SH_DICT
,ERROR_warn(0),e_lexnonstandard
,shp
->inlineno
);
565 else if(c
!='<' && c
!='>')
570 lp
->lex
.reservok
= 1;
571 lp
->lex
.skipword
= 0;
575 else if(c
=='<' && n
=='>')
582 lp
->token
= c
= IORDWRSYMT
;
590 else if(n
=='#' && (c
=='<'||c
=='>'))
592 else if(n
==';' && c
=='>')
606 lp
->lex
.incase
= (c
==BREAKCASESYM
|| c
==FALLTHRUSYM
);
610 if(lp
->lexd
.warn
&& (n
=fcpeek(0))!=RPAREN
&& n
!=' ' && n
!='\t')
611 errormsg(SH_DICT
,ERROR_warn(0),e_lexspace
,shp
->inlineno
,c
,n
);
614 if(c
==LPAREN
&& lp
->comp_assign
&& !lp
->lex
.intest
&& !lp
->lex
.incase
)
620 /* check for \<new-line> */
634 #endif /* SHOPT_CRNL */
648 fcsopen((char*)state
);
649 /* remove \new-line */
660 wordflags
|= ARG_QUOTED
;
664 else if(mode
==ST_NESTED
&& lp
->lexd
.warn
&&
665 endchar(lp
)==RBRACE
&&
666 sh_lexstates
[ST_DOL
][n
]==S_DIG
668 errormsg(SH_DICT
,ERROR_warn(0),e_lexfuture
,shp
->inlineno
,n
);
669 #endif /* STR_MAXIMAL */
672 if(!lp
->lex
.skipword
)
673 lp
->lex
.reservok
*= 2;
677 if(!lp
->lexd
.dolparen
)
678 lp
->lexd
.first
= fcseek(0)-LEN
;
679 else if(lp
->lexd
.docword
)
680 lp
->lexd
.docend
= fcseek(0)-LEN
;
689 if(c
=='~' && n
==LPAREN
&& lp
->lex
.incase
)
690 lp
->lex
.incase
= TEST_RE
;
702 /* skip new-line joining */
703 if(c
=='\\' && fcpeek(0)=='\n')
710 if(!lp
->lexd
.dolparen
)
711 lp
->lexd
.first
= fcseek(0);
712 else if(lp
->lexd
.docword
)
713 lp
->lexd
.docend
= fcseek(0);
714 if(c
=='[' && lp
->assignok
>=SH_ASSIGN
)
723 if(oldmode(lp
)==ST_NONE
&& !lp
->lexd
.noarg
) /* in ((...)) */
725 if((c
=fcpeek(0))==LPAREN
|| c
==RPAREN
|| c
=='$' || c
==LBRACE
|| c
==RBRACE
|| c
=='[' || c
==']')
732 wordflags
|= ARG_QUOTED
;
737 if(oldmode(lp
)==ST_QUOTE
) /* $' within "" or `` */
740 errormsg(SH_DICT
,ERROR_warn(0),e_lexslash
,shp
->inlineno
);
746 if(lp
->lexd
.warn
&& lp
->lex
.last_quote
&& shp
->inlineno
> lp
->lastline
)
747 errormsg(SH_DICT
,ERROR_warn(0),e_lexlongquote
,lp
->lastline
,lp
->lex
.last_quote
);
748 lp
->lex
.last_quote
= 0;
749 lp
->lastline
= shp
->inlineno
;
751 pushlevel(lp
,'\'',mode
);
755 /* check for multi-line single-quoted string */
756 else if(shp
->inlineno
> lp
->lastline
)
757 lp
->lex
.last_quote
= '\'';
771 if(lp
->lexd
.warn
&& (mode
!=ST_QUOTE
|| endchar(lp
)!='`'))
772 errormsg(SH_DICT
,ERROR_warn(0),e_lexobsolete1
,shp
->inlineno
);
773 wordflags
|=(ARG_MAC
|ARG_EXP
);
778 if(oldmode(lp
)==ST_NONE
&& lp
->lexd
.arith
) /* in ((...)) */
780 if(n
!=S_GRAVE
|| fcpeek(0)=='\'')
784 wordflags
|=ARG_QUOTED
;
787 if(c
!='"' || mode
!=ST_QNEST
)
789 if(lp
->lexd
.warn
&& lp
->lex
.last_quote
&& shp
->inlineno
> lp
->lastline
)
790 errormsg(SH_DICT
,ERROR_warn(0),e_lexlongquote
,lp
->lastline
,lp
->lex
.last_quote
);
791 lp
->lex
.last_quote
=0;
792 lp
->lastline
= shp
->inlineno
;
793 pushlevel(lp
,c
,mode
);
799 else if((n
=endchar(lp
))==c
)
801 if(shp
->inlineno
> lp
->lastline
)
802 lp
->lex
.last_quote
= c
;
806 else if(c
=='"' && n
==RBRACE
)
810 /* don't check syntax inside `` */
811 if(mode
==ST_QUOTE
&& ingrave
)
815 lp
->lexd
.kiaoff
= fcseek(0)-lp
->lexd
.first
;
817 lp
->lexd
.kiaoff
= stktell(stkp
)+fcseek(0)-fcfirst();
818 #endif /* SHOPT_KIA */
819 pushlevel(lp
,'$',mode
);
824 wordflags
|= ARG_MAC
;
828 wordflags
|= comsub(lp
,c
);
831 if((n
=endchar(lp
)) == '$')
833 if(mode
!=ST_QUOTE
|| n
==RBRACE
)
840 /* end $identifier */
844 #endif /* SHOPT_KIA */
845 if(lp
->lexd
.warn
&& c
==LBRACT
&& !lp
->lex
.intest
&& !lp
->lexd
.arith
&& oldmode(lp
)!= ST_NESTED
)
846 errormsg(SH_DICT
,ERROR_warn(0),e_lexusebrace
,shp
->inlineno
);
852 /* make sure next character is alpha */
860 if(isaletter(n
) || n
==LBRACT
)
874 wordflags
|= ARG_MAC
;
875 if(endchar(lp
)==RBRACE
)
882 if(c
=='.' && endchar(lp
)=='$')
886 wordflags
|= ARG_MAC
;
890 if(n
==S_ALP
) /* $identifier */
900 #endif /* SHOPT_TYPEDEF */
934 if((n
=endchar(lp
)) == '$')
936 if(c
=='*' || (n
=sh_lexstates
[ST_BRACE
][c
])!=S_MOD1
&& n
!=S_MOD2
)
938 /* see whether inside `...` */
941 if((n
= endchar(lp
)) != '`')
943 pushlevel(lp
,RBRACE
,mode
);
950 if(oldmode(lp
)==ST_QUOTE
|| oldmode(lp
)==ST_NONE
)
952 /* allow ' inside "${...}" */
953 if(c
==':' && fcgetc(n
)>0)
969 #endif /* SHOPT_KIA */
970 if(c
!=':' && fcgetc(n
)>0)
974 if(!c
|| (fcgetc(n
)>0))
984 else if(lp
->lexd
.warn
)
985 errormsg(SH_DICT
,ERROR_warn(0),e_lexquote
,shp
->inlineno
,'%');
992 if((c
=endchar(lp
)) == '$')
997 if(state
[c
]!=S_ERR
&& c
!=RBRACE
)
999 if((n
=sh_lexstates
[ST_BEGIN
][c
])==0 || n
==S_OP
|| n
==S_NLTOK
)
1016 if(lp
->lexd
.warn
&& c
!='/' && sh_lexstates
[ST_NORM
][c
]!=S_BREAK
&& (c
!='"' || mode
==ST_QUOTE
))
1017 errormsg(SH_DICT
,ERROR_warn(0),e_lexslash
,shp
->inlineno
);
1018 else if(c
=='"' && mode
!=ST_QUOTE
&& !ingrave
)
1019 wordflags
|= ARG_MESSAGE
;
1024 if(lp
->lexd
.warn
&& endchar(lp
)==RBRACE
)
1025 errormsg(SH_DICT
,ERROR_warn(0),e_lexusequote
,shp
->inlineno
,c
);
1028 pushlevel(lp
,RPAREN
,mode
);
1033 if(lp
->lexd
.level
<= inlevel
)
1035 if(lp
->lexd
.level
==inlevel
+1 && lp
->lex
.incase
>=TEST_RE
&& !lp
->lex
.intest
)
1041 if(c
==RBRACT
&& !(n
==RBRACT
|| n
==RPAREN
))
1043 if((c
==RBRACE
||c
==RPAREN
) && n
==RPAREN
)
1045 if(fcgetc(n
)==LPAREN
)
1055 if(c
==';' && n
!=';')
1057 if(lp
->lexd
.warn
&& n
==RBRACE
)
1058 errormsg(SH_DICT
,ERROR_warn(0),e_lexusequote
,shp
->inlineno
,c
);
1064 errormsg(SH_DICT
,ERROR_warn(0),e_lexescape
,shp
->inlineno
,c
);
1069 /* quotes in subscript need expansion */
1070 if(mode
==ST_NAME
&& (wordflags
&ARG_QUOTED
))
1071 wordflags
|= ARG_MAC
;
1072 /* check for ((...)) */
1073 if(n
==1 && c
==RPAREN
)
1075 if(fcgetc(n
)==RPAREN
)
1077 if(mode
==ST_NONE
&& !lp
->lexd
.dolparen
)
1079 lp
->lex
.reservok
= 1;
1080 lp
->lex
.skipword
= 0;
1081 return(lp
->token
=EXPRSYM
);
1083 /* backward compatibility */
1086 errormsg(SH_DICT
,ERROR_warn(0),e_lexnested
,shp
->inlineno
);
1087 if(!(state
=lp
->lexd
.first
))
1089 fcseek(state
-fcseek(0));
1092 lp
->arg
= (struct argnod
*)stkfreeze(stkp
,1);
1093 setupalias(lp
,lp
->arg
->argval
,NIL(Namval_t
*));
1097 return(lp
->token
=LPAREN
);
1106 if(c
==RBRACE
&& (mode
==ST_NAME
||mode
==ST_NORM
))
1110 assignment
= lp
->assignok
;
1115 if((c
=fcget())=='~')
1116 wordflags
|= ARG_MAC
;
1117 else if(c
!=LPAREN
&& assignment
==SH_COMPASSIGN
)
1123 if(lp
->lex
.reservok
&& !lp
->lex
.incase
)
1127 if(state
[c
]==S_BREAK
)
1135 /* check for possible subscript */
1136 if((n
=endchar(lp
))==RBRACT
|| n
==RPAREN
||
1138 (oldmode(lp
)==ST_NONE
) ||
1139 (mode
==ST_NAME
&& (lp
->assignok
||lp
->lexd
.level
)))
1147 errormsg(SH_DICT
,ERROR_exit(SYNBAD
),e_lexsyntax1
, shp
->inlineno
, "[]", "empty subscript");
1151 pushlevel(lp
,RBRACT
,mode
);
1152 wordflags
|= ARG_QUOTED
;
1156 wordflags
|= ARG_EXP
;
1161 if(lp
->lexd
.dolparen
)
1163 if(mode
==ST_BEGIN
&& (lp
->lex
.reservok
||lp
->comsub
))
1170 if(n
==RBRACT
|| sh_lexstates
[ST_NORM
][n
])
1171 return(lp
->token
=c
);
1175 else if(mode
==ST_BEGIN
)
1177 if(lp
->comsub
&& c
==RBRACE
)
1178 return(lp
->token
=c
);
1181 isfirst
= (lp
->lexd
.first
&&fcseek(0)==lp
->lexd
.first
+1);
1184 if(c
==LBRACE
&& n
==RBRACE
)
1188 else if(lp
->lex
.reservok
)
1190 /* check for reserved word { or } */
1191 if(lp
->lex
.reservok
&& state
[n
]==S_BREAK
&& isfirst
)
1193 if(sh_isoption(SH_BRACEEXPAND
) && c
==LBRACE
&& !assignment
&& state
[n
]!=S_BREAK
1194 && !lp
->lex
.incase
&& !lp
->lex
.intest
1195 && !lp
->lex
.skipword
)
1197 wordflags
|= ARG_EXP
;
1199 if(c
==RBRACE
&& n
==LPAREN
)
1204 wordflags
|= ARG_EXP
;
1208 if(fcgetc(n
)==LPAREN
)
1210 if(lp
->lex
.incase
==TEST_RE
)
1213 pushlevel(lp
,RPAREN
,ST_NORM
);
1216 wordflags
|= ARG_EXP
;
1217 pushlevel(lp
,RPAREN
,mode
);
1223 if(n
=='=' && c
=='+' && mode
==ST_NAME
)
1227 lp
->comp_assign
= 0;
1230 else if(mode
==ST_NONE
)
1236 lp
->lexd
.balance
= 0;
1239 if(lp
->lexd
.dolparen
)
1241 lp
->lexd
.balance
= 0;
1242 if(lp
->lexd
.docword
)
1244 lp
->lexd
.message
= (wordflags
&ARG_MESSAGE
);
1245 return(lp
->token
=0);
1247 if(!(state
=lp
->lexd
.first
))
1249 n
= fcseek(0)-(char*)state
;
1251 lp
->arg
= (struct argnod
*)stkseek(stkp
,ARGVAL
);
1253 sfwrite(stkp
,state
,n
);
1254 /* add balancing character if necessary */
1255 if(lp
->lexd
.balance
)
1257 sfputc(stkp
,lp
->lexd
.balance
);
1258 lp
->lexd
.balance
= 0;
1261 stkseek(stkp
,stktell(stkp
)-1);
1262 state
= stkptr(stkp
,ARGVAL
);
1263 n
= stktell(stkp
)-ARGVAL
;
1267 /* check for numbered redirection */
1269 if((c
=='<' || c
=='>') && isadigit(n
))
1272 lp
->digits
= (n
-'0');
1277 else if(n
==RBRACE
&& lp
->comsub
)
1278 return(lp
->token
=n
);
1282 c
= (wordflags
&ARG_EXP
);
1285 else if(n
>2 && state
[0]=='{' && state
[n
-1]=='}' && !lp
->lex
.intest
&& !lp
->lex
.incase
&& (c
=='<' || c
== '>') && sh_isoption(SH_BRACEEXPAND
))
1287 if(!strchr(state
,','))
1289 stkseek(stkp
,stktell(stkp
)-1);
1290 lp
->arg
= (struct argnod
*)stkfreeze(stkp
,1);
1291 return(lp
->token
=IOVNAME
);
1299 stkseek(stkp
,stktell(stkp
)-1);
1300 lp
->arg
= (struct argnod
*)stkfreeze(stkp
,1);
1301 lp
->lex
.reservok
= 1;
1302 return(lp
->token
=LABLSYM
);
1304 if(assignment
|| (lp
->lex
.intest
&&!lp
->lex
.incase
) || mode
==ST_NONE
)
1306 if((c
&ARG_EXP
) && (c
&ARG_QUOTED
))
1310 /* eliminate trailing )) */
1311 stkseek(stkp
,stktell(stkp
)-2);
1315 if(sh_isoption(SH_DICTIONARY
))
1316 lp
->arg
= sh_endword(shp
,2);
1317 if(!sh_isoption(SH_NOEXEC
))
1319 lp
->arg
= sh_endword(shp
,1);
1323 if(c
==0 || (c
&(ARG_MAC
|ARG_EXP
)) || (lp
->lexd
.warn
&& !lp
->lexd
.docword
))
1325 lp
->arg
= (struct argnod
*)stkfreeze(stkp
,1);
1326 lp
->arg
->argflag
= (c
?c
:ARG_RAW
);
1328 else if(mode
==ST_NONE
)
1329 lp
->arg
= sh_endword(shp
,-1);
1331 lp
->arg
= sh_endword(shp
,0);
1332 state
= lp
->arg
->argval
;
1333 lp
->comp_assign
= assignment
;
1335 lp
->arg
->argflag
|= ARG_ASSIGN
;
1336 else if(!lp
->lex
.skipword
)
1338 lp
->arg
->argchn
.cp
= 0;
1339 lp
->arg
->argnxt
.ap
= 0;
1341 return(lp
->token
=EXPRSYM
);
1346 lp
->lex
.testop1
= 0;
1347 if(n
==2 && state
[0]=='-' && state
[2]==0 &&
1348 strchr(test_opchars
,state
[1]))
1350 if(lp
->lexd
.warn
&& state
[1]=='a')
1351 errormsg(SH_DICT
,ERROR_warn(0),e_lexobsolete2
,shp
->inlineno
);
1352 lp
->digits
= state
[1];
1353 lp
->token
= TESTUNOP
;
1355 else if(n
==1 && state
[0]=='!' && state
[1]==0)
1357 lp
->lex
.testop1
= 1;
1362 lp
->lex
.testop2
= 1;
1368 c
= sh_lookup(state
,shtab_testops
);
1372 lp
->lex
.testop2
= lp
->lex
.intest
= 0;
1373 lp
->lex
.reservok
= 1;
1374 lp
->token
= ETESTSYM
;
1378 if(lp
->lexd
.warn
&& state
[1]==0)
1379 errormsg(SH_DICT
,ERROR_warn(0),e_lexobsolete3
,shp
->inlineno
);
1384 if(lp
->lexd
.warn
&& (c
&TEST_ARITH
))
1385 errormsg(SH_DICT
,ERROR_warn(0),e_lexobsolete4
,shp
->inlineno
,state
);
1388 else if(c
==TEST_REP
)
1389 lp
->lex
.incase
= TEST_RE
;
1390 lp
->lex
.testop2
= 0;
1392 lp
->token
= TESTBINOP
;
1396 case TEST_OR
: case TEST_AND
:
1398 return(lp
->token
=0);
1401 if(lp
->lex
.reservok
/* && !lp->lex.incase*/ && n
<=2)
1403 /* check for {, }, ! */
1405 if(n
==1 && (c
=='{' || c
=='}' || c
=='!'))
1407 if(lp
->lexd
.warn
&& c
=='{' && lp
->lex
.incase
==2)
1408 errormsg(SH_DICT
,ERROR_warn(0),e_lexobsolete6
,shp
->inlineno
);
1409 if(lp
->lex
.incase
==1 && c
==RBRACE
)
1411 return(lp
->token
=c
);
1413 else if(!lp
->lex
.incase
&& c
==LBRACT
&& state
[1]==LBRACT
)
1415 lp
->lex
.intest
= lp
->lex
.testop1
= 1;
1416 lp
->lex
.testop2
= lp
->lex
.reservok
= 0;
1417 return(lp
->token
=BTESTSYM
);
1421 if(!lp
->lex
.skipword
)
1423 if(n
>1 && lp
->lex
.reservok
==1 && mode
==ST_NAME
&&
1424 (c
=sh_lookup(state
,shtab_reserved
)))
1428 if(lp
->lex
.incase
>1)
1435 else if(c
==FORSYM
|| c
==CASESYM
|| c
==SELECTSYM
|| c
==FUNCTSYM
|| c
==NSPACESYM
)
1437 lp
->lex
.skipword
= 1;
1438 lp
->lex
.incase
= 2*(c
==CASESYM
);
1441 lp
->lex
.skipword
= 0;
1443 lp
->lex
.reservok
= 0;
1446 /* yech - POSIX requires time -p */
1447 while(fcgetc(n
)==' ' || n
=='\t');
1453 return(lp
->token
=c
);
1455 if(!(wordflags
&ARG_QUOTED
) && (lp
->lex
.reservok
||lp
->aliasok
))
1457 /* check for aliases */
1459 if(!lp
->lex
.incase
&& !assignment
&& fcpeek(0)!=LPAREN
&&
1460 (np
=nv_search(state
,shp
->alias_tree
,HASH_SCOPE
))
1461 && !nv_isattr(np
,NV_NOEXPAND
)
1463 && (!sh_isstate(SH_NOALIAS
) || nv_isattr(np
,NV_NOFREE
))
1465 && (state
=nv_getval(np
)))
1467 setupalias(lp
,state
,np
);
1468 nv_onattr(np
,NV_NOEXPAND
);
1469 lp
->lex
.reservok
= 1;
1470 lp
->assignok
|= lp
->lex
.reservok
;
1474 lp
->lex
.reservok
= 0;
1476 lp
->lex
.skipword
= lp
->lexd
.docword
= 0;
1477 return(lp
->token
=c
);
1481 * read to end of command substitution
1483 static int comsub(register Lex_t
*lp
, int endtok
)
1485 register int n
,c
,count
=1;
1486 register int line
=lp
->sh
->inlineno
;
1488 int off
, messages
=0, assignok
=lp
->assignok
, csub
;
1489 struct lexstate save
;
1492 sh_lexopen(lp
,lp
->sh
,1);
1493 lp
->lexd
.dolparen
++;
1496 lp
->comsub
= (endtok
==LBRACE
);
1497 off
= fcseek(0) - lp
->lexd
.first
;
1498 if(sh_lex(lp
)==endtok
)
1500 if(endtok
==LPAREN
&& fcseek(0)==lp
->lexd
.first
)
1508 /* look for case and esac */
1513 /* skip leading white space */
1514 if(n
==0 && !sh_lexstates
[ST_BEGIN
][c
])
1518 if(sh_lexstates
[ST_NAME
][c
])
1522 if(sh_lexstates
[ST_NAME
][c
]==S_BREAK
)
1524 if(memcmp(word
,"case",4)==0)
1526 else if(memcmp(word
,"esac",4)==0)
1530 if(c
&& (c
!='#' || n
==0))
1532 if(c
==RBRACE
&& lp
->lex
.incase
)
1534 switch(c
=sh_lex(lp
))
1537 if(endtok
==LBRACE
&& !lp
->lex
.incase
)
1545 if(endtok
==LBRACE
&& --count
<=0)
1547 lp
->comsub
= (count
==1);
1549 case IPROCSYM
: case OPROCSYM
:
1551 if(endtok
==LPAREN
&& !lp
->lex
.incase
)
1557 else if(endtok
==LPAREN
&& --count
<=0)
1561 lp
->lastline
= line
;
1562 lp
->lasttok
= endtok
;
1565 if(fcgetc(c
)!='#' && c
>0)
1569 lp
->lexd
.docextra
= 0;
1573 lp
->lex
.reservok
= 0;
1574 messages
|= lp
->lexd
.message
;
1578 if(c
==RBRACE
&& endtok
==LBRACE
)
1584 lp
->lex
.reservok
= 1;
1591 lp
->lastline
= line
;
1592 lp
->lexd
.dolparen
--;
1594 lp
->assignok
= (endchar(lp
)==RBRACT
?assignok
:0);
1599 * here-doc nested in $(...)
1600 * allocate ionode with delimiter filled in without disturbing stak
1602 static void nested_here(register Lex_t
*lp
)
1604 register struct ionod
*iop
;
1605 register int n
,offset
;
1606 struct argnod
*arg
= lp
->arg
;
1607 Stk_t
*stkp
= lp
->sh
->stk
;
1609 if(offset
=stktell(stkp
))
1610 base
= stkfreeze(stkp
,0);
1611 n
= fcseek(0)-lp
->lexd
.docend
;
1612 iop
= newof(0,struct ionod
,1,lp
->lexd
.docextra
+n
+ARGVAL
);
1613 iop
->iolst
= lp
->heredoc
;
1614 stkseek(stkp
,ARGVAL
);
1615 if(lp
->lexd
.docextra
)
1617 sfseek(lp
->sh
->strbuf
,(Sfoff_t
)0, SEEK_SET
);
1618 sfmove(lp
->sh
->strbuf
,stkp
,lp
->lexd
.docextra
,-1);
1620 sfwrite(stkp
,lp
->lexd
.docend
,n
);
1621 lp
->arg
= sh_endword(lp
->sh
,0);
1622 iop
->ioname
= (char*)(iop
+1);
1623 strcpy(iop
->ioname
,lp
->arg
->argval
);
1624 iop
->iofile
= (IODOC
|IORAW
);
1625 if(lp
->lexd
.docword
>1)
1626 iop
->iofile
|= IOSTRIP
;
1629 lp
->lexd
.docword
= 0;
1631 stkset(stkp
,base
,offset
);
1637 * skip to <close> character
1638 * if <copy> is non,zero, then the characters are copied to the stack
1639 * <state> is the initial lexical state
1641 void sh_lexskip(Lex_t
*lp
,int close
, register int copy
, int state
)
1644 lp
->lexd
.nest
= close
;
1645 lp
->lexd
.lex_state
= state
;
1648 fcnotify(lex_advance
,lp
);
1656 if(!(cp
=lp
->lexd
.first
))
1658 if((copy
= fcseek(0)-cp
) > 0)
1659 sfwrite(lp
->sh
->stk
,cp
,copy
);
1666 ssize_t
_sfwrite(Sfio_t
*sp
, const Void_t
*buff
, size_t n
)
1668 const char *cp
= (const char*)buff
, *next
=cp
, *ep
= cp
+ n
;
1670 while(next
= (const char*)memchr(next
,'\r',ep
-next
))
1675 if((k
=sfwrite(sp
,cp
,k
)) < 0)
1681 if((k
=sfwrite(sp
,cp
,ep
-cp
)) < 0)
1685 # define sfwrite _sfwrite
1686 #endif /* SHOPT_CRNL */
1689 * read in here-document from script
1690 * quoted here documents, and here-documents without special chars are
1691 * noted with the IOQUOTE flag
1692 * returns 1 for complete here-doc, 0 for EOF
1695 static int here_copy(Lex_t
*lp
,register struct ionod
*iop
)
1697 register const char *state
;
1699 register char *bufp
,*cp
;
1700 register Sfio_t
*sp
=lp
->sh
->heredocs
, *funlog
;
1701 int stripcol
=0,stripflg
, nsave
, special
=0;
1702 if(funlog
=lp
->sh
->funlog
)
1709 here_copy(lp
,iop
->iolst
);
1710 iop
->iooffset
= sfseek(sp
,(off_t
)0,SEEK_END
);
1712 iop
->iodelim
=iop
->ioname
;
1713 /* check for and strip quoted characters in delimiter string */
1714 if(stripflg
=iop
->iofile
&IOSTRIP
)
1716 while(*iop
->iodelim
=='\t')
1718 /* skip over leading tabs in document */
1719 if(iop
->iofile
&IOLSEEK
)
1721 iop
->iofile
&= ~IOLSEEK
;
1722 while(fcgetc(c
)=='\t' || c
==' ')
1727 stripcol
+= 8 - stripcol
%8;
1731 while(fcgetc(c
)=='\t');
1735 if(iop
->iofile
&IOQUOTE
)
1736 state
= sh_lexstates
[ST_LIT
];
1738 state
= sh_lexstates
[ST_QUOTE
];
1745 /* skip over regular characters */
1746 while((n
=STATE(state
,c
))==0);
1748 if(n
==S_EOF
|| !(c
=fcget()))
1750 if(!lp
->lexd
.dolparen
&& (c
=(fcseek(0)-1)-bufp
))
1754 if((c
=sfwrite(sp
,bufp
,c
))>0)
1757 if((c
=lexfill(lp
))<=0)
1762 if(c
=='\r' && (c
=fcget())!=NL
)
1764 #endif /* SHOPT_CRNL */
1778 if((stripcol
&& c
==' ') || (stripflg
&& c
=='\t'))
1780 if(!lp
->lexd
.dolparen
)
1782 /* write out line */
1784 if((n
=sfwrite(sp
,bufp
,n
))>0)
1787 /* skip over tabs */
1801 while (c
==' ' || c
=='\t');
1809 if(c
!=iop
->iodelim
[0])
1817 if(!lp
->lexd
.dolparen
&& (c
=cp
-bufp
))
1819 if((c
=sfwrite(sp
,cp
=bufp
,c
))>0)
1823 if((c
=lexfill(lp
))<=0)
1825 c
= iop
->iodelim
[n
]==0;
1830 if(c
=='\r' && (c
=fcget())!=NL
)
1836 #endif /* SHOPT_CRNL */
1839 if(iop
->iodelim
[n
]==0 && (c
==NL
||c
==RPAREN
))
1841 if(!lp
->lexd
.dolparen
&& (n
=cp
-bufp
))
1843 if((n
=sfwrite(sp
,bufp
,n
))>0)
1851 if(iop
->iodelim
[n
++]!=c
)
1854 * The match for delimiter failed.
1855 * nsave>0 only when a buffer boundary
1856 * was crossed while checking the
1859 if(!lp
->lexd
.dolparen
&& nsave
>0)
1861 if((n
=sfwrite(sp
,bufp
,nsave
))>0)
1887 #endif /* SHOPT_CRNL */
1890 /* new-line joining */
1892 if(!lp
->lexd
.dolparen
&& (n
=(fcseek(0)-bufp
)-n
)>=0)
1894 if(n
&& (n
=sfwrite(sp
,bufp
,n
))>0)
1912 lp
->sh
->funlog
= funlog
;
1913 if(lp
->lexd
.dolparen
)
1916 iop
->iofile
|= IOQUOTE
;
1921 * generates string for given token
1923 static char *fmttoken(Lex_t
*lp
, register int sym
, char *tok
)
1927 return((char*)sh_translate(e_lexzerobyte
));
1929 return(lp
->arg
?lp
->arg
->argval
:"?");
1930 if(lp
->lex
.intest
&& lp
->arg
&& *lp
->arg
->argval
)
1931 return(lp
->arg
->argval
);
1934 register const Shtable_t
*tp
=shtab_reserved
;
1935 while(tp
->sh_number
&& tp
->sh_number
!=sym
)
1937 return((char*)tp
->sh_name
);
1940 return((char*)sh_translate(e_endoffile
));
1942 return((char*)sh_translate(e_newline
));
1980 * print a bad syntax message
1983 void sh_syntax(Lex_t
*lp
)
1985 register Shell_t
*shp
= lp
->sh
;
1986 register const char *cp
= sh_translate(e_unexpected
);
1987 register char *tokstr
;
1988 register int tok
= lp
->token
;
1991 if((tok
==EOFSYM
) && lp
->lasttok
)
1994 cp
= sh_translate(e_unmatched
);
1997 lp
->lastline
= shp
->inlineno
;
1998 tokstr
= fmttoken(lp
,tok
,tokbuf
);
1999 if((sp
=fcfile()) || (shp
->infd
>=0 && (sp
=shp
->sftable
[shp
->infd
])))
2001 /* clear out any pending input */
2002 register Sfio_t
*top
;
2005 while(top
=sfstack(sp
,SF_POPSTACK
))
2010 shp
->inlineno
= lp
->inlineno
;
2011 shp
->st
.firstline
= lp
->firstline
;
2013 if(!sh_isstate(SH_INTERACTIVE
) && !sh_isstate(SH_PROFILE
))
2015 if(shp
->inlineno
!=1)
2017 errormsg(SH_DICT
,ERROR_exit(SYNBAD
),e_lexsyntax1
,lp
->lastline
,tokstr
,cp
);
2019 errormsg(SH_DICT
,ERROR_exit(SYNBAD
),e_lexsyntax2
,tokstr
,cp
);
2022 static char *stack_shift(Stk_t
*stkp
, register char *sp
,char *dp
)
2025 register int offset
= stktell(stkp
);
2026 register int left
= offset
-(sp
-stkptr(stkp
,0));
2027 register int shift
= (dp
+1-sp
);
2029 stkseek(stkp
,offset
);
2030 sp
= stkptr(stkp
,offset
);
2038 * Assumes that current word is unfrozen on top of the stak
2039 * If <mode> is zero, gets rid of quoting and consider argument as string
2040 * and returns pointer to frozen arg
2041 * If mode==1, just replace $"..." strings with international strings
2042 * The result is left on the stak
2043 * If mode==2, the each $"" string is printed on standard output
2045 struct argnod
*sh_endword(Shell_t
*shp
,int mode
)
2047 register const char *state
= sh_lexstates
[ST_NESTED
];
2049 register char *sp
,*dp
;
2050 register int inquote
=0, inlit
=0; /* set within quoted strings */
2051 struct argnod
* argp
=0;
2054 Stk_t
*stkp
=shp
->stk
;
2056 sp
= stkptr(stkp
,ARGVAL
);
2063 switch(len
= mbsize(sp
))
2065 case -1: /* illegal multi-byte char */
2072 * None of the state tables contain
2073 * entries for multibyte characters,
2074 * however, they should be treated
2075 * the same as any other alph
2076 * character. Therefore, we'll use
2077 * the state of the 'a' character.
2086 #endif /* SHOPT_MULTIBYTE */
2087 while((n
=state
[*sp
++])==0);
2096 stkseek(stkp
,dp
-stkptr(stkp
,0));
2099 argp
= (struct argnod
*)stkfreeze(stkp
,0);
2100 argp
->argflag
= ARG_RAW
|ARG_QUOTED
;
2107 if(mode
==0 || (mode
<0 && bracket
))
2120 if(mode
<0 && !bracket
)
2126 inquote
= inquote
^1;
2132 sfprintf(sfstdout
,"%.*s\n",dp
-ep
,ep
);
2137 #if ERROR_VERSION >= 20000317L
2138 msg
= ERROR_translate(0,error_info
.id
,0,ep
);
2140 # if ERROR_VERSION >= 20000101L
2141 msg
= ERROR_translate(error_info
.id
,ep
);
2143 msg
= ERROR_translate(ep
,2);
2150 sp
= stack_shift(stkp
,sp
,dp
);
2160 case S_DOL
: /* check for $'...' and $"..." */
2163 if(*sp
==LPAREN
|| *sp
==LBRACE
)
2170 if(*sp
=='\'' || *sp
=='"')
2177 if((mode
==0||(mode
<0&&bracket
)) || (inquote
&1))
2190 if(*sp
=='\r' && sp
[1]=='\n')
2192 #endif /* SHOPT_CRNL */
2199 sp
= stack_shift(stkp
,sp
,dp
+1);
2210 if(!(inquote
&1) && sh_lexstates
[ST_NORM
][n
]==0)
2212 #endif /* SHOPT_DOS */
2213 if(!(inquote
&1) || (sh_lexstates
[ST_QUOTE
][n
] && n
!=RBRACE
))
2225 if(!inlit
&& !(inquote
&1))
2229 dp
= sh_checkid(xp
,dp
);
2231 if(--bracket
<=0 && mode
<0)
2234 else if((inlit
||inquote
) && mode
<0)
2239 sp
= stack_shift(stkp
,sp
,dp
);
2250 if(inlit
|| (bracket
&&inquote
))
2255 sp
= stack_shift(stkp
,sp
,dp
);
2260 else if(bracket
++==0)
2271 switch(len
= mbsize(sp
))
2273 case -1: /* illegal multi-byte char */
2276 n
=state
[*dp
++ = *sp
++];
2280 * None of the state tables contain
2281 * entries for multibyte characters,
2282 * however, they should be treated
2283 * the same as any other alph
2284 * character. Therefore, we'll use
2285 * the state of the 'a' character.
2295 #endif /* SHOPT_MULTIBYTE */
2296 while((n
=state
[*dp
++ = *sp
++])==0);
2311 * This code gets called whenever an end of string is found with alias
2315 # define SF_ATEXIT 0
2318 * This code gets called whenever an end of string is found with alias
2321 static int alias_exceptf(Sfio_t
*iop
,int type
,void *data
, Sfdisc_t
*handle
)
2323 static int alias_exceptf(Sfio_t
*iop
,int type
,Sfdisc_t
*handle
)
2326 register struct alias
*ap
= (struct alias
*)handle
;
2327 register Namval_t
*np
;
2329 if(type
==0 || type
==SF_ATEXIT
|| !ap
)
2335 if(type
==SF_CLOSING
)
2337 register Sfdisc_t
*dp
= sfdisc(iop
,SF_POPDISC
);
2341 else if(type
==SF_FINAL
)
2347 /* if last character is a blank, then next work can be alias */
2348 register int c
= fcpeek(-1);
2351 *ap
->buf
= ap
->nextc
;
2353 sfsetbuf(iop
,ap
->buf
,1);
2358 nv_offattr(np
,NV_NOEXPAND
);
2363 static void setupalias(Lex_t
*lp
, const char *string
,Namval_t
*np
)
2365 register Sfio_t
*iop
, *base
;
2366 struct alias
*ap
= (struct alias
*)malloc(sizeof(struct alias
));
2367 ap
->disc
= alias_disc
;
2376 r
=kiaentity(lp
,nv_name(np
),-1,'p',0,0,lp
->current
,'a',0,"");
2377 sfprintf(lp
->kiatmp
,"p;%..64d;p;%..64d;%d;%d;e;\n",lp
->current
,r
,lp
->sh
->inlineno
,lp
->sh
->inlineno
);
2379 #endif /* SHOPT_KIA */
2380 if((ap
->nextc
=fcget())==0)
2385 iop
= sfopen(NIL(Sfio_t
*),(char*)string
,"s");
2386 sfdisc(iop
, &ap
->disc
);
2388 if(!(base
=fcfile()))
2389 base
= sfopen(NIL(Sfio_t
*),fcseek(0),"s");
2397 * grow storage stack for nested constructs by STACK_ARRAY
2399 static int stack_grow(Lex_t
*lp
)
2401 lp
->lexd
.lex_max
+= STACK_ARRAY
;
2402 if(lp
->lexd
.lex_match
)
2403 lp
->lexd
.lex_match
= (int*)realloc((char*)lp
->lexd
.lex_match
,sizeof(int)*lp
->lexd
.lex_max
);
2405 lp
->lexd
.lex_match
= (int*)malloc(sizeof(int)*STACK_ARRAY
);
2406 return(lp
->lexd
.lex_match
!=0);