which included commits to RCS files with non-trunk default branches. git-svn-id: svn://10.65.10.50/trunk@976 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			666 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			666 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
| /* r4total.c   (c)Copyright Sequiter Software Inc., 1991-1994.  All rights reserved. */
 | |
| 
 | |
| #include "d4all.h"
 | |
| 
 | |
| #include <math.h>
 | |
| 
 | |
| /* resets the totals values */
 | |
| void S4FUNCTION   total4value_reset( TOTAL4 *t4 )
 | |
| {
 | |
| 
 | |
|   t4->low = 1.7 * pow(10.0, 308.0);
 | |
|   t4->high = -1.7 * pow(10.0, 308.0);
 | |
|   t4->count = 0;
 | |
|   t4->total = 0.0;
 | |
| 
 | |
| }
 | |
| 
 | |
| /* frees the TOTAL4 related memory, then deletes the calculation used to
 | |
|    create the total */
 | |
| void S4FUNCTION   total4free( TOTAL4 *total )
 | |
| {
 | |
|   if( total->last_reset_value )
 | |
|   {
 | |
|     u4free( total->last_reset_value );
 | |
|     total->last_reset_value = NULL;
 | |
|   }
 | |
| 
 | |
|   if( total->reset_expression )
 | |
|   {
 | |
|     expr4free( total->reset_expression );
 | |
|     total->reset_expression = NULL;
 | |
|   }
 | |
| 
 | |
|   if( total->last_add_value )
 | |
|   {
 | |
|     u4free( total->last_add_value );
 | |
|     total->last_add_value = NULL;
 | |
|   }
 | |
| 
 | |
|   if( total->add_condition )
 | |
|   {
 | |
|     expr4free( total->add_condition );
 | |
|     total->add_condition = NULL;
 | |
|   }
 | |
| 
 | |
|   expr4calc_delete( total->calc_ptr );
 | |
| 
 | |
| }
 | |
| 
 | |
| /* creates a total */
 | |
| TOTAL4 * S4FUNCTION   total4create( REPORT4 *r4, char *name, char *expr_src, int total_type, char *reset_expr_src )
 | |
| {
 | |
|   EXPR4 *expr, *rexpr;
 | |
|   TOTAL4 *t4;
 | |
| 
 | |
|   if( !r4 )
 | |
|     return NULL;
 | |
| 
 | |
|   if( !name || name[0] == '\0' || !expr_src )
 | |
|   {
 | |
|     e4describe( r4->code_base, e4parm, E4_REP_TCREATEVAL, 0, 0 );
 | |
|     return NULL;
 | |
|   }
 | |
| 
 | |
|   /* parse the expression */
 | |
|   expr = expr4parse( r4->relate->data, expr_src );
 | |
|   if( !expr )
 | |
|   {
 | |
|     e4describe( r4->code_base, e4total_create, E4_REP_TEXPR, 0, 0 );
 | |
|     return NULL;
 | |
|   }
 | |
| 
 | |
|   /* allocate the TOTAL4 structure */
 | |
|   t4 = (TOTAL4 *)mem4create_alloc( r4->code_base, &r4->code_base->total_memory,
 | |
|                                   5, sizeof(TOTAL4), 5, 0 );
 | |
|   if( !t4 )
 | |
|   {
 | |
|     e4describe( r4->code_base, e4total_create, E4_REP_TMEM, 0, 0 );
 | |
|     expr4free( expr );
 | |
|     return NULL;
 | |
|   }
 | |
| 
 | |
|   /* create the calculation based on the expression */
 | |
|   t4->calc_ptr = expr4calc_create( r4->code_base, expr, name );
 | |
|   if( !t4->calc_ptr )
 | |
|   {
 | |
|     e4describe( r4->code_base, e4total_create, E4_REP_TCALC, 0, 0 );
 | |
|     u4free( t4 );
 | |
|     expr4free( expr );
 | |
|     return NULL;
 | |
|   }
 | |
| 
 | |
|   /* set the flags and pointers */
 | |
|   t4->calc_ptr->total = t4;
 | |
|   t4->report = r4;
 | |
|   t4->total_type = total_type;
 | |
| 
 | |
|   /* set the totals reset expression */
 | |
|   if( reset_expr_src && reset_expr_src[0] != '\0' )
 | |
|   {
 | |
|     rexpr = expr4parse( r4->relate->data, reset_expr_src );
 | |
|     if( !rexpr )
 | |
|     {
 | |
|       e4describe( r4->code_base, e4total_create, E4_REP_TREXPR, 0, 0 );
 | |
|       expr4free( expr );
 | |
|       u4free( t4 );
 | |
|       return NULL;
 | |
|     }
 | |
|     t4->reset_expression = rexpr;
 | |
|   }
 | |
| 
 | |
|   l4add( &r4->code_base->total_list, t4 );
 | |
| 
 | |
|   total4value_reset( t4 );
 | |
| 
 | |
|   return t4;
 | |
| }
 | |
