#include "util/tc_file.h" #include "util/tc_option.h" #include "parse.h" #include #include using namespace tars; void usage() { cout << "Usage : tarsmerge [OPTION] tarsfile " << endl; cout << "--out: output merge file" << endl; cout << endl; exit(100); } void check(vector &vTars) { for(size_t i = 0; i < vTars.size(); i++) { string ext = TC_File::extractFileExt(vTars[i]); if(ext == "tars") { if(!TC_File::isFileExist(vTars[i])) { cerr << "file '" << vTars[i] << "' not exists" << endl; usage(); } } else { cerr << "only support tars file." << endl; exit(100); } } } vector doParseAll(TC_Option& option, const vector& vTars) { set data; for(size_t i = 0; i < vTars.size(); i++) { data.insert(vTars[i]); g_parse->parse(vTars[i]); std::vector contexts = g_parse->getContexts(); for (auto c : contexts) { if(c->getFileName() != vTars[i]) { if(TC_File::isAbsolute(c->getFileName())) { data.insert(c->getFileName()); } else if(TC_File::isAbsolute(vTars[i])) { data.insert(TC_File::simplifyDirectory(TC_File::extractFilePath(vTars[i]) + FILE_SEP + c->getFileName())); } else { data.insert(c->getFileName()); } } } } return vector(data.begin(), data.end()); } string doTarsMerge(TC_Option& option, const vector& vTars) { //把所有依赖都分析出来 vector allTars = doParseAll(option, vTars); list orderFileNames; map::iterator> fileNames; for(size_t i = 0; i < allTars.size(); i++) { string fileName = TC_File::extractFileName(allTars[i]); orderFileNames.push_front(fileName); fileNames[fileName] = orderFileNames.begin(); } //按照依赖顺序排序 for(size_t i = 0; i < allTars.size(); i++) { g_parse->parse(allTars[i]); string currFileName = TC_File::extractFileName(allTars[i]); std::vector contexts = g_parse->getContexts(); for (auto c : contexts) { string fileName = TC_File::extractFileName(c->getFileName()); if(fileName != currFileName) { //引用的文件 挪到 自己文件前面 auto it = fileNames.find(fileName); if(it != fileNames.end()) { orderFileNames.erase(it->second); auto currIt = fileNames.find(currFileName); if(currIt != fileNames.end()) { orderFileNames.insert(currIt->second, fileName); } } } } } string buff; for(auto it = orderFileNames.begin(); it != orderFileNames.end(); ++it) { string f = *it; std::ifstream in(f); if (!in) { std::cout << "read error" << std::endl; exit(-1); } string file; std::string line; while (getline(in, line)) { if (TC_Common::trim(line).compare(0, 8, "#include") == 0) { continue; } file += line + "\r\n"; } in.close(); buff += file; } return buff; } int main(int argc, char* argv[]){ if(argc < 2) { usage(); return 100; } try { TC_Option option; option.decode(argc, argv); vector vTars = option.getSingle(); check(vTars); if (option.hasParam("help")) { usage(); } string out = doTarsMerge(option, vTars); if(option.hasParam("out")) { TC_File::save2file(option.getValue("out"), out); } else { cout << out << endl; } } catch(exception& e) { cerr<