// This file is part of the AspectC++ compiler 'ac++'.
// Copyright (C) 1999-2004  The 'ac++' developers (see aspectc.org)
//                                                                
// This program is free software;  you can redistribute it and/or 
// modify it under the terms of the GNU General Public License as 
// published by the Free Software Foundation; either version 2 of 
// the License, or (at your option) any later version.            
//                                                                
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of 
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  
// GNU General Public License for more details.                   
//                                                                
// You should have received a copy of the GNU General Public      
// License along with this program; if not, write to the Free     
// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
// MA  02111-1307  USA                                           


#include "ACCompiler.h"
#include "System.h"
#include "regex.h"
#include "file.h"

//stdc++ includes
#include<string>
using namespace std;
using namespace file;

//Puma includes 
#include "Puma/VerboseMgr.h"


bool ACCompiler::execute(){
		
	VerboseMgr vm(cout,_config.verbose());
	vm << "Weaving" << endvm;
	
	// command line string
	string exec_str= "\""+_config.acc_bin()+"\" --config \""+_config.puma_config()+"\" "+
	_config.optvec().getString(OptionItem::OPT_ACC);
 
	// get output path for .acc files from -o option
	string acc_output_path=_config.output_file();
	file::stripFilename(acc_output_path);
	
	// process each file separetly
	OptionVec::iterator opt = _config.optvec().begin();
	while(opt != _config.optvec().end()){
		
		if( (opt->flag() & OptionItem::OPT_FILE_ACC) != OptionItem::OPT_FILE_ACC){
			opt++;	
			continue;
		}
		
		const string file = opt->name();
		
		//construct name for intermediate output file
		string out_file(file);
		// if we want to weave more than one file  or want to compile a file
		// after weaving put intermediate .acc file in acc_output_path 
		if( _config.output_file().empty() || _config.compile() ){
		
			//out_file=*file;
			stripPath(out_file);
			
			int endpos =out_file.rfind('.') ;
			out_file.replace(endpos,string::npos,".acc");
			out_file = acc_output_path  + out_file;
			
		}else{
			out_file=_config.output_file();
		}
			

		// construct final command string
		string local_exec_str = exec_str+" -c \""+file+"\" -o \""+out_file+"\"";
		
		// execute AspectC++
		System acc(_err,_config,local_exec_str);
		if(! acc.execute() ){
			return false;
		}
		
		//change filename in input_file list, so that the next steps 
		//get the proper filename
		opt->name(out_file);
		opt->flag(opt->flag()|OptionItem::OPT_FILE_GCC);
		
		//AGxxConfig::FileCont::iterator tmp=file;
		opt++;	
	}

	
	if (_config.gen_includes()){
		string local_exec_str = exec_str+" -i -d \""+_config.dest_path()+"\"";
		System acc(_err,_config,local_exec_str);
		return acc.execute();
	}
	

	return true;
}
