Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <cassert>
- #include <filesystem>
- #include <fstream>
- #include <iostream>
- #include <regex>
- #include <sstream>
- #include <string>
- #include <vector>
- using namespace std;
- using filesystem::path;
- path operator""_p(const char* data, std::size_t sz) {
- return path(data, data + sz);
- }
- string obpath(path in_file) {
- string obspath = in_file.string();
- for (int i = obspath.size() - 1; i > 0 - 1; i--) {
- if (obspath[i] != '\\' && obspath[i] != '/') {
- obspath.resize(i);
- }
- else {
- break;
- }
- }
- return obspath;
- }
- // напишите эту функцию
- bool Preprocess(const path& in_file, const path& out_file, const vector<path>& include_directories) {
- ifstream input(in_file);
- if (!input.is_open()) {
- return false;
- }
- ofstream out(out_file);
- smatch coincidences;
- regex local_reg(R"/(\s*#\s*include\s*"([^"]*)"\s*)/");
- regex remote_reg(R"/(\s*#\s*include\s*<([^>]*)>\s*)/");
- string line;
- int number_line = 0;
- while (getline(input, line)) {
- number_line += 1;
- if (regex_match(line, coincidences, local_reg)) {
- if (coincidences.size() > 1) {
- string obspath = obpath(in_file);
- obspath += coincidences[1];
- string p2 = "sources\\include2\\";
- p2 += coincidences[1];
- if (filesystem::exists(obspath)) {
- //когда нашли файл
- Preprocess(obspath, out_file, include_directories);
- }
- else if(filesystem::exists(p2)) {
- Preprocess(p2, out_file, include_directories);
- }
- else {
- cout << "unknown include file "<< coincidences[1] << " at file "<< in_file.string() << " at line " << number_line << endl;
- return false;
- }
- }
- }
- else if (regex_match(line, coincidences, remote_reg)) {
- if (coincidences.size() > 1) {
- string p = "sources\\include1\\";
- p += coincidences[1];
- if (filesystem::exists(p)) {
- //когда нашли файл
- Preprocess(p, out_file, include_directories);
- }
- else {
- cout << "unknown include file " << coincidences[1] << " at file " << in_file.string() << " at line " << number_line << endl;
- return false;
- }
- }
- }
- else {
- cout << line << endl;
- }
- }
- return true;
- }
- string GetFileContents(string file) {
- ifstream stream(file);
- // конструируем string по двум итераторам
- return { (istreambuf_iterator<char>(stream)), istreambuf_iterator<char>() };
- }
- void Test() {
- error_code err;
- filesystem::remove_all("sources"_p, err);
- filesystem::create_directories("sources"_p / "include2"_p / "lib"_p, err);
- filesystem::create_directories("sources"_p / "include1"_p, err);
- filesystem::create_directories("sources"_p / "dir1"_p / "subdir"_p, err);
- {
- ofstream file("sources/a.cpp");
- file << "// this comment before include\n"
- "#include \"dir1/b.h\"\n"
- "// text between b.h and c.h\n"
- "#include \"dir1/d.h\"\n"
- "\n"
- "int SayHello() {\n"
- " cout << \"hello, world!\" << endl;\n"
- "# include<dummy.txt>\n"
- "}\n"s;
- }
- {
- ofstream file("sources/dir1/b.h");
- file << "// text from b.h before include\n"
- "#include \"subdir/c.h\"\n"
- "// text from b.h after include"s;
- }
- {
- ofstream file("sources/dir1/subdir/c.h");
- file << "// text from c.h before include\n"
- "#include <std1.h>\n"
- "// text from c.h after include\n"s;
- }
- {
- ofstream file("sources/dir1/d.h");
- file << "// text from d.h before include\n"
- "#include \"lib/std2.h\"\n"
- "// text from d.h after include\n"s;
- }
- {
- ofstream file("sources/include1/std1.h");
- file << "// std1\n"s;
- }
- {
- ofstream file("sources/include2/lib/std2.h");
- file << "// std2\n"s;
- }
- assert((!Preprocess("sources"_p / "a.cpp"_p, "sources"_p / "a.in"_p,
- { "sources"_p / "include1"_p,"sources"_p / "include2"_p })));
- ostringstream test_out;
- test_out << "// this comment before include\n"
- "// text from b.h before include\n"
- "// text from c.h before include\n"
- "// std1\n"
- "// text from c.h after include\n"
- "// text from b.h after include\n"
- "// text between b.h and c.h\n"
- "// text from d.h before include\n"
- "// std2\n"
- "// text from d.h after include\n"
- "\n"
- "int SayHello() {\n"
- " cout << \"hello, world!\" << endl;\n"s;
- assert(GetFileContents("sources/a.in"s) == test_out.str());
- }
- int main() {
- Test();
- }
Advertisement
Add Comment
Please, Sign In to add comment