home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c160 / 1.ddi / SOURCE / E4PARSE.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-11-19  |  17.1 KB  |  719 lines

  1.  
  2. /*  e4parse.c    (c)Copyright Sequiter Software Inc., 1987-1990.  All rights reserved. */
  3.  
  4. #include "p4misc.h"
  5. #include "d4all.h"
  6. #include "u4error.h"
  7. #include "e4parse.h"
  8.  
  9. #include <string.h>
  10.  
  11. extern  E4FUNCTIONS  v4functions[] ;
  12. extern  int   v4type ;
  13.  
  14. static  int   e4parse_expr(void) ;
  15. static  int   e4lookup(char *,int,int,int) ;
  16. static  int   e4operator_cur(void) ;
  17. static  int   e4parse_function(void) ;
  18. static  int   e4parse_value(void) ;
  19. static  int   e4get_operator(int *) ;
  20. static  int   e4operator_off(void) ;
  21. static  int   e4field_function(long) ;
  22. static  int   e4type_check(char *) ;
  23.  
  24. static void   e4push_int(int) ;
  25. static void   e4push_str(char *, int) ;
  26. static void   e4push(void *, int, int) ;
  27. static void   e4operator_put(int) ;
  28.  
  29. static int   *op_ptr ;
  30. static int    op_used ;
  31. static char  *source, *err_source ;
  32. static int    result_len, result_used ;
  33.  
  34. extern int    v4cur_base ;
  35.  
  36. extern char  *v4eval_space ;
  37. extern int    v4eval_len ;
  38.  
  39. static char  *result_ptr ;
  40.  
  41. /* e4lookup, searches 'v4functions' for an operator or function.
  42.  
  43.        str - the function name
  44.        len - the number of characters in the function name
  45.  
  46.    len <= 0
  47.  
  48.       Needs Exact Lookup.  All of the characters in 'v4functions'
  49.       must be present in 'str'.
  50.  
  51.    len > 0 
  52.  
  53.       Only examines 'len' characters in 'str'.  It needs an exact
  54.       match on 'len' characters.  If 'len <= 3', there cannot
  55.       be any extra characters in 'v4functions'.
  56.  
  57.    Returns:  
  58.        >= 0   The index into v4functions.
  59.          -1   Not Located
  60. */
  61.  
  62. static int  e4lookup( char *str, int len, int start_i, int end_i )
  63. {
  64.    char u_str[20] ;
  65.    int  i, exact_lookup ;
  66.  
  67.    if ( len <= 0 )
  68.    {
  69.       exact_lookup =  1 ;
  70.  
  71.       /* Determine 'len' */
  72.       for ( len=0; str[len] != ' ' && str[len] != '\000'; len++ ) ;
  73.    }
  74.    else
  75.       exact_lookup =  0 ;
  76.  
  77.    if (len >= sizeof(u_str))  len = sizeof(u_str)-1 ;
  78.    memcpy( u_str, str, (size_t) len ) ;
  79.    u_str[len] =  '\000' ;
  80.    u4upper( u_str ) ;
  81.  
  82.    for( i=start_i; i<= end_i; i++)
  83.    {
  84.       if ( v4functions[i].code < 0 )  break ;
  85.  
  86.       if ( v4functions[i].name[0] == u_str[0] )
  87.       {
  88.          if ( exact_lookup )
  89.      {
  90.         if ( v4functions[i].name_len <= len && v4functions[i].name_len > 0 )
  91.            if (memcmp(u_str, v4functions[i].name, (size_t) v4functions[i].name_len) == 0)
  92.           return( i ) ;
  93.          }
  94.          else
  95.             if ( memcmp(u_str, v4functions[i].name, (size_t) len) == 0)
  96.             {
  97.                if ( len >= 4 )  return( i ) ;
  98.                if ( v4functions[i].name_len == len )  return(i) ;
  99.             }
  100.       }
  101.    }
  102.    return -1 ;
  103. }
  104.  
  105.  
  106. static void  e4operator_put( int operator_code)
  107. {
  108.    op_used +=  sizeof(operator_code) ;
  109.    if ( op_used > OPERATOR_LEN )
  110.        u4error( E_OVERFLOW, err_source, (char *) 0 ) ;
  111.  
  112.    *op_ptr++ = operator_code ;
  113. }
  114.  
  115. static int  e4operator_off()
  116. {
  117.    if ( op_used == 0 )  return Q_NO_FUNCTION ;
  118.    op_used -=  sizeof(int) ;
  119.    return ( *(--op_ptr)  ) ;
  120. }
  121.  
  122. static int  e4operator_cur()
  123. {
  124.    if ( op_used == 0 )  return( Q_NO_FUNCTION ) ;
  125.    return( op_ptr[-1] ) ;
  126. }
  127.  
  128. static void  e4push( void *str, int str_len, int pointer_code )
  129. {
  130.    int  pointer_width ;
  131.  
  132.    if ( pointer_code == 0 )
  133.       pointer_width =  0 ;
  134.    else
  135.       pointer_width =  (int) sizeof(int) ;
  136.  
  137.    if ( result_used + str_len + pointer_width  >  result_len )
  138.       u4error( E_OVERFLOW, err_source, (char *) 0) ;
  139.  
  140.    result_used =  result_used+ str_len+ pointer_width ;
  141.  
  142.    if ( pointer_code != 0 )
  143.    {
  144.       memcpy( result_ptr, &pointer_code, sizeof(int) ) ;
  145.       result_ptr +=  sizeof(int) ;
  146.    }
  147.  
  148.    memcpy( result_ptr, str, (size_t) str_len ) ;
  149.    result_ptr +=  str_len ;
  150. }
  151.  
  152. static void  e4push_int( int i )
  153. {
  154.    e4push( &i, (int) sizeof(i), 0 ) ;
  155. }
  156.  
  157. static void  e4push_str( char *str, int len )
  158. {
  159.    e4push( str, 0, I_STRING ) ;
  160.    e4push( &len, (int) sizeof(len), 0 ) ;
  161.    e4push( str, len, 0 ) ;
  162. }
  163.  
  164.  
  165. /* Returns  0, -1 (Error) */
  166. static  int e4parse_function()
  167. {
  168.    int i, f_num, num_parms ;
  169.    double d ;
  170.  
  171.    i= 0 ;
  172.    while ( u4name_char( source[i])) i++ ;
  173.  
  174.    f_num =  e4lookup( source, i, FIRST_FUNCTION, 0x7FFF) ;
  175.    if (f_num== Q_NO_FUNCTION)
  176.    {
  177.       u4error( E_FUNCTION, err_source, (char *) 0) ;
  178.       return(-1) ;
  179.    }
  180.  
  181.    source += i ;
  182.    while (*source != '(') source++ ;
  183.    source++ ;
  184.  
  185.    e4operator_put( Q_L_BRACKET ) ;
  186.  
  187.    num_parms = 0 ;
  188.  
  189.    for(;;)
  190.    {
  191.       if (*source == '\000')
  192.       {
  193.      u4error( E_RIGHT, err_source, (char *) 0) ;
  194.      return(-1) ;
  195.       }
  196.       if (*source == ')')
  197.       {
  198.      source++;
  199.      break ;
  200.       }
  201.  
  202.       if ( e4parse_expr() == -1 )  return( -1 )  ;
  203.       num_parms++ ;
  204.  
  205.       while (*source <= ' ' &&  *source>='\001') source++ ;
  206.       if (*source == ')')
  207.       {
  208.      source++;
  209.      break ;
  210.       }
  211.       if (*source != ',')
  212.       {
  213.      u4error( E_EXPECT, err_source, (char *) 0) ;
  214.      return(-1) ;
  215.       }
  216.       source ++ ;
  217.    }
  218.    e4operator_off() ;  /* pop the left bracket */
  219.  
  220.    if ( num_parms != v4functions[f_num].num_parms )
  221.    {
  222.       if ( strcmp( v4functions[f_num].name, "STR" ) == 0 )
  223.       {
  224.          if ( num_parms == 1 )
  225.      {
  226.         d = 10.0 ;
  227.         e4push( &d, sizeof(double), I_DOUBLE ) ;
  228.             num_parms++ ;
  229.          }
  230.          if ( num_parms == 2 )
  231.      {
  232.         d = 0.0 ;
  233.         e4push( &d, sizeof(double), I_DOUBLE ) ;
  234.             num_parms++ ;
  235.          }
  236.       }
  237.       if ( strcmp( v4functions[f_num].name, "SUBSTR" ) == 0 )
  238.       {
  239.          if ( num_parms == 2 )
  240.      {
  241.         d = (double) 0x7FFF ;
  242.         e4push( &d, sizeof(double), I_DOUBLE ) ;
  243.             num_parms++ ;
  244.          }
  245.       }
  246.    }
  247.  
  248.    if ( num_parms != v4functions[f_num].num_parms )
  249.    {
  250.       u4error( E_NUM_PARMS, "Expression", err_source, "Function", v4functions[f_num].name, (char *) 0 ) ;
  251.       return -1 ;
  252.    }
  253.  
  254.    e4push_int( f_num ) ;
  255.    return(  0 ) ;
  256. }
  257.  
  258.  
  259. /*  Returns:  0, -1 (Error) */
  260. static int  e4parse_value()
  261. {
  262.    while (*source <= ' ' && *source>= '\001') source++ ;
  263.  
  264.    /* expression */
  265.    if ( *source == '(')
  266.    {
  267.       ++source;
  268.       e4operator_put( Q_L_BRACKET) ;
  269.       if ( e4parse_expr() == -1)  return( -1 ) ;
  270.       while (*source <= ' ' && *source >= '\001') source++ ;
  271.       if (*source++ != ')' )
  272.       {
  273.      u4error( E_RIGHT, err_source, (char *) 0) ;
  274.      return( -1 ) ;
  275.       }
  276.       e4operator_off() ;
  277.       return( 0 ) ;
  278.    }
  279.  
  280.    /* logical */
  281.    if ( *source == '.' )
  282.    {
  283.       int  i_functions ;
  284.  
  285.       i_functions =  e4lookup( source, -1, FIRST_LOG, LAST_LOG ) ;
  286.  
  287.       if ( i_functions >= 0 )
  288.       {
  289.      source +=  v4functions[i_functions].name_len ;
  290.  
  291.          if ( strcmp( v4functions[i_functions].name, ".NOT." ) == 0 )
  292.             /* special case of a one operand operator */
  293.         if ( e4parse_expr() < 0 )  return( -1 ) ;
  294.  
  295.      e4push_int( i_functions ) ;
  296.          return 0 ;
  297.       }
  298.    }
  299.  
  300.    /* real */
  301.    if (*source>='0' && *source<='9' || *source == '-' || *source == '+' || *source == '.' )
  302.    {
  303.       double d ;
  304.       int    len ;
  305.  
  306.       for( len = 1; 
  307.            source[len] >= '0' && source[len] <= '9' || source[len] == '.';
  308.            len++ ) ;
  309.  
  310.       d =  c4atod( source, len ) ;
  311.       e4push( &d, sizeof(d), I_DOUBLE ) ;
  312.       source +=  len ;
  313.  
  314.       if ( strnicmp(source-1, ".AND.",5) == 0 || strnicmp(source-1, ".OR.",4) == 0 ||
  315.        strnicmp(source-1, ".NOT.",5) == 0 )   source-- ;
  316.       return( 0 ) ;
  317.    }
  318.  
  319.    /* string */
  320.    if (*source == '\'' || *source == '\"')
  321.    {
  322.       char end_char, *on ;
  323.       int  len ;
  324.  
  325.       on = source ;
  326.       end_char = *on++ ;
  327.       len = 0 ;
  328.       while (on[len] != end_char && on[len] != '\000') len++ ;
  329.  
  330.       if (on[len] == '\000')
  331.       {
  332.      u4error( E_STRING_LONG, err_source, (char *) 0 ) ;
  333.      return(-1) ;
  334.       }
  335.  
  336.       e4push_str( ++source, len ) ;
  337.       source += len+1 ;
  338.       return( 0 ) ;
  339.    }
  340.  
  341.    /* function or base/field */
  342.    if (u4name_char(*source) )
  343.    {  /* Must be a function or a  base,field */
  344.       char b_name[258], f_name[11] ;
  345.       int  save_base, i, j ;
  346.       long f_num ;
  347.  
  348.       i=0 ;
  349.       while ( u4name_char( source[i] ) ) i++ ;
  350.       j=i ;
  351.       while ( source[j] <= ' ' && source[j] >= '\001') j++;
  352.  
  353.       /* Function */
  354.       if    ( source[j] == '(')  return( e4parse_function() ) ;
  355.  
  356.       save_base = v4cur_base ;
  357.       if    ( source[i] == '-' && source[i+1] == '>')
  358.       {
  359.      memmove(b_name, source, (size_t) i) ;
  360.      b_name[i] = '\000' ;
  361.  
  362.      v4cur_base =  d4ref( b_name) ;
  363.      if (v4cur_base< 0)
  364.      {
  365.         v4cur_base =  save_base ;
  366.         u4error( E_BASE_NAME, err_source, (char *) 0 ) ;
  367.         return(-1) ;
  368.      }
  369.      source += (i+2) ;
  370.      i = 0 ;
  371.      while ( u4name_char( source[i]) ) i++ ;
  372.       }
  373.       if (i<= 10)
  374.       {
  375.      memmove(f_name, source, (size_t) i) ;
  376.      f_name[i]  =  '\000' ;
  377.      f_num        =  f4ref( f_name) ;
  378.      if (f_num>=0)
  379.      {
  380.         source += i ;
  381.  
  382.         e4push_int( e4field_function(f_num) ) ;
  383.         e4push( &f_num, sizeof(f_num), 0 ) ;
  384.         v4cur_base =  save_base ;
  385.         return( 0 ) ;
  386.      }
  387.       }
  388.       v4cur_base =  save_base ;
  389.    }
  390.  
  391.    u4error( E_VALUE, err_source, (char *) 0) ;
  392.    return( -1) ;
  393. }
  394.  
  395.  
  396. /*    Looks at the input string and returns and puts a character code on the
  397.    result stack corresponding to the next operator.  The operators all operate
  398.    on two operands.  Ex. +,-,*,/, >=, <, .AND., ...
  399.  
  400.       If the operator is ambiguous, return the arithmatic choice.
  401.  
  402.    Returns -2 (Done), 0, -1 (Error)
  403. */
  404.  
  405. static int  e4get_operator( int *op_return)
  406. {
  407.    int  op ;
  408.  
  409.    while (*source <= ' ' && *source >= '\001' ) source++ ;
  410.    if (*source=='\000' || *source==')' || *source==',') return(-2) ; /* Done */
  411.  
  412.    op  =  e4lookup( source, -1, FIRST_OPERATOR, LAST_OPERATOR ) ;
  413.  
  414.    if ( op < 0 )
  415.    {
  416.       u4error( E_OPERATOR, err_source, (char *) 0) ;
  417.       return( -1 ) ;
  418.    }
  419.    else
  420.    {
  421.       source +=  v4functions[op].name_len ;
  422.       *op_return = op ;
  423.       return( 0) ;
  424.    }
  425. }
  426.  
  427.  
  428. /*
  429.    Parses an expression constisting of     value [[operator value] ...]
  430.    The expression is ended by a ')', a ',' or a '\000'.
  431.    Operators are only popped until a '(', a ',' or the start of the stack.
  432.    Left to right evaluation for operators of equal priority.
  433.  
  434.       An ambiguous operator is one which can be interpreted differently
  435.    depending on its operands.  However, its operands depend on the
  436.    priority of the operators and the evaluation order.    Fortunately, the
  437.    priority of an ambigous operator is constant regardless of its
  438.    interpretation.  Consequently, the evaluation order is determined first.
  439.    Then ambiguous operators can be exactly determined.
  440.  
  441.    Ambigous operators:    +, -,  >, <, <=, >=, =, <>, #
  442.  
  443.    Return
  444.  
  445.        0  Normal
  446.       -1  Error
  447. */
  448.  
  449. static int e4parse_expr()
  450. {
  451.    int  rc ;
  452.    int  op_value ;
  453.  
  454.    if ( e4parse_value() == -1 )  return(-1) ;
  455.  
  456.    for(;;)
  457.    {
  458.       rc =  e4get_operator(&op_value) ;
  459.       if (rc  == -1)  return(-1) ;
  460.       if (rc  == -2)
  461.       {
  462.          /* Done */
  463.      while( e4operator_cur() != Q_L_BRACKET
  464.             && e4operator_cur() != Q_COMMA
  465.             && e4operator_cur() != Q_NO_FUNCTION )
  466.         e4push_int( e4operator_off() ) ;
  467.      return( 0) ;
  468.       }
  469.  
  470.       /* Everything with a higher or equal priority than 'op_value' must be
  471.      exectuted first. (equal because of left to right evaluation order)
  472.      Consequently, all high priority operators are sent to the result
  473.      stack.
  474.       */
  475.       while ( e4operator_cur() >= 0 )
  476.       {
  477.      if ( v4functions[op_value].priority <=  v4functions[ e4operator_cur() ].priority )
  478.         e4push_int( e4operator_off() ) ;
  479.      else
  480.         break ;
  481.       }
  482.       e4operator_put( op_value) ;
  483.  
  484.       if ( e4parse_value() == -1) return(-1) ;
  485.    }
  486. }
  487.  
  488.  
  489. /*
  490.    e4parse
  491.  
  492.    Parameter Name    Type      Purpose
  493.  
  494.    base_ref         int       The expression will be parsed assuming
  495.                    'base_ref' refers to the active database.
  496.    expr_ptr         char *    Points to the source expression.
  497.    compile_ptr_ptr   void **   The value of the memory allocated
  498.                    compile string will be returned through
  499.                    'compile_ptr_ptr'.
  500.    Function Returns
  501.  
  502.       >=0   The length of the compiled expression
  503.        <0   Error
  504. */
  505.  
  506. e4parse( char *expr_ptr, char **compile_ptr_ptr )
  507. {
  508.    void *save_compile_ptr ;
  509.  
  510.    err_source =  source =  expr_ptr ;
  511.  
  512.    /*  Set up the stack pointers */
  513.    result_ptr =  v4eval_space ;
  514.    result_len =  v4eval_len - OPERATOR_LEN ;
  515.    result_used=  0 ;
  516.  
  517.    e4push_str( expr_ptr, (int) strlen(expr_ptr)+1 ) ;
  518.    e4push( &v4cur_base, (int) sizeof(v4cur_base), 0 ) ;
  519.  
  520.    op_ptr =  (int *) (v4eval_space + (v4eval_len-OPERATOR_LEN) ) ;
  521.    op_used =  0 ;
  522.  
  523.    save_compile_ptr =  result_ptr ;
  524.  
  525.    if ( e4parse_expr() == -1 )  return( -1) ;
  526.    if ( e4operator_cur() != Q_NO_FUNCTION)
  527.    {
  528.       u4error( E_COMPLETE, expr_ptr, (char *) 0) ;
  529.       return(-1) ;
  530.    }
  531.    e4push_int( -1 ) ;
  532.  
  533.    if ( e4type_check( (char *) save_compile_ptr) < 0 )   return -1 ;
  534.  
  535.    *compile_ptr_ptr =  h4alloc( result_used) ;
  536.    if ( *compile_ptr_ptr == (char *) 0 )   return( -1) ;
  537.  
  538.    memcpy( *compile_ptr_ptr, v4eval_space, (size_t) result_used ) ;
  539.  
  540.    return( result_used ) ;
  541. }
  542.  
  543. typedef struct parse_parm_st
  544. {
  545.    char *ptr ;
  546.    int   type ;
  547. }  PARSE_PARM ;
  548.  
  549. static int  get_f_code(char *,PARSE_PARM *) ;
  550.  
  551. static int  get_f_code( char *f_code_ptr, PARSE_PARM *parms )
  552. {
  553.    int  i, p_no, flg, i_functions ;
  554.  
  555.    /* flg Values
  556.      -1 -  Error
  557.       0 -  OK
  558.       1 -  Conversion Required
  559.    */
  560.  
  561.    memcpy( &i_functions, f_code_ptr, sizeof(int)) ;
  562.  
  563.    for ( i= i_functions; ; i++ )
  564.    {
  565.       if ( v4functions[i].code == 0 ||
  566.        v4functions[i].code != v4functions[i_functions].code )
  567.          break ;
  568.  
  569.       /* Check the Type Match */
  570.       for ( p_no = 0, flg = 0; p_no < v4functions[i].num_parms; p_no++ )
  571.       {
  572.          int  i_temp ;
  573.  
  574.      if ( v4functions[i].type[p_no] == parms[p_no].type )   continue ;
  575.  
  576.          memcpy( &i_temp, parms[p_no].ptr, sizeof(int) ) ;
  577.  
  578.      if ( v4functions[i].type[p_no] == T_NUM_DOUB )
  579.      {
  580.         if ( i_temp == I_FIELD_NUM_S )
  581.         {
  582.            flg =  1 ;
  583.            continue ;
  584.         }
  585.      }
  586.  
  587.      if ( v4functions[i].type[p_no] == T_DATE_DOUB )
  588.      {
  589.         if ( i_temp == I_FIELD_DATE_S ) 
  590.         {
  591.            flg =  1 ;
  592.            continue ;
  593.         }
  594.      }
  595.  
  596.      flg =  -1 ;  /* No Match */
  597.      break ;
  598.       }
  599.  
  600.       if ( flg >= 0 )
  601.       {
  602.          /* Success */
  603.      if ( flg > 0 )
  604.      {
  605.         /* Parameter Change Required First */
  606.             for ( p_no = 0, flg = 0; p_no < v4functions[i].num_parms; p_no++) 
  607.             {
  608.                int  i_temp ;
  609.  
  610.               if ( v4functions[i].type[p_no] == parms[i].type )   continue ;
  611.  
  612.                memcpy( &i_temp, parms[p_no].ptr, sizeof(int) ) ;
  613.            if ( i_temp == I_FIELD_DATE_S )
  614.                   i_temp = I_FIELD_DATE_D ;
  615.                else
  616.                {
  617.               if ( i_temp == I_FIELD_NUM_S )
  618.                      i_temp = I_FIELD_NUM_D ;
  619.                }
  620.                memcpy( parms[p_no].ptr, &i_temp, sizeof(int) ) ;
  621.             }
  622.      }
  623.  
  624.          memcpy( f_code_ptr, &i, sizeof(int) ) ;
  625.          f_code_ptr +=  sizeof(int) ;
  626.  
  627.      parms[0].type =  v4functions[i].return_type ;
  628.      parms[0].ptr  =  f_code_ptr ;
  629.  
  630.          return( 0 ) ;
  631.       }
  632.    }
  633.  
  634.    u4error( E_TYPE, "Expression:", err_source, "",
  635.             "Function:", v4functions[i_functions].name, (char *) 0) ;
  636.    return( -1 ) ;
  637. }
  638.  
  639. static int  e4type_check( char *compile_ptr )
  640. {
  641.    int         f_code ;
  642.    char       *f_code_ptr ;
  643.    int         n_parms, len ;
  644.    PARSE_PARM  parms[PARM_STACK_SIZE] ;
  645.  
  646.    parms[0].type =  0 ;
  647.  
  648.    for ( n_parms= 0;; )
  649.    {
  650.       f_code_ptr =  compile_ptr ;
  651.       memcpy( &f_code, f_code_ptr, sizeof(int) ) ;
  652.  
  653.       if ( f_code == -1 )
  654.       {
  655.      if (n_parms != 1)  u4error( E_INTERNAL, "e4type_check", err_source, (char *) 0 ) ;
  656.      v4type =  parms[0].type ;
  657.      return 0 ;
  658.       }
  659.  
  660.       if ( f_code <= LAST_IMMEDIATE )
  661.       {
  662.      parms[n_parms].type =  v4functions[f_code].return_type ;
  663.      parms[n_parms].ptr  =  compile_ptr ;
  664.          compile_ptr +=  sizeof(int) ;
  665.  
  666.      if ( f_code <= LAST_I_FIELD )
  667.         compile_ptr = compile_ptr + sizeof(long) ;
  668.      else
  669.      {
  670.         if ( f_code == I_DOUBLE )
  671.                len = sizeof(double) ;
  672.         else
  673.             {
  674.                memcpy( &len, compile_ptr, sizeof(int) ) ;
  675.            compile_ptr += sizeof(int) ;
  676.             }
  677.  
  678.         compile_ptr +=  len ;
  679.      }
  680.       }
  681.       else
  682.       {
  683.      n_parms -=  v4functions[f_code].num_parms ;
  684.      if ( n_parms < 0 )
  685.         u4error( E_INTERNAL, "e4type_check", err_source, (char *) 0 ) ;
  686.  
  687.      if ( get_f_code( f_code_ptr, parms+ n_parms ) < 0 )  return -1 ;
  688.      compile_ptr +=  sizeof(int) ;
  689.       }
  690.       n_parms++ ;
  691.  
  692.       if ( n_parms+1 >= PARM_STACK_SIZE )
  693.       {
  694.          u4error( E_OVERFLOW, err_source, (char *) 0 ) ;
  695.          return -1 ;
  696.       }
  697.    }
  698. }
  699.  
  700. static int  e4field_function( long field_ref )
  701. {
  702.    switch( f4type(field_ref) )
  703.    {
  704.       case 'C':
  705.          return  I_FIELD_STR ;
  706.  
  707.       case 'N':
  708.       case 'F':
  709.          return  I_FIELD_NUM_S ;
  710.  
  711.       case 'D':
  712.          return  I_FIELD_DATE_S ;
  713.  
  714.       case 'L':
  715.      return  I_FIELD_LOG ;
  716.    }
  717.    return -1 ;
  718. }
  719.