예제 #1
0
ParseNode* new_node(void *malloc_pool, ObItemType type, int num)
{
  ParseNode* node = (ParseNode*)parse_malloc(sizeof(ParseNode), malloc_pool);
  if (node != NULL)
  {
    memset(node, 0 , sizeof(ParseNode));

    node->type_ = type;
    node->num_child_ = num;
    if(num > 0)
    {
      int64_t alloc_size = sizeof(ParseNode*) * num ;
      //node->children_ = (ParseNode**)malloc(alloc_size);
      node->children_ = (ParseNode**)parse_malloc(alloc_size, malloc_pool);
      if (node->children_ != NULL)
      {
        memset(node->children_, 0, alloc_size);
      }
      else
      {
        parse_free(node);
        node = NULL;
      }
    }
    else
    {
      node->children_ = 0;
    }
  }
  return node;
}
예제 #2
0
파일: parse.c 프로젝트: Cabriter/abelkhan
void parse_file( OBJECT * f, FRAME * frame )
{
    /* Suspend scan of current file and push this new file in the stream. */
    yyfparse( f );

    /* Now parse each block of rules and execute it. Execute it outside of the
     * parser so that recursive calls to yyrun() work (no recursive yyparse's).
     */

    for ( ; ; )
    {
        PARSE * p;
        FUNCTION * func;

        /* Filled by yyparse() calling parse_save(). */
        yypsave = 0;

        /* If parse error or empty parse, outta here. */
        if ( yyparse() || !( p = yypsave ) )
            break;

        /* Run the parse tree. */
        func = function_compile( p );
        parse_free( p );
        list_free( function_run( func, frame, stack_global() ) );
        function_free( func );
    }

    yyfdone();
}
void destroy_token_list(token_list_t *list)
{
	int i;

	for(i=0; i< list->max_tokens; i++)
	{
		if (TK[i] != 0) parse_free(TK[i]);
	}
}
예제 #4
0
void destroy_tree(ParseNode* root)
{
  int i;
  if(root == 0)
    return;
  for(i = 0; i < root->num_child_; ++i)
  {
    destroy_tree(root->children_[i]);
  }
  if(root->str_value_ != NULL)
  {
    parse_free((char*)root->str_value_);
  }
  if(root->num_child_)
  {
    parse_free(root->children_);
  }
  parse_free(root);
}
예제 #5
0
파일: parse.c 프로젝트: Cabriter/abelkhan
void parse_free( PARSE * p )
{
    if ( --p->refs )
        return;

    if ( p->string )
        object_free( p->string );
    if ( p->string1 )
        object_free( p->string1 );
    if ( p->left )
        parse_free( p->left );
    if ( p->right )
        parse_free( p->right );
    if ( p->third )
        parse_free( p->third );
    if ( p->rulename )
        object_free( p->rulename );
    if ( p->file )
        object_free( p->file );

    BJAM_FREE( (char *)p );
}
예제 #6
0
파일: control.c 프로젝트: dacav/maillearn
void mbox_free (mbox_t *mbox)
{
    register thrdqueue_t *q = mbox->mail_queue;

    /* Join with thread */
    pthread_join(mbox->parser_th, NULL);

    thq_delete(q, (void (*)(void *))mbox_mail_free);
    parse_free(&mbox->parse);
    dstrbuf_free(mbox->aux.multiline);

    free(mbox);
}
예제 #7
0
파일: parse.c 프로젝트: arventwei/jamplus
void
parse_free( PARSE *p )
{
	if( --p->refs )
	    return;

	if( p->string )
	    freestr( p->string );
	if( p->string1 )
	    freestr( p->string1 );
	if( p->left )
	    parse_free( p->left );
	if( p->right )
	    parse_free( p->right );
	if( p->third )
	    parse_free( p->third );
	
#ifdef OPT_IMPROVED_MEMUSE_EXT
	mempool_free(parse_pool, p);
#else
	free( (char *)p );
#endif
}
예제 #8
0
파일: rules.c 프로젝트: Albermg7/boost
/*
 * set_rule_body() - set the argument list and procedure of the given rule
 */
