da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/***********************************************************************
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* This software is part of the ast package *
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner* Copyright (c) 1982-2010 AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* and is licensed under the *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Common Public License, Version 1.0 *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* by AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* A copy of the License is available at *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* http://www.opensource.org/licenses/cpl1.0.txt *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Information and Software Systems Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* AT&T Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Florham Park NJ *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* David Korn <dgk@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin***********************************************************************/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#pragma prototyped
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Shell arithmetic - uses streval library
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * David Korn
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * AT&T Labs
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "defs.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "lexstates.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "name.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "streval.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "variables.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifndef LLONG_MAX
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define LLONG_MAX LONG_MAX
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic Sfdouble_t NaN, Inf, Fun;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic Namval_t Infnod =
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { 0 },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "Inf",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin NV_NOFREE|NV_LDOUBLE,NV_RDONLY
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin};
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic Namval_t NaNnod =
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { 0 },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "NaN",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin NV_NOFREE|NV_LDOUBLE,NV_RDONLY
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin};
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic Namval_t FunNode =
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin { 0 },
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin "?",
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin NV_NOFREE|NV_LDOUBLE,NV_RDONLY
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin};
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic Namval_t *scope(Shell_t *shp,register Namval_t *np,register struct lval *lvalue,int assign)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int flag = lvalue->flag;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register char *sub=0, *cp=(char*)np;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register Namval_t *mp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int flags = HASH_NOSCOPE|HASH_SCOPE|HASH_BUCKET;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner int nosub = lvalue->nosub;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Dt_t *sdict = (shp->st.real_fun? shp->st.real_fun->sdict:0);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz Dt_t *root = shp->var_tree;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin assign = assign?NV_ASSIGN:NV_NOASSIGN;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner lvalue->nosub = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(cp>=lvalue->expr && cp < lvalue->expr+lvalue->elen)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int offset;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* do binding to node now */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int c = cp[flag];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin cp[flag] = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((!(np = nv_open(cp,shp->var_tree,assign|NV_VARNAME|NV_NOADD|NV_NOFAIL)) || nv_isnull(np)) && sh_macfun(shp,cp, offset = staktell()))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Fun = sh_arith(sub=stakptr(offset));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin FunNode.nvalue.ldp = &Fun;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp[flag] = c;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(&FunNode);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(!np && assign)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz np = nv_open(cp,shp->var_tree,assign|NV_VARNAME);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(!np)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz return(0);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz root = shp->last_root;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin cp[flag] = c;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(cp[flag+1]=='[')
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin flag++;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin flag = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin cp = (char*)np;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if((lvalue->emode&ARITH_COMP) && dtvnext(root) && ((mp=nv_search(cp,root,flags))||(sdict && (mp=nv_search(cp,sdict,flags)))))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin while(nv_isref(mp))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sub = nv_refsub(mp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin mp = nv_refnode(mp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin np = mp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if(!nosub && (flag || sub))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!sub)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sub = (char*)&lvalue->expr[flag];
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz nv_endsubscript(np,sub,NV_ADD|NV_SUBQUOTE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic Sfdouble_t arith(const char **ptr, struct lval *lvalue, int type, Sfdouble_t n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Shell_t *shp = &sh;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Sfdouble_t r= 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *str = (char*)*ptr;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register char *cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch(type)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case ASSIGN:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Namval_t *np = (Namval_t*)(lvalue->value);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin np = scope(shp,np,lvalue,1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_putval(np, (char*)&n, NV_LDOUBLE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin r=nv_getnum(np);
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner lvalue->value = (char*)np;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case LOOKUP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c = *str;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *xp=str;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin lvalue->value = (char*)0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c=='.')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin str++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = mbchar(str);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(isaletter(c))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Namval_t *np;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int dot=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(xp=str, c=mbchar(str), isaname(c));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin str = xp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(c=='[' && dot==NV_NOADD)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin str = nv_endsubscript((Namval_t*)0,str,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin c = *str;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c!='.')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin dot=NV_NOADD;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((c = *++str) !='[')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin str = nv_endsubscript((Namval_t*)0,cp=str,NV_SUBQUOTE)-1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh_checkid(cp+1,(char*)0))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin str -=2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c=='(')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int fsize = str- (char*)(*ptr);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin const struct mathtab *tp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = **ptr;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin lvalue->fun = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fsize<=(sizeof(tp->fname)-2)) for(tp=shtab_math; *tp->fname; tp++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*tp->fname > c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(tp->fname[1]==c && tp->fname[fsize+1]==0 && strncmp(&tp->fname[1],*ptr,fsize)==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin lvalue->fun = tp->fnptr;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin lvalue->nargs = *tp->fname;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(lvalue->fun)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin lvalue->value = (char*)ERROR_dictionary(e_function);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(r);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((lvalue->emode&ARITH_COMP) && dot)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin lvalue->value = (char*)*ptr;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin lvalue->flag = str-lvalue->value;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *str = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh_isoption(SH_NOEXEC))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np = L_ARGNOD;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int offset = staktell();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *saveptr = stakfreeze(0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Dt_t *root = (lvalue->emode&ARITH_COMP)?shp->var_base:shp->var_tree;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *str = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(c=='[' || c=='.')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c=='[')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin str = nv_endsubscript(np,cp=str,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((c= *str)!='[' && c!='.')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin str = cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = '[';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin dot = NV_NOADD|NV_NOFAIL;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin str++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(xp=str, c=mbchar(str), isaname(c));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin str = xp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *str = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin cp = (char*)*ptr;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if ((cp[0] == 'i' || cp[0] == 'I') && (cp[1] == 'n' || cp[1] == 'N') && (cp[2] == 'f' || cp[2] == 'F') && cp[3] == 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Inf = strtold("Inf", NiL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Infnod.nvalue.ldp = &Inf;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np = &Infnod;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if ((cp[0] == 'n' || cp[0] == 'N') && (cp[1] == 'a' || cp[1] == 'A') && (cp[2] == 'n' || cp[2] == 'N') && cp[3] == 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin NaN = strtold("NaN", NiL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin NaNnod.nvalue.ldp = &NaN;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np = &NaNnod;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(!(np = nv_open(*ptr,root,NV_NOASSIGN|NV_VARNAME|dot)))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lvalue->value = (char*)*ptr;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lvalue->flag = str-lvalue->value;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(saveptr != stakptr(0))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakset(saveptr,offset);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakseek(offset);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *str = c;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!np && lvalue->value)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin lvalue->value = (char*)np;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz /* bind subscript later */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(nv_isattr(np,NV_DOUBLE)==NV_DOUBLE)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz lvalue->isfloat=1;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz lvalue->flag = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c=='[')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz lvalue->flag = (str-lvalue->expr);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin do
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz str = nv_endsubscript(np,str,0);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz while((c= *str)=='[');
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char lastbase=0, *val = xp, oerrno = errno;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errno = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin r = strtonll(val,&str, &lastbase,-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*str=='8' || *str=='9')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin lastbase=10;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errno = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin r = strtonll(val,&str, &lastbase,-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(lastbase<=1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin lastbase=10;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*val=='0')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(*val=='0')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin val++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*val==0 || *val=='.' || *val=='x' || *val=='X')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin val--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(r==LLONG_MAX && errno)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c='e';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = *str;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(c==GETDECIMAL(0) || c=='e' || c == 'E' || lastbase ==
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin 16 && (c == 'p' || c == 'P'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin lvalue->isfloat=1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin r = strtold(val,&str);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(lastbase==10 && val[1])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(val[2]=='#')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin val += 3;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((str-val)>2*sizeof(Sflong_t))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfdouble_t rr;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin rr = strtold(val,&str);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(rr!=r)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin r = rr;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin lvalue->isfloat=1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errno = oerrno;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case VALUE:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Namval_t *np = (Namval_t*)(lvalue->value);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh_isoption(SH_NOEXEC))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin np = scope(shp,np,lvalue,0);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(!np)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(sh_isoption(SH_NOUNSET))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz *ptr = lvalue->value;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz goto skip;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz return(0);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(((lvalue->emode&2) || lvalue->level>1 || sh_isoption(SH_NOUNSET)) && nv_isnull(np) && !nv_isattr(np,NV_INTEGER))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *ptr = nv_name(np);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz skip:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin lvalue->value = (char*)ERROR_dictionary(e_notset);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin lvalue->emode |= 010;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin r = nv_getnum(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nv_isattr(np,NV_INTEGER|NV_BINARY)==(NV_INTEGER|NV_BINARY))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin lvalue->isfloat= (r!=(Sflong_t)r);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(nv_isattr(np,NV_DOUBLE)==NV_DOUBLE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin lvalue->isfloat=1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(r);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case MESSAGE:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfsync(NIL(Sfio_t*));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if 0
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(warn)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_warn(0),lvalue->value,*ptr);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_exit((lvalue->emode&3)!=0),lvalue->value,*ptr);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *ptr = str;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(r);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * convert number defined by string to a Sfdouble_t
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * ptr is set to the last character processed
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * if mode>0, an error will be fatal with value <mode>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSfdouble_t sh_strnum(register const char *str, char** ptr, int mode)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Sfdouble_t d;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char base=0, *last;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*str==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ptr)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *ptr = (char*)str;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errno = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin d = strtonll(str,&last,&base,-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*last || errno)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!last || *last!='.' || last[1]!='.')
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin d = strval(str,&last,arith,mode);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!ptr && *last && mode>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_exit(1),e_lexbadchar,*last,str);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if (!d && *str=='-')
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin d = -0.0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ptr)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *ptr = last;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(d);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSfdouble_t sh_arith(register const char *str)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(sh_strnum(str, (char**)0, 1));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid *sh_arithcomp(register char *str)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin const char *ptr = str;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Arith_t *ep;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep = arith_compile(str,(char**)&ptr,arith,ARITH_COMP|1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*ptr)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_exit(1),e_lexbadchar,*ptr,str);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return((void*)ep);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}