| //===- 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 |