error_code FileOutputBuffer::create(StringRef FilePath, size_t Size, OwningPtr<FileOutputBuffer> &Result, unsigned Flags) { // If file already exists, it must be a regular file (to be mappable). sys::fs::file_status Stat; error_code EC = sys::fs::status(FilePath, Stat); switch (Stat.type()) { case sys::fs::file_type::file_not_found: // If file does not exist, we'll create one. break; case sys::fs::file_type::regular_file: { // If file is not currently writable, error out. // FIXME: There is no sys::fs:: api for checking this. // FIXME: In posix, you use the access() call to check this. } break; default: if (EC) return EC; else return make_error_code(errc::operation_not_permitted); } // Delete target file. bool Existed; EC = sys::fs::remove(FilePath, Existed); if (EC) return EC; unsigned Mode = sys::fs::all_read | sys::fs::all_write; // If requested, make the output file executable. if (Flags & F_executable) Mode |= sys::fs::all_exe; // Create new file in same directory but with random name. SmallString<128> TempFilePath; int FD; EC = sys::fs::createUniqueFile(Twine(FilePath) + ".tmp%%%%%%%", FD, TempFilePath, Mode); if (EC) return EC; OwningPtr<mapped_file_region> MappedFile(new mapped_file_region( FD, true, mapped_file_region::readwrite, Size, 0, EC)); if (EC) return EC; Result.reset(new FileOutputBuffer(MappedFile.get(), FilePath, TempFilePath)); if (Result) MappedFile.take(); return error_code::success(); }
bool Preprocessor::HandleInclude(size_t line_no, Tokenizer & tok){ bool issection = false; if (tok.next_token() == "section"){ issection = true; tok.next_token(); } if (tok.get_type() != Tokenizer::Type::String){ throw Exception::Error("Include name must be quoted string; got `" + tok.get_string() + "`."); } MappedFile mfile; std::string section = ""; if (issection){ section = tok.get_string(); trim_ends(section); mfile = filedata; } else{ std::string file = tok; trim_ends(file); size_t pos = file.find_first_of("?"); if (pos != std::string::npos){ section = file.substr(pos + 1); file.erase(file.begin() + pos, file.end()); } else{ if (tok.next_token()){ if (tok == "section"){ if (tok.next_token().get_type() == Tokenizer::Type::String){ section = tok.get_string(); trim_ends(section); } else{ throw Exception::Error("String expected after `section`; got `" + tok.get_string() + "`."); } } else{ throw Exception::Error("Unknown include specifier `" + tok.get_string() + "`. Did you mean to use `section`?"); } } } mfile = MappedFile(file, include_paths); } size_t file_number;// = push_file(filenames, mfile.name()); std::string test_name = "___ONCE_INCLUDE " + section + "?" + mfile.name(); if (Defined(section, test_name)){ currentData.push_back('\n'); return true; } //currentData += "#line 1 " + std::to_string(file_number) + "\n"; defines.push_back(§ions[currentSection].defines); Preprocessor p = Preprocessor(mfile, include_paths, defines, filenames, section); auto newSections = p.Preprocess(); auto& back = *defines.back(); defines.pop_back(); for (auto & def : back){ Define(def.first, def.second); } file_number = push_file(filenames, filedata.name()); currentData += newSections.at(section).data; currentData.push_back('\n'); currentData += "#line " + std::to_string(line_no) + " " + std::to_string(file_number) + "\n"; return true; }