Пример #1
0
void call_bind_rule( OBJECT * target_, OBJECT * boundname_ )
{
    LIST * const bind_rule = var_get( root_module(), constant_BINDRULE );
    if ( !list_empty( bind_rule ) )
    {
        OBJECT * target = object_copy( target_ );
        OBJECT * boundname = object_copy( boundname_ );
        if ( boundname && target )
        {
            /* Prepare the argument list. */
            FRAME frame[ 1 ];
            frame_init( frame );

            /* First argument is the target name. */
            lol_add( frame->args, list_new( target ) );

            lol_add( frame->args, list_new( boundname ) );
            if ( lol_get( frame->args, 1 ) )
            {
                OBJECT * rulename = list_front( bind_rule );
                list_free( evaluate_rule( bindrule( rulename, root_module() ), rulename, frame ) );
            }

            /* Clean up */
            frame_free( frame );
        }
        else
        {
            if ( boundname )
                object_free( boundname );
            if ( target )
                object_free( target );
        }
    }
}
Пример #2
0
CMD * cmd_new( RULE * rule, LIST * targets, LIST * sources, LIST * shell )
{
    CMD * cmd = (CMD *)BJAM_MALLOC( sizeof( CMD ) );
    FRAME frame[ 1 ];

    assert( cmd );
    cmd->rule = rule;
    cmd->shell = shell;
    cmd->next = 0;
    cmd->noop = 0;

    lol_init( &cmd->args );
    lol_add( &cmd->args, targets );
    lol_add( &cmd->args, sources );
    string_new( cmd->buf );

    frame_init( frame );
    frame->module = rule->module;
    lol_init( frame->args );
    lol_add( frame->args, list_copy( targets ) );
    lol_add( frame->args, list_copy( sources ) );
    function_run_actions( rule->actions->command, frame, stack_global(),
        cmd->buf );
    frame_free( frame );

    return cmd;
}
Пример #3
0
void
headers( TARGET *t )
{
	LIST	*hdrscan;
	LIST	*hdrrule;
	LIST	*hdrcache;
	LOL	lol;

	if( !( hdrscan = var_get( "HDRSCAN" ) ) || 
	    !( hdrrule = var_get( "HDRRULE" ) ) )
	        return;

	/* Doctor up call to HDRRULE rule */
	/* Call headers1() to get LIST of included files. */

	if( DEBUG_HEADER )
	    printf( "header scan %s\n", t->name );

	lol_init( &lol );

	lol_add( &lol, list_new( L0, t->name, 1 ) );
	lol_add( &lol, headers1( t->boundname, hdrscan ) );

	if( lol_get( &lol, 1 ) )
	    list_free( evaluate_rule( 0, hdrrule->string, &lol, L0 ) );

	/* Clean up */

	lol_free( &lol );
}
Пример #4
0
static void call_action_rule
(
    TARGET * target,
    int status,
    timing_info const * time,
    char const * executed_command,
    char const * command_output
)
{
    LIST * action_rule;

    pushsettings( root_module(), target->settings );
    action_rule = var_get( root_module(), constant_ACTION_RULE );
    popsettings( root_module(), target->settings );

    if ( !list_empty( action_rule ) )
    {
        /* rule action-rule (
            args * :
            target :
            command status start end user system :
            output ? ) */

        /* Prepare the argument list. */
        FRAME frame[ 1 ];
        OBJECT * rulename = list_front( action_rule );
        frame_init( frame );

        /* args * :: $(__ACTION_RULE__[2-]) */
        lol_add( frame->args, list_copy_range( action_rule, list_next(
            list_begin( action_rule ) ), list_end( action_rule ) ) );

        /* target :: the name of the target */
        lol_add( frame->args, list_new( object_copy( target->name ) ) );

        /* command status start end user system :: info about the action command
         */
        lol_add( frame->args,
            list_push_back( list_push_back( list_push_back( list_push_back( list_push_back( list_new(
                object_new( executed_command ) ),
                outf_int( status ) ),
                outf_time( &time->start ) ),
                outf_time( &time->end ) ),
                outf_double( time->user ) ),
                outf_double( time->system ) ) );

        /* output ? :: the output of the action command */
        if ( command_output )
            lol_add( frame->args, list_new( object_new( command_output ) ) );
        else
            lol_add( frame->args, L0 );

        /* Call the rule. */
        evaluate_rule( bindrule( rulename, root_module() ), rulename, frame );

        /* Clean up. */
        frame_free( frame );
    }
}
Пример #5
0
void
headers( TARGET * t )
{
    LIST   * hdrscan;
    LIST   * hdrrule;
	#ifndef OPT_HEADER_CACHE_EXT
    LIST   * headlist = L0;
	#endif
    regexp * re[ MAXINC ];
    int rec = 0;
    LISTITER iter, end;

    hdrscan = var_get( root_module(), constant_HDRSCAN );
    if ( list_empty( hdrscan ) )
        return;

    hdrrule = var_get( root_module(), constant_HDRRULE );
    if ( list_empty( hdrrule ) )
        return;

    if ( DEBUG_HEADER )
        printf( "header scan %s\n", object_str( t->name ) );

    /* Compile all regular expressions in HDRSCAN */
    iter = list_begin( hdrscan ), end = list_end( hdrscan );
    for ( ; ( rec < MAXINC ) && iter != end; iter = list_next( iter ) )
    {
        re[ rec++ ] = regex_compile( list_item( iter ) );
    }

    /* Doctor up call to HDRRULE rule */
    /* Call headers1() to get LIST of included files. */
    {
        FRAME   frame[1];
        frame_init( frame );
        lol_add( frame->args, list_new( object_copy( t->name ) ) );
#ifdef OPT_HEADER_CACHE_EXT
        lol_add( frame->args, hcache( t, rec, re, hdrscan ) );
#else
        lol_add( frame->args, headers1( headlist, t->boundname, rec, re ) );
#endif

        if ( lol_get( frame->args, 1 ) )
        {
            /* The third argument to HDRRULE is the bound name of
             * $(<) */
            lol_add( frame->args, list_new( object_copy( t->boundname ) ) );

            list_free( evaluate_rule( list_front( hdrrule ), frame ) );
        }

        /* Clean up. */
        frame_free( frame );
    }
}
Пример #6
0
/* Look up the __ACTION_RULE__ variable on the given target, and if
 * non-empty, invoke the rule it names, passing the given info, 
 * timing_info, executed command and command output
 */