static void set_rule_body( RULE* rule, argument_list* args, PARSE* procedure )
{
    if ( args )
        args_refer( args );
    if ( rule->arguments )
        args_free( rule->arguments );
    rule->arguments = args;
    
    if ( procedure )
        parse_refer( procedure );
    if ( rule->procedure )
        parse_free( rule->procedure );
    rule->procedure = procedure;
}
예제 #9
0
파일: rules.c 프로젝트: Albermg7/boost
void
rule_free( RULE* r )
{
    freestr( r->name );
    r->name = "";
    parse_free( r->procedure );
    r->procedure = 0;
	if ( r->arguments )
	    args_free( r->arguments );
    r->arguments = 0;
    if ( r->actions )
		actions_free( r->actions );
    r->actions = 0;
}
예제 #10
0
LIST *
compile_setcomp(
	PARSE	*parse,
	LOL	*args,
	int	*jmp )
{
	RULE	*rule = bindrule( parse->string );
	LIST	*params = 0;
	PARSE	*p;

	/* Build param list */

	for( p = parse->left; p; p = p->left )
	    params = list_append( params, p->string, 1 );

	if( DEBUG_COMPILE )
	{
	    debug_compile( 0, "rule" );
	    printf( "%s ", parse->string );
	    list_print( params );
	    printf( "\n" );
	}

	/* Free old one, if present */

	if( rule->procedure )
	    parse_free( rule->procedure );

	if( rule->params )
	    list_free( rule->params );

	rule->procedure = parse->right;
	rule->params = params;

	/* we now own this parse tree */
	/* don't let parse_free() release it */

	parse_refer( parse->right );

	return L0;
}
예제 #11
0
/**
 * Simplify the command and call one of the sub parser functions
 *
 * @param cmd Raw command string. This parameter is mutated. This
 * parameter cannot be NULL.
 * @param cmd_len Length in bytes of the command string.
 * @return Program status.
 */
