home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
BURKS 2
/
BURKS_AUG97.ISO
/
BURKS
/
SOFTWARE
/
SOURCES
/
MAWK11AS.ZIP
/
BI_FUNCT.C
(
.txt
)
< prev
next >
Wrap
C/C++ Source or Header
|
1991-12-18
|
20KB
|
867 lines
/********************************************
bi_funct.c
copyright 1991, Michael D. Brennan
This is a source file for mawk, an implementation of
the AWK programming language.
Mawk is distributed without warranty under the terms of
the GNU General Public License, version 2, 1991.
********************************************/
/* $Log: bi_funct.c,v $
* Revision 5.1 91/12/05 07:55:35 brennan
* 1.1 pre-release
*
*/
#include "mawk.h"
#include "bi_funct.h"
#include "bi_vars.h"
#include "memory.h"
#include "init.h"
#include "files.h"
#include "fin.h"
#include "field.h"
#include "regexp.h"
#include "repl.h"
#include <math.h>
/* statics */
static STRING *PROTO(gsub, (PTR, CELL *, char *, int) ) ;
static void PROTO( fplib_err, (char *, double, char *) ) ;
/* global for the disassembler */
BI_REC bi_funct[] = { /* info to load builtins */
"index" , bi_index , 2, 2 ,
"substr" , bi_substr, 2, 3,
"length" , bi_length, 0, 1,
"sprintf" , bi_sprintf, 1, 255,
"sin", bi_sin , 1, 1 ,
"cos", bi_cos , 1, 1 ,
"atan2", bi_atan2, 2,2,
"exp", bi_exp, 1, 1,
"log", bi_log , 1, 1 ,
"int", bi_int, 1, 1,
"sqrt", bi_sqrt, 1, 1,
"rand" , bi_rand, 0, 0,
"srand", bi_srand, 0, 1,
"close", bi_close, 1, 1,
"system", bi_system, 1, 1,
"toupper", bi_toupper, 1, 1,
"tolower", bi_tolower, 1, 1,
(char *) 0, (PF_CP) 0, 0, 0 } ;
void bi_funct_init()
{ register BI_REC *p = bi_funct ;
register SYMTAB *stp ;
while ( p->name )
{ stp = insert( p->name ) ;
stp->type = ST_BUILTIN ;
stp->stval.bip = p++ ;
}
/* seed rand() off the clock */
{ CELL c ;
c.type = 0 ; (void) bi_srand(&c) ;
}
}
/**************************************************
string builtins (except split (in split.c) and [g]sub (at end))
**************************************************/
CELL *bi_length(sp)
register CELL *sp ;
{ unsigned len ;
if ( sp->type == 0 ) cellcpy(sp, field) ;
else sp-- ;
if ( sp->type < C_STRING ) cast1_to_s(sp) ;
len = string(sp)->len ;
free_STRING( string(sp) ) ;
sp->type = C_DOUBLE ;
sp->dval = (double) len ;
return sp ;
}
char *str_str(target, key , key_len)
register char *target, *key ;
unsigned key_len ;
{
switch( key_len )
{ case 0 : return (char *) 0 ;
case 1 : return strchr( target, *key) ;
case 2 :
while ( target = strchr(target, *key) )
if ( target[1] == key[1] ) return target ;
else target++ ;
/*failed*/
return (char *) 0 ;
}
key_len-- ;
while ( target = strchr(target, *key) )
if ( memcmp(target+1, key+1, SIZE_T(key_len)) == 0 ) return target ;
else target++ ;
/*failed*/
return (char *) 0 ;
}
CELL *bi_index(sp)
register CELL *sp ;
{ register int idx ;
unsigned len ;
char *p ;
sp-- ;
if ( TEST2(sp) != TWO_STRINGS )
cast2_to_s(sp) ;
if ( len = string(sp+1)->len )
idx = (p = str_str(string(sp)->str,string(sp+1)->str,len))
? p - string(sp)->str + 1 : 0 ;
else /* index of the empty string */
idx = 1 ;
free_STRING( string(sp) ) ;
free_STRING( string(sp+1) ) ;
sp->type = C_DOUBLE ;
sp->dval = (double) idx ;
return sp ;
}
/* substr(s, i, n)
if l = length(s)
then get the characters
from max(1,i) to min(l,n-i-1) inclusive */
CELL *bi_substr(sp)
CELL *sp ;
{ int n_args, len ;
register int i, n ;
STRING *sval ; /* substr(sval->str, i, n) */
n_args = sp->type ;
sp -= n_args ;
if ( sp->type != C_STRING ) cast1_to_s(sp) ;
/* don't use < C_STRING shortcut */
sval = string(sp) ;
if ( (len = sval->len) == 0 ) /* substr on null string */
{ if ( n_args == 3 ) cell_destroy(sp+2) ;
cell_destroy(sp+1) ;
return sp ;
}
if ( n_args == 2 )
{ n = MAX__INT ;
if ( sp[1].type != C_DOUBLE ) cast1_to_d(sp+1) ;
}
else
{ if ( TEST2(sp+1) != TWO_DOUBLES ) cast2_to_d(sp+1) ;
n = (int) sp[2].dval ;
}
i = (int) sp[1].dval - 1 ; /* i now indexes into string */
if ( i < 0 ) { n += i ; i = 0 ; }
if ( n > len - i ) n = len - i ;
if ( n <= 0 ) /* the null string */
{
sp->ptr = (PTR) &null_str ;
null_str.ref_cnt++ ;
}
else /* got something */
{
sp->ptr = (PTR) new_STRING((char *)0, n) ;
(void) memcpy(string(sp)->str, sval->str + i, SIZE_T(n)) ;
}
free_STRING(sval) ;
return sp ;
}
/*
match(s,r)
sp[0] holds r, sp[-1] holds s
*/
CELL *bi_match(sp)
register CELL *sp ;
{
char *p ;
unsigned length ;
if ( sp->type != C_RE ) cast_to_RE(sp) ;
if ( (--sp)->type < C_STRING ) cast1_to_s(sp) ;
cell_destroy(RSTART) ;
cell_destroy(RLENGTH) ;
RSTART->type = C_DOUBLE ;
RLENGTH->type = C_DOUBLE ;
p = REmatch(string(sp)->str, (sp+1)->ptr, &length) ;
if ( p )
{ sp->dval = (double) ( p - string(sp)->str + 1 ) ;
RLENGTH->dval = (double) length ;
}
else
{ sp->dval = 0.0 ;
RLENGTH->dval = -1.0 ; /* posix */
}
free_STRING(string(sp)) ;
sp->type = C_DOUBLE ;
RSTART->dval = sp->dval ;
return sp ;
}
CELL *bi_toupper(sp)
CELL *sp ;
{ STRING *old ;
register char *p, *q ;
if ( sp->type != C_STRING ) cast1_to_s(sp) ;
old = string(sp) ;
sp->ptr = (PTR) new_STRING((char *) 0, old->len) ;
q = string(sp)->str ; p = old->str ;
while ( *p )
{
*q = *p++ ;
if ( *q >= 'a' && *q <= 'z' ) *q += 'A' - 'a' ;
q++ ;
}
free_STRING(old) ;
return sp ;
}
CELL *bi_tolower(sp)
CELL *sp ;
{ STRING *old ;
register char *p, *q ;
if ( sp->type != C_STRING ) cast1_to_s(sp) ;
old = string(sp) ;
sp->ptr = (PTR) new_STRING((char *) 0, old->len) ;
q = string(sp)->str ; p = old->str ;
while ( *p )
{
*q = *p++ ;
if ( *q >= 'A' && *q <= 'Z' ) *q += 'a' - 'A' ;
q++ ;
}
free_STRING(old) ;
return sp ;
}
/************************************************
arithemetic builtins
************************************************/
static void fplib_err( fname, val, error)
char *fname ;
double val ;
char *error ;
{
rt_error("%s(%g) : %s" , fname, val, error) ;
}
CELL *bi_sin(sp)
register CELL *sp ;
{
#if ! STDC_MATHERR
if ( sp->type != C_DOUBLE ) cast1_to_d(sp) ;
sp->dval = sin( sp->dval ) ;
return sp ;
#else
double x ;
errno = 0 ;
if ( sp->type != C_DOUBLE ) cast1_to_d(sp) ;
x = sp->dval ;
sp->dval = sin( sp->dval ) ;
if ( errno ) fplib_err("sin", x, "loss of precision") ;
return sp ;
#endif
}
CELL *bi_cos(sp)
register CELL *sp ;
{
#if ! STDC_MATHERR
if ( sp->type != C_DOUBLE ) cast1_to_d(sp) ;
sp->dval = cos( sp->dval ) ;
return sp ;
#else
double x ;
errno = 0 ;
if ( sp->type != C_DOUBLE ) cast1_to_d(sp) ;
x = sp->dval ;
sp->dval = cos( sp->dval ) ;
if ( errno ) fplib_err("cos", x, "loss of precision") ;
return sp ;
#endif
}
CELL *bi_atan2(sp)
register CELL *sp ;
{
#if ! STDC_MATHERR
sp-- ;
if ( TEST2(sp) != TWO_DOUBLES ) cast2_to_d(sp) ;
sp->dval = atan2(sp->dval, (sp+1)->dval) ;
return sp ;
#else
errno = 0 ;
sp-- ;
if ( TEST2(sp) != TWO_DOUBLES ) cast2_to_d(sp) ;
sp->dval = atan2(sp->dval, (sp+1)->dval) ;
if ( errno ) rt_error("atan2(0,0) : domain error") ;
return sp ;
#endif
}
CELL *bi_log(sp)
register CELL *sp ;
{
#if ! STDC_MATHERR
if ( sp->type != C_DOUBLE ) cast1_to_d(sp) ;
sp->dval = log( sp->dval ) ;
return sp ;
#else
double x ;
errno = 0 ;
if ( sp->type != C_DOUBLE ) cast1_to_d(sp) ;
x = sp->dval ;
sp->dval = log( sp->dval ) ;
if ( errno ) fplib_err("log", x, "domain error") ;
return sp ;
#endif
}
CELL *bi_exp(sp)
register CELL *sp ;
{
#if ! STDC_MATHERR
if ( sp->type != C_DOUBLE ) cast1_to_d(sp) ;
sp->dval = exp(sp->dval) ;
return sp ;
#else
double x ;
errno = 0 ;
if ( sp->type != C_DOUBLE ) cast1_to_d(sp) ;
x = sp->dval ;
sp->dval = exp(sp->dval) ;
if ( errno && sp->dv