static void call_action_rule(TARGET* target, int status, timing_info* time,
    char *executed_command, char *command_output)
{
    LIST* action_rule;

    pushsettings(target->settings);
    action_rule = var_get( "__ACTION_RULE__" );
    popsettings(target->settings);

    if (action_rule)
    {
        /* rule action-rule (
            args * :
            target :
            command status start end user system :
            output ? ) */

        /* Prepare the argument list */
        FRAME frame[1];
        frame_init( frame );

        /* args * :: $(__ACTION_RULE__[2-]) */
        lol_add( frame->args, list_copy( L0, action_rule->next ) );

        /* target :: the name of the target */
        lol_add( frame->args, list_new( L0, target->name ) );

        /* command status start end user system :: info about the action command */
        lol_add( frame->args,
            list_new( list_new( list_new( list_new( list_new( list_new( L0,
                newstr(executed_command) ),
                outf_int(status) ),
                outf_time(time->start) ),
                outf_time(time->end) ),
                outf_double(time->user) ),
                outf_double(time->system) ) );

        /* output ? :: the output of the action command */
        if (command_output)
            lol_add(frame->args, list_new(L0, newstr(command_output)));
        else
            lol_add(frame->args, L0);

        /* Call the rule. */
        evaluate_rule( action_rule->string, frame );

        /* Clean up */
        frame_free( frame );
    }
}
Пример #7
0
void
headers( TARGET *t )
{
    LIST	*hdrscan;
    LIST	*hdrrule;
    LIST	*headlist = 0;
    regexp	*re[ MAXINC ];
    int	rec = 0;
        
    if( !( hdrscan = var_get( "HDRSCAN" ) ) || 
        !( hdrrule = var_get( "HDRRULE" ) ) )
        return;

    if( DEBUG_HEADER )
        printf( "header scan %s\n", t->name );

    /* Compile all regular expressions in HDRSCAN */

    while( rec < MAXINC && hdrscan )
    {
        re[rec++] = regex_compile( hdrscan->string );
        hdrscan = list_next( hdrscan );
    }

    /* Doctor up call to HDRRULE rule */
    /* Call headers1() to get LIST of included files. */
    {
        FRAME	frame[1];
        frame_init( frame );
        lol_add( frame->args, list_new( L0, t->name ) );
#ifdef OPT_HEADER_CACHE_EXT
        lol_add( frame->args, hcache( t, rec, re, hdrscan ) );
#else
        lol_add( frame->args, headers1( headlist, t->boundname, rec, re ) );
#endif

        if( lol_get( frame->args, 1 ) )
        {
            /* The third argument to HDRRULE is the bound name of
             * $(<) */
            lol_add( frame->args, list_new( L0, t->boundname ) );

            list_free( evaluate_rule( hdrrule->string, frame ) );
        }

        /* Clean up */

        frame_free( frame );
    }
}
Пример #8
0
int LS_jam_evaluaterule(ls_lua_State *L)
{
    LOL lol;
    int i;
    LIST *list;
    int index;

    int numParams = ls_lua_gettop(L);
    if (numParams < 1)
	return 0;

    if (!ls_lua_isstring(L, 1))
	return 0;

    lol_init(&lol);

    for (i = 0; i < numParams - 1; ++i)
    {
	lol_add(&lol, luahelper_addtolist(L, L0, 2 + i));
    }
    list = evaluate_rule(ls_lua_tostring(L, 1), &lol, L0);
    lol_free(&lol);

    ls_lua_newtable(L);
    index = 1;
    for (; list; list = list_next(list), ++index)
    {
	ls_lua_pushnumber(L, index);
	ls_lua_pushstring(L, list->string);
	ls_lua_settable(L, -3);
    }

    return 1;
}
Пример #9
0
LIST * call_rule( char * rulename, FRAME * caller_frame, ... )
{
    va_list va;
    LIST * result;

    FRAME       inner[1];
    frame_init( inner );
    inner->prev = caller_frame;
    inner->prev_user = caller_frame->module->user_module ?
        caller_frame : caller_frame->prev_user;
    inner->module = caller_frame->module;
    inner->procedure = 0;

    va_start( va, caller_frame );
    for ( ; ; )
    {
        LIST * l = va_arg( va, LIST* );
        if ( !l )
            break;
        lol_add( inner->args, l );
    }
    va_end( va );

    result = evaluate_rule( rulename, inner );

    frame_free( inner );

    return result;
}
Пример #10
0
LIST * compile_rule( PARSE * parse, FRAME * frame )
{
    FRAME   inner[ 1 ];
    LIST  * result;
    PARSE * p;

    /* Build up the list of arg lists. */
    frame_init( inner );
    inner->prev = frame;
    inner->prev_user = frame->module->user_module ? frame : frame->prev_user;
    inner->module = frame->module;  /* This gets fixed up in evaluate_rule(), below. */
    inner->procedure = parse;
    /* Special-case LOL of length 1 where the first list is totally empty.
       This is created when calling functions with no parameters, due to
       the way jam grammar is written. This is OK when one jam function
       calls another, but really not good when Jam function calls Python.  */
    if ( parse->left->left == NULL && parse->left->right->func == compile_null)
        ;
    else
        for ( p = parse->left; p; p = p->left )
            lol_add( inner->args, parse_evaluate( p->right, frame ) );

    /* And invoke the rule. */
    result = evaluate_rule( parse->string, inner );
    frame_free( inner );
    return result;
}
Пример #11
0
LIST *
compile_rule(
    PARSE   *parse,
    FRAME *frame )
{
    FRAME       inner[1];
    LIST    *result;
    PARSE   *p;
    

    /* Build up the list of arg lists */

    frame_init( inner );
    inner->prev = frame;
    inner->prev_user = frame->module->user_module ? frame : frame->prev_user;
    inner->module = frame->module; /* This gets fixed up in evaluate_rule(), below */
    inner->procedure = parse;

    for( p = parse->left; p; p = p->left )
        lol_add( inner->args, parse_evaluate( p->right, frame ) );

    /* And invoke rule */

    result = evaluate_rule( parse->string, inner );

    frame_free( inner );

    return result;
}
Пример #12
0
/* Look up the __TIMING_RULE__ variable on the given target, and if
 * non-empty, invoke the rule it names, passing the given
 * timing_info
 */
