llvm.org GIT mirror llvm / 8786570
YAMLIO: Allow scalars to dictate quotation rules Introduce ScalarTraits::mustQuote which determines whether or not a StringRef needs quoting before it is acceptable to output. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205955 91177308-0d34-0410-b5e6-96231b3b80d8 David Majnemer 6 years ago
7 changed file(s) with 159 addition(s) and 24 deletion(s). Raw diff Collapse all Expand all
425425 static StringRef input(StringRef scalar, T &value) {
426426 // do custom parsing here. Return the empty string on success,
427427 // or an error message on failure.
428 return StringRef();
429 }
428 return StringRef();
429 }
430 // Determine if this scalar needs quotes.
431 static bool mustQuote(StringRef) { return true; }
430432 };
431433
432434
107107 static void output(const object::yaml::BinaryRef &, void *,
108108 llvm::raw_ostream &);
109109 static StringRef input(StringRef, void *, object::yaml::BinaryRef &);
110 static bool mustQuote(StringRef S) { return needsQuotes(S); }
110111 };
111112 }
112113
1919 #include "llvm/ADT/StringSwitch.h"
2020 #include "llvm/ADT/Twine.h"
2121 #include "llvm/Support/Compiler.h"
22 #include "llvm/Support/Regex.h"
2223 #include "llvm/Support/SourceMgr.h"
2324 #include "llvm/Support/YAMLParser.h"
2425 #include "llvm/Support/raw_ostream.h"
9798 /// // return empty string on success, or error string
9899 /// return StringRef();
99100 /// }
101 /// static bool mustQuote(StringRef) { return true; }
100102 /// };
101103 template
102104 struct ScalarTraits {
108110 // Function to convert a string to a value. Returns the empty
109111 // StringRef on success or an error string if string is malformed:
110112 //static StringRef input(StringRef scalar, void *ctxt, T &value);
113 //
114 // Function to determine if the value should be quoted.
115 //static bool mustQuote(StringRef);
111116 };
112117
113118
197202 {
198203 typedef StringRef (*Signature_input)(StringRef, void*, T&);
199204 typedef void (*Signature_output)(const T&, void*, llvm::raw_ostream&);
200
201 template
202 static char test(SameType*,
203 SameType*);
205 typedef bool (*Signature_mustQuote)(StringRef);
206
207 template
208 static char test(SameType *,
209 SameType *,
210 SameType *);
204211
205212 template
206213 static double test(...);
207214
208215 public:
209216 static bool const value =
210 (sizeof(test >(nullptr,nullptr)) == 1);
217 (sizeof(test>(nullptr, nullptr, nullptr)) == 1);
211218 };
212219
213220
315322 static bool const value = (sizeof(test >(0)) == 1);
316323 };
317324
318
325 inline bool isNumber(StringRef S) {
326 static const char OctalChars[] = "01234567";
327 if (S.startswith("0") &&
328 S.drop_front().find_first_not_of(OctalChars) == StringRef::npos)
329 return true;
330
331 if (S.startswith("0o") &&
332 S.drop_front(2).find_first_not_of(OctalChars) == StringRef::npos)
333 return true;
334
335 static const char HexChars[] = "0123456789abcdefABCDEF";
336 if (S.startswith("0x") &&
337 S.drop_front(2).find_first_not_of(HexChars) == StringRef::npos)
338 return true;
339
340 static const char DecChars[] = "0123456789";
341 if (S.find_first_not_of(DecChars) == StringRef::npos)
342 return true;
343
344 if (S.equals(".inf") || S.equals(".Inf") || S.equals(".INF"))
345 return true;
346
347 Regex FloatMatcher("^(\\.[0-9]+|[0-9]+(\\.[0-9]*)?)([eE][-+]?[0-9]+)?$");
348 if (FloatMatcher.match(S))
349 return true;
350
351 return false;
352 }
353
354 inline bool isNumeric(StringRef S) {
355 if ((S.front() == '-' || S.front() == '+') && isNumber(S.drop_front()))
356 return true;
357
358 if (isNumber(S))
359 return true;
360
361 if (S.equals(".nan") || S.equals(".NaN") || S.equals(".NAN"))
362 return true;
363
364 return false;
365 }
366
367 inline bool isNull(StringRef S) {
368 return S.equals("null") || S.equals("Null") || S.equals("NULL") ||
369 S.equals("~");
370 }
371
372 inline bool isBool(StringRef S) {
373 return S.equals("true") || S.equals("True") || S.equals("TRUE") ||
374 S.equals("false") || S.equals("False") || S.equals("FALSE");
375 }
376
377 inline bool needsQuotes(StringRef S) {
378 if (S.empty())
379 return true;
380 if (isspace(S.front()) || isspace(S.back()))
381 return true;
382 if (S.front() == ',')
383 return true;
384
385 static const char ScalarSafeChars[] =
386 "abcdefghijklmnopqrstuvwxyz"
387 "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-/^., \t";
388 if (S.find_first_not_of(ScalarSafeChars) != StringRef::npos)
389 return true;
390
391 if (isNull(S))
392 return true;
393 if (isBool(S))
394 return true;
395 if (isNumeric(S))
396 return true;
397
398 return false;
399 }
319400
320401
321402 template
370451 virtual bool bitSetMatch(const char*, bool) = 0;
371452 virtual void endBitSetScalar() = 0;
372453
373 virtual void scalarString(StringRef &) = 0;
454 virtual void scalarString(StringRef &, bool) = 0;
374455
375456 virtual void setError(const Twine &) = 0;
376457
520601 llvm::raw_string_ostream Buffer(Storage);
521602 ScalarTraits::output(Val, io.getContext(), Buffer);
522603 StringRef Str = Buffer.str();
523 io.scalarString(Str);
604 io.scalarString(Str, ScalarTraits::mustQuote(Str));
524605 }
525606 else {
526607 StringRef Str;
527 io.scalarString(Str);
608 io.scalarString(Str, ScalarTraits::mustQuote(Str));
528609 StringRef Result = ScalarTraits::input(Str, io.getContext(), Val);
529610 if ( !Result.empty() ) {
530611 io.setError(llvm::Twine(Result));
601682 struct ScalarTraits {
602683 static void output(const bool &, void*, llvm::raw_ostream &);
603684 static StringRef input(StringRef, void*, bool &);
685 static bool mustQuote(StringRef) { return false; }
604686 };
605687
606688 template<>
607689 struct ScalarTraits {
608690 static void output(const StringRef &, void*, llvm::raw_ostream &);
609691 static StringRef input(StringRef, void*, StringRef &);
692 static bool mustQuote(StringRef S) { return needsQuotes(S); }
610693 };
611694
612695 template<>
613696 struct ScalarTraits {
614697 static void output(const std::string &, void*, llvm::raw_ostream &);
615698 static StringRef input(StringRef, void*, std::string &);
699 static bool mustQuote(StringRef S) { return needsQuotes(S); }
616700 };
617701
618702 template<>
619703 struct ScalarTraits {
620704 static void output(const uint8_t &, void*, llvm::raw_ostream &);
621705 static StringRef input(StringRef, void*, uint8_t &);
706 static bool mustQuote(StringRef) { return false; }
622707 };
623708
624709 template<>
625710 struct ScalarTraits {
626711 static void output(const uint16_t &, void*, llvm::raw_ostream &);
627712 static StringRef input(StringRef, void*, uint16_t &);
713 static bool mustQuote(StringRef) { return false; }
628714 };
629715
630716 template<>
631717 struct ScalarTraits {
632718 static void output(const uint32_t &, void*, llvm::raw_ostream &);
633719 static StringRef input(StringRef, void*, uint32_t &);
720 static bool mustQuote(StringRef) { return false; }
634721 };
635722
636723 template<>
637724 struct ScalarTraits {
638725 static void output(const uint64_t &, void*, llvm::raw_ostream &);
639726 static StringRef input(StringRef, void*, uint64_t &);
727 static bool mustQuote(StringRef) { return false; }
640728 };
641729
642730 template<>
643731 struct ScalarTraits {
644732 static void output(const int8_t &, void*, llvm::raw_ostream &);
645733 static StringRef input(StringRef, void*, int8_t &);
734 static bool mustQuote(StringRef) { return false; }
646735 };
647736
648737 template<>
649738 struct ScalarTraits {
650739 static void output(const int16_t &, void*, llvm::raw_ostream &);
651740 static StringRef input(StringRef, void*, int16_t &);
741 static bool mustQuote(StringRef) { return false; }
652742 };
653743
654744 template<>
655745 struct ScalarTraits {
656746 static void output(const int32_t &, void*, llvm::raw_ostream &);
657747 static StringRef input(StringRef, void*, int32_t &);
748 static bool mustQuote(StringRef) { return false; }
658749 };
659750
660751 template<>
661752 struct ScalarTraits {
662753 static void output(const int64_t &, void*, llvm::raw_ostream &);
663754 static StringRef input(StringRef, void*, int64_t &);
755 static bool mustQuote(StringRef) { return false; }
664756 };
665757
666758 template<>
667759 struct ScalarTraits {
668760 static void output(const float &, void*, llvm::raw_ostream &);
669761 static StringRef input(StringRef, void*, float &);
762 static bool mustQuote(StringRef) { return false; }
670763 };
671764
672765 template<>
673766 struct ScalarTraits {
674767 static void output(const double &, void*, llvm::raw_ostream &);
675768 static StringRef input(StringRef, void*, double &);
769 static bool mustQuote(StringRef) { return false; }
676770 };
677771
678772
794888 bool beginBitSetScalar(bool &) override;
795889 bool bitSetMatch(const char *, bool ) override;
796890 void endBitSetScalar() override;
797 void scalarString(StringRef &) override;
891 void scalarString(StringRef &, bool) override;
798892 void setError(const Twine &message) override;
799893 bool canElideEmptySequence() override;
800894
9191013 bool beginBitSetScalar(bool &) override;
9201014 bool bitSetMatch(const char *, bool ) override;
9211015 void endBitSetScalar() override;
922 void scalarString(StringRef &) override;
1016 void scalarString(StringRef &, bool) override;
9231017 void setError(const Twine &message) override;
9241018 bool canElideEmptySequence() override;
9251019 public:
9901084 struct ScalarTraits {
9911085 static void output(const Hex8 &, void*, llvm::raw_ostream &);
9921086 static StringRef input(StringRef, void*, Hex8 &);
1087 static bool mustQuote(StringRef) { return false; }
9931088 };
9941089
9951090 template<>
9961091 struct ScalarTraits {
9971092 static void output(const Hex16 &, void*, llvm::raw_ostream &);
9981093 static StringRef input(StringRef, void*, Hex16 &);
1094 static bool mustQuote(StringRef) { return false; }
9991095 };
10001096
10011097 template<>
10021098 struct ScalarTraits {
10031099 static void output(const Hex32 &, void*, llvm::raw_ostream &);
10041100 static StringRef input(StringRef, void*, Hex32 &);
1101 static bool mustQuote(StringRef) { return false; }
10051102 };
10061103
10071104 template<>
10081105 struct ScalarTraits {
10091106 static void output(const Hex64 &, void*, llvm::raw_ostream &);
10101107 static StringRef input(StringRef, void*, Hex64 &);
1108 static bool mustQuote(StringRef) { return false; }
10111109 };
10121110
10131111
161161 static void output(const MCModuleYAML::Operand &, void *,
162162 llvm::raw_ostream &);
163163 static StringRef input(StringRef, void *, MCModuleYAML::Operand &);
164 static bool mustQuote(StringRef) { return false; }
164165 };
165166
166167 template <> struct ScalarTraits {
167168 static void output(const MCModuleYAML::OpcodeEnum &, void *,
168169 llvm::raw_ostream &);
169170 static StringRef input(StringRef, void *, MCModuleYAML::OpcodeEnum &);
171 static bool mustQuote(StringRef) { return false; }
170172 };
171173
172174 void ScalarEnumerationTraits::enumeration(
284284 }
285285 }
286286
287 void Input::scalarString(StringRef &S) {
287 void Input::scalarString(StringRef &S, bool) {
288288 if (ScalarHNode *SN = dyn_cast(CurrentNode)) {
289289 S = SN->value();
290290 } else {
540540 this->outputUpToEndOfLine(" ]");
541541 }
542542
543 void Output::scalarString(StringRef &S) {
544 const char ScalarSafeChars[] = "abcdefghijklmnopqrstuvwxyz"
545 "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-/^., \t";
546
543 void Output::scalarString(StringRef &S, bool MustQuote) {
547544 this->newLineCheck();
548545 if (S.empty()) {
549546 // Print '' for the empty string because leaving the field empty is not
551548 this->outputUpToEndOfLine("''");
552549 return;
553550 }
554 bool isOctalString = S.front() == '0' && S.size() > 2 && !S.startswith("0x");
555 if (S.find_first_not_of(ScalarSafeChars) == StringRef::npos &&
556 !isspace(S.front()) && !isspace(S.back()) && !isOctalString) {
557 // If the string consists only of safe characters, print it out without
558 // quotes.
551 if (!MustQuote) {
552 // Only quote if we must.
559553 this->outputUpToEndOfLine(S);
560554 return;
561555 }
3737 #CFG: Type: Data
3838
3939 ## 4: 06 (bad)
40 #CFG: Content: 06
40 #CFG: Content: '06'
4141
4242 #CFG: - StartAddress: 0x0000000000000005
4343 #CFG: Size: 1
302302 llvm::StringRef str4;
303303 llvm::StringRef str5;
304304 llvm::StringRef str6;
305 llvm::StringRef str7;
306 llvm::StringRef str8;
307 llvm::StringRef str9;
308 llvm::StringRef str10;
309 llvm::StringRef str11;
305310 std::string stdstr1;
306311 std::string stdstr2;
307312 std::string stdstr3;
308313 std::string stdstr4;
309314 std::string stdstr5;
310315 std::string stdstr6;
316 std::string stdstr7;
317 std::string stdstr8;
318 std::string stdstr9;
319 std::string stdstr10;
320 std::string stdstr11;
311321 };
312322
313323 namespace llvm {
321331 io.mapRequired("str4", st.str4);
322332 io.mapRequired("str5", st.str5);
323333 io.mapRequired("str6", st.str6);
334 io.mapRequired("str7", st.str7);
335 io.mapRequired("str8", st.str8);
336 io.mapRequired("str9", st.str9);
337 io.mapRequired("str10", st.str10);
338 io.mapRequired("str11", st.str11);
324339 io.mapRequired("stdstr1", st.stdstr1);
325340 io.mapRequired("stdstr2", st.stdstr2);
326341 io.mapRequired("stdstr3", st.stdstr3);
327342 io.mapRequired("stdstr4", st.stdstr4);
328343 io.mapRequired("stdstr5", st.stdstr5);
329344 io.mapRequired("stdstr6", st.stdstr6);
345 io.mapRequired("stdstr7", st.stdstr7);
346 io.mapRequired("stdstr8", st.stdstr8);
347 io.mapRequired("stdstr9", st.stdstr9);
348 io.mapRequired("stdstr10", st.stdstr10);
349 io.mapRequired("stdstr11", st.stdstr11);
330350 }
331351 };
332352 }
342362 map.str4 = "@ddd";
343363 map.str5 = "";
344364 map.str6 = "0000000004000000";
365 map.str7 = "true";
366 map.str8 = "FALSE";
367 map.str9 = "~";
368 map.str10 = "0.2e20";
369 map.str11 = "0x30";
345370 map.stdstr1 = "'eee";
346371 map.stdstr2 = "\"fff";
347372 map.stdstr3 = "`ggg";
348373 map.stdstr4 = "@hhh";
349374 map.stdstr5 = "";
350375 map.stdstr6 = "0000000004000000";
376 map.stdstr7 = "true";
377 map.stdstr8 = "FALSE";
378 map.stdstr9 = "~";
379 map.stdstr10 = "0.2e20";
380 map.stdstr11 = "0x30";
351381
352382 llvm::raw_string_ostream ostr(intermediate);
353383 Output yout(ostr);
361391 EXPECT_NE(llvm::StringRef::npos, flowOut.find("'@ddd'"));
362392 EXPECT_NE(llvm::StringRef::npos, flowOut.find("''\n"));
363393 EXPECT_NE(llvm::StringRef::npos, flowOut.find("'0000000004000000'\n"));
394 EXPECT_NE(llvm::StringRef::npos, flowOut.find("'true'\n"));
395 EXPECT_NE(llvm::StringRef::npos, flowOut.find("'FALSE'\n"));
396 EXPECT_NE(llvm::StringRef::npos, flowOut.find("'~'\n"));
397 EXPECT_NE(llvm::StringRef::npos, flowOut.find("'0.2e20'\n"));
398 EXPECT_NE(llvm::StringRef::npos, flowOut.find("'0x30'\n"));
364399 EXPECT_NE(std::string::npos, flowOut.find("'''eee"));
365400 EXPECT_NE(std::string::npos, flowOut.find("'\"fff'"));
366401 EXPECT_NE(std::string::npos, flowOut.find("'`ggg'"));
611646 return "malformed by";
612647 }
613648 }
649 static bool mustQuote(StringRef) { return true; }
614650 };
615651 }
616652 }
672708 value = n;
673709 return StringRef();
674710 }
711
712 static bool mustQuote(StringRef) { return false; }
675713 };
676714 }
677715 }