prizrak567890

preproc2

Feb 1st, 2024 (edited)
1,129
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.16 KB | None | 0 0
  1. #include <cassert>
  2. #include <filesystem>
  3. #include <fstream>
  4. #include <iostream>
  5. #include <regex>
  6. #include <sstream>
  7. #include <string>
  8. #include <vector>
  9. using namespace std;
  10. using filesystem::path;
  11.  
  12. path operator""_p(const char* data, std::size_t sz) {
  13.     return path(data, data + sz);
  14. }
  15.  
  16.  
  17. string obpath(path in_file) {
  18.  
  19.     string obspath = in_file.string();
  20.  
  21.     for (int i = obspath.size() - 1; i > 0 - 1; i--) {
  22.         if (obspath[i] != '\\' && obspath[i] != '/') {
  23.             obspath.resize(i);
  24.         }
  25.         else {
  26.             break;
  27.         }
  28.     }
  29.     return obspath;
  30. }
  31.  
  32. // напишите эту функцию
  33. bool Preprocess(const path& in_file, const path& out_file, const vector<path>& include_directories) {
  34.  
  35.     ifstream input(in_file);
  36.     if (!input.is_open()) {
  37.         return false;
  38.     }
  39.    
  40.     ofstream out(out_file);
  41.     smatch coincidences;
  42.     regex local_reg(R"/(\s*#\s*include\s*"([^"]*)"\s*)/");
  43.    regex remote_reg(R"/(\s*#\s*include\s*<([^>]*)>\s*)/");
  44.  
  45.     string line;
  46.     int number_line = 0;
  47.     while (getline(input, line)) {
  48.         number_line += 1;
  49.         if (regex_match(line, coincidences, local_reg)) {
  50.             if (coincidences.size() > 1) {
  51.                 string obspath = obpath(in_file);
  52.                 obspath += coincidences[1];
  53.                 string p2 = "sources\\include2\\";
  54.                 p2 += coincidences[1];
  55.                 if (filesystem::exists(obspath)) {
  56.                     //когда нашли файл
  57.                     Preprocess(obspath, out_file, include_directories);
  58.  
  59.                 }
  60.                 else if(filesystem::exists(p2)) {
  61.                     Preprocess(p2, out_file, include_directories);
  62.                 }
  63.                 else {
  64.                     cout << "unknown include file "<< coincidences[1] << " at file "<< in_file.string() << " at line " << number_line << endl;
  65.                     return false;
  66.                 }
  67.             }
  68.         }
  69.         else if (regex_match(line, coincidences, remote_reg)) {
  70.             if (coincidences.size() > 1) {
  71.                 string p = "sources\\include1\\";
  72.                 p += coincidences[1];
  73.                 if (filesystem::exists(p)) {
  74.                     //когда нашли файл
  75.                     Preprocess(p, out_file, include_directories);
  76.                 }
  77.                 else {
  78.                     cout << "unknown include file " << coincidences[1] << " at file " << in_file.string() << " at line " << number_line << endl;
  79.                     return false;
  80.                 }
  81.             }
  82.         }
  83.         else {
  84.             cout << line << endl;
  85.         }
  86.     }
  87.     return true;
  88.    
  89. }
  90.  
  91.  
  92.  
  93.  
  94. string GetFileContents(string file) {
  95.     ifstream stream(file);
  96.  
  97.     // конструируем string по двум итераторам
  98.     return { (istreambuf_iterator<char>(stream)), istreambuf_iterator<char>() };
  99. }
  100.  
  101. void Test() {
  102.     error_code err;
  103.     filesystem::remove_all("sources"_p, err);
  104.     filesystem::create_directories("sources"_p / "include2"_p / "lib"_p, err);
  105.     filesystem::create_directories("sources"_p / "include1"_p, err);
  106.     filesystem::create_directories("sources"_p / "dir1"_p / "subdir"_p, err);
  107.  
  108.     {
  109.         ofstream file("sources/a.cpp");
  110.         file << "// this comment before include\n"
  111.             "#include \"dir1/b.h\"\n"
  112.             "// text between b.h and c.h\n"
  113.             "#include \"dir1/d.h\"\n"
  114.             "\n"
  115.             "int SayHello() {\n"
  116.             "    cout << \"hello, world!\" << endl;\n"
  117.             "#   include<dummy.txt>\n"
  118.             "}\n"s;
  119.     }
  120.     {
  121.         ofstream file("sources/dir1/b.h");
  122.         file << "// text from b.h before include\n"
  123.             "#include \"subdir/c.h\"\n"
  124.             "// text from b.h after include"s;
  125.     }
  126.     {
  127.         ofstream file("sources/dir1/subdir/c.h");
  128.         file << "// text from c.h before include\n"
  129.             "#include <std1.h>\n"
  130.             "// text from c.h after include\n"s;
  131.     }
  132.     {
  133.         ofstream file("sources/dir1/d.h");
  134.         file << "// text from d.h before include\n"
  135.             "#include \"lib/std2.h\"\n"
  136.             "// text from d.h after include\n"s;
  137.     }
  138.     {
  139.         ofstream file("sources/include1/std1.h");
  140.         file << "// std1\n"s;
  141.     }
  142.     {
  143.         ofstream file("sources/include2/lib/std2.h");
  144.         file << "// std2\n"s;
  145.     }
  146.  
  147.     assert((!Preprocess("sources"_p / "a.cpp"_p, "sources"_p / "a.in"_p,
  148.         { "sources"_p / "include1"_p,"sources"_p / "include2"_p })));
  149.  
  150.     ostringstream test_out;
  151.     test_out << "// this comment before include\n"
  152.         "// text from b.h before include\n"
  153.         "// text from c.h before include\n"
  154.         "// std1\n"
  155.         "// text from c.h after include\n"
  156.         "// text from b.h after include\n"
  157.         "// text between b.h and c.h\n"
  158.         "// text from d.h before include\n"
  159.         "// std2\n"
  160.         "// text from d.h after include\n"
  161.         "\n"
  162.         "int SayHello() {\n"
  163.         "    cout << \"hello, world!\" << endl;\n"s;
  164.  
  165.     assert(GetFileContents("sources/a.in"s) == test_out.str());
  166. }
  167.  
  168. int main() {
  169.     Test();
  170. }
Advertisement
Add Comment
Please, Sign In to add comment