本文整理汇总了C++中MemoryBuffer::getBufferSize方法的典型用法代码示例。如果您正苦于以下问题:C++ MemoryBuffer::getBufferSize方法的具体用法?C++ MemoryBuffer::getBufferSize怎么用?C++ MemoryBuffer::getBufferSize使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类MemoryBuffer
的用法示例。
在下文中一共展示了MemoryBuffer::getBufferSize方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: Buffer
line_iterator::line_iterator(const MemoryBuffer &Buffer, char CommentMarker)
: Buffer(Buffer.getBufferSize() ? &Buffer : nullptr),
CommentMarker(CommentMarker), LineNumber(1),
CurrentLine(Buffer.getBufferSize() ? Buffer.getBufferStart() : nullptr,
0) {
// Ensure that if we are constructed on a non-empty memory buffer that it is
// a null terminated buffer.
if (Buffer.getBufferSize()) {
assert(Buffer.getBufferEnd()[0] == '\0');
advance();
}
}
示例2: Buffer
line_iterator::line_iterator(const MemoryBuffer &Buffer, bool SkipBlanks,
char CommentMarker)
: Buffer(Buffer.getBufferSize() ? &Buffer : nullptr),
CommentMarker(CommentMarker), SkipBlanks(SkipBlanks), LineNumber(1),
CurrentLine(Buffer.getBufferSize() ? Buffer.getBufferStart() : nullptr,
0) {
// Ensure that if we are constructed on a non-empty memory buffer that it is
// a null terminated buffer.
if (Buffer.getBufferSize()) {
assert(Buffer.getBufferEnd()[0] == '\0');
// Make sure we don't skip a leading newline if we're keeping blanks
if (SkipBlanks || !isAtLineEnd(Buffer.getBufferStart()))
advance();
}
}
示例3: WriteBundle
void WriteBundle(raw_fd_ostream &OS, MemoryBuffer &Input) final {
Module *M = AuxModule.get();
// Create the new section name, it will consist of the reserved prefix
// concatenated with the triple.
std::string SectionName = OFFLOAD_BUNDLER_MAGIC_STR;
SectionName += CurrentTriple;
// Create the constant with the content of the section. For the input we are
// bundling into (the host input), this is just a place-holder, so a single
// byte is sufficient.
assert(HostInputIndex != ~0u && "Host input index undefined??");
Constant *Content;
if (NumberOfProcessedInputs == HostInputIndex + 1) {
uint8_t Byte[] = {0};
Content = ConstantDataArray::get(VMContext, Byte);
} else
Content = ConstantDataArray::get(
VMContext, ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(
Input.getBufferStart()),
Input.getBufferSize()));
// Create the global in the desired section. We don't want these globals in
// the symbol table, so we mark them private.
auto *GV = new GlobalVariable(*M, Content->getType(), /*IsConstant=*/true,
GlobalVariable::PrivateLinkage, Content);
GV->setSection(SectionName);
}
示例4:
bool RawInstrProfReader<IntPtrT>::hasFormat(const MemoryBuffer &DataBuffer) {
if (DataBuffer.getBufferSize() < sizeof(uint64_t))
return false;
uint64_t Magic =
*reinterpret_cast<const uint64_t *>(DataBuffer.getBufferStart());
return RawInstrProf::getMagic<IntPtrT>() == Magic ||
sys::getSwappedBytes(RawInstrProf::getMagic<IntPtrT>()) == Magic;
}
示例5: hasFormat
bool TextInstrProfReader::hasFormat(const MemoryBuffer &Buffer) {
// Verify that this really looks like plain ASCII text by checking a
// 'reasonable' number of characters (up to profile magic size).
size_t count = std::min(Buffer.getBufferSize(), sizeof(uint64_t));
StringRef buffer = Buffer.getBufferStart();
return count == 0 || std::all_of(buffer.begin(), buffer.begin() + count,
[](char c) { return ::isprint(c) || ::isspace(c); });
}
示例6: hasFormat
bool IndexedInstrProfReader::hasFormat(const MemoryBuffer &DataBuffer) {
if (DataBuffer.getBufferSize() < 8)
return false;
using namespace support;
uint64_t Magic =
endian::read<uint64_t, little, aligned>(DataBuffer.getBufferStart());
return Magic == IndexedInstrProf::Magic;
}
示例7: printFile
static void printFile(const sys::Path *err)
{
std::string ErrMsg;
ErrMsg.clear();
MemoryBuffer *buf = MemoryBuffer::getFile(err->c_str(), &ErrMsg);
errs().write(buf->getBufferStart(), buf->getBufferSize());
delete buf;
}
示例8: fillHeader
// Write one member out to the file.
bool
Archive::writeMember(
const ArchiveMember& member,
raw_fd_ostream& ARFile,
std::string* ErrMsg
) {
uint64_t filepos = ARFile.tell();
filepos -= 8;
// Get the data and its size either from the
// member's in-memory data or directly from the file.
size_t fSize = member.getSize();
const char *data = (const char*)member.getData();
MemoryBuffer *mFile = 0;
if (!data) {
ErrorOr<std::unique_ptr<MemoryBuffer> > FileOrErr =
MemoryBuffer::getFile(member.getPath());
if (!FileOrErr) {
if (ErrMsg)
*ErrMsg = FileOrErr.getError().message();
return true;
}
mFile = FileOrErr.get().release();
data = mFile->getBufferStart();
fSize = mFile->getBufferSize();
}
int hdrSize = fSize;
// Compute the fields of the header
ArchiveMemberHeader Hdr;
bool writeLongName = fillHeader(member,Hdr,hdrSize);
// Write header to archive file
ARFile.write((char*)&Hdr, sizeof(Hdr));
// Write the long filename if its long
if (writeLongName) {
StringRef Name = sys::path::filename(member.getPath());
ARFile.write(Name.data(), Name.size());
}
// Write the (possibly compressed) member's content to the file.
ARFile.write(data,fSize);
// Make sure the member is an even length
if ((ARFile.tell() & 1) == 1)
ARFile << ARFILE_PAD;
// Close the mapped file if it was opened
delete mFile;
return false;
}
示例9: ReadBundle
void ReadBundle(raw_fd_ostream &OS, MemoryBuffer &Input) final {
// If the current section has size one, that means that the content we are
// interested in is the file itself. Otherwise it is the content of the
// section.
//
// TODO: Instead of copying the input file as is, deactivate the section
// that is no longer needed.
StringRef Content;
CurrentSection->getContents(Content);
if (Content.size() < 2)
OS.write(Input.getBufferStart(), Input.getBufferSize());
else
OS.write(Content.data(), Content.size());
}
示例10: run
void LicenseInHeaderRule::run(const ast_matchers::MatchFinder::MatchResult& result)
{
const TranslationUnitDecl* translationUnitDeclaration = result.Nodes.getNodeAs<TranslationUnitDecl>("translationUnitDecl");
if (translationUnitDeclaration == nullptr)
return;
if (m_context.licenseTemplateLines.empty())
return;
SourceManager& sourceManager = *result.SourceManager;
FileID mainFileID = m_context.sourceLocationHelper.GetMainFileID(sourceManager);
MemoryBuffer* buffer = sourceManager.getBuffer(mainFileID);
const char* bufferChars = buffer->getBufferStart();
int bufferSize = buffer->getBufferSize();
if (bufferSize == 0)
return;
int bufferPos = 0;
int lineNumber = 0;
for (const auto& licenseLine : m_context.licenseTemplateLines)
{
++lineNumber;
StringRef line = GetNextBufferLine(bufferChars, bufferPos, bufferSize);
bufferPos += line.size();
bufferPos += 1; // newline character
if (line != licenseLine)
{
StringRef fileName = m_context.sourceLocationHelper.GetCleanFilename(mainFileID, sourceManager);
m_context.outputPrinter->PrintRuleViolation(
"license header",
Severity::Style,
boost::str(boost::format("File doesn't have proper license header; expected line was '%s'")
% licenseLine),
fileName,
lineNumber);
break;
}
}
}
示例11: AnalyzeBitcode
/// AnalyzeBitcode - Analyze the bitcode file specified by InputFilename.
static int AnalyzeBitcode() {
// Read the input file.
MemoryBuffer *MemBuf = MemoryBuffer::getFileOrSTDIN(InputFilename.c_str());
if (MemBuf == 0)
return Error("Error reading '" + InputFilename + "'.");
if (MemBuf->getBufferSize() & 3)
return Error("Bitcode stream should be a multiple of 4 bytes in length");
unsigned char *BufPtr = (unsigned char *)MemBuf->getBufferStart();
unsigned char *EndBufPtr = BufPtr+MemBuf->getBufferSize();
// If we have a wrapper header, parse it and ignore the non-bc file contents.
// The magic number is 0x0B17C0DE stored in little endian.
if (isBitcodeWrapper(BufPtr, EndBufPtr))
if (SkipBitcodeWrapperHeader(BufPtr, EndBufPtr))
return Error("Invalid bitcode wrapper header");
BitstreamReader StreamFile(BufPtr, EndBufPtr);
BitstreamCursor Stream(StreamFile);
StreamFile.CollectBlockInfoNames();
// Read the stream signature.
char Signature[6];
Signature[0] = Stream.Read(8);
Signature[1] = Stream.Read(8);
Signature[2] = Stream.Read(4);
Signature[3] = Stream.Read(4);
Signature[4] = Stream.Read(4);
Signature[5] = Stream.Read(4);
// Autodetect the file contents, if it is one we know.
CurStreamType = UnknownBitstream;
if (Signature[0] == 'B' && Signature[1] == 'C' &&
Signature[2] == 0x0 && Signature[3] == 0xC &&
Signature[4] == 0xE && Signature[5] == 0xD)
CurStreamType = LLVMIRBitstream;
unsigned NumTopBlocks = 0;
// Parse the top-level structure. We only allow blocks at the top-level.
while (!Stream.AtEndOfStream()) {
unsigned Code = Stream.ReadCode();
if (Code != bitc::ENTER_SUBBLOCK)
return Error("Invalid record at top-level");
if (ParseBlock(Stream, 0))
return true;
++NumTopBlocks;
}
if (Dump) errs() << "\n\n";
uint64_t BufferSizeBits = (EndBufPtr-BufPtr)*CHAR_BIT;
// Print a summary of the read file.
errs() << "Summary of " << InputFilename << ":\n";
errs() << " Total size: ";
PrintSize(BufferSizeBits);
errs() << "\n";
errs() << " Stream type: ";
switch (CurStreamType) {
default: assert(0 && "Unknown bitstream type");
case UnknownBitstream: errs() << "unknown\n"; break;
case LLVMIRBitstream: errs() << "LLVM IR\n"; break;
}
errs() << " # Toplevel Blocks: " << NumTopBlocks << "\n";
errs() << "\n";
// Emit per-block stats.
errs() << "Per-block Summary:\n";
for (std::map<unsigned, PerBlockIDStats>::iterator I = BlockIDStats.begin(),
E = BlockIDStats.end(); I != E; ++I) {
errs() << " Block ID #" << I->first;
if (const char *BlockName = GetBlockName(I->first, StreamFile))
errs() << " (" << BlockName << ")";
errs() << ":\n";
const PerBlockIDStats &Stats = I->second;
errs() << " Num Instances: " << Stats.NumInstances << "\n";
errs() << " Total Size: ";
PrintSize(Stats.NumBits);
errs() << "\n";
double pct = (Stats.NumBits * 100.0) / BufferSizeBits;
errs() << " Percent of file: " << format("%2.4f%%", pct) << "\n";
if (Stats.NumInstances > 1) {
errs() << " Average Size: ";
PrintSize(Stats.NumBits/(double)Stats.NumInstances);
errs() << "\n";
errs() << " Tot/Avg SubBlocks: " << Stats.NumSubBlocks << "/"
<< Stats.NumSubBlocks/(double)Stats.NumInstances << "\n";
errs() << " Tot/Avg Abbrevs: " << Stats.NumAbbrevs << "/"
<< Stats.NumAbbrevs/(double)Stats.NumInstances << "\n";
errs() << " Tot/Avg Records: " << Stats.NumRecords << "/"
<< Stats.NumRecords/(double)Stats.NumInstances << "\n";
} else {
errs() << " Num SubBlocks: " << Stats.NumSubBlocks << "\n";
errs() << " Num Abbrevs: " << Stats.NumAbbrevs << "\n";
errs() << " Num Records: " << Stats.NumRecords << "\n";
//.........这里部分代码省略.........
示例12: GetBitcodeSymbols
// Write one member out to the file.
bool
Archive::writeMember(
const ArchiveMember& member,
std::ofstream& ARFile,
bool CreateSymbolTable,
bool TruncateNames,
bool ShouldCompress,
std::string* ErrMsg
) {
unsigned filepos = ARFile.tellp();
filepos -= 8;
// Get the data and its size either from the
// member's in-memory data or directly from the file.
size_t fSize = member.getSize();
const char *data = (const char*)member.getData();
MemoryBuffer *mFile = 0;
if (!data) {
mFile = MemoryBuffer::getFile(member.getPath().c_str(), ErrMsg);
if (mFile == 0)
return true;
data = mFile->getBufferStart();
fSize = mFile->getBufferSize();
}
// Now that we have the data in memory, update the
// symbol table if its a bitcode file.
if (CreateSymbolTable && member.isBitcode()) {
std::vector<std::string> symbols;
std::string FullMemberName = archPath.str() + "(" + member.getPath().str()
+ ")";
Module* M =
GetBitcodeSymbols((const unsigned char*)data,fSize,
FullMemberName, Context, symbols, ErrMsg);
// If the bitcode parsed successfully
if ( M ) {
for (std::vector<std::string>::iterator SI = symbols.begin(),
SE = symbols.end(); SI != SE; ++SI) {
std::pair<SymTabType::iterator,bool> Res =
symTab.insert(std::make_pair(*SI,filepos));
if (Res.second) {
symTabSize += SI->length() +
numVbrBytes(SI->length()) +
numVbrBytes(filepos);
}
}
// We don't need this module any more.
delete M;
} else {
delete mFile;
if (ErrMsg)
*ErrMsg = "Can't parse bitcode member: " + member.getPath().str()
+ ": " + *ErrMsg;
return true;
}
}
int hdrSize = fSize;
// Compute the fields of the header
ArchiveMemberHeader Hdr;
bool writeLongName = fillHeader(member,Hdr,hdrSize,TruncateNames);
// Write header to archive file
ARFile.write((char*)&Hdr, sizeof(Hdr));
// Write the long filename if its long
if (writeLongName) {
ARFile.write(member.getPath().str().data(),
member.getPath().str().length());
}
// Write the (possibly compressed) member's content to the file.
ARFile.write(data,fSize);
// Make sure the member is an even length
if ((ARFile.tellp() & 1) == 1)
ARFile << ARFILE_PAD;
// Close the mapped file if it was opened
delete mFile;
return false;
}
示例13: main
int main(int argc, char **argv) {
sys::PrintStackTraceOnErrorSignal();
PrettyStackTraceProgram X(argc, argv);
cl::ParseCommandLineOptions(argc, argv);
SourceMgr SM;
// Read the expected strings from the check file.
std::vector<CheckString> CheckStrings;
if (ReadCheckFile(SM, CheckStrings))
return 2;
// Open the file to check and add it to SourceMgr.
OwningPtr<MemoryBuffer> File;
if (error_code ec =
MemoryBuffer::getFileOrSTDIN(InputFilename.c_str(), File)) {
errs() << "Could not open input file '" << InputFilename << "': "
<< ec.message() << '\n';
return 2;
}
MemoryBuffer *F = File.take();
if (F->getBufferSize() == 0) {
errs() << "FileCheck error: '" << InputFilename << "' is empty.\n";
return 2;
}
// Remove duplicate spaces in the input file if requested.
// Remove DOS style line endings.
F = CanonicalizeInputFile(F, NoCanonicalizeWhiteSpace);
SM.AddNewSourceBuffer(F, SMLoc());
/// VariableTable - This holds all the current filecheck variables.
StringMap<StringRef> VariableTable;
// Check that we have all of the expected strings, in order, in the input
// file.
StringRef Buffer = F->getBuffer();
const char *LastMatch = Buffer.data();
for (unsigned StrNo = 0, e = CheckStrings.size(); StrNo != e; ++StrNo) {
const CheckString &CheckStr = CheckStrings[StrNo];
StringRef SearchFrom = Buffer;
// Find StrNo in the file.
size_t MatchLen = 0;
size_t MatchPos = CheckStr.Pat.Match(Buffer, MatchLen, VariableTable);
Buffer = Buffer.substr(MatchPos);
// If we didn't find a match, reject the input.
if (MatchPos == StringRef::npos) {
PrintCheckFailed(SM, CheckStr, SearchFrom, VariableTable);
return 1;
}
StringRef SkippedRegion(LastMatch, Buffer.data()-LastMatch);
// If this check is a "CHECK-NEXT", verify that the previous match was on
// the previous line (i.e. that there is one newline between them).
if (CheckStr.IsCheckNext) {
// Count the number of newlines between the previous match and this one.
assert(LastMatch != F->getBufferStart() &&
"CHECK-NEXT can't be the first check in a file");
unsigned NumNewLines = CountNumNewlinesBetween(SkippedRegion);
if (NumNewLines == 0) {
SM.PrintMessage(CheckStr.Loc, SourceMgr::DK_Error,
CheckPrefix+"-NEXT: is on the same line as previous match");
SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()),
SourceMgr::DK_Note, "'next' match was here");
SM.PrintMessage(SMLoc::getFromPointer(LastMatch), SourceMgr::DK_Note,
"previous match was here");
return 1;
}
if (NumNewLines != 1) {
SM.PrintMessage(CheckStr.Loc, SourceMgr::DK_Error, CheckPrefix+
"-NEXT: is not on the line after the previous match");
SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()),
SourceMgr::DK_Note, "'next' match was here");
SM.PrintMessage(SMLoc::getFromPointer(LastMatch), SourceMgr::DK_Note,
"previous match was here");
return 1;
}
}
// If this match had "not strings", verify that they don't exist in the
// skipped region.
for (unsigned ChunkNo = 0, e = CheckStr.NotStrings.size();
ChunkNo != e; ++ChunkNo) {
size_t MatchLen = 0;
size_t Pos = CheckStr.NotStrings[ChunkNo].second.Match(SkippedRegion,
MatchLen,
VariableTable);
if (Pos == StringRef::npos) continue;
SM.PrintMessage(SMLoc::getFromPointer(LastMatch+Pos), SourceMgr::DK_Error,
//.........这里部分代码省略.........
示例14: LinkInFile
/// LinkInFile - opens a bitcode file and links in all objects which
/// provide symbols that are currently undefined.
///
/// Inputs:
/// File - The pathname of the bitcode file.
///
/// Outputs:
/// ErrorMessage - A C++ string detailing what error occurred, if any.
///
/// Return Value:
/// TRUE - An error occurred.
/// FALSE - No errors.
///
bool Linker::LinkInFile(const sys::Path &File, bool &is_native) {
is_native = false;
// Check for a file of name "-", which means "read standard input"
if (File.str() == "-") {
std::auto_ptr<Module> M;
MemoryBuffer *Buffer = MemoryBuffer::getSTDIN();
if (!Buffer->getBufferSize()) {
delete Buffer;
Error = "standard input is empty";
} else {
M.reset(ParseBitcodeFile(Buffer, Context, &Error));
delete Buffer;
if (M.get())
if (!LinkInModule(M.get(), &Error))
return false;
}
return error("Cannot link stdin: " + Error);
}
// Make sure we can at least read the file
if (!File.canRead())
return error("Cannot find linker input '" + File.str() + "'");
// If its an archive, try to link it in
std::string Magic;
File.getMagicNumber(Magic, 64);
switch (sys::IdentifyFileType(Magic.c_str(), 64)) {
default: llvm_unreachable("Bad file type identification");
case sys::Unknown_FileType:
return warning("Ignoring file '" + File.str() +
"' because does not contain bitcode.");
case sys::Archive_FileType:
// A user may specify an ar archive without -l, perhaps because it
// is not installed as a library. Detect that and link the archive.
if (LinkInArchive(File, is_native))
return true;
break;
case sys::Bitcode_FileType: {
verbose("Linking bitcode file '" + File.str() + "'");
std::auto_ptr<Module> M(LoadObject(File));
if (M.get() == 0)
return error("Cannot load file '" + File.str() + "': " + Error);
if (LinkInModule(M.get(), &Error))
return error("Cannot link file '" + File.str() + "': " + Error);
verbose("Linked in file '" + File.str() + "'");
break;
}
case sys::ELF_Relocatable_FileType:
case sys::ELF_SharedObject_FileType:
case sys::Mach_O_Object_FileType:
case sys::Mach_O_FixedVirtualMemorySharedLib_FileType:
case sys::Mach_O_DynamicallyLinkedSharedLib_FileType:
case sys::Mach_O_DynamicallyLinkedSharedLibStub_FileType:
case sys::COFF_FileType:
is_native = true;
break;
}
return false;
}
示例15: AnalyzeBitcode
/// AnalyzeBitcode - Analyze the bitcode file specified by InputFilename.
static int AnalyzeBitcode() {
// Read the input file.
MemoryBuffer *Buffer;
if (InputFilename == "-")
Buffer = MemoryBuffer::getSTDIN();
else
Buffer = MemoryBuffer::getFile(&InputFilename[0], InputFilename.size());
if (Buffer == 0)
return Error("Error reading '" + InputFilename + "'.");
if (Buffer->getBufferSize() & 3)
return Error("Bitcode stream should be a multiple of 4 bytes in length");
unsigned char *BufPtr = (unsigned char *)Buffer->getBufferStart();
BitstreamReader Stream(BufPtr, BufPtr+Buffer->getBufferSize());
// Read the stream signature.
char Signature[6];
Signature[0] = Stream.Read(8);
Signature[1] = Stream.Read(8);
Signature[2] = Stream.Read(4);
Signature[3] = Stream.Read(4);
Signature[4] = Stream.Read(4);
Signature[5] = Stream.Read(4);
// Autodetect the file contents, if it is one we know.
CurStreamType = UnknownBitstream;
if (Signature[0] == 'B' && Signature[1] == 'C' &&
Signature[2] == 0x0 && Signature[3] == 0xC &&
Signature[4] == 0xE && Signature[5] == 0xD)
CurStreamType = LLVMIRBitstream;
unsigned NumTopBlocks = 0;
// Parse the top-level structure. We only allow blocks at the top-level.
while (!Stream.AtEndOfStream()) {
unsigned Code = Stream.ReadCode();
if (Code != bitc::ENTER_SUBBLOCK)
return Error("Invalid record at top-level");
if (ParseBlock(Stream, 0))
return true;
++NumTopBlocks;
}
if (Dump) std::cerr << "\n\n";
uint64_t BufferSizeBits = Buffer->getBufferSize()*8;
// Print a summary of the read file.
std::cerr << "Summary of " << InputFilename << ":\n";
std::cerr << " Total size: ";
PrintSize(BufferSizeBits);
std::cerr << "\n";
std::cerr << " Stream type: ";
switch (CurStreamType) {
default: assert(0 && "Unknown bitstream type");
case UnknownBitstream: std::cerr << "unknown\n"; break;
case LLVMIRBitstream: std::cerr << "LLVM IR\n"; break;
}
std::cerr << " # Toplevel Blocks: " << NumTopBlocks << "\n";
std::cerr << "\n";
// Emit per-block stats.
std::cerr << "Per-block Summary:\n";
for (std::map<unsigned, PerBlockIDStats>::iterator I = BlockIDStats.begin(),
E = BlockIDStats.end(); I != E; ++I) {
std::cerr << " Block ID #" << I->first;
if (const char *BlockName = GetBlockName(I->first))
std::cerr << " (" << BlockName << ")";
std::cerr << ":\n";
const PerBlockIDStats &Stats = I->second;
std::cerr << " Num Instances: " << Stats.NumInstances << "\n";
std::cerr << " Total Size: ";
PrintSize(Stats.NumBits);
std::cerr << "\n";
std::cerr << " % of file: "
<< Stats.NumBits/(double)BufferSizeBits*100 << "\n";
if (Stats.NumInstances > 1) {
std::cerr << " Average Size: ";
PrintSize(Stats.NumBits/(double)Stats.NumInstances);
std::cerr << "\n";
std::cerr << " Tot/Avg SubBlocks: " << Stats.NumSubBlocks << "/"
<< Stats.NumSubBlocks/(double)Stats.NumInstances << "\n";
std::cerr << " Tot/Avg Abbrevs: " << Stats.NumAbbrevs << "/"
<< Stats.NumAbbrevs/(double)Stats.NumInstances << "\n";
std::cerr << " Tot/Avg Records: " << Stats.NumRecords << "/"
<< Stats.NumRecords/(double)Stats.NumInstances << "\n";
} else {
std::cerr << " Num SubBlocks: " << Stats.NumSubBlocks << "\n";
std::cerr << " Num Abbrevs: " << Stats.NumAbbrevs << "\n";
std::cerr << " Num Records: " << Stats.NumRecords << "\n";
}
if (Stats.NumRecords)
std::cerr << " % Abbrev Recs: " << (Stats.NumAbbreviatedRecords/
(double)Stats.NumRecords)*100 << "\n";
std::cerr << "\n";
//.........这里部分代码省略.........