| 
 | |
| /* This function is used for evaluating look ahead totals, it skips ahead
 | |
|    through the records incrementing the total appropriately until the reset
 | |
|    condition is met */
 | |
| void total4evaluate_lookahead( PTOTAL4 total )
 | |
| {
 | |
|   long reccount = 0;
 | |
|   int  flag, len, addflag;
 | |
|   char *ptr;
 | |
|   double tvalue;
 | |
| 
 | |
|   if( !total->reset_expression && total->donce )
 | |
|     return;
 | |
| 
 | |
|   total->donce = 1;
 | |
|   addflag = 1;
 | |
| 
 | |
|   /* check the conditional add */
 | |
|   if( total->add_condition )
 | |
|   {
 | |
|     addflag = 0;
 | |
|     if( total->logcon == 0 )
 | |
|     {
 | |
|       len = expr4vary( total->add_condition, &ptr );
 | |
|       if( memcmp( total->last_add_value, ptr, len ) != 0 )
 | |
|       {
 | |
|         memset( total->last_add_value, 0, len+1 );
 | |
|         memcpy( total->last_add_value, ptr, len );
 | |
|         addflag = 1;
 | |
|       }
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|       if( expr4true( total->add_condition ) )
 | |
|         addflag = 1;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /* increment the total for the current record */
 | |
|   if( addflag == 1 )
 | |
|   {
 | |
|     tvalue = expr4double( total->calc_ptr->expr ) ;
 | |
|     total->total += tvalue ;
 | |
|     total->count += 1 ;
 | |
|     if ( tvalue < total->low )
 | |
|       total->low = tvalue ;
 | |
| 
 | |
|     if( tvalue > total->high )
 | |
|       total->high = tvalue ;
 | |
|   }
 | |
| 
 | |
|   /* start going through the records */
 | |
|   flag = 1;
 | |
|   while( flag )
 | |
|   {
 | |
|     if( relate4skip( total->report->relate, 1L ) != 0 )
 | |
|     {
 | |
|       reccount++;
 | |
|       break;
 | |
|     }
 | |
| 
 | |
|     reccount++;
 | |
| 
 | |
|     /* if this total has a reset expression */
 | |
|     if( total->reset_expression )
 | |
|     {
 | |
|       len = expr4vary( total->reset_expression, &ptr );
 | |
|       /* if the reset condition is not met */
 | |
|       if( memcmp( ptr, total->last_reset_value, len ) == 0 )
 | |
|       {
 | |
|         addflag = 1;
 | |
| 
 | |
|         /* check for a conditional total */
 | |
|         if( total->add_condition )
 | |
|         {
 | |
|           addflag = 0;
 | |
|           if( total->logcon == 0 )
 | |
|           {
 | |
|             len = expr4vary( total->add_condition, &ptr );
 | |
|             if( memcmp( total->last_add_value, ptr, len ) != 0 )
 | |
|             {
 | |
|               memset( total->last_add_value, 0, len+1 );
 | |
|               memcpy( total->last_add_value, ptr, len );
 | |
|               addflag = 1;
 | |
|             }
 | |
|           }
 | |
|           else
 | |
|           {
 | |
|             if( expr4true( total->add_condition ) )
 | |
|               addflag = 1;
 | |
|           }
 | |
|         }
 | |
| 
 | |
|         /* increment the total */
 | |
|         if( addflag == 1 )
 | |
|         {
 | |
|           tvalue = expr4double( total->calc_ptr->expr ) ;
 | |
|           total->total += tvalue ;
 | |
|           total->count += 1 ;
 | |
|           if ( tvalue < total->low )
 | |
|             total->low = tvalue ;
 | |
| 
 | |
|           if( tvalue > total->high )
 | |
|             total->high = tvalue ;
 | |
|         }
 | |
|       }
 | |
|       else /* if the reset condition is met */
 | |
|       {
 | |
|         flag = 0;
 | |
|       }
 | |
|     }
 | |
|     else /* if no reset condition */
 | |
|     {
 | |
|       addflag = 1;
 | |
| 
 | |
|       /* check for a conditional total */
 | |
|       if( total->add_condition )
 | |
|       {
 | |
|         addflag = 0;
 | |
|         if( total->logcon == 0 )
 | |
|         {
 | |
|           len = expr4vary( total->add_condition, &ptr );
 | |
|           if( memcmp( total->last_add_value, ptr, len ) != 0 )
 | |
|           {
 | |
|             memset( total->last_add_value, 0, len+1 );
 | |
|             memcpy( total->last_add_value, ptr, len );
 | |
|             addflag = 1;
 | |
|           }
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|           if( expr4true( total->add_condition ) )
 | |
|             addflag = 1;
 | |
|         }
 | |
|       }
 | |
| 
 | |
|       /* increment the total for the current record */
 | |
|       if( addflag == 1 )
 | |
|       {
 | |
|         tvalue = expr4double( total->calc_ptr->expr ) ;
 | |
|         total->total += tvalue ;
 | |
|         total->count += 1 ;
 | |
|         if ( tvalue < total->low )
 | |
|           total->low = tvalue ;
 | |
| 
 | |
|         if( tvalue > total->high )
 | |
|           total->high = tvalue ;
 | |
|       }
 | |
|     }
 | |
| 
 | |
|   }
 | |
| 
 | |
|   /* skip back the appropriate number of records */
 | |
|   relate4skip( total->report->relate, (long)(-1 * reccount) );
 | |
| 
 | |
| }
 | |
| 
 | |
| /* updates the totals internals */
 | |
| void total4value_update( TOTAL4 *total )
 | |
| {
 | |
|   double tvalue;
 | |
|   int len, flag = 1;
 | |
|   char *ptr;
 | |
|   int addflag;
 | |
| 
 | |
|   /* check for a reset on the total */
 | |
|   if( total->reset_expression )
 | |
|   {
 | |
|     len = expr4vary( total->reset_expression, &ptr );
 | |
|     if( (flag = memcmp(total->last_reset_value, ptr, len)) != 0 )
 | |
|     {
 | |
|       memset( total->last_reset_value, 0, len+1 );
 | |
|       memcpy( total->last_reset_value, ptr, len );
 | |
|       total->low = 1.7 * pow( 10,308 ) ;
 | |
|       total->high = -1.7 * pow( 10,308 ) ;
 | |
|       total->total = 0.0 ;
 | |
|       total->count = 0;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /* for non-lookahead totals */
 | |
|   if( !total->lookahead )
 | |
|   {
 | |
|     addflag = 1;
 | |
| 
 | |
|     /* check for conditional total */
 | |
|     if( total->add_condition )
 | |
|     {
 | |
|       addflag = 0;
 | |
|       if( total->logcon == 0 )
 | |
|       {
 | |
|         len = expr4vary( total->add_condition, &ptr );
 | |
|         if( memcmp( total->last_add_value, ptr, len ) != 0 )
 | |
|         {
 | |
|           memset( total->last_add_value, 0, len+1 );
 | |
|           memcpy( total->last_add_value, ptr, len );
 | |
|           addflag = 1;
 | |
|         }
 | |
|       }
 | |
|       else
 | |
|       {
 | |
|         if( expr4true( total->add_condition ) )
 | |
|           addflag = 1;
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     /* increment the total */
 | |
|     if( addflag )
 | |
|     {
 | |
|       tvalue = expr4double( total->calc_ptr->expr ) ;
 | |
|       total->total += tvalue ;
 | |
|       total->count += 1 ;
 | |
|       if( tvalue < total->low )
 | |
|         total->low = tvalue ;
 | |
| 
 | |
|       if( tvalue > total->high )
 | |
|         total->high = tvalue ;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /* evaluate the lookahead */
 | |
|   if( total->lookahead && flag != 0 )
 | |
|   {
 | |
|     total4evaluate_lookahead( total );
 | |
|   }
 | |
| }
 | |
| 
 | |
| /* returns a pointer to the TOTAL4 with the given name */
 | |
| TOTAL4 * S4FUNCTION total4lookup( REPORT4 *report, char *name )
 | |
| {
 | |
|   TOTAL4 *total_on ;
 | |
| 
 | |
|   if( !report )
 | |
|     return NULL;
 | |
| 
 | |
|   if( !name || name[0] == '\0' )
 | |
|   {
 | |
|     e4describe( report->code_base, e4parm, E4_REP_TLKP, 0, 0 );
 | |
|     return NULL;
 | |
|   }
 | |
| 
 | |
|   total_on = (TOTAL4 *) l4first( &report->code_base->total_list );
 | |
|   while(total_on)
 | |
|   {
 | |
|     if ( strcmp( name, total_on->calc_ptr->name ) == 0 )
 | |
|       return total_on ;
 | |
| 
 | |
|     total_on = (TOTAL4 *) l4next( &report->code_base->total_list,total_on);
 | |
|   }
 | |
|   return NULL ;
 | |
| }
 | |
| 
 | |
| 
 | |
| /* this function is used when checking whether objects are dependant on a
 | |
|    certain total or calculation, also in deleting any dependant objects.
 | |
|    If the function is being used to check for dependancies (delflag = 0) it
 | |
|    simply returns 1 at the first dependant object found.  If delflag = 1 any
 | |
|    dependant objects are delted */
 | |
| int report4checkObjExpr( POBJ4 obj, int delflag )
 | |
| {
 | |
|   EXPR4CALC *calc_on;
 | |
|   POBJ4     obj_on, obj_next;
 | |
|   EXPR4     *expr;
 | |
|   CODE4     *cb;
 | |
|   int       rc;
 | |
| 
 | |
|   cb = obj->area->report->code_base;
 | |
| 
 | |
|   obj_on = (POBJ4)l4first( &obj->contained );
 | |
|   while( obj_on )
 | |
|   {
 | |
|     obj_next = (POBJ4)l4next( &obj->contained, obj_on );
 | |
|     rc = report4checkObjExpr( obj_on, delflag );
 | |
|     if( rc == 1 )
 | |
|       return rc;
 | |
|     obj_on = obj_next;
 | |
|   }
 | |
| 
 | |
|   switch( obj->obj_type_num )
 | |
|   {
 | |
|   case obj4type_expr:
 | |
|     expr = expr4parse( obj->area->report->relate->data, expr4source((EXPR4 *)obj->data) );
 | |
|     if( expr )
 | |
|     {
 | |
|       expr4free( expr );
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|       if( delflag )
 | |
|         obj4delete( obj );
 | |
|       else
 | |
|         return 1;
 | |
|     }
 | |
|     break;
 | |
| 
 | |
|   case obj4type_total:
 | |
|     rc = 0;
 | |
|     calc_on = (EXPR4CALC *)l4first( &cb->calc_list );
 | |
|     while( calc_on )
 | |
|     {
 | |
|       if( calc_on == ((PTOTAL4)obj->data)->calc_ptr )
 | |
|       {
 | |
|         rc = 1;
 | |
|         calc_on = NULL;
 | |
|       }
 | |
|       else
 | |
|         calc_on = (EXPR4CALC *)l4next( &cb->calc_list, calc_on );
 | |
|     }
 | |
|     if( rc == 0 )
 | |
|     {
 | |
|       if( delflag )
 | |
|       {
 | |
|         obj->data = NULL;
 | |
|         obj4free( obj );
 | |
|       }
 | |
|       else
 | |
|         return 1;
 | |
|     }
 | |
|     break;
 | |
| 
 | |
|   case obj4type_calc:
 | |
|     rc = 0;
 | |
|     calc_on = (EXPR4CALC *)l4first( &cb->calc_list );
 | |
|     while( calc_on )
 | |
|     {
 | |
|       if( calc_on == (EXPR4CALC *)obj->data )
 | |
|       {
 | |
|         rc = 1;
 | |
|         calc_on = NULL;
 | |
|       }
 | |
|       else
 | |
|         calc_on = (EXPR4CALC *)l4next( &cb->calc_list, calc_on );
 | |
|     }
 | |
|     if( rc == 0 )
 | |
|     {
 | |
|       if( delflag )
 | |
|         obj4delete( obj );
 | |
|       else
 | |
|         return 1;
 | |
|     }
 | |
|     break;
 | |
|   }
 | |
| 
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| 
 | |
| /* USED to delete a calc/total from the report */
 | |
| int S4FUNCTION report4deleteCalc( PREPORT4 report, EXPR4CALC S4PTR *del_calc )
 | |
| {
 | |
|   POBJ4 obj_on, obj_next;
 | |
|   EXPR4 *expr;
 | |
|   LIST4 temp_calc_list;
 | |
|   CODE4 *code_base;
 | |
|   PGROUP4 group_on;
 | |
|   PAREA4  area_on;
 | |
|   EXPR4CALC *calc_on, *calc_next;
 | |
|   int   calc_transfered = 1, expr_error, rc = 0;
 | |
| 
 | |
|   if( report == NULL || del_calc == NULL )
 | |
|   {
 | |
| 
 | |
|     return -1;
 | |
|   }
 | |
| 
 | |
|   code_base = report->code_base;
 | |
| 
 | |
|   /* separate the calculations so that a temporary list contains all
 | |
|      calculations dependant on the calculation to be deleted */
 | |
| 
 | |
|   memcpy( &temp_calc_list, &code_base->calc_list, sizeof(temp_calc_list) );
 | |
|   memset( &code_base->calc_list, 0, sizeof(code_base->calc_list) );
 | |
| 
 | |
|   if( l4seek( &temp_calc_list, del_calc ) != 0 )
 | |
|     l4remove( &temp_calc_list, del_calc );
 | |
| 
 | |
|   expr_error = code_base->expr_error;
 | |
| 
 | |
|   code_base->expr_error = 0;
 | |
| 
 | |
|   while( calc_transfered )
 | |
|   {
 | |
|     calc_transfered = 0;
 | |
|     calc_on = (EXPR4CALC *)l4first( &temp_calc_list );
 | |
|     while( calc_on )
 | |
|     {
 | |
|       calc_next = (EXPR4CALC *)l4next( &temp_calc_list, calc_on );
 | |
| 
 | |
|       expr = expr4parse( calc_on->expr->data, expr4source(calc_on->expr) );
 | |
|       if( expr )
 | |
|       {
 | |
|         expr4free( expr );
 | |
|         l4remove( &temp_calc_list, calc_on );
 | |
|         l4add( &code_base->calc_list, calc_on );
 | |
|         calc_transfered = 1;
 | |
|       }
 | |
| 
 | |
|       calc_on = calc_next;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   l4add( &code_base->calc_list, del_calc );
 | |
|   expr4calc_delete( del_calc );
 | |
| 
 | |
|   calc_on = (EXPR4CALC *)l4pop( &temp_calc_list );
 | |
|   while( calc_on )
 | |
|   {
 | |
|     l4add( &code_base->calc_list, calc_on ) ;
 | |
|     expr4calc_delete( calc_on ) ;
 | |
|     calc_on = (EXPR4CALC *)l4pop( &temp_calc_list );
 | |
|   }
 | |
| 
 | |
| 
 | |
|   /* Now check on all the objects in the report */
 | |
|   /* start with the page header and footer */
 | |
|   group_on = report->page_header_footer;
 | |
|   if( group_on )
 | |
|   {
 | |
|     area_on = (PAREA4)l4first( &group_on->header_areas );
 | |
|     while( area_on )
 | |
|     {
 | |
|       obj_on = (POBJ4)l4first( &area_on->objects );
 | |
|       while( obj_on )
 | |
|       {
 | |
|         obj_next = (POBJ4)l4next( &area_on->objects, obj_on );
 | |
|         rc = report4checkObjExpr( obj_on, 1 );
 | |
|         if( rc == 1 )
 | |
|           obj_on = NULL;
 | |
|         else
 | |
|           obj_on = obj_next;
 | |
|       }
 | |
|       if( rc == 1 )
 | |
|         area_on = NULL;
 | |
|       else
 | |
|         area_on = (PAREA4)l4next( &group_on->header_areas, area_on );
 | |
|     }
 | |
| 
 | |
|     area_on = (PAREA4)l4first( &group_on->footer_areas );
 | |
|     while( area_on )
 | |
|     {
 | |
|       obj_on = (POBJ4)l4first( &area_on->objects );
 | |
|       while( obj_on )
 | |
|       {
 | |
|         obj_next = (POBJ4)l4next( &area_on->objects, obj_on );
 | |
|         rc = report4checkObjExpr( obj_on, 1 );
 | |
|         if( rc == 1 )
 | |
|           obj_on = NULL;
 | |
|         else
 | |
|           obj_on = obj_next;
 | |
|       }
 | |
|       if( rc == 1 )
 | |
|         area_on = NULL;
 | |
|       else
 | |
|         area_on = (PAREA4)l4next( &group_on->footer_areas, area_on );
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   group_on = (PGROUP4)l4first( &report->groups );
 | |
|   if( rc == 1 )
 | |
|     group_on = NULL;
 | |
|   while( group_on )
 | |
|   {
 | |
|     area_on = (PAREA4)l4first( &group_on->header_areas );
 | |
|     while( area_on )
 | |
|     {
 | |
|       obj_on = (POBJ4)l4first( &area_on->objects );
 | |
|       while( obj_on )
 | |
|       {
 | |
|         obj_next = (POBJ4)l4next( &area_on->objects, obj_on );
 | |
|         rc = report4checkObjExpr( obj_on, 1 );
 | |
|         if( rc == 1 )
 | |
|           obj_on = NULL;
 | |
|         else
 | |
|           obj_on = obj_next;
 | |
|       }
 | |
|       if( rc == 1 )
 | |
|         area_on = NULL;
 | |
|       else
 | |
|         area_on = (PAREA4)l4next( &group_on->header_areas, area_on );
 | |
|     }
 | |
| 
 | |
|     area_on = (PAREA4)l4first( &group_on->footer_areas );
 | |
|     while( area_on )
 | |
|     {
 | |
|       obj_on = (POBJ4)l4first( &area_on->objects );
 | |
|       while( obj_on )
 | |
|       {
 | |
|         obj_next = (POBJ4)l4next( &area_on->objects, obj_on );
 | |
|         rc = report4checkObjExpr( obj_on, 1 );
 | |
|         if( rc == 1 )
 | |
|           obj_on = NULL;
 | |
|         else
 | |
|           obj_on = obj_next;
 | |
|       }
 | |
|       if( rc == 1 )
 | |
|         area_on = NULL;
 | |
|       else
 | |
|         area_on = (PAREA4)l4next( &group_on->footer_areas, area_on );
 | |
|     }
 | |
| 
 | |
|     if( rc == 1 )
 | |
|       group_on = NULL;
 | |
|     else
 | |
|       group_on = (PGROUP4)l4next( &report->groups, group_on );
 | |
|   }
 | |
| 
 | |
| 
 | |
| 
 | |
|   report->code_base->expr_error = expr_error;
 | |
| 
 | |
|   return 0;
 | |
| 
 | |
| }
 | |
| 
 | |
| 
 | |
| /* SEE THE CODEREPORTER MANUAL */
 | |
| int S4FUNCTION total4addCondition( PTOTAL4 total, char *add_condition_src, int logcon )
 | |
| {
 | |
|   EXPR4 *expr;
 | |
| 
 | |
|   if( !total || !add_condition_src || logcon < 0 )
 | |
|     return -1;
 | |
| 
 | |
|   if( total->report == NULL )
 | |
|     return -1;
 | |
| 
 | |
|   expr = expr4parse( total->report->relate->data, add_condition_src );
 | |
|   if( expr )
 | |
|   {
 | |
|     if( logcon && expr4type(expr) != r4log )
 | |
|       return -1;
 | |
| 
 | |
|     if( total->add_condition )
 | |
|       expr4free( total->add_condition );
 | |
|     total->add_condition = expr;
 | |
|     if( total->last_add_value )
 | |
|     {
 | |
|       u4free( total->last_add_value );
 | |
|       total->last_add_value = NULL;
 | |
|     }
 | |
|     total->logcon = logcon;
 | |
|     return 0;
 | |
|   }
 | |
|   else
 | |
|     e4set( total->report->code_base, 0 );
 | |
| 
 | |
|   return -1;
 | |
| }
 |