Home | History | Annotate | Download | only in Support
      1 //===- lib/Support/YAMLTraits.cpp -----------------------------------------===//
      2 //
      3 //                             The LLVM Linker
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 #include "llvm/Support/YAMLTraits.h"
     11 #include "llvm/ADT/STLExtras.h"
     12 #include "llvm/ADT/SmallString.h"
     13 #include "llvm/ADT/StringExtras.h"
     14 #include "llvm/ADT/StringRef.h"
     15 #include "llvm/ADT/Twine.h"
     16 #include "llvm/Support/Casting.h"
     17 #include "llvm/Support/Errc.h"
     18 #include "llvm/Support/ErrorHandling.h"
     19 #include "llvm/Support/Format.h"
     20 #include "llvm/Support/LineIterator.h"
     21 #include "llvm/Support/MemoryBuffer.h"
     22 #include "llvm/Support/Unicode.h"
     23 #include "llvm/Support/YAMLParser.h"
     24 #include "llvm/Support/raw_ostream.h"
     25 #include <algorithm>
     26 #include <cassert>
     27 #include <cstdint>
     28 #include <cstdlib>
     29 #include <cstring>
     30 #include <string>
     31 #include <vector>
     32 
     33 using namespace llvm;
     34 using namespace yaml;
     35 
     36 //===----------------------------------------------------------------------===//
     37 //  IO
     38 //===----------------------------------------------------------------------===//
     39 
     40 IO::IO(void *Context) : Ctxt(Context) {}
     41 
     42 IO::~IO() = default;
     43 
     44 void *IO::getContext() {
     45   return Ctxt;
     46 }
     47 
     48 void IO::setContext(void *Context) {
     49   Ctxt = Context;
     50 }
     51 
     52 //===----------------------------------------------------------------------===//
     53 //  Input
     54 //===----------------------------------------------------------------------===//
     55 
     56 Input::Input(StringRef InputContent, void *Ctxt,
     57              SourceMgr::DiagHandlerTy DiagHandler, void *DiagHandlerCtxt)
     58     : IO(Ctxt), Strm(new Stream(InputContent, SrcMgr, false, &EC)) {
     59   if (DiagHandler)
     60     SrcMgr.setDiagHandler(DiagHandler, DiagHandlerCtxt);
     61   DocIterator = Strm->begin();
     62 }
     63 
     64 Input::Input(MemoryBufferRef Input, void *Ctxt,
     65              SourceMgr::DiagHandlerTy DiagHandler, void *DiagHandlerCtxt)
     66     : IO(Ctxt), Strm(new Stream(Input, SrcMgr, false, &EC)) {
     67   if (DiagHandler)
     68     SrcMgr.setDiagHandler(DiagHandler, DiagHandlerCtxt);
     69   DocIterator = Strm->begin();
     70 }
     71 
     72 Input::~Input() = default;
     73 
     74 std::error_code Input::error() { return EC; }
     75 
     76 // Pin the vtables to this file.
     77 void Input::HNode::anchor() {}
     78 void Input::EmptyHNode::anchor() {}
     79 void Input::ScalarHNode::anchor() {}
     80 void Input::MapHNode::anchor() {}
     81 void Input::SequenceHNode::anchor() {}
     82 
     83 bool Input::outputting() {
     84   return false;
     85 }
     86 
     87 bool Input::setCurrentDocument() {
     88   if (DocIterator != Strm->end()) {
     89     Node *N = DocIterator->getRoot();
     90     if (!N) {
     91       assert(Strm->failed() && "Root is NULL iff parsing failed");
     92       EC = make_error_code(errc::invalid_argument);
     93       return false;
     94     }
     95 
     96     if (isa<NullNode>(N)) {
     97       // Empty files are allowed and ignored
     98       ++DocIterator;
     99       return setCurrentDocument();
    100     }
    101     TopNode = this->createHNodes(N);
    102     CurrentNode = TopNode.get();
    103     return true;
    104   }
    105   return false;
    106 }
    107 
    108 bool Input::nextDocument() {
    109   return ++DocIterator != Strm->end();
    110 }
    111 
    112 const Node *Input::getCurrentNode() const {
    113   return CurrentNode ? CurrentNode->_node : nullptr;
    114 }
    115 
    116 bool Input::mapTag(StringRef Tag, bool Default) {
    117   std::string foundTag = CurrentNode->_node->getVerbatimTag();
    118   if (foundTag.empty()) {
    119     // If no tag found and 'Tag' is the default, say it was found.
    120     return Default;
    121   }
    122   // Return true iff found tag matches supplied tag.
    123   return Tag.equals(foundTag);
    124 }
    125 
    126 void Input::beginMapping() {
    127   if (EC)
    128     return;
    129   // CurrentNode can be null if the document is empty.
    130   MapHNode *MN = dyn_cast_or_null<MapHNode>(CurrentNode);
    131   if (MN) {
    132     MN->ValidKeys.clear();
    133   }
    134 }
    135 
    136 std::vector<StringRef> Input::keys() {
    137   MapHNode *MN = dyn_cast<MapHNode>(CurrentNode);
    138   std::vector<StringRef> Ret;
    139   if (!MN) {
    140     setError(CurrentNode, "not a mapping");
    141     return Ret;
    142   }
    143   for (auto &P : MN->Mapping)
    144     Ret.push_back(P.first());
    145   return Ret;
    146 }
    147 
    148 bool Input::preflightKey(const char *Key, bool Required, bool, bool &UseDefault,
    149                          void *&SaveInfo) {
    150   UseDefault = false;
    151   if (EC)
    152     return false;
    153 
    154   // CurrentNode is null for empty documents, which is an error in case required
    155   // nodes are present.
    156   if (!CurrentNode) {
    157     if (Required)
    158       EC = make_error_code(errc::invalid_argument);
    159     return false;
    160   }
    161 
    162   MapHNode *MN = dyn_cast<MapHNode>(CurrentNode);
    163   if (!MN) {
    164     if (Required || !isa<EmptyHNode>(CurrentNode))
    165       setError(CurrentNode, "not a mapping");
    166     return false;
    167   }
    168   MN->ValidKeys.push_back(Key);
    169   HNode *Value = MN->Mapping[Key].get();
    170   if (!Value) {
    171     if (Required)
    172       setError(CurrentNode, Twine("missing required key '") + Key + "'");
    173     else
    174       UseDefault = true;
    175     return false;
    176   }
    177   SaveInfo = CurrentNode;
    178   CurrentNode = Value;
    179   return true;
    180 }
    181 
    182 void Input::postflightKey(void *saveInfo) {
    183   CurrentNode = reinterpret_cast<HNode *>(saveInfo);
    184 }
    185 
    186 void Input::endMapping() {
    187   if (EC)
    188     return;
    189   // CurrentNode can be null if the document is empty.
    190   MapHNode *MN = dyn_cast_or_null<MapHNode>(CurrentNode);
    191   if (!MN)
    192     return;
    193   for (const auto &NN : MN->Mapping) {
    194     if (!is_contained(MN->ValidKeys, NN.first())) {
    195       setError(NN.second.get(), Twine("unknown key '") + NN.first() + "'");
    196       break;
    197     }
    198   }
    199 }
    200 
    201 void Input::beginFlowMapping() { beginMapping(); }
    202 
    203 void Input::endFlowMapping() { endMapping(); }
    204 
    205 unsigned Input::beginSequence() {
    206   if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode))
    207     return SQ->Entries.size();
    208   if (isa<EmptyHNode>(CurrentNode))
    209     return 0;
    210   // Treat case where there's a scalar "null" value as an empty sequence.
    211   if (ScalarHNode *SN = dyn_cast<ScalarHNode>(CurrentNode)) {
    212     if (isNull(SN->value()))
    213       return 0;
    214   }
    215   // Any other type of HNode is an error.
    216   setError(CurrentNode, "not a sequence");
    217   return 0;
    218 }
    219 
    220 void Input::endSequence() {
    221 }
    222 
    223 bool Input::preflightElement(unsigned Index, void *&SaveInfo) {
    224   if (EC)
    225     return false;
    226   if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
    227     SaveInfo = CurrentNode;
    228     CurrentNode = SQ->Entries[Index].get();
    229     return true;
    230   }
    231   return false;
    232 }
    233 
    234 void Input::postflightElement(void *SaveInfo) {
    235   CurrentNode = reinterpret_cast<HNode *>(SaveInfo);
    236 }
    237 
    238 unsigned Input::beginFlowSequence() { return beginSequence(); }
    239 
    240 bool Input::preflightFlowElement(unsigned index, void *&SaveInfo) {
    241   if (EC)
    242     return false;
    243   if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
    244     SaveInfo = CurrentNode;
    245     CurrentNode = SQ->Entries[index].get();
    246     return true;
    247   }
    248   return false;
    249 }
    250 
    251 void Input::postflightFlowElement(void *SaveInfo) {
    252   CurrentNode = reinterpret_cast<HNode *>(SaveInfo);
    253 }
    254 
    255 void Input::endFlowSequence() {
    256 }
    257 
    258 void Input::beginEnumScalar() {
    259   ScalarMatchFound = false;
    260 }
    261 
    262 bool Input::matchEnumScalar(const char *Str, bool) {
    263   if (ScalarMatchFound)
    264     return false;
    265   if (ScalarHNode *SN = dyn_cast<ScalarHNode>(CurrentNode)) {
    266     if (SN->value().equals(Str)) {
    267       ScalarMatchFound = true;
    268       return true;
    269     }
    270   }
    271   return false;
    272 }
    273 
    274 bool Input::matchEnumFallback() {
    275   if (ScalarMatchFound)
    276     return false;
    277   ScalarMatchFound = true;
    278   return true;
    279 }
    280 
    281 void Input::endEnumScalar() {
    282   if (!ScalarMatchFound) {
    283     setError(CurrentNode, "unknown enumerated scalar");
    284   }
    285 }
    286 
    287 bool Input::beginBitSetScalar(bool &DoClear) {
    288   BitValuesUsed.clear();
    289   if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
    290     BitValuesUsed.insert(BitValuesUsed.begin(), SQ->Entries.size(), false);
    291   } else {
    292     setError(CurrentNode, "expected sequence of bit values");
    293   }
    294   DoClear = true;
    295   return true;
    296 }
    297 
    298 bool Input::bitSetMatch(const char *Str, bool) {
    299   if (EC)
    300     return false;
    301   if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
    302     unsigned Index = 0;
    303     for (auto &N : SQ->Entries) {
    304       if (ScalarHNode *SN = dyn_cast<ScalarHNode>(N.get())) {
    305         if (SN->value().equals(Str)) {
    306           BitValuesUsed[Index] = true;
    307           return true;
    308         }
    309       } else {
    310         setError(CurrentNode, "unexpected scalar in sequence of bit values");
    311       }
    312       ++Index;
    313     }
    314   } else {
    315     setError(CurrentNode, "expected sequence of bit values");
    316   }
    317   return false;
    318 }
    319 
    320 void Input::endBitSetScalar() {
    321   if (EC)
    322     return;
    323   if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
    324     assert(BitValuesUsed.size() == SQ->Entries.size());
    325     for (unsigned i = 0; i < SQ->Entries.size(); ++i) {
    326       if (!BitValuesUsed[i]) {
    327         setError(SQ->Entries[i].get(), "unknown bit value");
    328         return;
    329       }
    330     }
    331   }
    332 }
    333 
    334 void Input::scalarString(StringRef &S, QuotingType) {
    335   if (ScalarHNode *SN = dyn_cast<ScalarHNode>(CurrentNode)) {
    336     S = SN->value();
    337   } else {
    338     setError(CurrentNode, "unexpected scalar");
    339   }
    340 }
    341 
    342 void Input::blockScalarString(StringRef &S) { scalarString(S, QuotingType::None); }
    343 
    344 void Input::setError(HNode *hnode, const Twine &message) {
    345   assert(hnode && "HNode must not be NULL");
    346   this->setError(hnode->_node, message);
    347 }
    348 
    349 void Input::setError(Node *node, const Twine &message) {
    350   Strm->printError(node, message);
    351   EC = make_error_code(errc::invalid_argument);
    352 }
    353 
    354 std::unique_ptr<Input::HNode> Input::createHNodes(Node *N) {
    355   SmallString<128> StringStorage;
    356   if (ScalarNode *SN = dyn_cast<ScalarNode>(N)) {
    357     StringRef KeyStr = SN->getValue(StringStorage);
    358     if (!StringStorage.empty()) {
    359       // Copy string to permanent storage
    360       KeyStr = StringStorage.str().copy(StringAllocator);
    361     }
    362     return llvm::make_unique<ScalarHNode>(N, KeyStr);
    363   } else if (BlockScalarNode *BSN = dyn_cast<BlockScalarNode>(N)) {
    364     StringRef ValueCopy = BSN->getValue().copy(StringAllocator);
    365     return llvm::make_unique<ScalarHNode>(N, ValueCopy);
    366   } else if (SequenceNode *SQ = dyn_cast<SequenceNode>(N)) {
    367     auto SQHNode = llvm::make_unique<SequenceHNode>(N);
    368     for (Node &SN : *SQ) {
    369       auto Entry = this->createHNodes(&SN);
    370       if (EC)
    371         break;
    372       SQHNode->Entries.push_back(std::move(Entry));
    373     }
    374     return std::move(SQHNode);
    375   } else if (MappingNode *Map = dyn_cast<MappingNode>(N)) {
    376     auto mapHNode = llvm::make_unique<MapHNode>(N);
    377     for (KeyValueNode &KVN : *Map) {
    378       Node *KeyNode = KVN.getKey();
    379       ScalarNode *Key = dyn_cast<ScalarNode>(KeyNode);
    380       Node *Value = KVN.getValue();
    381       if (!Key || !Value) {
    382         if (!Key)
    383           setError(KeyNode, "Map key must be a scalar");
    384         if (!Value)
    385           setError(KeyNode, "Map value must not be empty");
    386         break;
    387       }
    388       StringStorage.clear();
    389       StringRef KeyStr = Key->getValue(StringStorage);
    390       if (!StringStorage.empty()) {
    391         // Copy string to permanent storage
    392         KeyStr = StringStorage.str().copy(StringAllocator);
    393       }
    394       auto ValueHNode = this->createHNodes(Value);
    395       if (EC)
    396         break;
    397       mapHNode->Mapping[KeyStr] = std::move(ValueHNode);
    398     }
    399     return std::move(mapHNode);
    400   } else if (isa<NullNode>(N)) {
    401     return llvm::make_unique<EmptyHNode>(N);
    402   } else {
    403     setError(N, "unknown node kind");
    404     return nullptr;
    405   }
    406 }
    407 
    408 void Input::setError(const Twine &Message) {
    409   this->setError(CurrentNode, Message);
    410 }
    411 
    412 bool Input::canElideEmptySequence() {
    413   return false;
    414 }
    415 
    416 //===----------------------------------------------------------------------===//
    417 //  Output
    418 //===----------------------------------------------------------------------===//
    419 
    420 Output::Output(raw_ostream &yout, void *context, int WrapColumn)
    421     : IO(context), Out(yout), WrapColumn(WrapColumn) {}
    422 
    423 Output::~Output() = default;
    424 
    425 bool Output::outputting() {
    426   return true;
    427 }
    428 
    429 void Output::beginMapping() {
    430   StateStack.push_back(inMapFirstKey);
    431   NeedsNewLine = true;
    432 }
    433 
    434 bool Output::mapTag(StringRef Tag, bool Use) {
    435   if (Use) {
    436     // If this tag is being written inside a sequence we should write the start
    437     // of the sequence before writing the tag, otherwise the tag won't be
    438     // attached to the element in the sequence, but rather the sequence itself.
    439     bool SequenceElement =
    440         StateStack.size() > 1 && (StateStack[StateStack.size() - 2] == inSeq ||
    441           StateStack[StateStack.size() - 2] == inFlowSeq);
    442     if (SequenceElement && StateStack.back() == inMapFirstKey) {
    443       this->newLineCheck();
    444     } else {
    445       this->output(" ");
    446     }
    447     this->output(Tag);
    448     if (SequenceElement) {
    449       // If we're writing the tag during the first element of a map, the tag
    450       // takes the place of the first element in the sequence.
    451       if (StateStack.back() == inMapFirstKey) {
    452         StateStack.pop_back();
    453         StateStack.push_back(inMapOtherKey);
    454       }
    455       // Tags inside maps in sequences should act as keys in the map from a
    456       // formatting perspective, so we always want a newline in a sequence.
    457       NeedsNewLine = true;
    458     }
    459   }
    460   return Use;
    461 }
    462 
    463 void Output::endMapping() {
    464   StateStack.pop_back();
    465 }
    466 
    467 std::vector<StringRef> Output::keys() {
    468   report_fatal_error("invalid call");
    469 }
    470 
    471 bool Output::preflightKey(const char *Key, bool Required, bool SameAsDefault,
    472                           bool &UseDefault, void *&) {
    473   UseDefault = false;
    474   if (Required || !SameAsDefault || WriteDefaultValues) {
    475     auto State = StateStack.back();
    476     if (State == inFlowMapFirstKey || State == inFlowMapOtherKey) {
    477       flowKey(Key);
    478     } else {
    479       this->newLineCheck();
    480       this->paddedKey(Key);
    481     }
    482     return true;
    483   }
    484   return false;
    485 }
    486 
    487 void Output::postflightKey(void *) {
    488   if (StateStack.back() == inMapFirstKey) {
    489     StateStack.pop_back();
    490     StateStack.push_back(inMapOtherKey);
    491   } else if (StateStack.back() == inFlowMapFirstKey) {
    492     StateStack.pop_back();
    493     StateStack.push_back(inFlowMapOtherKey);
    494   }
    495 }
    496 
    497 void Output::beginFlowMapping() {
    498   StateStack.push_back(inFlowMapFirstKey);
    499   this->newLineCheck();
    500   ColumnAtMapFlowStart = Column;
    501   output("{ ");
    502 }
    503 
    504 void Output::endFlowMapping() {
    505   StateStack.pop_back();
    506   this->outputUpToEndOfLine(" }");
    507 }
    508 
    509 void Output::beginDocuments() {
    510   this->outputUpToEndOfLine("---");
    511 }
    512 
    513 bool Output::preflightDocument(unsigned index) {
    514   if (index > 0)
    515     this->outputUpToEndOfLine("\n---");
    516   return true;
    517 }
    518 
    519 void Output::postflightDocument() {
    520 }
    521 
    522 void Output::endDocuments() {
    523   output("\n...\n");
    524 }
    525 
    526 unsigned Output::beginSequence() {
    527   StateStack.push_back(inSeq);
    528   NeedsNewLine = true;
    529   return 0;
    530 }
    531 
    532 void Output::endSequence() {
    533   StateStack.pop_back();
    534 }
    535 
    536 bool Output::preflightElement(unsigned, void *&) {
    537   return true;
    538 }
    539 
    540 void Output::postflightElement(void *) {
    541 }
    542 
    543 unsigned Output::beginFlowSequence() {
    544   StateStack.push_back(inFlowSeq);
    545   this->newLineCheck();
    546   ColumnAtFlowStart = Column;
    547   output("[ ");
    548   NeedFlowSequenceComma = false;
    549   return 0;
    550 }
    551 
    552 void Output::endFlowSequence() {
    553   StateStack.pop_back();
    554   this->outputUpToEndOfLine(" ]");
    555 }
    556 
    557 bool Output::preflightFlowElement(unsigned, void *&) {
    558   if (NeedFlowSequenceComma)
    559     output(", ");
    560   if (WrapColumn && Column > WrapColumn) {
    561     output("\n");
    562     for (int i = 0; i < ColumnAtFlowStart; ++i)
    563       output(" ");
    564     Column = ColumnAtFlowStart;
    565     output("  ");
    566   }
    567   return true;
    568 }
    569 
    570 void Output::postflightFlowElement(void *) {
    571   NeedFlowSequenceComma = true;
    572 }
    573 
    574 void Output::beginEnumScalar() {
    575   EnumerationMatchFound = false;
    576 }
    577 
    578 bool Output::matchEnumScalar(const char *Str, bool Match) {
    579   if (Match && !EnumerationMatchFound) {
    580     this->newLineCheck();
    581     this->outputUpToEndOfLine(Str);
    582     EnumerationMatchFound = true;
    583   }
    584   return false;
    585 }
    586 
    587 bool Output::matchEnumFallback() {
    588   if (EnumerationMatchFound)
    589     return false;
    590   EnumerationMatchFound = true;
    591   return true;
    592 }
    593 
    594 void Output::endEnumScalar() {
    595   if (!EnumerationMatchFound)
    596     llvm_unreachable("bad runtime enum value");
    597 }
    598 
    599 bool Output::beginBitSetScalar(bool &DoClear) {
    600   this->newLineCheck();
    601   output("[ ");
    602   NeedBitValueComma = false;
    603   DoClear = false;
    604   return true;
    605 }
    606 
    607 bool Output::bitSetMatch(const char *Str, bool Matches) {
    608   if (Matches) {
    609     if (NeedBitValueComma)
    610       output(", ");
    611     this->output(Str);
    612     NeedBitValueComma = true;
    613   }
    614   return false;
    615 }
    616 
    617 void Output::endBitSetScalar() {
    618   this->outputUpToEndOfLine(" ]");
    619 }
    620 
    621 void Output::scalarString(StringRef &S, QuotingType MustQuote) {
    622   this->newLineCheck();
    623   if (S.empty()) {
    624     // Print '' for the empty string because leaving the field empty is not
    625     // allowed.
    626     this->outputUpToEndOfLine("''");
    627     return;
    628   }
    629   if (MustQuote == QuotingType::None) {
    630     // Only quote if we must.
    631     this->outputUpToEndOfLine(S);
    632     return;
    633   }
    634 
    635   unsigned i = 0;
    636   unsigned j = 0;
    637   unsigned End = S.size();
    638   const char *Base = S.data();
    639 
    640   const char *const Quote = MustQuote == QuotingType::Single ? "'" : "\"";
    641   output(Quote); // Starting quote.
    642 
    643   // When using double-quoted strings (and only in that case), non-printable characters may be
    644   // present, and will be escaped using a variety of unicode-scalar and special short-form
    645   // escapes. This is handled in yaml::escape.
    646   if (MustQuote == QuotingType::Double) {
    647     output(yaml::escape(Base, /* EscapePrintable= */ false));
    648     this->outputUpToEndOfLine(Quote);
    649     return;
    650   }
    651 
    652   // When using single-quoted strings, any single quote ' must be doubled to be escaped.
    653   while (j < End) {
    654     if (S[j] == '\'') {                    // Escape quotes.
    655       output(StringRef(&Base[i], j - i));  // "flush".
    656       output(StringLiteral("''"));         // Print it as ''
    657       i = j + 1;
    658     }
    659     ++j;
    660   }
    661   output(StringRef(&Base[i], j - i));
    662   this->outputUpToEndOfLine(Quote); // Ending quote.
    663 }
    664 
    665 void Output::blockScalarString(StringRef &S) {
    666   if (!StateStack.empty())
    667     newLineCheck();
    668   output(" |");
    669   outputNewLine();
    670 
    671   unsigned Indent = StateStack.empty() ? 1 : StateStack.size();
    672 
    673   auto Buffer = MemoryBuffer::getMemBuffer(S, "", false);
    674   for (line_iterator Lines(*Buffer, false); !Lines.is_at_end(); ++Lines) {
    675     for (unsigned I = 0; I < Indent; ++I) {
    676       output("  ");
    677     }
    678     output(*Lines);
    679     outputNewLine();
    680   }
    681 }
    682 
    683 void Output::setError(const Twine &message) {
    684 }
    685 
    686 bool Output::canElideEmptySequence() {
    687   // Normally, with an optional key/value where the value is an empty sequence,
    688   // the whole key/value can be not written.  But, that produces wrong yaml
    689   // if the key/value is the only thing in the map and the map is used in
    690   // a sequence.  This detects if the this sequence is the first key/value
    691   // in map that itself is embedded in a sequnce.
    692   if (StateStack.size() < 2)
    693     return true;
    694   if (StateStack.back() != inMapFirstKey)
    695     return true;
    696   return (StateStack[StateStack.size()-2] != inSeq);
    697 }
    698 
    699 void Output::output(StringRef s) {
    700   Column += s.size();
    701   Out << s;
    702 }
    703 
    704 void Output::outputUpToEndOfLine(StringRef s) {
    705   this->output(s);
    706   if (StateStack.empty() || (StateStack.back() != inFlowSeq &&
    707                              StateStack.back() != inFlowMapFirstKey &&
    708                              StateStack.back() != inFlowMapOtherKey))
    709     NeedsNewLine = true;
    710 }
    711 
    712 void Output::outputNewLine() {
    713   Out << "\n";
    714   Column = 0;
    715 }
    716 
    717 // if seq at top, indent as if map, then add "- "
    718 // if seq in middle, use "- " if firstKey, else use "  "
    719 //
    720 
    721 void Output::newLineCheck() {
    722   if (!NeedsNewLine)
    723     return;
    724   NeedsNewLine = false;
    725 
    726   this->outputNewLine();
    727 
    728   assert(StateStack.size() > 0);
    729   unsigned Indent = StateStack.size() - 1;
    730   bool OutputDash = false;
    731 
    732   if (StateStack.back() == inSeq) {
    733     OutputDash = true;
    734   } else if ((StateStack.size() > 1) && ((StateStack.back() == inMapFirstKey) ||
    735              (StateStack.back() == inFlowSeq) ||
    736              (StateStack.back() == inFlowMapFirstKey)) &&
    737              (StateStack[StateStack.size() - 2] == inSeq)) {
    738     --Indent;
    739     OutputDash = true;
    740   }
    741 
    742   for (unsigned i = 0; i < Indent; ++i) {
    743     output("  ");
    744   }
    745   if (OutputDash) {
    746     output("- ");
    747   }
    748 
    749 }
    750 
    751 void Output::paddedKey(StringRef key) {
    752   output(key);
    753   output(":");
    754   const char *spaces = "                ";
    755   if (key.size() < strlen(spaces))
    756     output(&spaces[key.size()]);
    757   else
    758     output(" ");
    759 }
    760 
    761 void Output::flowKey(StringRef Key) {
    762   if (StateStack.back() == inFlowMapOtherKey)
    763     output(", ");
    764   if (WrapColumn && Column > WrapColumn) {
    765     output("\n");
    766     for (int I = 0; I < ColumnAtMapFlowStart; ++I)
    767       output(" ");
    768     Column = ColumnAtMapFlowStart;
    769     output("  ");
    770   }
    771   output(Key);
    772   output(": ");
    773 }
    774 
    775 //===----------------------------------------------------------------------===//
    776 //  traits for built-in types
    777 //===----------------------------------------------------------------------===//
    778 
    779 void ScalarTraits<bool>::output(const bool &Val, void *, raw_ostream &Out) {
    780   Out << (Val ? "true" : "false");
    781 }
    782 
    783 StringRef ScalarTraits<bool>::input(StringRef Scalar, void *, bool &Val) {
    784   if (Scalar.equals("true")) {
    785     Val = true;
    786     return StringRef();
    787   } else if (Scalar.equals("false")) {
    788     Val = false;
    789     return StringRef();
    790   }
    791   return "invalid boolean";
    792 }
    793 
    794 void ScalarTraits<StringRef>::output(const StringRef &Val, void *,
    795                                      raw_ostream &Out) {
    796   Out << Val;
    797 }
    798 
    799 StringRef ScalarTraits<StringRef>::input(StringRef Scalar, void *,
    800                                          StringRef &Val) {
    801   Val = Scalar;
    802   return StringRef();
    803 }
    804 
    805 void ScalarTraits<std::string>::output(const std::string &Val, void *,
    806                                      raw_ostream &Out) {
    807   Out << Val;
    808 }
    809 
    810 StringRef ScalarTraits<std::string>::input(StringRef Scalar, void *,
    811                                          std::string &Val) {
    812   Val = Scalar.str();
    813   return StringRef();
    814 }
    815 
    816 void ScalarTraits<uint8_t>::output(const uint8_t &Val, void *,
    817                                    raw_ostream &Out) {
    818   // use temp uin32_t because ostream thinks uint8_t is a character
    819   uint32_t Num = Val;
    820   Out << Num;
    821 }
    822 
    823 StringRef ScalarTraits<uint8_t>::input(StringRef Scalar, void *, uint8_t &Val) {
    824   unsigned long long n;
    825   if (getAsUnsignedInteger(Scalar, 0, n))
    826     return "invalid number";
    827   if (n > 0xFF)
    828     return "out of range number";
    829   Val = n;
    830   return StringRef();
    831 }
    832 
    833 void ScalarTraits<uint16_t>::output(const uint16_t &Val, void *,
    834                                     raw_ostream &Out) {
    835   Out << Val;
    836 }
    837 
    838 StringRef ScalarTraits<uint16_t>::input(StringRef Scalar, void *,
    839                                         uint16_t &Val) {
    840   unsigned long long n;
    841   if (getAsUnsignedInteger(Scalar, 0, n))
    842     return "invalid number";
    843   if (n > 0xFFFF)
    844     return "out of range number";
    845   Val = n;
    846   return StringRef();
    847 }
    848 
    849 void ScalarTraits<uint32_t>::output(const uint32_t &Val, void *,
    850                                     raw_ostream &Out) {
    851   Out << Val;
    852 }
    853 
    854 StringRef ScalarTraits<uint32_t>::input(StringRef Scalar, void *,
    855                                         uint32_t &Val) {
    856   unsigned long long n;
    857   if (getAsUnsignedInteger(Scalar, 0, n))
    858     return "invalid number";
    859   if (n > 0xFFFFFFFFUL)
    860     return "out of range number";
    861   Val = n;
    862   return StringRef();
    863 }
    864 
    865 void ScalarTraits<uint64_t>::output(const uint64_t &Val, void *,
    866                                     raw_ostream &Out) {
    867   Out << Val;
    868 }
    869 
    870 StringRef ScalarTraits<uint64_t>::input(StringRef Scalar, void *,
    871                                         uint64_t &Val) {
    872   unsigned long long N;
    873   if (getAsUnsignedInteger(Scalar, 0, N))
    874     return "invalid number";
    875   Val = N;
    876   return StringRef();
    877 }
    878 
    879 void ScalarTraits<int8_t>::output(const int8_t &Val, void *, raw_ostream &Out) {
    880   // use temp in32_t because ostream thinks int8_t is a character
    881   int32_t Num = Val;
    882   Out << Num;
    883 }
    884 
    885 StringRef ScalarTraits<int8_t>::input(StringRef Scalar, void *, int8_t &Val) {
    886   long long N;
    887   if (getAsSignedInteger(Scalar, 0, N))
    888     return "invalid number";
    889   if ((N > 127) || (N < -128))
    890     return "out of range number";
    891   Val = N;
    892   return StringRef();
    893 }
    894 
    895 void ScalarTraits<int16_t>::output(const int16_t &Val, void *,
    896                                    raw_ostream &Out) {
    897   Out << Val;
    898 }
    899 
    900 StringRef ScalarTraits<int16_t>::input(StringRef Scalar, void *, int16_t &Val) {
    901   long long N;
    902   if (getAsSignedInteger(Scalar, 0, N))
    903     return "invalid number";
    904   if ((N > INT16_MAX) || (N < INT16_MIN))
    905     return "out of range number";
    906   Val = N;
    907   return StringRef();
    908 }
    909 
    910 void ScalarTraits<int32_t>::output(const int32_t &Val, void *,
    911                                    raw_ostream &Out) {
    912   Out << Val;
    913 }
    914 
    915 StringRef ScalarTraits<int32_t>::input(StringRef Scalar, void *, int32_t &Val) {
    916   long long N;
    917   if (getAsSignedInteger(Scalar, 0, N))
    918     return "invalid number";
    919   if ((N > INT32_MAX) || (N < INT32_MIN))
    920     return "out of range number";
    921   Val = N;
    922   return StringRef();
    923 }
    924 
    925 void ScalarTraits<int64_t>::output(const int64_t &Val, void *,
    926                                    raw_ostream &Out) {
    927   Out << Val;
    928 }
    929 
    930 StringRef ScalarTraits<int64_t>::input(StringRef Scalar, void *, int64_t &Val) {
    931   long long N;
    932   if (getAsSignedInteger(Scalar, 0, N))
    933     return "invalid number";
    934   Val = N;
    935   return StringRef();
    936 }
    937 
    938 void ScalarTraits<double>::output(const double &Val, void *, raw_ostream &Out) {
    939   Out << format("%g", Val);
    940 }
    941 
    942 StringRef ScalarTraits<double>::input(StringRef Scalar, void *, double &Val) {
    943   if (to_float(Scalar, Val))
    944     return StringRef();
    945   return "invalid floating point number";
    946 }
    947 
    948 void ScalarTraits<float>::output(const float &Val, void *, raw_ostream &Out) {
    949   Out << format("%g", Val);
    950 }
    951 
    952 StringRef ScalarTraits<float>::input(StringRef Scalar, void *, float &Val) {
    953   if (to_float(Scalar, Val))
    954     return StringRef();
    955   return "invalid floating point number";
    956 }
    957 
    958 void ScalarTraits<Hex8>::output(const Hex8 &Val, void *, raw_ostream &Out) {
    959   uint8_t Num = Val;
    960   Out << format("0x%02X", Num);
    961 }
    962 
    963 StringRef ScalarTraits<Hex8>::input(StringRef Scalar, void *, Hex8 &Val) {
    964   unsigned long long n;
    965   if (getAsUnsignedInteger(Scalar, 0, n))
    966     return "invalid hex8 number";
    967   if (n > 0xFF)
    968     return "out of range hex8 number";
    969   Val = n;
    970   return StringRef();
    971 }
    972 
    973 void ScalarTraits<Hex16>::output(const Hex16 &Val, void *, raw_ostream &Out) {
    974   uint16_t Num = Val;
    975   Out << format("0x%04X", Num);
    976 }
    977 
    978 StringRef ScalarTraits<Hex16>::input(StringRef Scalar, void *, Hex16 &Val) {
    979   unsigned long long n;
    980   if (getAsUnsignedInteger(Scalar, 0, n))
    981     return "invalid hex16 number";
    982   if (n > 0xFFFF)
    983     return "out of range hex16 number";
    984   Val = n;
    985   return StringRef();
    986 }
    987 
    988 void ScalarTraits<Hex32>::output(const Hex32 &Val, void *, raw_ostream &Out) {
    989   uint32_t Num = Val;
    990   Out << format("0x%08X", Num);
    991 }
    992 
    993 StringRef ScalarTraits<Hex32>::input(StringRef Scalar, void *, Hex32 &Val) {
    994   unsigned long long n;
    995   if (getAsUnsignedInteger(Scalar, 0, n))
    996     return "invalid hex32 number";
    997   if (n > 0xFFFFFFFFUL)
    998     return "out of range hex32 number";
    999   Val = n;
   1000   return StringRef();
   1001 }
   1002 
   1003 void ScalarTraits<Hex64>::output(const Hex64 &Val, void *, raw_ostream &Out) {
   1004   uint64_t Num = Val;
   1005   Out << format("0x%016llX", Num);
   1006 }
   1007 
   1008 StringRef ScalarTraits<Hex64>::input(StringRef Scalar, void *, Hex64 &Val) {
   1009   unsigned long long Num;
   1010   if (getAsUnsignedInteger(Scalar, 0, Num))
   1011     return "invalid hex64 number";
   1012   Val = Num;
   1013   return StringRef();
   1014 }
   1015