static void make_closure( void *closure, int status, timing_info* time, char *executed_command, char *command_output) { TARGET* built = (TARGET*)closure; call_timing_rule(built, time); if (DEBUG_EXECCMD) printf("%f sec system; %f sec user\n", time->system, time->user); call_action_rule(built, status, time, executed_command, command_output); push_state(&state_stack, built, NULL, T_STATE_MAKE1D)->status = status; }
static void make1c_closure ( void * const closure, int status_orig, timing_info const * const time, char const * const cmd_stdout, char const * const cmd_stderr, int const cmd_exit_reason ) { TARGET * const t = (TARGET *)closure; CMD * const cmd = (CMD *)t->cmds; char const * rule_name = 0; char const * target_name = 0; assert( cmd ); --cmdsrunning; /* Calculate the target's status from the cmd execution result. */ { /* Store the target's status. */ t->status = status_orig; /* Invert OK/FAIL target status when FAIL_EXPECTED has been applied. */ if ( t->flags & T_FLAG_FAIL_EXPECTED && !globs.noexec ) { switch ( t->status ) { case EXEC_CMD_FAIL: t->status = EXEC_CMD_OK; break; case EXEC_CMD_OK: t->status = EXEC_CMD_FAIL; break; } } /* Ignore failures for actions marked as 'ignore'. */ if ( t->status == EXEC_CMD_FAIL && cmd->rule->actions->flags & RULE_IGNORE ) t->status = EXEC_CMD_OK; } if ( DEBUG_MAKEQ || ( DEBUG_MAKE && !( cmd->rule->actions->flags & RULE_QUIETLY ) ) ) { rule_name = object_str( cmd->rule->name ); target_name = object_str( list_front( lol_get( (LOL *)&cmd->args, 0 ) ) ); } out_action( rule_name, target_name, cmd->buf->value, cmd_stdout, cmd_stderr, cmd_exit_reason ); if ( !globs.noexec ) { call_timing_rule( t, time ); if ( DEBUG_EXECCMD ) printf( "%f sec system; %f sec user\n", time->system, time->user ); /* Assume -p0 is in effect, i.e. cmd_stdout contains merged output. */ call_action_rule( t, status_orig, time, cmd->buf->value, cmd_stdout ); } /* Print command text on failure. */ if ( t->status == EXEC_CMD_FAIL && DEBUG_MAKE ) { if ( !DEBUG_EXEC ) printf( "%s\n", cmd->buf->value ); printf( "...failed %s ", object_str( cmd->rule->name ) ); list_print( lol_get( (LOL *)&cmd->args, 0 ) ); printf( "...\n" ); } /* On interrupt, set intr so _everything_ fails. Do the same for failed * commands if we were asked to stop the build in case of any errors. */ if ( t->status == EXEC_CMD_INTR || ( t->status == EXEC_CMD_FAIL && globs.quitquick ) ) ++intr; /* If the command was not successful remove all of its targets not marked as * "precious". */ if ( t->status != EXEC_CMD_OK ) { LIST * const targets = lol_get( (LOL *)&cmd->args, 0 ); LISTITER iter = list_begin( targets ); LISTITER const end = list_end( targets ); for ( ; iter != end; iter = list_next( iter ) ) { char const * const filename = object_str( list_item( iter ) ); TARGET const * const t = bindtarget( list_item( iter ) ); if ( !( t->flags & T_FLAG_PRECIOUS ) && !unlink( filename ) ) printf( "...removing %s\n", filename ); } } /* Free this command and push the MAKE1C state to execute the next one * scheduled for building this same target. */ t->cmds = (char *)cmd_next( cmd ); cmd_free( cmd ); push_state( &state_stack, t, NULL, T_STATE_MAKE1C ); }