Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
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;
}
Exemplo n.º 3
0
    // 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;
    }