//===- StringToOffsetTable.h - Emit a big concatenated string ---*- C++ -*-===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #ifndef TBLGEN_STRING_TO_OFFSET_TABLE_H #define TBLGEN_STRING_TO_OFFSET_TABLE_H #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Support/raw_ostream.h" namespace llvm { /// StringToOffsetTable - This class uniques a bunch of nul-terminated strings /// and keeps track of their offset in a massive contiguous string allocation. /// It can then output this string blob and use indexes into the string to /// reference each piece. class StringToOffsetTable { StringMap<unsigned> StringOffset; std::string AggregateString; public: unsigned GetOrAddStringOffset(StringRef Str) { unsigned &Entry = StringOffset[Str]; if (Entry == 0) { // Add the string to the aggregate if this is the first time found. Entry = AggregateString.size(); AggregateString.append(Str.begin(), Str.end()); AggregateString += '\0'; } return Entry; } void EmitString(raw_ostream &O) { // Escape the string. SmallString<256> Str; raw_svector_ostream(Str).write_escaped(AggregateString); AggregateString = Str.str(); O << " \""; unsigned CharsPrinted = 0; for (unsigned i = 0, e = AggregateString.size(); i != e; ++i) { if (CharsPrinted > 70) { O << "\"\n \""; CharsPrinted = 0; } O << AggregateString[i]; ++CharsPrinted; // Print escape sequences all together. if (AggregateString[i] != '\\') continue; assert(i+1 < AggregateString.size() && "Incomplete escape sequence!"); if (isdigit(AggregateString[i+1])) { assert(isdigit(AggregateString[i+2]) && isdigit(AggregateString[i+3]) && "Expected 3 digit octal escape!"); O << AggregateString[++i]; O << AggregateString[++i]; O << AggregateString[++i]; CharsPrinted += 3; } else { O << AggregateString[++i]; ++CharsPrinted; } } O << "\""; } }; } // end namespace llvm #endif