123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 |
- #include "util/tc_file.h"
- #include "util/tc_option.h"
- #include "parse.h"
- #include <set>
- #include <list>
- using namespace tars;
- void usage()
- {
- cout << "Usage : tarsmerge [OPTION] tarsfile " << endl;
- cout << "--out: output merge file" << endl;
- cout << endl;
- exit(100);
- }
- void check(vector<string> &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<string> doParseAll(TC_Option& option, const vector<string>& vTars)
- {
- set<string> data;
- for(size_t i = 0; i < vTars.size(); i++) {
- data.insert(vTars[i]);
- g_parse->parse(vTars[i]);
- std::vector<ContextPtr> 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<string>(data.begin(), data.end());
- }
- string doTarsMerge(TC_Option& option, const vector<string>& vTars)
- {
- //把所有依赖都分析出来
- vector<string> allTars = doParseAll(option, vTars);
- list<string> orderFileNames;
- map<string, list<string>::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<ContextPtr> 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<string> 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<<e.what()<<endl;
- }
- return 0;
- }
|