static void call_timing_rule(TARGET* target, timing_info* time)
{
    LIST* timing_rule;
    
    pushsettings(target->settings);
    timing_rule = var_get( "__TIMING_RULE__" );
    popsettings(target->settings);

    if (timing_rule)
    {
        /* We'll prepend $(__TIMING_RULE__[2-]) to the first argument */
        LIST* initial_args = list_copy( L0, timing_rule->next );
            
        /* Prepare the argument list */
        FRAME frame[1];
        frame_init( frame );

        /* First argument is the name of the timed target */
        lol_add( frame->args, list_new( initial_args, target->name ) );
        append_double_string(frame->args, time->user);
        append_double_string(frame->args, time->system);

        if( lol_get( frame->args, 2 ) )
            evaluate_rule( timing_rule->string, frame );
            
        /* Clean up */
        frame_free( frame );
    }
}
Пример #13
0
LIST *
compile_rule(
	PARSE	*parse,
	LOL	*args,
	int	*jmp )
{
	LOL	nargs[1];
	LIST	*result = 0;
	LIST	*ll;
	LISTITEM *l;
	PARSE	*p;

	/* list of rules to run -- normally 1! */

	ll = (*parse->left->func)( parse->left, args, jmp );

	/* Build up the list of arg lists */

	lol_init( nargs );

	for( p = parse->right; p; p = p->left )
	    lol_add( nargs, (*p->right->func)( p->right, args, jmp ) );

	/* Run rules, appending results from each */

	for( l = list_first(ll); l; l = list_next( l ) ) {
	    list_free(result); /* Keep only last result */
	    result = evaluate_rule( list_value(l), nargs, result );
	}

	list_free( ll );
	lol_free( nargs );

	return result;
}
Пример #14
0
static void type_check
(
    char  * type_name,
    LIST  * values,
    FRAME * caller,
    RULE  * called,
    LIST  * arg_name
)
{
    static module_t * typecheck = 0;

    /* If nothing to check, bail now. */
    if ( !values || !type_name )
        return;

    if ( !typecheck )
        typecheck = bindmodule( ".typecheck" );

    /* If the checking rule can not be found, also bail. */
    {
        RULE checker_, *checker = &checker_;

        checker->name = type_name;
        if ( !typecheck->rules || !hashcheck( typecheck->rules, (HASHDATA * *)&checker ) )
            return;
    }

    exit_module( caller->module );

    while ( values != 0 )
    {
        LIST *error;
        FRAME frame[1];
        frame_init( frame );
        frame->module = typecheck;
        frame->prev = caller;
        frame->prev_user = caller->module->user_module ? caller : caller->prev_user;

        enter_module( typecheck );
        /* Prepare the argument list */
        lol_add( frame->args, list_new( L0, values->string ) );
        error = evaluate_rule( type_name, frame );

        exit_module( typecheck );

        if ( error )
            argument_error( error->string, called, caller, arg_name );

        frame_free( frame );
        values = values->next;
    }

    enter_module( caller->module );
}
Пример #15
0
/* Look up the __TIMING_RULE__ variable on the given target, and if
 * non-empty, invoke the rule it names, passing the given
 * timing_info
 */
