arith.c revision da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968
/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 1982-2007 AT&T Knowledge Ventures *
* and is licensed under the *
* Common Public License, Version 1.0 *
* by AT&T Knowledge Ventures *
* *
* A copy of the License is available at *
* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
* *
* Information and Software Systems Research *
* AT&T Research *
* Florham Park NJ *
* *
* David Korn <dgk@research.att.com> *
* *
***********************************************************************/
#pragma prototyped
/*
* Shell arithmetic - uses streval library
* David Korn
* AT&T Labs
*/
#include "defs.h"
#include <ctype.h>
#include "lexstates.h"
#include "name.h"
#include "streval.h"
#include "variables.h"
#ifndef LLONG_MAX
#endif
{
{ 0 },
"Inf",
};
{
{ 0 },
"NaN",
};
{
register char *sub=0;
{
{
/* do bindiing to node now */
flag++;
else
flag = 0;
}
else if(dtvnext(sh.var_tree) && (mp=nv_search((char*)np,sh.var_tree,HASH_NOSCOPE|HASH_SCOPE|HASH_BUCKET)))
{
{
}
}
}
{
if(!sub)
else
}
return(np);
}
{
register Sfdouble_t r= 0;
switch(type)
{
case ASSIGN:
{
break;
}
case LOOKUP:
{
register int c = *str;
if(c=='.')
str++;
if(isaletter(c))
{
int dot=0;
char *cp;
while(1)
{
if(c!='.')
break;
dot=1;
if((c = *++str) !='[')
continue;
str -=2;
}
if(c=='(')
{
c = **ptr;
{
break;
{
break;
}
}
break;
return(r);
}
{
break;
}
*str = 0;
if(sh_isoption(SH_NOEXEC))
else
{
char *saveptr = stakfreeze(0);
*str = c;
while(c=='[' || c=='.')
{
if(c=='[')
{
{
c = '[';
break;
}
}
else
{
str++;
}
}
*str = 0;
{
}
{
}
else
else
}
*str = c;
{
/* bind subscript later */
if(c=='[')
{
do
while((c= *str)=='[');
}
break;
}
if(c=='[')
{
do
while((c=*str)=='[');
}
else if(nv_isarray(np))
}
else
{
errno = 0;
{
lastbase=10;
errno = 0;
}
if(lastbase<=1)
lastbase=10;
if(*val=='0')
{
while(*val=='0')
val++;
val--;
}
c='e';
else
c = *str;
{
}
{
val += 3;
{
if(rr!=r)
{
r = rr;
}
}
}
}
break;
}
case VALUE:
{
if(sh_isoption(SH_NOEXEC))
return(0);
if(((lvalue->emode&2) || lvalue->level>1 || sh_isoption(SH_NOUNSET)) && nv_isnull(np) && !nv_isattr(np,NV_INTEGER))
{
return(0);
}
return(r);
}
case MESSAGE:
#if 0
if(warn)
else
#endif
}
return(r);
}
/*
* convert number defined by string to a Sfdouble_t
* ptr is set to the last character processed
* if mode>0, an error will be fatal with value <mode>
*/
{
register Sfdouble_t d;
if(*str==0)
{
if(ptr)
return(0);
}
errno = 0;
{
}
if(ptr)
return(d);
}
{
}
void *sh_arithcomp(register char *str)
{
if(*ptr)
return((void*)ep);
}