static status_t parse_command(char* cmd, int cmd_len)
{
	assert(cmd != NULL);

	int ws_cursor = 0;

	if (cmd[0] == '\0' || cmd[0] == '\n' || cmd[0] == '\r')
		return SUCCESS;

	// remove whitespace from command
	for (int i = 0; i < cmd_len; ++i) {
		switch (cmd[i]) {
		case ' ':
		case '\n':
		case '\r':
		case '\t':
			break;

		default:
			cmd[ws_cursor++] = cmd[i];
		}
	}

	status_t status;

	// We have 2 commands: alloc and free.
	if (strstr(cmd, "alloc") != NULL)
		status = parse_alloc(cmd);
	else if (strstr(cmd, "free") != NULL)
		status = parse_free(cmd);
	else
		return parse_error(cmd);

	if (status != SUCCESS)
		return status;

	// Output free blocks
	buddy_dump();

	return SUCCESS;
}
예제 #12
0
파일: parse.c 프로젝트: arventwei/jamplus
void
parse_lines( const char *s, char** lines )
{
	/* Suspend scan of current file */
	/* and push this new file in the stream */

	yyfparselines(s, lines);

	/* Now parse each block of rules and execute it. */
	/* Execute it outside of the parser so that recursive */
	/* calls to yyrun() work (no recursive yyparse's). */

	for(;;)
	{
	    LOL l;
	    PARSE *p;
	    int jmp = 0; /* JMP_NONE */

	    /* $(<) and $(>) empty in outer scope. */

	    lol_init( &l );

	    /* Filled by yyparse() calling parse_save() */

	    yypsave = 0;

	    /* If parse error or empty parse, outta here */

	    if( yyparse() || !( p = yypsave ) )
		break;

	    /* Run the parse tree. */

	    list_free( (*(p->func))( p, &l, &jmp ) );


	    parse_free( p );
	}
}
예제 #13
0
파일: main.c 프로젝트: darksoul42/bitrig
int
vmmaction(struct parse_result *res)
{
	struct sockaddr_un	 sun;
	struct imsg		 imsg;
	int			 done = 0;
	int			 n;
	int			 ret, action;

	if (ctl_sock == -1) {
		if ((ctl_sock = socket(AF_UNIX,
		    SOCK_STREAM|SOCK_CLOEXEC, 0)) == -1)
			err(1, "socket");

		bzero(&sun, sizeof(sun));
		sun.sun_family = AF_UNIX;
		strlcpy(sun.sun_path, socket_name, sizeof(sun.sun_path));

		if (connect(ctl_sock,
		    (struct sockaddr *)&sun, sizeof(sun)) == -1)
			err(1, "connect: %s", socket_name);

		if ((ibuf = malloc(sizeof(struct imsgbuf))) == NULL)
			err(1, "malloc");
		imsg_init(ibuf, ctl_sock);
	}

	switch (res->action) {
	case CMD_START:
		/* XXX validation should be done in start_vm() */
		if (res->size < 1)
			errx(1, "specified memory size too small");
		if (res->path == NULL)
			errx(1, "no kernel specified");
		if (res->ndisks > VMM_MAX_DISKS_PER_VM)
			errx(1, "too many disks");
		else if (res->ndisks == 0)
			warnx("starting without disks");
		if (res->nifs == -1)
			res->nifs = 0;
		if (res->nifs == 0)
			warnx("starting without network interfaces");

		ret = start_vm(res->name, res->size, res->nifs,
		    res->ndisks, res->disks, res->path);
		if (ret) {
			errno = ret;
			err(1, "start VM operation failed");
		}
		break;
	case CMD_STOP:
		terminate_vm(res->id, res->name);
		break;
	case CMD_STATUS:
		get_info_vm(res->id, res->name, 0);
		break;
	case CMD_CONSOLE:
		get_info_vm(res->id, res->name, 1);
		break;
	case CMD_RELOAD:
		imsg_compose(ibuf, IMSG_VMDOP_RELOAD, 0, 0, -1,
		    res->path, res->path == NULL ? 0 : strlen(res->path) + 1);
		done = 1;
		break;
	case CMD_LOAD:
		imsg_compose(ibuf, IMSG_VMDOP_LOAD, 0, 0, -1,
		    res->path, res->path == NULL ? 0 : strlen(res->path) + 1);
		done = 1;
		break;
	case CMD_CREATE:
	case NONE:
		break;
	}

	action = res->action;
	parse_free(res);

	while (ibuf->w.queued)
		if (msgbuf_write(&ibuf->w) <= 0 && errno != EAGAIN)
			err(1, "write error");

	while (!done) {
		if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN)
			errx(1, "imsg_read error");
		if (n == 0)
			errx(1, "pipe closed");

		while (!done) {
			if ((n = imsg_get(ibuf, &imsg)) == -1)
				errx(1, "imsg_get error");
			if (n == 0)
				break;

			if (imsg.hdr.type == IMSG_CTL_FAIL) {
				if (IMSG_DATA_SIZE(&imsg) == sizeof(ret)) {
					memcpy(&ret, imsg.data, sizeof(ret));
					errno = ret;
					warn("command failed");
				} else {
					warnx("command failed");
				}
				done = 1;
				break;
			}

			ret = 0;
			switch (action) {
			case CMD_START:
				done = start_vm_complete(&imsg, &ret,
				    tty_autoconnect);
				break;
			case CMD_STOP:
				done = terminate_vm_complete(&imsg, &ret);
				break;
			case CMD_CONSOLE:
			case CMD_STATUS:
				done = add_info(&imsg, &ret);
				break;
			default:
				done = 1;
				break;
			}

			imsg_free(&imsg);
		}
	}

	return (0);
}
예제 #14
0
파일: compile.c 프로젝트: 4ukuta/core
LIST *
evaluate_rule(
    char  * rulename,
    FRAME * frame )
{
    LIST          * result = L0;
    RULE          * rule;
    profile_frame   prof[1];
    module_t      * prev_module = frame->module;

    LIST * l;
    {
        LOL arg_context_, * arg_context = &arg_context_;
        if ( !frame->prev )
            lol_init(arg_context);
        else
            arg_context = frame->prev->args;
        l = var_expand( L0, rulename, rulename+strlen(rulename), arg_context, 0 );
    }

    if ( !l )
    {
        backtrace_line( frame->prev );
        printf( "warning: rulename %s expands to empty string\n", rulename );
        backtrace( frame->prev );
        return result;
    }

    rulename = l->string;
    rule = bindrule( l->string, frame->module );

#ifdef HAVE_PYTHON
    if ( rule->python_function )
    {
        /* The below messing with modules is due to the way modules are
         * implemented in Jam. Suppose we are in module M1 now. The global
         * variable map actually holds 'M1' variables, and M1->variables hold
         * global variables.
         *
         * If we call Python right away, Python calls back Jam and then Jam
         * does 'module M1 { }' then Jam will try to swap the current global
         * variables with M1->variables. The result will be that global
         * variables map will hold global variables, and any variable settings
         * we do will go to the global module, not M1.
         *
         * By restoring basic state, where the global variable map holds global
         * variable, we make sure any future 'module M1' entry will work OK.
         */

        LIST * result;
        module_t * m = python_module();

        frame->module = m;

        exit_module( prev_module );
        enter_module( m );

        result = call_python_function( rule, frame );

        exit_module( m );
        enter_module ( prev_module );

        return result;
    }
#endif

    /* Drop the rule name. */
    l = list_pop_front( l );

    /* Tack the rest of the expansion onto the front of the first argument. */
    frame->args->list[0] = list_append( l, lol_get( frame->args, 0 ) );

    if ( DEBUG_COMPILE )
    {
        /* Try hard to indicate in which module the rule is going to execute. */
        if ( rule->module != frame->module
             && rule->procedure != 0 && strcmp( rulename, rule->procedure->rulename ) )
        {
            char buf[256] = "";
            strncat( buf, rule->module->name, sizeof( buf ) - 1 );
            strncat( buf, rule->name, sizeof( buf ) - 1 );
            debug_compile( 1, buf, frame );
        }
        else
        {
            debug_compile( 1, rulename, frame );
        }

        lol_print( frame->args );
        printf( "\n" );
    }

    if ( rule->procedure && rule->module != prev_module )
    {
        /* Propagate current module to nested rule invocations. */
        frame->module = rule->module;

        /* Swap variables. */
        exit_module( prev_module );
        enter_module( rule->module );
    }

    /* Record current rule name in frame. */
    if ( rule->procedure )
    {
        frame->rulename = rulename;
        /* And enter record profile info. */
        if ( DEBUG_PROFILE )
            profile_enter( rule->procedure->rulename, prof );
    }

    /* Check traditional targets $(<) and sources $(>). */
    if ( !rule->actions && !rule->procedure )
    {
        backtrace_line( frame->prev );
        printf( "rule %s unknown in module %s\n", rule->name, frame->module->name );
        backtrace( frame->prev );
        exit( 1 );
    }

    /* 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 *)BJAM_MALLOC( sizeof( ACTION ) );
        memset( (char *)action, '\0', sizeof( *action ) );

        action->rule = rule;
        action->targets = targetlist( (TARGETS *)0, lol_get( frame->args, 0 ) );
        action->sources = targetlist( (TARGETS *)0, lol_get( frame->args, 1 ) );

        /* If we have a group of targets all being built using the same action
         * then we must not allow any of them to be used as sources unless they
         * had all already been built in the first place or their joined action
         * has had a chance to finish its work and build all of them anew.
         *
         * Without this it might be possible, in case of a multi-process build,
         * for their action, triggered by buiding one of the targets, to still
         * be running when another target in the group reports as done in order
         * to avoid triggering the same action again and gets used prematurely.
         *
         * As a quick-fix to achieve this effect we make all the targets list
         * each other as 'included targets'. More precisely, we mark the first
         * listed target as including all the other targets in the list and vice
         * versa. This makes anyone depending on any of those targets implicitly
         * depend on all of them, thus making sure none of those targets can be
         * used as sources until all of them have been built. Note that direct
         * dependencies could not have been used due to the 'circular
         * dependency' issue.
         *
         * TODO: Although the current implementation solves the problem of one
         * of the targets getting used before its action completes its work it
         * also forces the action to run whenever any of the targets in the
         * group is not up to date even though some of them might not actually
         * be used by the targets being built. We should see how we can
         * correctly recognize such cases and use that to avoid running the
         * action if possible and not rebuild targets not actually depending on
         * targets that are not up to date.
         *
         * TODO: Using the 'include' feature might have side-effects due to
         * interaction with the actual 'inclusion scanning' system. This should
         * be checked.
         */
        if ( action->targets )
        {
            TARGET * t0 = action->targets->target;
            for ( t = action->targets->next; t; t = t->next )
            {
                target_include( t->target, t0 );
                target_include( t0, t->target );
            }
        }

        /* Append this action to the actions of each target. */
        for ( t = action->targets; t; t = t->next )
            t->target->actions = actionlist( t->target->actions, action );
    }

    /* Now recursively compile any parse tree associated with this rule.
     * parse_refer()/parse_free() call pair added to ensure rule not freed
     * during use.
     */
    if ( rule->procedure )
    {
        SETTINGS * local_args = collect_arguments( rule, frame );
        PARSE * parse = rule->procedure;
        parse_refer( parse );

        pushsettings( local_args );
        result = parse_evaluate( parse, frame );
        popsettings( local_args );
        freesettings( local_args );

        parse_free( parse );
    }

    if ( frame->module != prev_module )
    {
        exit_module( frame->module );
        enter_module( prev_module );
    }

    if ( DEBUG_PROFILE && rule->procedure )
        profile_exit( prof );

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

    return result;
}
예제 #15
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;
}
예제 #16
0
파일: compile.c 프로젝트: GustavoMOG/edelib
LIST *
evaluate_rule(
	const char *rulename,
	LOL	*args, 
	LIST	*result,
	int	*jmp )
{
	RULE	*rule = bindrule( rulename );

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

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

	if( !rule->actions && !rule->procedure )
	    printf( "warning: unknown rule %s\n", rule->name );

	/* 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;
	    action->targets = targetlist( (TARGETS *)0, lol_get( args, 0 ) );
	    action->sources = targetlist( (TARGETS *)0, lol_get( args, 1 ) );

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

	    for( t = action->targets; t; t = t->next )
		t->target->actions = actionlist( t->target->actions, action );
	}

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

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

# ifdef OPT_RULE_PROFILING_EXT
		struct timeval startTime, endTime;

		if ( DEBUG_PROFILE_RULES )
			gettimeofday(&startTime, 0);
# endif

	    /* build parameters as local vars */

	    for( l = rule->params, i = 0; l; l = l->next, i++ )
		s = addsettings( s, 0, l->string, 
		    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_append( result, (*parse->func)( parse, args, jmp ) );
	    popsettings( s );
	    freesettings( s );

	    parse_free( parse );

# ifdef OPT_RULE_PROFILING_EXT
		if ( DEBUG_PROFILE_RULES )
		{
			gettimeofday(&endTime, 0);

			rule->invocations++;
			rule->invocation_time
				+= (endTime.tv_sec - startTime.tv_sec) * (int64_t)1000000
					+ (endTime.tv_usec - startTime.tv_usec);
		}
# endif

	}

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

	return result;
}
예제 #17
0
/**
 * @brief  Run command described by string stored in buffer
 *
 * @param buffer command to be executed
 *
 * @return   true on success
 */
