main.cpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. #include "util/tc_file.h"
  2. #include "util/tc_option.h"
  3. #include "parse.h"
  4. #include <set>
  5. #include <list>
  6. using namespace tars;
  7. void usage()
  8. {
  9. cout << "Usage : tarsmerge [OPTION] tarsfile " << endl;
  10. cout << "--out: output merge file" << endl;
  11. cout << endl;
  12. exit(100);
  13. }
  14. void check(vector<string> &vTars)
  15. {
  16. for(size_t i = 0; i < vTars.size(); i++)
  17. {
  18. string ext = TC_File::extractFileExt(vTars[i]);
  19. if(ext == "tars")
  20. {
  21. if(!TC_File::isFileExist(vTars[i]))
  22. {
  23. cerr << "file '" << vTars[i] << "' not exists" << endl;
  24. usage();
  25. }
  26. }
  27. else
  28. {
  29. cerr << "only support tars file." << endl;
  30. exit(100);
  31. }
  32. }
  33. }
  34. vector<string> doParseAll(TC_Option& option, const vector<string>& vTars)
  35. {
  36. set<string> data;
  37. for(size_t i = 0; i < vTars.size(); i++) {
  38. data.insert(vTars[i]);
  39. g_parse->parse(vTars[i]);
  40. std::vector<ContextPtr> contexts = g_parse->getContexts();
  41. for (auto c : contexts) {
  42. if(c->getFileName() != vTars[i])
  43. {
  44. if(TC_File::isAbsolute(c->getFileName()))
  45. {
  46. data.insert(c->getFileName());
  47. }
  48. else if(TC_File::isAbsolute(vTars[i]))
  49. {
  50. data.insert(TC_File::simplifyDirectory(TC_File::extractFilePath(vTars[i]) + FILE_SEP + c->getFileName()));
  51. }
  52. else
  53. {
  54. data.insert(c->getFileName());
  55. }
  56. }
  57. }
  58. }
  59. return vector<string>(data.begin(), data.end());
  60. }
  61. string doTarsMerge(TC_Option& option, const vector<string>& vTars)
  62. {
  63. //把所有依赖都分析出来
  64. vector<string> allTars = doParseAll(option, vTars);
  65. list<string> orderFileNames;
  66. map<string, list<string>::iterator> fileNames;
  67. for(size_t i = 0; i < allTars.size(); i++) {
  68. string fileName = TC_File::extractFileName(allTars[i]);
  69. orderFileNames.push_front(fileName);
  70. fileNames[fileName] = orderFileNames.begin();
  71. }
  72. //按照依赖顺序排序
  73. for(size_t i = 0; i < allTars.size(); i++) {
  74. g_parse->parse(allTars[i]);
  75. string currFileName = TC_File::extractFileName(allTars[i]);
  76. std::vector<ContextPtr> contexts = g_parse->getContexts();
  77. for (auto c : contexts) {
  78. string fileName = TC_File::extractFileName(c->getFileName());
  79. if(fileName != currFileName)
  80. {
  81. //引用的文件 挪到 自己文件前面
  82. auto it = fileNames.find(fileName);
  83. if(it != fileNames.end()) {
  84. orderFileNames.erase(it->second);
  85. auto currIt = fileNames.find(currFileName);
  86. if(currIt != fileNames.end()) {
  87. orderFileNames.insert(currIt->second, fileName);
  88. }
  89. }
  90. }
  91. }
  92. }
  93. string buff;
  94. for(auto it = orderFileNames.begin(); it != orderFileNames.end(); ++it) {
  95. string f = *it;
  96. std::ifstream in(f);
  97. if (!in) {
  98. std::cout << "read error" << std::endl;
  99. exit(-1);
  100. }
  101. string file;
  102. std::string line;
  103. while (getline(in, line)) {
  104. if (TC_Common::trim(line).compare(0, 8, "#include") == 0) {
  105. continue;
  106. }
  107. file += line + "\r\n";
  108. }
  109. in.close();
  110. buff += file;
  111. }
  112. return buff;
  113. }
  114. int main(int argc, char* argv[]){
  115. if(argc < 2)
  116. {
  117. usage();
  118. return 100;
  119. }
  120. try
  121. {
  122. TC_Option option;
  123. option.decode(argc, argv);
  124. vector<string> vTars = option.getSingle();
  125. check(vTars);
  126. if (option.hasParam("help"))
  127. {
  128. usage();
  129. }
  130. string out = doTarsMerge(option, vTars);
  131. if(option.hasParam("out"))
  132. {
  133. TC_File::save2file(option.getValue("out"), out);
  134. }
  135. else
  136. {
  137. cout << out << endl;
  138. }
  139. }
  140. catch(exception& e)
  141. {
  142. cerr<<e.what()<<endl;
  143. }
  144. return 0;
  145. }