static void call_timing_rule(TARGET* target, timing_info* time)
{
    LIST* timing_rule;
    
    pushsettings(target->settings);
    timing_rule = var_get( "__TIMING_RULE__" );
    popsettings(target->settings);

    if (timing_rule)
    {
        /* rule timing-rule (
            args * :
            target :
            start end user system ) */

        /* Prepare the argument list */
        FRAME frame[1];
        frame_init( frame );

        /* args * :: $(__TIMING_RULE__[2-]) */
        lol_add( frame->args, list_copy( L0, timing_rule->next ) );

        /* target :: the name of the target */
        lol_add( frame->args, list_new( L0, target->name ) );

        /* start end user system :: info about the action command */
        lol_add( frame->args,
            list_new( list_new( list_new( list_new( L0,
                outf_time(time->start) ),
                outf_time(time->end) ),
                outf_double(time->user) ),
                outf_double(time->system) ) );

        /* Call the rule. */
        evaluate_rule( timing_rule->string, frame );

        /* Clean up */
        frame_free( frame );
    }
}
Пример #16
0
void
headers( TARGET *t )
{
	LIST	*hdrscan;
	LIST	*hdrrule;
	LOL	lol;

	if( !list_first( hdrscan = var_get( "HDRSCAN" ) ) ||
	    !list_first( hdrrule = var_get( "HDRRULE" ) ) )
	        return;

	/* Doctor up call to HDRRULE rule */
	/* Call headers1() to get LIST of included files. */

	if( DEBUG_HEADER )
	    printf( "header scan %s\n", t->name );

	lol_init( &lol );

	lol_add( &lol, list_append( L0, t->name, 1 ) );
#ifdef OPT_HEADER_CACHE_EXT
	lol_add( &lol, hcache( t, hdrscan ) );
#else
	lol_add( &lol, headers1( t->boundname, hdrscan ) );
#endif

	if( list_first(lol_get( &lol, 1 )) )
	{
#ifdef OPT_HDRRULE_BOUNDNAME_ARG_EXT
	    /* The third argument to HDRRULE is the bound name of
	     * $(<) */
	    lol_add( &lol, list_append( L0, t->boundname, 0 ) );
#endif
	    list_free( evaluate_rule( list_value(list_first(hdrrule)), &lol, L0 ) );
	}

	/* Clean up */

	lol_free( &lol );
}
Пример #17
0
LIST *
headers1(
	const char *file,
	LIST *hdrscan )
{
	FILE	*f;
	LIST	*result = 0;
	LIST    *hdrpipe;
	LIST	*hdrpipefile;

	if ( list_first(hdrpipe = var_get( "HDRPIPE" )) )
	{
		LOL args;
		BUFFER buff;
		lol_init( &args );
		lol_add( &args, list_append( L0, file, 0 ) );
		buffer_init( &buff );
		if ( var_string( list_value(list_first(hdrpipe)), &buff, 0, &args, ' ') < 0 )  {
		    printf( "Cannot expand HDRPIPE '%s' !\n", list_value(list_first(hdrpipe)) );
		    exit( EXITBAD );
		}
		buffer_addchar( &buff, 0 );
		if ( !( f = file_popen( (const char*)buffer_ptr( &buff ), "r" ) ) ) {
		    buffer_free( &buff );
		    return result;
		}
		buffer_free( &buff );
		lol_free( &args );
	}
	else
	{
		if( !( f = fopen( file, "r" ) ) )
		    return result;
	}

	result = headers1helper( f, hdrscan );

	if ( list_first(hdrpipe) )
		file_pclose( f );
	else
		fclose( f );

	if ( list_first(hdrpipefile = var_get( "HDRPIPEFILE" )) )
	{
		if( !( f = fopen( list_value(list_first(hdrpipefile)), "r" ) ) )
		    return result;
		result = headers1helper( f, hdrscan );
		fclose( f );
	}

	return result;
}
Пример #18
0
void call_bind_rule(
    char* target_,
    char* boundname_ )
{
    LIST* bind_rule = var_get( "BINDRULE" );
    if( bind_rule )
    {
        /* No guarantee that target is an allocated string, so be on the
         * safe side */
        char* target = copystr( target_ );
        
        /* Likewise, don't rely on implementation details of newstr.c: allocate
         * a copy of boundname */
        char* boundname = copystr( boundname_ );
        if( boundname && target )
        {
            /* Prepare the argument list */
            FRAME frame[1];
            frame_init( frame );
                    
            /* First argument is the target name */
            lol_add( frame->args, list_new( L0, target ) );
                    
            lol_add( frame->args, list_new( L0, boundname ) );
            if( lol_get( frame->args, 1 ) )
                evaluate_rule( bind_rule->string, frame );
            
            /* Clean up */
            frame_free( frame );
        }
        else
        {
            if( boundname )
                freestr( boundname );
            if( target )
                freestr( target );
        }
    }
}
Пример #19
0
static void call_timing_rule( TARGET * target, timing_info const * const time )
{
    LIST * timing_rule;

    pushsettings( root_module(), target->settings );
    timing_rule = var_get( root_module(), constant_TIMING_RULE );
    popsettings( root_module(), target->settings );

    if ( !list_empty( timing_rule ) )
    {
        /* rule timing-rule ( args * : target : start end user system ) */

        /* Prepare the argument list. */
        FRAME frame[ 1 ];
        OBJECT * rulename = list_front( timing_rule );
        frame_init( frame );

        /* args * :: $(__TIMING_RULE__[2-]) */
        lol_add( frame->args, list_copy_range( timing_rule, list_next(
            list_begin( timing_rule ) ), list_end( timing_rule ) ) );

        /* target :: the name of the target */
        lol_add( frame->args, list_new( object_copy( target->name ) ) );

        /* start end user system :: info about the action command */
        lol_add( frame->args, list_push_back( list_push_back( list_push_back( list_new(
            outf_time( &time->start ) ),
            outf_time( &time->end ) ),
            outf_double( time->user ) ),
            outf_double( time->system ) ) );

        /* Call the rule. */
        evaluate_rule( bindrule( rulename , root_module() ), rulename, frame );

        /* Clean up. */
        frame_free( frame );
    }
}
Пример #20
0
void call_bind_rule
(
    OBJECT * target_,
    OBJECT * boundname_
)
{
    OBJECT * varname = object_new( "BINDRULE" );
    LIST * bind_rule = var_get( varname );
    object_free( varname );
    if ( bind_rule )
    {
        OBJECT * target = object_copy( target_ );
        OBJECT * boundname = object_copy( boundname_ );
        if ( boundname && target )
        {
            /* Prepare the argument list. */
            FRAME frame[1];
            frame_init( frame );

            /* First argument is the target name. */
            lol_add( frame->args, list_new( L0, target ) );

            lol_add( frame->args, list_new( L0, boundname ) );
            if ( lol_get( frame->args, 1 ) )
                list_free( evaluate_rule( bind_rule->value, frame ) );

            /* Clean up */
            frame_free( frame );
        }
        else
        {
            if ( boundname )
                object_free( boundname );
            if ( target )
                object_free( target );
        }
    }
}
Пример #21
0
LIST * compile_setcomp( PARSE * parse, FRAME * frame )
{
    argument_list * arg_list = 0;

    /* Create new LOL describing argument requirements if supplied. */
    if ( parse->right )
    {
        PARSE * p;
        arg_list = args_new();
        for ( p = parse->right; p; p = p->left )
            lol_add( arg_list->data, parse_evaluate( p->right, frame ) );
    }

    new_rule_body( frame->module, parse->string, arg_list, parse->left, !parse->num );
    return L0;
}
Пример #22
0
LIST *
compile_rule(
	PARSE	*parse,
	LOL	*args,
	int	*jmp )
{
	LOL	nargs[1];
	LIST	*result = 0;
	LIST	*ll, *l;
	PARSE	*p;

	/* list of rules to run -- normally 1! */

	ll = (*parse->left->func)( parse->left, args, jmp );

	/* Build up the list of arg lists */

	lol_init( nargs );

	for( p = parse->right; p; p = p->left )
	    lol_add( nargs, (*p->right->func)( p->right, args, jmp ) );

	/* Run rules, appending results from each */

	for( l = ll; l; l = list_next( l ) )
	{
	    int localJmp = JMP_NONE;
	    result = evaluate_rule( l->string, nargs, result, &localJmp );
	    if (localJmp == JMP_EOF)
	    {
			*jmp = JMP_EOF;
			break;
	    }
	}

	list_free( ll );
	lol_free( nargs );

	return result;
}
Пример #23
0
int LS_jam_evaluaterule(ls_lua_State *L)
{
    LOL lol;
    int i;
    LIST *list;
    LISTITEM* item;
    int index;
    const char* rule;

    int numParams = ls_lua_gettop(L);
    if (numParams < 1)
        return 0;

    if (!ls_lua_isstring(L, 1))
        return 0;

    lol_init(&lol);

    rule = ls_lua_tostring(L, 1);
    for (i = 0; i < numParams - 1; ++i)
    {
        lol_add(&lol, luahelper_addtolist(L, L0, 2 + i));
    }
    list = evaluate_rule(rule, &lol, L0);
    lol_free(&lol);

    ls_lua_newtable(L);
    index = 1;
    for (item = list_first(list); item; item = list_next(item), ++index)
    {
        ls_lua_pushnumber(L, index);
        ls_lua_pushstring(L, list_value(item));
        ls_lua_settable(L, -3);
    }

    return 1;
}
Пример #24
0
CMD *
cmd_new(
	RULE	*rule,
	LIST	*targets,
	LIST	*sources,
	LIST	*shell )
{
    CMD *cmd = (CMD *)malloc( sizeof( CMD ) );
    /* lift line-length limitation entirely when JAMSHELL is just "%" */
    int no_limit = ( shell && !strcmp(shell->string,"%") && !list_next(shell) );
    int max_line = MAXLINE;
    int allocated = -1;

    if ( DEBUG_PROFILE )
        profile_memory( sizeof( CMD ) );

    cmd->rule = rule;
    cmd->shell = shell;
    cmd->next = 0;

    lol_init( &cmd->args );
    lol_add( &cmd->args, targets );
    lol_add( &cmd->args, sources );
    cmd->buf = 0;

    do
    {
        free(cmd->buf); /* free any buffer from previous iteration */
        
        cmd->buf = (char*)malloc(max_line + 1);

        if ( DEBUG_PROFILE )
            profile_memory( max_line + 1 );
        
        if (cmd->buf == 0)
            break;
        
        allocated = var_string( rule->actions->command, cmd->buf, max_line, &cmd->args );
        
        max_line = max_line * 2;
    }
    while( allocated < 0 && max_line < INT_MAX / 2 );

    if ( !no_limit )
    {
        /* Bail if the result won't fit in MAXLINE */
        char *s = cmd->buf;
        while ( *s )
        {
            size_t l = strcspn( s, "\n" );
            
            if ( l > MAXLINE )
            {
                /* We don't free targets/sources/shell if bailing. */
                cmd_free( cmd );
                return 0;
            }
            
            s += l;
            if ( *s )
                ++s;
        }
    }

    return cmd;
}
Пример #25
0
LIST *
evaluate_rule(
	const char *rulename,
	LOL	*args, 
	LIST	*result )
{
#ifdef OPT_EXPAND_RULE_NAMES_EXT
	RULE	*rule;
	char	*expanded;
	char	*c;
	int i;
	BUFFER	buff;

	buffer_init( &buff );

	if( (i = var_string( rulename, &buff, 0, args, ' ' )) < 0 )
	{
	    printf( "Failed to expand rule %s -- expansion too long\n", rulename );
	    exit( EXITBAD );
	}
	expanded = buffer_ptr( &buff );
	while ( expanded[0] == ' ' )
	    expanded++;
	while ( (c = strrchr(expanded, ' ')) )
	    *c = '\0';

	if( DEBUG_COMPILE )
	{
	    debug_compile( 1, rulename );
	    if ( strcmp(rulename, expanded) )
		printf( "-> %s  ", expanded );
	    lol_print( args );
	    printf( "\n" );
	}

	rule = bindrule( expanded );
#else	
	RULE	*rule = bindrule( rulename );

	if( DEBUG_COMPILE )
	{
	    debug_compile( 1, rulename );
	    lol_print( args );
	    printf( "\n" );
	}
#endif

#ifdef OPT_LOAD_MISSING_RULE_EXT
	if( !rule->actions && !rule->procedure )
	{
		if( ruleexists( "FindMissingRule" ) )
		{
			LOL lol;
			LIST *args = list_append( L0, expanded, 0 );
			LIST *result;

			lol_init( &lol );
			lol_add( &lol, args );
			result = evaluate_rule( "FindMissingRule", &lol, L0 );
			lol_free( &lol );

			if( list_first( result ) ) {
				rule = bindrule( list_value( list_first( result ) ) );
			}

			list_free( result );
		}
	}
#endif /* OPT_LOAD_MISSING_RULE_EXT */

	/* Check traditional targets $(<) and sources $(>) */

#ifdef OPT_IMPROVED_WARNINGS_EXT
	if( !rule->actions && !rule->procedure && !globs.silence )
	    printf( "warning: unknown rule %s %s\n", rule->name,
		   file_and_line());
#else
	if( !rule->actions && !rule->procedure )
	    printf( "warning: unknown rule %s\n", rule->name );
#endif

	/* If this rule will be executed for updating the targets */
	/* then construct the action for make(). */

	if( rule->actions )
	{
	    TARGETS	*t;
	    ACTION	*action;

	    /* The action is associated with this instance of this rule */

	    action = (ACTION *)malloc( sizeof( ACTION ) );
	    memset( (char *)action, '\0', sizeof( *action ) );

	    action->rule = rule;
#ifdef OPT_BUILTIN_NEEDS_EXT
	    action->targets = targetlist( (TARGETS *)0, lol_get( args, 0 ), 0 );
	    action->sources = targetlist( (TARGETS *)0, lol_get( args, 1 ), 0 );
	    action->autosettings = targetlist( (TARGETS *)0, lol_get( args, 2 ), 0 );
#else
	    action->targets = targetlist( (TARGETS *)0, lol_get( args, 0 ) );
	    action->sources = targetlist( (TARGETS *)0, lol_get( args, 1 ) );
#endif
#ifdef OPT_USE_CHECKSUMS_EXT
	    action->extratargets = targetlist( (TARGETS *)0, lol_get( args, 3 ), 0 );
#endif /* OPT_USE_CHECKSUMS_EXT */

#ifdef OPT_CLEAN_GLOBS_EXT
		{
			TARGETS* targets;
			for ( targets = action->targets; targets; targets = targets->next ) {
				if ( !( targets->target->flags & T_FLAG_NOTFILE ) )
					add_used_target_to_hash( targets->target );
			}
		}
#endif /* OPT_CLEAN_GLOBS_EXT */

	    /* Append this action to the actions of each target */

#ifdef OPT_MULTIPASS_EXT
	    action->pass = actionpass;
	    for( t = action->targets; t; t = t->next ) {
		t->target->progress = T_MAKE_INIT;
		t->target->actions = actionlist( t->target->actions, action );
	    }
#else
	    for( t = action->targets; t; t = t->next )
		t->target->actions = actionlist( t->target->actions, action );
#endif
	}

	/* Now recursively compile any parse tree associated with this rule */

	if( rule->procedure )
	{
	    PARSE *parse = rule->procedure;
	    SETTINGS *s = 0;
	    int jmp = JMP_NONE;
	    LISTITEM *l;
	    int i;

	    /* build parameters as local vars */
	    for( l = list_first(rule->params), i = 0; l; l = list_next(l), i++ )
		s = addsettings( s, 0, list_value(l), 
		    list_copy( L0, lol_get( args, i ) ) );

	    /* Run rule. */
	    /* Bring in local params. */
	    /* refer/free to ensure rule not freed during use. */

	    parse_refer( parse );

	    pushsettings( s );
	    result = list_appendList( result, (*parse->func)( parse, args, &jmp ) );
	    popsettings( s );
	    freesettings( s );

	    parse_free( parse );
	}

	if( DEBUG_COMPILE )
	    debug_compile( -1, 0 );

#ifdef OPT_EXPAND_RULE_NAMES_EXT
	buffer_free( &buff );
#endif

	return result;
}
Пример #26
0
/* To l, append a 1-element list containing the string representation
 * of x
 */