static
void * run_command(void * p) {
	UNUSED(p);
	char ** cmd = NULL;
	int ret;
	int i = 0;
	struct parse_list_t cmd_list;
	struct parse_litem_t * it;


	pthread_mutex_lock(&buffer_mutex_exec);
	pthread_cond_wait(&buffer_cond_exec, &buffer_mutex_exec);
	while (! g_exit) {
		parse_list_init(&cmd_list);

		if (! parse_command(&cmd_list, buffer)) {
			print_error(ERR_PARSE_FAILED);
			goto signalize;
		}

		if (cmd_list.length == 1 && ! strcmp(cmd_list.head->token, CMD_EXIT)) {
			g_exit = true;
			goto signalize;
		}
		//write(1, MSG_COMMAND, strlen(MSG_COMMAND));

		if (cmd_list.length == 0) {
			goto signalize; // nothing to do
		}

		cmd = (char **) malloc((cmd_list.length + 1) * sizeof(char *));
		if (! cmd) { parse_free(&cmd_list); goto signalize; }

		for (it = cmd_list.head, i = 0; it; it = it->next, ++i) {
			//printf("cmd[%d] == %s\n", i, it->token);
			cmd[i] = it->token;
		}
		cmd[cmd_list.length] = (char *) 0;

		ret = vfork();

		if (ret < 0) {
			perror("fork failed");
		} else if (ret == 0) { // child
			// open input
			if (cmd_list.input) {
				ret = open(cmd_list.input, O_RDONLY);
				if (ret < 0) {
					perror(cmd_list.input);
					exit(EXIT_FAILURE);
				}

				if (dup2(ret, STDIN_FILENO) < 0) {
					perror("dup2 STDIN_FILENO");
					exit(EXIT_FAILURE);
				}
			} else if (cmd_list.background) {
				close(STDIN_FILENO);
			}

			// open output
			if (cmd_list.output) {
				ret = open(cmd_list.output, O_WRONLY | O_CREAT | O_TRUNC, 0666);
				if (ret < 0) {
					perror(cmd_list.output);
					exit(EXIT_FAILURE);
				}

				if (dup2(ret, STDOUT_FILENO) < 0) {
					perror("dup2 STDOUT_FILENO");
					exit(EXIT_FAILURE);
				}
			}

			/*
			 * Restore signal handlers
			 */
			signal_handler_restore();

			if (cmd_list.background) {
				pidlist_insert(&pidlist, getpid());
				fprintf(stderr, "\r>>> child %d is running in background\n", getpid());
			} else {
				// run in foreground, unblock SIGINT
				sigint_unblock();
			}

			// run it! :-*
			ret = execvp(cmd_list.head->token, cmd);
			if (ret < 0) {
				perror(cmd_list.head->token);
				exit(EXIT_FAILURE);
			}
		} else { // parent
			if (! cmd_list.background)
				waitpid(ret, NULL, 0);
		}
signalize:
		if (cmd) {
			free(cmd); cmd = NULL;
		}
		parse_free(&cmd_list);
		buffer[0] = '\0'; // mark buffer as empty
		pthread_cond_signal(&buffer_cond_read);
		if (! g_exit) // wait only if no exit signaled
			pthread_cond_wait(&buffer_cond_exec, &buffer_mutex_exec);
	} // g_exit

	pthread_mutex_unlock(&buffer_mutex_exec);

	return NULL;
}
예제 #18
0
파일: compile.c 프로젝트: Albermg7/boost
LIST *
evaluate_rule(
    char    *rulename,
    FRAME *frame )
{
    LIST      *result = L0;
    RULE          *rule;
    profile_frame prof[1];
    module_t    *prev_module = frame->module;
    
    LIST      *l;
    {
        LOL arg_context_, *arg_context = &arg_context_;
        if ( !frame->prev )
            lol_init(arg_context);
        else
            arg_context = frame->prev->args;
        
        l = var_expand( L0, rulename, rulename+strlen(rulename), arg_context, 0 );
    }

    if ( !l )
    {
        backtrace_line( frame->prev );
        printf( "warning: rulename %s expands to empty string\n", rulename );
        backtrace( frame->prev );
        return result;
    }

    rulename = l->string;
    rule = bindrule( l->string, frame->module );

#ifdef HAVE_PYTHON
    if (rule->python_function)
    {
        return call_python_function(rule, frame);
    }
#endif

    /* drop the rule name */
    l = list_pop_front( l );

    /* tack the rest of the expansion onto the front of the first argument */
    frame->args->list[0] = list_append( l, lol_get( frame->args, 0 ) );

    if ( DEBUG_COMPILE )
    {
        /* Try hard to indicate in which module the rule is going to execute */
        if ( rule->module != frame->module
             && rule->procedure != 0 && strcmp(rulename, rule->procedure->rulename) )
        {
            char buf[256] = "";
            strncat( buf, rule->module->name, sizeof(buf) - 1 );
            strncat( buf, rule->name, sizeof(buf) - 1 );
            debug_compile( 1, buf, frame);
        }
        else
        {
            debug_compile( 1, rulename, frame);
        }

        lol_print( frame->args );
        printf( "\n" );
    }
    
    if ( rule->procedure && rule->module != prev_module )
    {
        /* propagate current module to nested rule invocations */
        frame->module = rule->module;
        
        /* swap variables */
        exit_module( prev_module );
        enter_module( rule->module );
    }
        
    /* record current rule name in frame */
    if ( rule->procedure )
    {
        frame->rulename = rulename;
        /* and enter record profile info */
        if ( DEBUG_PROFILE )
            profile_enter( rule->procedure->rulename, prof );
    }

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

    if( !rule->actions && !rule->procedure )
    {
        backtrace_line( frame->prev );
        printf( "rule %s unknown in module %s\n", rule->name, frame->module->name );
        backtrace( frame->prev );
        exit(1);
    }

    /* 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;
        action->targets = targetlist( (TARGETS *)0, lol_get( frame->args, 0 ) );
        action->sources = targetlist( (TARGETS *)0, lol_get( frame->args, 1 ) );

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

        for( t = action->targets; t; t = t->next )
            t->target->actions = actionlist( t->target->actions, action );
    }

    /* Now recursively compile any parse tree associated with this rule */
    /* refer/free to ensure rule not freed during use */

    if( rule->procedure )
    {
        SETTINGS *local_args = collect_arguments( rule, frame );
        PARSE *parse = rule->procedure;
        parse_refer( parse );
        
        pushsettings( local_args );
        result = parse_evaluate( parse, frame );
        popsettings( local_args );
        freesettings( local_args );
        
        parse_free( parse );
    }

    if ( frame->module != prev_module )
    {
        exit_module( frame->module );
        enter_module( prev_module );
    }

    if ( DEBUG_PROFILE && rule->procedure )
        profile_exit( prof );

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

    return result;
}