static bool fillRanges(SourceManager &Sources, FileID ID, const MemoryBuffer *Code, std::vector<CharSourceRange> &Ranges) { if (!LineRanges.empty()) { if (!Offsets.empty() || !Lengths.empty()) { llvm::errs() << "error: cannot use -lines with -offset/-length\n"; return true; } for (unsigned i = 0, e = LineRanges.size(); i < e; ++i) { unsigned FromLine, ToLine; if (parseLineRange(LineRanges[i], FromLine, ToLine)) { llvm::errs() << "error: invalid <start line>:<end line> pair\n"; return true; } if (FromLine > ToLine) { llvm::errs() << "error: start line should be less than end line\n"; return true; } SourceLocation Start = Sources.translateLineCol(ID, FromLine, 1); SourceLocation End = Sources.translateLineCol(ID, ToLine, UINT_MAX); if (Start.isInvalid() || End.isInvalid()) return true; Ranges.push_back(CharSourceRange::getCharRange(Start, End)); } return false; } if (Offsets.empty()) Offsets.push_back(0); if (Offsets.size() != Lengths.size() && !(Offsets.size() == 1 && Lengths.empty())) { llvm::errs() << "error: number of -offset and -length arguments must match.\n"; return true; } for (unsigned i = 0, e = Offsets.size(); i != e; ++i) { if (Offsets[i] >= Code->getBufferSize()) { llvm::errs() << "error: offset " << Offsets[i] << " is outside the file\n"; return true; } SourceLocation Start = Sources.getLocForStartOfFile(ID).getLocWithOffset(Offsets[i]); SourceLocation End; if (i < Lengths.size()) { if (Offsets[i] + Lengths[i] > Code->getBufferSize()) { llvm::errs() << "error: invalid length " << Lengths[i] << ", offset + length (" << Offsets[i] + Lengths[i] << ") is outside the file.\n"; return true; } End = Start.getLocWithOffset(Lengths[i]); } else { End = Sources.getLocForEndOfFile(ID); } Ranges.push_back(CharSourceRange::getCharRange(Start, End)); } return false; }
static bool fillRanges(MemoryBuffer *Code, std::vector<tooling::Range> &Ranges) { IntrusiveRefCntPtr<vfs::InMemoryFileSystem> InMemoryFileSystem( new vfs::InMemoryFileSystem); FileManager Files(FileSystemOptions(), InMemoryFileSystem); DiagnosticsEngine Diagnostics( IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs), new DiagnosticOptions); SourceManager Sources(Diagnostics, Files); FileID ID = createInMemoryFile("<irrelevant>", Code, Sources, Files, InMemoryFileSystem.get()); if (!LineRanges.empty()) { if (!Offsets.empty() || !Lengths.empty()) { errs() << "error: cannot use -lines with -offset/-length\n"; return true; } for (unsigned i = 0, e = LineRanges.size(); i < e; ++i) { unsigned FromLine, ToLine; if (parseLineRange(LineRanges[i], FromLine, ToLine)) { errs() << "error: invalid <start line>:<end line> pair\n"; return true; } if (FromLine > ToLine) { errs() << "error: start line should be less than end line\n"; return true; } SourceLocation Start = Sources.translateLineCol(ID, FromLine, 1); SourceLocation End = Sources.translateLineCol(ID, ToLine, UINT_MAX); if (Start.isInvalid() || End.isInvalid()) return true; unsigned Offset = Sources.getFileOffset(Start); unsigned Length = Sources.getFileOffset(End) - Offset; Ranges.push_back(tooling::Range(Offset, Length)); } return false; } if (Offsets.empty()) Offsets.push_back(0); if (Offsets.size() != Lengths.size() && !(Offsets.size() == 1 && Lengths.empty())) { errs() << "error: number of -offset and -length arguments must match.\n"; return true; } for (unsigned i = 0, e = Offsets.size(); i != e; ++i) { if (Offsets[i] >= Code->getBufferSize()) { errs() << "error: offset " << Offsets[i] << " is outside the file\n"; return true; } SourceLocation Start = Sources.getLocForStartOfFile(ID).getLocWithOffset(Offsets[i]); SourceLocation End; if (i < Lengths.size()) { if (Offsets[i] + Lengths[i] > Code->getBufferSize()) { errs() << "error: invalid length " << Lengths[i] << ", offset + length (" << Offsets[i] + Lengths[i] << ") is outside the file.\n"; return true; } End = Start.getLocWithOffset(Lengths[i]); } else { End = Sources.getLocForEndOfFile(ID); } unsigned Offset = Sources.getFileOffset(Start); unsigned Length = Sources.getFileOffset(End) - Offset; Ranges.push_back(tooling::Range(Offset, Length)); } return false; }
// Returns true on error. static bool format(StringRef FileName) { ErrorOr<std::unique_ptr<MemoryBuffer>> CodeOrErr = MemoryBuffer::getFileOrSTDIN(FileName); if (std::error_code EC = CodeOrErr.getError()) { llvm::errs() << EC.message() << "\n"; return true; } std::unique_ptr<llvm::MemoryBuffer> Code = std::move(CodeOrErr.get()); if (Code->getBufferSize() == 0) return false; // Empty files are formatted correctly. FormatterDocument Doc(std::move(Code)); if (!Offsets.empty() || !Lengths.empty()) { if (Offsets.size() != Lengths.size()) { llvm::errs() << "error: number of offsets not equal to number of lengths.\n"; return true; } for ( unsigned i=0 ; i < Offsets.size() ; i++ ) { unsigned FromLine = Doc.getLineAndColumn(Offsets[i]).first; unsigned ToLine = Doc.getLineAndColumn(Offsets[i] + Lengths[i]).first; if (ToLine == 0) { llvm::errs() << "error: offset + length after end of file\n"; return true; } std::ostringstream s; s << FromLine << ":" << ToLine; LineRanges.push_back(s.str()); } } if (LineRanges.empty()) LineRanges.push_back("1:999999"); std::string Output = Doc.memBuffer().getBuffer(); Replacements Replaces; for ( unsigned Range = 0 ; Range < LineRanges.size() ; Range++ ) { unsigned FromLine, ToLine; if (parseLineRange(LineRanges[Range], FromLine, ToLine)) { llvm::errs() << "error: invalid <start line>:<end line> pair\n"; return true; } if (FromLine > ToLine) { llvm::errs() << "error: start line should be less than end line\n"; return true; } for ( unsigned Line = FromLine ; Line<=ToLine ; Line++ ) { size_t Offset = getOffsetOfLine(Line,Output); ssize_t Length = getOffsetOfLine(Line+1,Output)-1-Offset; if (Length < 0) break; std::string Formatted = Doc.reformat(LineRange(Line,1), FormatOptions).second; if (Formatted.find_first_not_of(" \t\v\f", 0) == StringRef::npos) Formatted = ""; if (Formatted == Output.substr(Offset, Length)) continue; Output.replace(Offset, Length, Formatted); Doc.updateCode(std::move(MemoryBuffer::getMemBuffer(Output))); Replaces.insert(clang::tooling::Replacement(FileName, Offset, Length, Formatted)); } } if (OutputXML) { llvm::outs() << "<?xml version='1.0'?>\n<replacements>\n"; outputReplacementsXML(Replaces); llvm::outs() << "</replacements>\n"; } else { if (Inplace) { if (FileName == "-") { llvm::errs() << "error: cannot use -i when reading from stdin.\n"; return true; } else { std::error_code EC; raw_fd_ostream writer(FileName, EC, llvm::sys::fs::F_None); if (EC) { llvm::errs() << "error: writing " << FileName << ": " << EC.message() << "\n"; return true; } writer << Output; } } else { llvm::outs() << Output; } } return false; }