home *** CD-ROM | disk | FTP | other *** search
/ BURKS 2 / BURKS_AUG97.ISO / BURKS / SOFTWARE / SOURCES / MAWK11AS.ZIP / BI_FUNCT.C (.txt) < prev    next >
C/C++ Source or Header  |  1991-12-18  |  20KB  |  867 lines

  1.  
  2. /********************************************
  3. bi_funct.c
  4. copyright 1991, Michael D. Brennan
  5.  
  6. This is a source file for mawk, an implementation of
  7. the AWK programming language.
  8.  
  9. Mawk is distributed without warranty under the terms of
  10. the GNU General Public License, version 2, 1991.
  11. ********************************************/
  12.  
  13. /* $Log:    bi_funct.c,v $
  14.  * Revision 5.1  91/12/05  07:55:35  brennan
  15.  * 1.1 pre-release
  16.  * 
  17. */
  18.  
  19.  
  20. #include "mawk.h"
  21. #include "bi_funct.h"
  22. #include "bi_vars.h"
  23. #include "memory.h"
  24. #include "init.h"
  25. #include "files.h"
  26. #include "fin.h"
  27. #include "field.h"
  28. #include "regexp.h"
  29. #include "repl.h"
  30. #include <math.h>
  31.  
  32.  
  33. /* statics */
  34. static STRING *PROTO(gsub, (PTR, CELL *, char *, int) ) ;
  35. static void  PROTO( fplib_err, (char *, double, char *) ) ;
  36.  
  37.  
  38. /* global for the disassembler */
  39. BI_REC  bi_funct[] = { /* info to load builtins */
  40.  
  41. "index" , bi_index , 2, 2 ,
  42. "substr" , bi_substr, 2, 3,
  43. "length" , bi_length, 0, 1,
  44. "sprintf" , bi_sprintf, 1, 255,
  45. "sin", bi_sin , 1, 1 ,
  46. "cos", bi_cos , 1, 1 ,
  47. "atan2", bi_atan2, 2,2,
  48. "exp", bi_exp, 1, 1,
  49. "log", bi_log , 1, 1 ,
  50. "int", bi_int, 1, 1,
  51. "sqrt", bi_sqrt, 1, 1,
  52. "rand" , bi_rand, 0, 0,
  53. "srand", bi_srand, 0, 1,
  54. "close", bi_close, 1, 1,
  55. "system", bi_system, 1, 1,
  56. "toupper", bi_toupper, 1, 1,
  57. "tolower", bi_tolower, 1, 1,
  58.  
  59. (char *) 0, (PF_CP) 0, 0, 0 } ;
  60.  
  61.  
  62.  
  63. void bi_funct_init()
  64. { register BI_REC *p = bi_funct ;
  65.   register SYMTAB *stp ;
  66.  
  67.   while ( p->name )
  68.   { stp = insert( p->name ) ;
  69.     stp->type = ST_BUILTIN ;
  70.     stp->stval.bip = p++ ;
  71.   }
  72.   /* seed rand() off the clock */
  73.   { CELL c ;
  74.  
  75.     c.type = 0 ; (void) bi_srand(&c) ;
  76.   }
  77.  
  78. }
  79.  
  80. /**************************************************
  81.  string builtins (except split (in split.c) and [g]sub (at end))
  82.  **************************************************/
  83.  
  84. CELL *bi_length(sp)
  85.   register  CELL *sp ;
  86. { unsigned len ;
  87.  
  88.   if ( sp->type == 0 )  cellcpy(sp, field) ;
  89.   else sp-- ;
  90.  
  91.   if ( sp->type < C_STRING ) cast1_to_s(sp) ;
  92.   len = string(sp)->len ;
  93.  
  94.   free_STRING( string(sp) ) ;
  95.   sp->type = C_DOUBLE ;
  96.   sp->dval = (double) len ;
  97.  
  98.   return sp ;
  99. }
  100.  
  101. char *str_str(target, key , key_len)
  102.   register char *target, *key ;
  103.   unsigned key_len ;
  104.   switch( key_len )
  105.   { case 0 :  return (char *) 0 ;
  106.     case 1 :  return strchr( target, *key) ;
  107.     case 2 :
  108.         while ( target = strchr(target, *key) )
  109.           if ( target[1] == key[1] )  return  target ;
  110.           else target++ ;
  111.         /*failed*/
  112.         return (char *) 0 ;
  113.   }
  114.   key_len-- ;
  115.   while ( target = strchr(target, *key) )
  116.         if ( memcmp(target+1, key+1, SIZE_T(key_len)) == 0 ) return target ;
  117.         else target++ ;
  118.   /*failed*/
  119.   return (char *) 0 ;
  120. }
  121.  
  122.  
  123.  
  124. CELL *bi_index(sp)
  125.   register CELL *sp ;
  126. { register int idx ;
  127.   unsigned len ;
  128.   char *p ;
  129.  
  130.   sp-- ;
  131.   if ( TEST2(sp) != TWO_STRINGS )
  132.         cast2_to_s(sp) ;
  133.  
  134.   if ( len = string(sp+1)->len )
  135.     idx = (p = str_str(string(sp)->str,string(sp+1)->str,len))
  136.           ? p - string(sp)->str + 1 : 0 ;
  137.  
  138.   else  /* index of the empty string */
  139.     idx = 1 ;
  140.   
  141.   free_STRING( string(sp) ) ;
  142.   free_STRING( string(sp+1) ) ;
  143.   sp->type = C_DOUBLE ;
  144.   sp->dval = (double) idx ;
  145.   return sp ;
  146. }
  147.  
  148. /*  substr(s, i, n)
  149.     if l = length(s)
  150.     then get the characters
  151.     from  max(1,i) to min(l,n-i-1) inclusive */
  152.  
  153. CELL *bi_substr(sp)
  154.   CELL *sp ;
  155. { int n_args, len ;
  156.   register int i, n ;
  157.   STRING *sval ;  /* substr(sval->str, i, n) */
  158.  
  159.   n_args = sp->type ;
  160.   sp -= n_args ;
  161.   if ( sp->type != C_STRING )  cast1_to_s(sp) ;
  162.       /* don't use < C_STRING shortcut */
  163.   sval = string(sp) ;
  164.  
  165.   if ( (len = sval->len) == 0 )  /* substr on null string */
  166.   {  if ( n_args == 3 )  cell_destroy(sp+2) ;
  167.      cell_destroy(sp+1) ;
  168.      return sp ;
  169.   }
  170.  
  171.   if ( n_args == 2 )  
  172.   { n = MAX__INT  ;  
  173.     if ( sp[1].type != C_DOUBLE ) cast1_to_d(sp+1) ; 
  174.   }
  175.   else
  176.   { if ( TEST2(sp+1) != TWO_DOUBLES ) cast2_to_d(sp+1) ;
  177.     n = (int) sp[2].dval ;
  178.   }
  179.   i = (int) sp[1].dval - 1 ; /* i now indexes into string */
  180.  
  181.   if ( i < 0 ) { n += i ; i = 0 ; }
  182.   if ( n > len - i )  n = len - i ;
  183.  
  184.   if ( n <= 0 )  /* the null string */
  185.   { 
  186.     sp->ptr = (PTR) &null_str ;
  187.     null_str.ref_cnt++ ;
  188.   }
  189.   else  /* got something */
  190.   { 
  191.     sp->ptr = (PTR) new_STRING((char *)0, n) ;
  192.     (void) memcpy(string(sp)->str, sval->str + i, SIZE_T(n)) ;
  193.   }
  194.  
  195.   free_STRING(sval) ;
  196.   return sp ;
  197.  
  198. /*
  199.   match(s,r)
  200.   sp[0] holds r, sp[-1] holds s
  201. */
  202.  
  203. CELL *bi_match(sp)
  204.   register CELL *sp ;
  205.   char *p ;
  206.   unsigned length ;
  207.  
  208.   if ( sp->type != C_RE )  cast_to_RE(sp) ;
  209.   if ( (--sp)->type < C_STRING )  cast1_to_s(sp) ;
  210.  
  211.   cell_destroy(RSTART) ;
  212.   cell_destroy(RLENGTH) ;
  213.   RSTART->type = C_DOUBLE ;
  214.   RLENGTH->type = C_DOUBLE ;
  215.  
  216.   p = REmatch(string(sp)->str, (sp+1)->ptr, &length) ;
  217.  
  218.   if ( p )
  219.   { sp->dval = (double) ( p - string(sp)->str + 1 ) ;
  220.     RLENGTH->dval = (double) length ;
  221.   }
  222.   else
  223.   { sp->dval = 0.0 ;
  224.     RLENGTH->dval = -1.0 ; /* posix */
  225.   }
  226.  
  227.   free_STRING(string(sp)) ;
  228.   sp->type = C_DOUBLE ;
  229.  
  230.   RSTART->dval = sp->dval ;
  231.  
  232.   return sp ;
  233. }
  234.  
  235. CELL *bi_toupper(sp)
  236.   CELL *sp ;
  237. { STRING *old ;
  238.   register char *p, *q ;
  239.  
  240.   if ( sp->type != C_STRING )  cast1_to_s(sp) ;
  241.   old = string(sp) ;
  242.   sp->ptr = (PTR) new_STRING((char *) 0, old->len) ;
  243.  
  244.   q = string(sp)->str ; p = old->str ;
  245.  
  246.   while ( *p )
  247.   {
  248.     *q = *p++ ;
  249.     if ( *q >= 'a' && *q <= 'z' )  *q += 'A' - 'a' ;
  250.     q++ ;
  251.   }
  252.   free_STRING(old) ;
  253.   return sp ;
  254. }
  255.  
  256. CELL *bi_tolower(sp)
  257.   CELL *sp ;
  258. { STRING *old ;
  259.   register char *p, *q ;
  260.  
  261.   if ( sp->type != C_STRING )  cast1_to_s(sp) ;
  262.   old = string(sp) ;
  263.   sp->ptr = (PTR) new_STRING((char *) 0, old->len) ;
  264.  
  265.   q = string(sp)->str ; p = old->str ;
  266.  
  267.   while ( *p )
  268.   {
  269.     *q = *p++ ;
  270.     if ( *q >= 'A' && *q <= 'Z' )  *q += 'a' - 'A' ;
  271.     q++ ;
  272.   }
  273.   free_STRING(old) ;
  274.   return sp ;
  275. }
  276.  
  277.  
  278. /************************************************
  279.   arithemetic builtins
  280.  ************************************************/
  281.  
  282. static void fplib_err( fname, val, error)
  283.   char *fname ;
  284.   double val ;
  285.   char *error ;
  286. {
  287.   rt_error("%s(%g) : %s" , fname, val, error) ;
  288. }
  289.  
  290.  
  291. CELL *bi_sin(sp)
  292.   register CELL *sp ;
  293. #if ! STDC_MATHERR
  294.   if ( sp->type != C_DOUBLE )  cast1_to_d(sp) ;
  295.   sp->dval = sin( sp->dval ) ;
  296.   return sp ;
  297. #else
  298.   double x ;
  299.  
  300.   errno = 0 ;
  301.   if ( sp->type != C_DOUBLE )  cast1_to_d(sp) ;
  302.   x = sp->dval ;
  303.   sp->dval = sin( sp->dval ) ;
  304.   if ( errno )  fplib_err("sin", x, "loss of precision") ;
  305.   return sp ;
  306. #endif
  307. }
  308.  
  309. CELL *bi_cos(sp)
  310.   register CELL *sp ;
  311. #if ! STDC_MATHERR
  312.   if ( sp->type != C_DOUBLE )  cast1_to_d(sp) ;
  313.   sp->dval = cos( sp->dval ) ;
  314.   return sp ;
  315. #else
  316.   double x ;
  317.  
  318.   errno = 0 ;
  319.   if ( sp->type != C_DOUBLE )  cast1_to_d(sp) ;
  320.   x = sp->dval ;
  321.   sp->dval = cos( sp->dval ) ;
  322.   if ( errno )  fplib_err("cos", x, "loss of precision") ;
  323.   return sp ;
  324. #endif
  325. }
  326.  
  327. CELL *bi_atan2(sp)
  328.   register CELL *sp ;
  329. #if  !  STDC_MATHERR
  330.   sp-- ;
  331.   if ( TEST2(sp) != TWO_DOUBLES ) cast2_to_d(sp) ;
  332.   sp->dval = atan2(sp->dval, (sp+1)->dval) ;
  333.   return sp ;
  334. #else
  335.  
  336.   errno = 0 ;
  337.   sp-- ;
  338.   if ( TEST2(sp) != TWO_DOUBLES ) cast2_to_d(sp) ;
  339.   sp->dval = atan2(sp->dval, (sp+1)->dval) ;
  340.   if ( errno ) rt_error("atan2(0,0) : domain error") ;
  341.   return sp ;
  342. #endif
  343. }
  344.  
  345. CELL *bi_log(sp)
  346.   register CELL *sp ;
  347. #if ! STDC_MATHERR
  348.   if ( sp->type != C_DOUBLE )  cast1_to_d(sp) ;
  349.   sp->dval = log( sp->dval ) ;
  350.   return sp ;
  351. #else
  352.   double  x ;
  353.  
  354.   errno = 0 ;
  355.   if ( sp->type != C_DOUBLE )  cast1_to_d(sp) ;
  356.   x = sp->dval ;
  357.   sp->dval = log( sp->dval ) ;
  358.   if ( errno )  fplib_err("log", x, "domain error") ;
  359.   return sp ;
  360. #endif
  361. }
  362.  
  363. CELL *bi_exp(sp)
  364.   register CELL *sp ;
  365. #if  ! STDC_MATHERR
  366.   if ( sp->type != C_DOUBLE )  cast1_to_d(sp) ;
  367.   sp->dval = exp(sp->dval) ;
  368.   return sp ;
  369. #else
  370.   double  x ;
  371.  
  372.   errno = 0 ;
  373.   if ( sp->type != C_DOUBLE )  cast1_to_d(sp) ;
  374.   x = sp->dval ;
  375.   sp->dval = exp(sp->dval) ;
  376.   if ( errno && sp->dv