YAMLTraits.cpp revision 327952
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
33using namespace llvm;
34using namespace yaml;
35
36//===----------------------------------------------------------------------===//
37//  IO
38//===----------------------------------------------------------------------===//
39
40IO::IO(void *Context) : Ctxt(Context) {}
41
42IO::~IO() = default;
43
44void *IO::getContext() {
45  return Ctxt;
46}
47
48void IO::setContext(void *Context) {
49  Ctxt = Context;
50}
51
52//===----------------------------------------------------------------------===//
53//  Input
54//===----------------------------------------------------------------------===//
55
56Input::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
64Input::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
72Input::~Input() = default;
73
74std::error_code Input::error() { return EC; }
75
76// Pin the vtables to this file.
77void Input::HNode::anchor() {}
78void Input::EmptyHNode::anchor() {}
79void Input::ScalarHNode::anchor() {}
80void Input::MapHNode::anchor() {}
81void Input::SequenceHNode::anchor() {}
82
83bool Input::outputting() {
84  return false;
85}
86
87bool 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
108bool Input::nextDocument() {
109  return ++DocIterator != Strm->end();
110}
111
112const Node *Input::getCurrentNode() const {
113  return CurrentNode ? CurrentNode->_node : nullptr;
114}
115
116bool 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
126void 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
136std::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
148bool 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
182void Input::postflightKey(void *saveInfo) {
183  CurrentNode = reinterpret_cast<HNode *>(saveInfo);
184}
185
186void 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
201void Input::beginFlowMapping() { beginMapping(); }
202
203void Input::endFlowMapping() { endMapping(); }
204
205unsigned 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
220void Input::endSequence() {
221}
222
223bool 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
234void Input::postflightElement(void *SaveInfo) {
235  CurrentNode = reinterpret_cast<HNode *>(SaveInfo);
236}
237
238unsigned Input::beginFlowSequence() { return beginSequence(); }
239
240bool 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
251void Input::postflightFlowElement(void *SaveInfo) {
252  CurrentNode = reinterpret_cast<HNode *>(SaveInfo);
253}
254
255void Input::endFlowSequence() {
256}
257
258void Input::beginEnumScalar() {
259  ScalarMatchFound = false;
260}
261
262bool 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
274bool Input::matchEnumFallback() {
275  if (ScalarMatchFound)
276    return false;
277  ScalarMatchFound = true;
278  return true;
279}
280
281void Input::endEnumScalar() {
282  if (!ScalarMatchFound) {
283    setError(CurrentNode, "unknown enumerated scalar");
284  }
285}
286
287bool 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
298bool 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
320void 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
334void 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
342void Input::blockScalarString(StringRef &S) { scalarString(S, QuotingType::None); }
343
344void Input::setError(HNode *hnode, const Twine &message) {
345  assert(hnode && "HNode must not be NULL");
346  this->setError(hnode->_node, message);
347}
348
349void Input::setError(Node *node, const Twine &message) {
350  Strm->printError(node, message);
351  EC = make_error_code(errc::invalid_argument);
352}
353
354std::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
408void Input::setError(const Twine &Message) {
409  this->setError(CurrentNode, Message);
410}
411
412bool Input::canElideEmptySequence() {
413  return false;
414}
415
416//===----------------------------------------------------------------------===//
417//  Output
418//===----------------------------------------------------------------------===//
419
420Output::Output(raw_ostream &yout, void *context, int WrapColumn)
421    : IO(context), Out(yout), WrapColumn(WrapColumn) {}
422
423Output::~Output() = default;
424
425bool Output::outputting() {
426  return true;
427}
428
429void Output::beginMapping() {
430  StateStack.push_back(inMapFirstKey);
431  NeedsNewLine = true;
432}
433
434bool 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
463void Output::endMapping() {
464  StateStack.pop_back();
465}
466
467std::vector<StringRef> Output::keys() {
468  report_fatal_error("invalid call");
469}
470
471bool 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
487void 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
497void Output::beginFlowMapping() {
498  StateStack.push_back(inFlowMapFirstKey);
499  this->newLineCheck();
500  ColumnAtMapFlowStart = Column;
501  output("{ ");
502}
503
504void Output::endFlowMapping() {
505  StateStack.pop_back();
506  this->outputUpToEndOfLine(" }");
507}
508
509void Output::beginDocuments() {
510  this->outputUpToEndOfLine("---");
511}
512
513bool Output::preflightDocument(unsigned index) {
514  if (index > 0)
515    this->outputUpToEndOfLine("\n---");
516  return true;
517}
518
519void Output::postflightDocument() {
520}
521
522void Output::endDocuments() {
523  output("\n...\n");
524}
525
526unsigned Output::beginSequence() {
527  StateStack.push_back(inSeq);
528  NeedsNewLine = true;
529  return 0;
530}
531
532void Output::endSequence() {
533  StateStack.pop_back();
534}
535
536bool Output::preflightElement(unsigned, void *&) {
537  return true;
538}
539
540void Output::postflightElement(void *) {
541}
542
543unsigned Output::beginFlowSequence() {
544  StateStack.push_back(inFlowSeq);
545  this->newLineCheck();
546  ColumnAtFlowStart = Column;
547  output("[ ");
548  NeedFlowSequenceComma = false;
549  return 0;
550}
551
552void Output::endFlowSequence() {
553  StateStack.pop_back();
554  this->outputUpToEndOfLine(" ]");
555}
556
557bool 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
570void Output::postflightFlowElement(void *) {
571  NeedFlowSequenceComma = true;
572}
573
574void Output::beginEnumScalar() {
575  EnumerationMatchFound = false;
576}
577
578bool 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
587bool Output::matchEnumFallback() {
588  if (EnumerationMatchFound)
589    return false;
590  EnumerationMatchFound = true;
591  return true;
592}
593
594void Output::endEnumScalar() {
595  if (!EnumerationMatchFound)
596    llvm_unreachable("bad runtime enum value");
597}
598
599bool Output::beginBitSetScalar(bool &DoClear) {
600  this->newLineCheck();
601  output("[ ");
602  NeedBitValueComma = false;
603  DoClear = false;
604  return true;
605}
606
607bool 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
617void Output::endBitSetScalar() {
618  this->outputUpToEndOfLine(" ]");
619}
620
621void 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  const char QuoteChar = MustQuote == QuotingType::Single ? '\'' : '"';
642
643  output(Quote); // Starting quote.
644
645  // When using single-quoted strings, any single quote ' must be doubled to be
646  // escaped.
647  // When using double-quoted strings, print \x + hex for non-printable ASCII
648  // characters, and escape double quotes.
649  while (j < End) {
650    if (S[j] == QuoteChar) {                  // Escape quotes.
651      output(StringRef(&Base[i], j - i));     // "flush".
652      if (MustQuote == QuotingType::Double) { // Print it as \"
653        output(StringLiteral("\\"));
654        output(StringRef(Quote, 1));
655      } else {                       // Single
656        output(StringLiteral("''")); // Print it as ''
657      }
658      i = j + 1;
659    } else if (MustQuote == QuotingType::Double &&
660               !sys::unicode::isPrintable(S[j]) && (S[j] & 0x80) == 0) {
661      // If we're double quoting non-printable characters, we prefer printing
662      // them as "\x" + their hex representation. Note that special casing is
663      // needed for UTF-8, where a byte may be part of a UTF-8 sequence and
664      // appear as non-printable, in which case we want to print the correct
665      // unicode character and not its hex representation.
666      output(StringRef(&Base[i], j - i)); // "flush"
667      output(StringLiteral("\\x"));
668
669      // Output the byte 0x0F as \x0f.
670      auto FormattedHex = format_hex_no_prefix(S[j], 2);
671      Out << FormattedHex;
672      Column += 4; // one for the '\', one for the 'x', and two for the hex
673
674      i = j + 1;
675    }
676    ++j;
677  }
678  output(StringRef(&Base[i], j - i));
679  this->outputUpToEndOfLine(Quote); // Ending quote.
680}
681
682void Output::blockScalarString(StringRef &S) {
683  if (!StateStack.empty())
684    newLineCheck();
685  output(" |");
686  outputNewLine();
687
688  unsigned Indent = StateStack.empty() ? 1 : StateStack.size();
689
690  auto Buffer = MemoryBuffer::getMemBuffer(S, "", false);
691  for (line_iterator Lines(*Buffer, false); !Lines.is_at_end(); ++Lines) {
692    for (unsigned I = 0; I < Indent; ++I) {
693      output("  ");
694    }
695    output(*Lines);
696    outputNewLine();
697  }
698}
699
700void Output::setError(const Twine &message) {
701}
702
703bool Output::canElideEmptySequence() {
704  // Normally, with an optional key/value where the value is an empty sequence,
705  // the whole key/value can be not written.  But, that produces wrong yaml
706  // if the key/value is the only thing in the map and the map is used in
707  // a sequence.  This detects if the this sequence is the first key/value
708  // in map that itself is embedded in a sequnce.
709  if (StateStack.size() < 2)
710    return true;
711  if (StateStack.back() != inMapFirstKey)
712    return true;
713  return (StateStack[StateStack.size()-2] != inSeq);
714}
715
716void Output::output(StringRef s) {
717  Column += s.size();
718  Out << s;
719}
720
721void Output::outputUpToEndOfLine(StringRef s) {
722  this->output(s);
723  if (StateStack.empty() || (StateStack.back() != inFlowSeq &&
724                             StateStack.back() != inFlowMapFirstKey &&
725                             StateStack.back() != inFlowMapOtherKey))
726    NeedsNewLine = true;
727}
728
729void Output::outputNewLine() {
730  Out << "\n";
731  Column = 0;
732}
733
734// if seq at top, indent as if map, then add "- "
735// if seq in middle, use "- " if firstKey, else use "  "
736//
737
738void Output::newLineCheck() {
739  if (!NeedsNewLine)
740    return;
741  NeedsNewLine = false;
742
743  this->outputNewLine();
744
745  assert(StateStack.size() > 0);
746  unsigned Indent = StateStack.size() - 1;
747  bool OutputDash = false;
748
749  if (StateStack.back() == inSeq) {
750    OutputDash = true;
751  } else if ((StateStack.size() > 1) && ((StateStack.back() == inMapFirstKey) ||
752             (StateStack.back() == inFlowSeq) ||
753             (StateStack.back() == inFlowMapFirstKey)) &&
754             (StateStack[StateStack.size() - 2] == inSeq)) {
755    --Indent;
756    OutputDash = true;
757  }
758
759  for (unsigned i = 0; i < Indent; ++i) {
760    output("  ");
761  }
762  if (OutputDash) {
763    output("- ");
764  }
765
766}
767
768void Output::paddedKey(StringRef key) {
769  output(key);
770  output(":");
771  const char *spaces = "                ";
772  if (key.size() < strlen(spaces))
773    output(&spaces[key.size()]);
774  else
775    output(" ");
776}
777
778void Output::flowKey(StringRef Key) {
779  if (StateStack.back() == inFlowMapOtherKey)
780    output(", ");
781  if (WrapColumn && Column > WrapColumn) {
782    output("\n");
783    for (int I = 0; I < ColumnAtMapFlowStart; ++I)
784      output(" ");
785    Column = ColumnAtMapFlowStart;
786    output("  ");
787  }
788  output(Key);
789  output(": ");
790}
791
792//===----------------------------------------------------------------------===//
793//  traits for built-in types
794//===----------------------------------------------------------------------===//
795
796void ScalarTraits<bool>::output(const bool &Val, void *, raw_ostream &Out) {
797  Out << (Val ? "true" : "false");
798}
799
800StringRef ScalarTraits<bool>::input(StringRef Scalar, void *, bool &Val) {
801  if (Scalar.equals("true")) {
802    Val = true;
803    return StringRef();
804  } else if (Scalar.equals("false")) {
805    Val = false;
806    return StringRef();
807  }
808  return "invalid boolean";
809}
810
811void ScalarTraits<StringRef>::output(const StringRef &Val, void *,
812                                     raw_ostream &Out) {
813  Out << Val;
814}
815
816StringRef ScalarTraits<StringRef>::input(StringRef Scalar, void *,
817                                         StringRef &Val) {
818  Val = Scalar;
819  return StringRef();
820}
821
822void ScalarTraits<std::string>::output(const std::string &Val, void *,
823                                     raw_ostream &Out) {
824  Out << Val;
825}
826
827StringRef ScalarTraits<std::string>::input(StringRef Scalar, void *,
828                                         std::string &Val) {
829  Val = Scalar.str();
830  return StringRef();
831}
832
833void ScalarTraits<uint8_t>::output(const uint8_t &Val, void *,
834                                   raw_ostream &Out) {
835  // use temp uin32_t because ostream thinks uint8_t is a character
836  uint32_t Num = Val;
837  Out << Num;
838}
839
840StringRef ScalarTraits<uint8_t>::input(StringRef Scalar, void *, uint8_t &Val) {
841  unsigned long long n;
842  if (getAsUnsignedInteger(Scalar, 0, n))
843    return "invalid number";
844  if (n > 0xFF)
845    return "out of range number";
846  Val = n;
847  return StringRef();
848}
849
850void ScalarTraits<uint16_t>::output(const uint16_t &Val, void *,
851                                    raw_ostream &Out) {
852  Out << Val;
853}
854
855StringRef ScalarTraits<uint16_t>::input(StringRef Scalar, void *,
856                                        uint16_t &Val) {
857  unsigned long long n;
858  if (getAsUnsignedInteger(Scalar, 0, n))
859    return "invalid number";
860  if (n > 0xFFFF)
861    return "out of range number";
862  Val = n;
863  return StringRef();
864}
865
866void ScalarTraits<uint32_t>::output(const uint32_t &Val, void *,
867                                    raw_ostream &Out) {
868  Out << Val;
869}
870
871StringRef ScalarTraits<uint32_t>::input(StringRef Scalar, void *,
872                                        uint32_t &Val) {
873  unsigned long long n;
874  if (getAsUnsignedInteger(Scalar, 0, n))
875    return "invalid number";
876  if (n > 0xFFFFFFFFUL)
877    return "out of range number";
878  Val = n;
879  return StringRef();
880}
881
882void ScalarTraits<uint64_t>::output(const uint64_t &Val, void *,
883                                    raw_ostream &Out) {
884  Out << Val;
885}
886
887StringRef ScalarTraits<uint64_t>::input(StringRef Scalar, void *,
888                                        uint64_t &Val) {
889  unsigned long long N;
890  if (getAsUnsignedInteger(Scalar, 0, N))
891    return "invalid number";
892  Val = N;
893  return StringRef();
894}
895
896void ScalarTraits<int8_t>::output(const int8_t &Val, void *, raw_ostream &Out) {
897  // use temp in32_t because ostream thinks int8_t is a character
898  int32_t Num = Val;
899  Out << Num;
900}
901
902StringRef ScalarTraits<int8_t>::input(StringRef Scalar, void *, int8_t &Val) {
903  long long N;
904  if (getAsSignedInteger(Scalar, 0, N))
905    return "invalid number";
906  if ((N > 127) || (N < -128))
907    return "out of range number";
908  Val = N;
909  return StringRef();
910}
911
912void ScalarTraits<int16_t>::output(const int16_t &Val, void *,
913                                   raw_ostream &Out) {
914  Out << Val;
915}
916
917StringRef ScalarTraits<int16_t>::input(StringRef Scalar, void *, int16_t &Val) {
918  long long N;
919  if (getAsSignedInteger(Scalar, 0, N))
920    return "invalid number";
921  if ((N > INT16_MAX) || (N < INT16_MIN))
922    return "out of range number";
923  Val = N;
924  return StringRef();
925}
926
927void ScalarTraits<int32_t>::output(const int32_t &Val, void *,
928                                   raw_ostream &Out) {
929  Out << Val;
930}
931
932StringRef ScalarTraits<int32_t>::input(StringRef Scalar, void *, int32_t &Val) {
933  long long N;
934  if (getAsSignedInteger(Scalar, 0, N))
935    return "invalid number";
936  if ((N > INT32_MAX) || (N < INT32_MIN))
937    return "out of range number";
938  Val = N;
939  return StringRef();
940}
941
942void ScalarTraits<int64_t>::output(const int64_t &Val, void *,
943                                   raw_ostream &Out) {
944  Out << Val;
945}
946
947StringRef ScalarTraits<int64_t>::input(StringRef Scalar, void *, int64_t &Val) {
948  long long N;
949  if (getAsSignedInteger(Scalar, 0, N))
950    return "invalid number";
951  Val = N;
952  return StringRef();
953}
954
955void ScalarTraits<double>::output(const double &Val, void *, raw_ostream &Out) {
956  Out << format("%g", Val);
957}
958
959StringRef ScalarTraits<double>::input(StringRef Scalar, void *, double &Val) {
960  if (to_float(Scalar, Val))
961    return StringRef();
962  return "invalid floating point number";
963}
964
965void ScalarTraits<float>::output(const float &Val, void *, raw_ostream &Out) {
966  Out << format("%g", Val);
967}
968
969StringRef ScalarTraits<float>::input(StringRef Scalar, void *, float &Val) {
970  if (to_float(Scalar, Val))
971    return StringRef();
972  return "invalid floating point number";
973}
974
975void ScalarTraits<Hex8>::output(const Hex8 &Val, void *, raw_ostream &Out) {
976  uint8_t Num = Val;
977  Out << format("0x%02X", Num);
978}
979
980StringRef ScalarTraits<Hex8>::input(StringRef Scalar, void *, Hex8 &Val) {
981  unsigned long long n;
982  if (getAsUnsignedInteger(Scalar, 0, n))
983    return "invalid hex8 number";
984  if (n > 0xFF)
985    return "out of range hex8 number";
986  Val = n;
987  return StringRef();
988}
989
990void ScalarTraits<Hex16>::output(const Hex16 &Val, void *, raw_ostream &Out) {
991  uint16_t Num = Val;
992  Out << format("0x%04X", Num);
993}
994
995StringRef ScalarTraits<Hex16>::input(StringRef Scalar, void *, Hex16 &Val) {
996  unsigned long long n;
997  if (getAsUnsignedInteger(Scalar, 0, n))
998    return "invalid hex16 number";
999  if (n > 0xFFFF)
1000    return "out of range hex16 number";
1001  Val = n;
1002  return StringRef();
1003}
1004
1005void ScalarTraits<Hex32>::output(const Hex32 &Val, void *, raw_ostream &Out) {
1006  uint32_t Num = Val;
1007  Out << format("0x%08X", Num);
1008}
1009
1010StringRef ScalarTraits<Hex32>::input(StringRef Scalar, void *, Hex32 &Val) {
1011  unsigned long long n;
1012  if (getAsUnsignedInteger(Scalar, 0, n))
1013    return "invalid hex32 number";
1014  if (n > 0xFFFFFFFFUL)
1015    return "out of range hex32 number";
1016  Val = n;
1017  return StringRef();
1018}
1019
1020void ScalarTraits<Hex64>::output(const Hex64 &Val, void *, raw_ostream &Out) {
1021  uint64_t Num = Val;
1022  Out << format("0x%016llX", Num);
1023}
1024
1025StringRef ScalarTraits<Hex64>::input(StringRef Scalar, void *, Hex64 &Val) {
1026  unsigned long long Num;
1027  if (getAsUnsignedInteger(Scalar, 0, Num))
1028    return "invalid hex64 number";
1029  Val = Num;
1030  return StringRef();
1031}
1032