Line data Source code
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 11241 : IO::IO(void *Context) : Ctxt(Context) {}
41 :
42 : IO::~IO() = default;
43 :
44 502951 : void *IO::getContext() {
45 502951 : return Ctxt;
46 : }
47 :
48 3180 : void IO::setContext(void *Context) {
49 3180 : Ctxt = Context;
50 3180 : }
51 :
52 : //===----------------------------------------------------------------------===//
53 : // Input
54 : //===----------------------------------------------------------------------===//
55 :
56 4009 : Input::Input(StringRef InputContent, void *Ctxt,
57 4009 : SourceMgr::DiagHandlerTy DiagHandler, void *DiagHandlerCtxt)
58 4009 : : IO(Ctxt), Strm(new Stream(InputContent, SrcMgr, false, &EC)) {
59 4009 : if (DiagHandler)
60 : SrcMgr.setDiagHandler(DiagHandler, DiagHandlerCtxt);
61 4009 : DocIterator = Strm->begin();
62 4009 : }
63 :
64 3 : Input::Input(MemoryBufferRef Input, void *Ctxt,
65 3 : SourceMgr::DiagHandlerTy DiagHandler, void *DiagHandlerCtxt)
66 3 : : IO(Ctxt), Strm(new Stream(Input, SrcMgr, false, &EC)) {
67 3 : if (DiagHandler)
68 : SrcMgr.setDiagHandler(DiagHandler, DiagHandlerCtxt);
69 3 : DocIterator = Strm->begin();
70 3 : }
71 :
72 : Input::~Input() = default;
73 :
74 8153 : std::error_code Input::error() { return EC; }
75 :
76 : // Pin the vtables to this file.
77 0 : void Input::HNode::anchor() {}
78 0 : void Input::EmptyHNode::anchor() {}
79 0 : void Input::ScalarHNode::anchor() {}
80 0 : void Input::MapHNode::anchor() {}
81 0 : void Input::SequenceHNode::anchor() {}
82 :
83 1451722 : bool Input::outputting() {
84 1451722 : return false;
85 : }
86 :
87 10737 : bool Input::setCurrentDocument() {
88 10737 : if (DocIterator != Strm->end()) {
89 8406 : Node *N = DocIterator->getRoot();
90 8406 : if (!N) {
91 : assert(Strm->failed() && "Root is NULL iff parsing failed");
92 1 : EC = make_error_code(errc::invalid_argument);
93 1 : return false;
94 : }
95 :
96 8405 : if (isa<NullNode>(N)) {
97 : // Empty files are allowed and ignored
98 554 : ++DocIterator;
99 554 : return setCurrentDocument();
100 : }
101 15702 : TopNode = createHNodes(N);
102 7851 : CurrentNode = TopNode.get();
103 7851 : return true;
104 : }
105 : return false;
106 : }
107 :
108 6709 : bool Input::nextDocument() {
109 6709 : return ++DocIterator != Strm->end();
110 : }
111 :
112 43399 : const Node *Input::getCurrentNode() const {
113 43399 : return CurrentNode ? CurrentNode->_node : nullptr;
114 : }
115 :
116 3959 : bool Input::mapTag(StringRef Tag, bool Default) {
117 3959 : std::string foundTag = CurrentNode->_node->getVerbatimTag();
118 3959 : 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 46993 : void Input::beginMapping() {
127 46993 : if (EC)
128 : return;
129 : // CurrentNode can be null if the document is empty.
130 46990 : MapHNode *MN = dyn_cast_or_null<MapHNode>(CurrentNode);
131 : if (MN) {
132 46914 : MN->ValidKeys.clear();
133 : }
134 : }
135 :
136 85 : std::vector<StringRef> Input::keys() {
137 85 : MapHNode *MN = dyn_cast<MapHNode>(CurrentNode);
138 : std::vector<StringRef> Ret;
139 85 : if (!MN) {
140 0 : setError(CurrentNode, "not a mapping");
141 0 : return Ret;
142 : }
143 325 : for (auto &P : MN->Mapping)
144 155 : Ret.push_back(P.first());
145 : return Ret;
146 : }
147 :
148 325291 : bool Input::preflightKey(const char *Key, bool Required, bool, bool &UseDefault,
149 : void *&SaveInfo) {
150 325291 : UseDefault = false;
151 325291 : 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 325227 : if (!CurrentNode) {
157 2 : if (Required)
158 1 : EC = make_error_code(errc::invalid_argument);
159 2 : return false;
160 : }
161 :
162 : MapHNode *MN = dyn_cast<MapHNode>(CurrentNode);
163 : if (!MN) {
164 6 : if (Required || !isa<EmptyHNode>(CurrentNode))
165 0 : setError(CurrentNode, "not a mapping");
166 6 : return false;
167 : }
168 650438 : MN->ValidKeys.push_back(Key);
169 325219 : HNode *Value = MN->Mapping[Key].get();
170 325219 : if (!Value) {
171 157613 : if (Required)
172 23 : setError(CurrentNode, Twine("missing required key '") + Key + "'");
173 : else
174 157590 : UseDefault = true;
175 157613 : return false;
176 : }
177 167606 : SaveInfo = CurrentNode;
178 167606 : CurrentNode = Value;
179 167606 : return true;
180 : }
181 :
182 167606 : void Input::postflightKey(void *saveInfo) {
183 167606 : CurrentNode = reinterpret_cast<HNode *>(saveInfo);
184 167606 : }
185 :
186 46993 : void Input::endMapping() {
187 46993 : if (EC)
188 : return;
189 : // CurrentNode can be null if the document is empty.
190 46936 : MapHNode *MN = dyn_cast_or_null<MapHNode>(CurrentNode);
191 : if (!MN)
192 : return;
193 417912 : for (const auto &NN : MN->Mapping) {
194 648406 : if (!is_contained(MN->ValidKeys, NN.first())) {
195 26 : setError(NN.second.get(), Twine("unknown key '") + NN.first() + "'");
196 13 : break;
197 : }
198 : }
199 : }
200 :
201 17050 : void Input::beginFlowMapping() { beginMapping(); }
202 :
203 17050 : void Input::endFlowMapping() { endMapping(); }
204 :
205 11697 : unsigned Input::beginSequence() {
206 11697 : if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode))
207 18418 : return SQ->Entries.size();
208 2488 : 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 5 : if (isNull(SN->value()))
213 : return 0;
214 : }
215 : // Any other type of HNode is an error.
216 3 : setError(CurrentNode, "not a sequence");
217 3 : return 0;
218 : }
219 :
220 10763 : void Input::endSequence() {
221 10763 : }
222 :
223 34001 : bool Input::preflightElement(unsigned Index, void *&SaveInfo) {
224 34001 : if (EC)
225 : return false;
226 34001 : if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
227 34001 : SaveInfo = CurrentNode;
228 34001 : CurrentNode = SQ->Entries[Index].get();
229 34001 : return true;
230 : }
231 : return false;
232 : }
233 :
234 34001 : void Input::postflightElement(void *SaveInfo) {
235 34001 : CurrentNode = reinterpret_cast<HNode *>(SaveInfo);
236 34001 : }
237 :
238 934 : unsigned Input::beginFlowSequence() { return beginSequence(); }
239 :
240 8907 : bool Input::preflightFlowElement(unsigned index, void *&SaveInfo) {
241 8907 : if (EC)
242 : return false;
243 8907 : if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
244 8907 : SaveInfo = CurrentNode;
245 8907 : CurrentNode = SQ->Entries[index].get();
246 8907 : return true;
247 : }
248 : return false;
249 : }
250 :
251 8907 : void Input::postflightFlowElement(void *SaveInfo) {
252 8907 : CurrentNode = reinterpret_cast<HNode *>(SaveInfo);
253 8907 : }
254 :
255 934 : void Input::endFlowSequence() {
256 934 : }
257 :
258 19810 : void Input::beginEnumScalar() {
259 19810 : ScalarMatchFound = false;
260 19810 : }
261 :
262 1074265 : bool Input::matchEnumScalar(const char *Str, bool) {
263 1074265 : if (ScalarMatchFound)
264 : return false;
265 273383 : if (ScalarHNode *SN = dyn_cast<ScalarHNode>(CurrentNode)) {
266 : if (SN->value().equals(Str)) {
267 19777 : ScalarMatchFound = true;
268 19777 : return true;
269 : }
270 : }
271 : return false;
272 : }
273 :
274 1644 : bool Input::matchEnumFallback() {
275 1644 : if (ScalarMatchFound)
276 : return false;
277 31 : ScalarMatchFound = true;
278 31 : return true;
279 : }
280 :
281 19810 : void Input::endEnumScalar() {
282 19810 : if (!ScalarMatchFound) {
283 2 : setError(CurrentNode, "unknown enumerated scalar");
284 : }
285 19810 : }
286 :
287 3390 : bool Input::beginBitSetScalar(bool &DoClear) {
288 3390 : BitValuesUsed.clear();
289 3390 : if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
290 6780 : BitValuesUsed.insert(BitValuesUsed.begin(), SQ->Entries.size(), false);
291 : } else {
292 0 : setError(CurrentNode, "expected sequence of bit values");
293 : }
294 3390 : DoClear = true;
295 3390 : return true;
296 : }
297 :
298 37734 : bool Input::bitSetMatch(const char *Str, bool) {
299 37734 : if (EC)
300 : return false;
301 37734 : if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
302 : unsigned Index = 0;
303 107202 : for (auto &N : SQ->Entries) {
304 : if (ScalarHNode *SN = dyn_cast<ScalarHNode>(N.get())) {
305 : if (SN->value().equals(Str)) {
306 6019 : BitValuesUsed[Index] = true;
307 : return true;
308 : }
309 : } else {
310 0 : setError(CurrentNode, "unexpected scalar in sequence of bit values");
311 : }
312 69468 : ++Index;
313 : }
314 : } else {
315 0 : setError(CurrentNode, "expected sequence of bit values");
316 : }
317 : return false;
318 : }
319 :
320 3390 : void Input::endBitSetScalar() {
321 3390 : if (EC)
322 : return;
323 3390 : if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
324 : assert(BitValuesUsed.size() == SQ->Entries.size());
325 12799 : for (unsigned i = 0; i < SQ->Entries.size(); ++i) {
326 12040 : if (!BitValuesUsed[i]) {
327 1 : setError(SQ->Entries[i].get(), "unknown bit value");
328 1 : return;
329 : }
330 : }
331 : }
332 : }
333 :
334 135609 : void Input::scalarString(StringRef &S, QuotingType) {
335 135609 : if (ScalarHNode *SN = dyn_cast<ScalarHNode>(CurrentNode)) {
336 135609 : S = SN->value();
337 : } else {
338 0 : setError(CurrentNode, "unexpected scalar");
339 : }
340 135609 : }
341 :
342 4575 : void Input::blockScalarString(StringRef &S) { scalarString(S, QuotingType::None); }
343 :
344 78 : void Input::setError(HNode *hnode, const Twine &message) {
345 : assert(hnode && "HNode must not be NULL");
346 78 : setError(hnode->_node, message);
347 78 : }
348 :
349 80 : void Input::setError(Node *node, const Twine &message) {
350 80 : Strm->printError(node, message);
351 80 : EC = make_error_code(errc::invalid_argument);
352 80 : }
353 :
354 224190 : std::unique_ptr<Input::HNode> Input::createHNodes(Node *N) {
355 : SmallString<128> StringStorage;
356 : if (ScalarNode *SN = dyn_cast<ScalarNode>(N)) {
357 156530 : StringRef KeyStr = SN->getValue(StringStorage);
358 156530 : if (!StringStorage.empty()) {
359 : // Copy string to permanent storage
360 11 : KeyStr = StringStorage.str().copy(StringAllocator);
361 : }
362 : return llvm::make_unique<ScalarHNode>(N, KeyStr);
363 : } else if (BlockScalarNode *BSN = dyn_cast<BlockScalarNode>(N)) {
364 5479 : 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 61662 : for (Node &SN : *SQ) {
369 49015 : auto Entry = createHNodes(&SN);
370 49015 : if (EC)
371 : break;
372 49015 : SQHNode->Entries.push_back(std::move(Entry));
373 : }
374 : return std::move(SQHNode);
375 : } else if (MappingNode *Map = dyn_cast<MappingNode>(N)) {
376 46976 : auto mapHNode = llvm::make_unique<MapHNode>(N);
377 214300 : for (KeyValueNode &KVN : *Map) {
378 167326 : Node *KeyNode = KVN.getKey();
379 : ScalarNode *Key = dyn_cast<ScalarNode>(KeyNode);
380 167326 : Node *Value = KVN.getValue();
381 167326 : if (!Key || !Value) {
382 2 : if (!Key)
383 1 : setError(KeyNode, "Map key must be a scalar");
384 2 : if (!Value)
385 1 : setError(KeyNode, "Map value must not be empty");
386 2 : break;
387 : }
388 : StringStorage.clear();
389 167324 : StringRef KeyStr = Key->getValue(StringStorage);
390 167324 : if (!StringStorage.empty()) {
391 : // Copy string to permanent storage
392 0 : KeyStr = StringStorage.str().copy(StringAllocator);
393 : }
394 167324 : auto ValueHNode = createHNodes(Value);
395 167324 : if (EC)
396 : break;
397 167324 : mapHNode->Mapping[KeyStr] = std::move(ValueHNode);
398 : }
399 : return std::move(mapHNode);
400 2558 : } else if (isa<NullNode>(N)) {
401 : return llvm::make_unique<EmptyHNode>(N);
402 : } else {
403 0 : setError(N, "unknown node kind");
404 : return nullptr;
405 : }
406 : }
407 :
408 36 : void Input::setError(const Twine &Message) {
409 36 : setError(CurrentNode, Message);
410 36 : }
411 :
412 12122 : bool Input::canElideEmptySequence() {
413 12122 : return false;
414 : }
415 :
416 : //===----------------------------------------------------------------------===//
417 : // Output
418 : //===----------------------------------------------------------------------===//
419 :
420 7229 : Output::Output(raw_ostream &yout, void *context, int WrapColumn)
421 7229 : : IO(context), Out(yout), WrapColumn(WrapColumn) {}
422 :
423 : Output::~Output() = default;
424 :
425 1926080 : bool Output::outputting() {
426 1926080 : return true;
427 : }
428 :
429 55221 : void Output::beginMapping() {
430 55221 : StateStack.push_back(inMapFirstKey);
431 55221 : NeedsNewLine = true;
432 55221 : }
433 :
434 1431 : bool Output::mapTag(StringRef Tag, bool Use) {
435 1431 : 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 1484 : StateStack.size() > 1 && (StateStack[StateStack.size() - 2] == inSeq ||
441 : StateStack[StateStack.size() - 2] == inFlowSeq);
442 57 : if (SequenceElement && StateStack.back() == inMapFirstKey) {
443 57 : newLineCheck();
444 : } else {
445 685 : output(" ");
446 : }
447 742 : output(Tag);
448 742 : 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 57 : if (StateStack.back() == inMapFirstKey) {
452 57 : StateStack.pop_back();
453 57 : 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 57 : NeedsNewLine = true;
458 : }
459 : }
460 1431 : return Use;
461 : }
462 :
463 55221 : void Output::endMapping() {
464 : StateStack.pop_back();
465 55221 : }
466 :
467 0 : std::vector<StringRef> Output::keys() {
468 0 : report_fatal_error("invalid call");
469 : }
470 :
471 589434 : bool Output::preflightKey(const char *Key, bool Required, bool SameAsDefault,
472 : bool &UseDefault, void *&) {
473 589434 : UseDefault = false;
474 589434 : if (Required || !SameAsDefault || WriteDefaultValues) {
475 438899 : auto State = StateStack.back();
476 438899 : if (State == inFlowMapFirstKey || State == inFlowMapOtherKey) {
477 84611 : flowKey(Key);
478 : } else {
479 354288 : newLineCheck();
480 354288 : paddedKey(Key);
481 : }
482 438899 : return true;
483 : }
484 : return false;
485 : }
486 :
487 438899 : void Output::postflightKey(void *) {
488 438899 : if (StateStack.back() == inMapFirstKey) {
489 55003 : StateStack.pop_back();
490 55003 : StateStack.push_back(inMapOtherKey);
491 383896 : } else if (StateStack.back() == inFlowMapFirstKey) {
492 25797 : StateStack.pop_back();
493 25797 : StateStack.push_back(inFlowMapOtherKey);
494 : }
495 438899 : }
496 :
497 25797 : void Output::beginFlowMapping() {
498 25797 : StateStack.push_back(inFlowMapFirstKey);
499 25797 : newLineCheck();
500 25797 : ColumnAtMapFlowStart = Column;
501 25797 : output("{ ");
502 25797 : }
503 :
504 25797 : void Output::endFlowMapping() {
505 : StateStack.pop_back();
506 25797 : outputUpToEndOfLine(" }");
507 25797 : }
508 :
509 7396 : void Output::beginDocuments() {
510 7396 : outputUpToEndOfLine("---");
511 7396 : }
512 :
513 7397 : bool Output::preflightDocument(unsigned index) {
514 7397 : if (index > 0)
515 2 : outputUpToEndOfLine("\n---");
516 7397 : return true;
517 : }
518 :
519 7397 : void Output::postflightDocument() {
520 7397 : }
521 :
522 7396 : void Output::endDocuments() {
523 7396 : output("\n...\n");
524 7396 : }
525 :
526 31395 : unsigned Output::beginSequence() {
527 31395 : StateStack.push_back(inSeq);
528 31395 : NeedsNewLine = true;
529 31395 : return 0;
530 : }
531 :
532 31395 : void Output::endSequence() {
533 : StateStack.pop_back();
534 31395 : }
535 :
536 70516 : bool Output::preflightElement(unsigned, void *&) {
537 70516 : return true;
538 : }
539 :
540 70516 : void Output::postflightElement(void *) {
541 70516 : }
542 :
543 1951 : unsigned Output::beginFlowSequence() {
544 1951 : StateStack.push_back(inFlowSeq);
545 1951 : newLineCheck();
546 1951 : ColumnAtFlowStart = Column;
547 1951 : output("[ ");
548 1951 : NeedFlowSequenceComma = false;
549 1951 : return 0;
550 : }
551 :
552 1951 : void Output::endFlowSequence() {
553 : StateStack.pop_back();
554 1951 : outputUpToEndOfLine(" ]");
555 1951 : }
556 :
557 8514 : bool Output::preflightFlowElement(unsigned, void *&) {
558 8514 : if (NeedFlowSequenceComma)
559 6588 : output(", ");
560 8514 : if (WrapColumn && Column > WrapColumn) {
561 337 : output("\n");
562 7457 : for (int i = 0; i < ColumnAtFlowStart; ++i)
563 7120 : output(" ");
564 337 : Column = ColumnAtFlowStart;
565 337 : output(" ");
566 : }
567 8514 : return true;
568 : }
569 :
570 8514 : void Output::postflightFlowElement(void *) {
571 8514 : NeedFlowSequenceComma = true;
572 8514 : }
573 :
574 49297 : void Output::beginEnumScalar() {
575 49297 : EnumerationMatchFound = false;
576 49297 : }
577 :
578 1108154 : bool Output::matchEnumScalar(const char *Str, bool Match) {
579 1108154 : if (Match && !EnumerationMatchFound) {
580 49274 : newLineCheck();
581 49274 : outputUpToEndOfLine(Str);
582 49274 : EnumerationMatchFound = true;
583 : }
584 1108154 : return false;
585 : }
586 :
587 6799 : bool Output::matchEnumFallback() {
588 6799 : if (EnumerationMatchFound)
589 : return false;
590 23 : EnumerationMatchFound = true;
591 23 : return true;
592 : }
593 :
594 49297 : void Output::endEnumScalar() {
595 49297 : if (!EnumerationMatchFound)
596 0 : llvm_unreachable("bad runtime enum value");
597 49297 : }
598 :
599 1449 : bool Output::beginBitSetScalar(bool &DoClear) {
600 1449 : newLineCheck();
601 1449 : output("[ ");
602 1449 : NeedBitValueComma = false;
603 1449 : DoClear = false;
604 1449 : return true;
605 : }
606 :
607 12380 : bool Output::bitSetMatch(const char *Str, bool Matches) {
608 12380 : if (Matches) {
609 2629 : if (NeedBitValueComma)
610 1463 : output(", ");
611 2629 : output(Str);
612 2629 : NeedBitValueComma = true;
613 : }
614 12380 : return false;
615 : }
616 :
617 1449 : void Output::endBitSetScalar() {
618 1449 : outputUpToEndOfLine(" ]");
619 1449 : }
620 :
621 354511 : void Output::scalarString(StringRef &S, QuotingType MustQuote) {
622 354511 : newLineCheck();
623 354511 : if (S.empty()) {
624 : // Print '' for the empty string because leaving the field empty is not
625 : // allowed.
626 56328 : outputUpToEndOfLine("''");
627 56328 : return;
628 : }
629 298183 : if (MustQuote == QuotingType::None) {
630 : // Only quote if we must.
631 285280 : outputUpToEndOfLine(S);
632 285280 : return;
633 : }
634 :
635 : unsigned i = 0;
636 : unsigned j = 0;
637 12903 : unsigned End = S.size();
638 : const char *Base = S.data();
639 :
640 12903 : const char *const Quote = MustQuote == QuotingType::Single ? "'" : "\"";
641 12903 : 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 12903 : if (MustQuote == QuotingType::Double) {
647 10 : output(yaml::escape(Base, /* EscapePrintable= */ false));
648 7 : outputUpToEndOfLine(Quote);
649 7 : return;
650 : }
651 :
652 : // When using single-quoted strings, any single quote ' must be doubled to be escaped.
653 290208 : while (j < End) {
654 554624 : if (S[j] == '\'') { // Escape quotes.
655 26 : output(StringRef(&Base[i], j - i)); // "flush".
656 13 : output(StringLiteral("''")); // Print it as ''
657 13 : i = j + 1;
658 : }
659 277312 : ++j;
660 : }
661 25792 : output(StringRef(&Base[i], j - i));
662 12896 : outputUpToEndOfLine(Quote); // Ending quote.
663 : }
664 :
665 5891 : void Output::blockScalarString(StringRef &S) {
666 5891 : if (!StateStack.empty())
667 4770 : newLineCheck();
668 5891 : output(" |");
669 5891 : outputNewLine();
670 :
671 5891 : unsigned Indent = StateStack.empty() ? 1 : StateStack.size();
672 :
673 5891 : auto Buffer = MemoryBuffer::getMemBuffer(S, "", false);
674 105639 : for (line_iterator Lines(*Buffer, false); !Lines.is_at_end(); ++Lines) {
675 199496 : for (unsigned I = 0; I < Indent; ++I) {
676 99748 : output(" ");
677 : }
678 99748 : output(*Lines);
679 99748 : outputNewLine();
680 : }
681 5891 : }
682 :
683 0 : void Output::setError(const Twine &message) {
684 0 : }
685 :
686 21115 : 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 42230 : if (StateStack.size() < 2)
693 : return true;
694 19499 : if (StateStack.back() != inMapFirstKey)
695 : return true;
696 770 : return (StateStack[StateStack.size()-2] != inSeq);
697 : }
698 :
699 2882292 : void Output::output(StringRef s) {
700 2882292 : Column += s.size();
701 2882292 : Out << s;
702 2882292 : }
703 :
704 440380 : void Output::outputUpToEndOfLine(StringRef s) {
705 440380 : output(s);
706 440380 : if (StateStack.empty() || (StateStack.back() != inFlowSeq &&
707 398655 : StateStack.back() != inFlowMapFirstKey &&
708 : StateStack.back() != inFlowMapOtherKey))
709 347255 : NeedsNewLine = true;
710 440380 : }
711 :
712 495681 : void Output::outputNewLine() {
713 495681 : Out << "\n";
714 495681 : Column = 0;
715 495681 : }
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 792097 : void Output::newLineCheck() {
722 792097 : if (!NeedsNewLine)
723 : return;
724 390042 : NeedsNewLine = false;
725 :
726 390042 : outputNewLine();
727 :
728 : assert(StateStack.size() > 0);
729 780084 : unsigned Indent = StateStack.size() - 1;
730 : bool OutputDash = false;
731 :
732 390042 : if (StateStack.back() == inSeq) {
733 : OutputDash = true;
734 304029 : } else if ((StateStack.size() > 1) && ((StateStack.back() == inMapFirstKey) ||
735 255382 : (StateStack.back() == inFlowSeq) ||
736 379965 : (StateStack.back() == inFlowMapFirstKey)) &&
737 148528 : (StateStack[StateStack.size() - 2] == inSeq)) {
738 60439 : --Indent;
739 : OutputDash = true;
740 : }
741 :
742 1169362 : for (unsigned i = 0; i < Indent; ++i) {
743 779320 : output(" ");
744 : }
745 390042 : if (OutputDash) {
746 70516 : output("- ");
747 : }
748 :
749 : }
750 :
751 354288 : void Output::paddedKey(StringRef key) {
752 354288 : output(key);
753 354288 : output(":");
754 : const char *spaces = " ";
755 354288 : if (key.size() < strlen(spaces))
756 571762 : output(&spaces[key.size()]);
757 : else
758 68407 : output(" ");
759 354288 : }
760 :
761 84611 : void Output::flowKey(StringRef Key) {
762 84611 : if (StateStack.back() == inFlowMapOtherKey)
763 58814 : output(", ");
764 84611 : if (WrapColumn && Column > WrapColumn) {
765 2059 : output("\n");
766 11404 : for (int I = 0; I < ColumnAtMapFlowStart; ++I)
767 9345 : output(" ");
768 2059 : Column = ColumnAtMapFlowStart;
769 2059 : output(" ");
770 : }
771 84611 : output(Key);
772 84611 : output(": ");
773 84611 : }
774 :
775 : //===----------------------------------------------------------------------===//
776 : // traits for built-in types
777 : //===----------------------------------------------------------------------===//
778 :
779 72464 : void ScalarTraits<bool>::output(const bool &Val, void *, raw_ostream &Out) {
780 134559 : Out << (Val ? "true" : "false");
781 72464 : }
782 :
783 18105 : StringRef ScalarTraits<bool>::input(StringRef Scalar, void *, bool &Val) {
784 : if (Scalar.equals("true")) {
785 7086 : Val = true;
786 7086 : return StringRef();
787 : } else if (Scalar.equals("false")) {
788 11019 : Val = false;
789 11019 : return StringRef();
790 : }
791 0 : return "invalid boolean";
792 : }
793 :
794 27232 : void ScalarTraits<StringRef>::output(const StringRef &Val, void *,
795 : raw_ostream &Out) {
796 27232 : Out << Val;
797 27232 : }
798 :
799 13947 : StringRef ScalarTraits<StringRef>::input(StringRef Scalar, void *,
800 : StringRef &Val) {
801 13947 : Val = Scalar;
802 13947 : return StringRef();
803 : }
804 :
805 23703 : void ScalarTraits<std::string>::output(const std::string &Val, void *,
806 : raw_ostream &Out) {
807 : Out << Val;
808 23703 : }
809 :
810 8375 : StringRef ScalarTraits<std::string>::input(StringRef Scalar, void *,
811 : std::string &Val) {
812 16750 : Val = Scalar.str();
813 8375 : return StringRef();
814 : }
815 :
816 7402 : 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 7402 : uint32_t Num = Val;
820 : Out << Num;
821 7402 : }
822 :
823 1303 : StringRef ScalarTraits<uint8_t>::input(StringRef Scalar, void *, uint8_t &Val) {
824 : unsigned long long n;
825 1303 : if (getAsUnsignedInteger(Scalar, 0, n))
826 0 : return "invalid number";
827 1303 : if (n > 0xFF)
828 1 : return "out of range number";
829 1302 : Val = n;
830 1302 : return StringRef();
831 : }
832 :
833 11848 : void ScalarTraits<uint16_t>::output(const uint16_t &Val, void *,
834 : raw_ostream &Out) {
835 11848 : Out << Val;
836 11848 : }
837 :
838 5451 : StringRef ScalarTraits<uint16_t>::input(StringRef Scalar, void *,
839 : uint16_t &Val) {
840 : unsigned long long n;
841 5451 : if (getAsUnsignedInteger(Scalar, 0, n))
842 0 : return "invalid number";
843 5451 : if (n > 0xFFFF)
844 1 : return "out of range number";
845 5450 : Val = n;
846 5450 : return StringRef();
847 : }
848 :
849 109929 : void ScalarTraits<uint32_t>::output(const uint32_t &Val, void *,
850 : raw_ostream &Out) {
851 109929 : Out << Val;
852 109929 : }
853 :
854 36469 : StringRef ScalarTraits<uint32_t>::input(StringRef Scalar, void *,
855 : uint32_t &Val) {
856 : unsigned long long n;
857 36469 : if (getAsUnsignedInteger(Scalar, 0, n))
858 1 : return "invalid number";
859 36468 : if (n > 0xFFFFFFFFUL)
860 1 : return "out of range number";
861 36467 : Val = n;
862 36467 : return StringRef();
863 : }
864 :
865 12775 : void ScalarTraits<uint64_t>::output(const uint64_t &Val, void *,
866 : raw_ostream &Out) {
867 12775 : Out << Val;
868 12775 : }
869 :
870 3773 : StringRef ScalarTraits<uint64_t>::input(StringRef Scalar, void *,
871 : uint64_t &Val) {
872 : unsigned long long N;
873 3773 : if (getAsUnsignedInteger(Scalar, 0, N))
874 1 : return "invalid number";
875 3772 : Val = N;
876 3772 : return StringRef();
877 : }
878 :
879 1 : 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 1 : int32_t Num = Val;
882 : Out << Num;
883 1 : }
884 :
885 10 : StringRef ScalarTraits<int8_t>::input(StringRef Scalar, void *, int8_t &Val) {
886 : long long N;
887 10 : if (getAsSignedInteger(Scalar, 0, N))
888 0 : return "invalid number";
889 10 : if ((N > 127) || (N < -128))
890 2 : return "out of range number";
891 8 : Val = N;
892 8 : return StringRef();
893 : }
894 :
895 2 : void ScalarTraits<int16_t>::output(const int16_t &Val, void *,
896 : raw_ostream &Out) {
897 2 : Out << Val;
898 2 : }
899 :
900 12 : StringRef ScalarTraits<int16_t>::input(StringRef Scalar, void *, int16_t &Val) {
901 : long long N;
902 12 : if (getAsSignedInteger(Scalar, 0, N))
903 0 : return "invalid number";
904 12 : if ((N > INT16_MAX) || (N < INT16_MIN))
905 2 : return "out of range number";
906 10 : Val = N;
907 10 : return StringRef();
908 : }
909 :
910 5714 : void ScalarTraits<int32_t>::output(const int32_t &Val, void *,
911 : raw_ostream &Out) {
912 5714 : Out << Val;
913 5714 : }
914 :
915 3983 : StringRef ScalarTraits<int32_t>::input(StringRef Scalar, void *, int32_t &Val) {
916 : long long N;
917 3983 : if (getAsSignedInteger(Scalar, 0, N))
918 0 : return "invalid number";
919 3983 : if ((N > INT32_MAX) || (N < INT32_MIN))
920 2 : return "out of range number";
921 3981 : Val = N;
922 3981 : return StringRef();
923 : }
924 :
925 1238 : void ScalarTraits<int64_t>::output(const int64_t &Val, void *,
926 : raw_ostream &Out) {
927 1238 : Out << Val;
928 1238 : }
929 :
930 518 : StringRef ScalarTraits<int64_t>::input(StringRef Scalar, void *, int64_t &Val) {
931 : long long N;
932 518 : if (getAsSignedInteger(Scalar, 0, N))
933 2 : return "invalid number";
934 516 : Val = N;
935 516 : return StringRef();
936 : }
937 :
938 8 : void ScalarTraits<double>::output(const double &Val, void *, raw_ostream &Out) {
939 16 : Out << format("%g", Val);
940 8 : }
941 :
942 23 : StringRef ScalarTraits<double>::input(StringRef Scalar, void *, double &Val) {
943 23 : if (to_float(Scalar, Val))
944 22 : return StringRef();
945 1 : return "invalid floating point number";
946 : }
947 :
948 2 : void ScalarTraits<float>::output(const float &Val, void *, raw_ostream &Out) {
949 4 : Out << format("%g", Val);
950 2 : }
951 :
952 8 : StringRef ScalarTraits<float>::input(StringRef Scalar, void *, float &Val) {
953 8 : if (to_float(Scalar, Val))
954 7 : return StringRef();
955 1 : return "invalid floating point number";
956 : }
957 :
958 399 : void ScalarTraits<Hex8>::output(const Hex8 &Val, void *, raw_ostream &Out) {
959 399 : uint8_t Num = Val;
960 399 : Out << format("0x%02X", Num);
961 399 : }
962 :
963 6248 : StringRef ScalarTraits<Hex8>::input(StringRef Scalar, void *, Hex8 &Val) {
964 : unsigned long long n;
965 6248 : if (getAsUnsignedInteger(Scalar, 0, n))
966 0 : return "invalid hex8 number";
967 6248 : if (n > 0xFF)
968 1 : return "out of range hex8 number";
969 6247 : Val = n;
970 6247 : return StringRef();
971 : }
972 :
973 12 : void ScalarTraits<Hex16>::output(const Hex16 &Val, void *, raw_ostream &Out) {
974 12 : uint16_t Num = Val;
975 12 : Out << format("0x%04X", Num);
976 12 : }
977 :
978 41 : StringRef ScalarTraits<Hex16>::input(StringRef Scalar, void *, Hex16 &Val) {
979 : unsigned long long n;
980 41 : if (getAsUnsignedInteger(Scalar, 0, n))
981 0 : return "invalid hex16 number";
982 41 : if (n > 0xFFFF)
983 1 : return "out of range hex16 number";
984 40 : Val = n;
985 40 : return StringRef();
986 : }
987 :
988 2587 : void ScalarTraits<Hex32>::output(const Hex32 &Val, void *, raw_ostream &Out) {
989 2587 : uint32_t Num = Val;
990 2587 : Out << format("0x%08X", Num);
991 2587 : }
992 :
993 2399 : StringRef ScalarTraits<Hex32>::input(StringRef Scalar, void *, Hex32 &Val) {
994 : unsigned long long n;
995 2399 : if (getAsUnsignedInteger(Scalar, 0, n))
996 0 : return "invalid hex32 number";
997 2399 : if (n > 0xFFFFFFFFUL)
998 1 : return "out of range hex32 number";
999 2398 : Val = n;
1000 2398 : return StringRef();
1001 : }
1002 :
1003 934 : void ScalarTraits<Hex64>::output(const Hex64 &Val, void *, raw_ostream &Out) {
1004 934 : uint64_t Num = Val;
1005 934 : Out << format("0x%016llX", Num);
1006 934 : }
1007 :
1008 3896 : StringRef ScalarTraits<Hex64>::input(StringRef Scalar, void *, Hex64 &Val) {
1009 : unsigned long long Num;
1010 3896 : if (getAsUnsignedInteger(Scalar, 0, Num))
1011 1 : return "invalid hex64 number";
1012 3895 : Val = Num;
1013 3895 : return StringRef();
1014 : }
|