static void append_double_string( LOL *l, double x )
{
    char buffer[50];
    sprintf(buffer, "%f", x);
    lol_add( l, list_new( L0, newstr( buffer ) ) );
}
Пример #27
0
LIST *
	hcache( TARGET *t, LIST *hdrscan )
{
	HCACHEDATA	cachedata, *c = &cachedata;
	HCACHEFILE	*file;
	LIST	*l = 0;
	int		use_cache = 1;
	const char *target;
# ifdef DOWNSHIFT_PATHS
	char path[ MAXJPATH ];
	char *p;
# endif

	target = t->boundname;

# ifdef DOWNSHIFT_PATHS
	p = path;

	do *p++ = (char)tolower( *target );
	while( *target++ );

	target = path;
# endif

	++queries;

	c->boundname = target;

	file = hcachefile_get( t );
	//    if ( file )
	{
		if( hashcheck( file->hcachehash, (HASHDATA **) &c ) )
		{
#ifdef OPT_BUILTIN_MD5CACHE_EXT
			if( c->time == t->time  &&  md5matchescommandline( t ) )
#else
			if( c->time == t->time )
#endif
			{
				LIST *l1 = hdrscan, *l2 = c->hdrscan;
				while( l1 && l2 ) {
					if( l1->string != l2->string ) {
						l1 = 0;
					} else {
						l1 = list_next( l1 );
						l2 = list_next( l2 );
					}
				}
				if( l1 || l2 )
					use_cache = 0;
			}
			else
				use_cache = 0;

			if( use_cache ) {
				if( DEBUG_HEADER )
					printf( "using header cache for %s\n", t->boundname );
				c->age = 0; /* The entry has been used, its young again */
				++hits;
				l = list_copy( 0, c->includes );
				{
					LIST *hdrfilter = var_get( "HDRFILTER" );
					if ( hdrfilter )
					{
						LOL lol;
						lol_init( &lol );
						lol_add( &lol, list_new( L0, t->name, 1 ) );
						lol_add( &lol, l );
						lol_add( &lol, list_new( L0, t->boundname, 0 ) );
						l = evaluate_rule( hdrfilter->string, &lol, L0 );
						lol_free( &lol );
					}
				}
				return l;
			}
			else {
				if( DEBUG_HEADER )
					printf( "header cache out of date for %s\n", t->boundname );
				list_free( c->includes );
				list_free( c->hdrscan );
				c->includes = 0;
				c->hdrscan = 0;
			}
		} else {
			if( hashenter( file->hcachehash, (HASHDATA **)&c ) ) {
				c->boundname = newstr( c->boundname );
				c->next = file->hcachelist;
				file->hcachelist = c;
#ifdef OPT_BUILTIN_MD5CACHE_EXT
				c->mtime = 0;
				memset( &c->rulemd5sum, 0, MD5_SUMSIZE );
				memset( &c->currentrulemd5sum, 0, MD5_SUMSIZE );
				memset( &c->contentmd5sum, 0, MD5_SUMSIZE );
				memset( &c->currentcontentmd5sum, 0, MD5_SUMSIZE );
#endif
			}
		}
	}

	file->dirty = 1;

	/* 'c' points at the cache entry.  Its out of date. */

	l = headers1( c->boundname, hdrscan );

	l = list_append( list_copy( 0, var_get( "HDREXTRA" ) ), l );

	c->includes = list_copy( 0, l );

	{
		LIST *hdrfilter = var_get( "HDRFILTER" );
		if ( hdrfilter )
		{
			LOL lol;
			lol_init( &lol );
			lol_add( &lol, list_new( L0, t->name, 1 ) );
			lol_add( &lol, l );
			lol_add( &lol, list_new( L0, t->boundname, 0 ) );
			l = evaluate_rule( hdrfilter->string, &lol, L0 );
			lol_free( &lol );
		}
	}

	c->time = t->time;
	c->age = 0;

	c->hdrscan = list_copy( 0, hdrscan );

	return l;
}