12
12
13
13
#include " llvm/ADT/Optional.h"
14
14
#include " llvm/ADT/SmallVector.h"
15
+ #include " llvm/ADT/StringExtras.h"
15
16
#include " llvm/ADT/StringMap.h"
16
17
#include " llvm/ADT/StringRef.h"
17
18
#include " llvm/ADT/Twine.h"
@@ -117,6 +118,11 @@ struct ScalarBitSetTraits {
117
118
// static void bitset(IO &io, T &value);
118
119
};
119
120
121
+ // / Describe which type of quotes should be used when quoting is necessary.
122
+ // / Some non-printable characters need to be double-quoted, while some others
123
+ // / are fine with simple-quoting, and some don't need any quoting.
124
+ enum class QuotingType { None, Single, Double };
125
+
120
126
// / This class should be specialized by type that requires custom conversion
121
127
// / to/from a yaml scalar. For example:
122
128
// /
@@ -131,7 +137,7 @@ struct ScalarBitSetTraits {
131
137
// / // return empty string on success, or error string
132
138
// / return StringRef();
133
139
// / }
134
- // / static bool mustQuote(StringRef) { return true ; }
140
+ // / static QuotingType mustQuote(StringRef) { return QuotingType::Single ; }
135
141
// / };
136
142
template <typename T>
137
143
struct ScalarTraits {
@@ -145,7 +151,7 @@ struct ScalarTraits {
145
151
// static StringRef input(StringRef scalar, void *ctxt, T &value);
146
152
//
147
153
// Function to determine if the value should be quoted.
148
- // static bool mustQuote(StringRef);
154
+ // static QuotingType mustQuote(StringRef);
149
155
};
150
156
151
157
// / This class should be specialized by type that requires custom conversion
@@ -270,7 +276,7 @@ struct has_ScalarTraits
270
276
{
271
277
using Signature_input = StringRef (*)(StringRef, void *, T&);
272
278
using Signature_output = void (*)(const T&, void *, raw_ostream&);
273
- using Signature_mustQuote = bool (*)(StringRef);
279
+ using Signature_mustQuote = QuotingType (*)(StringRef);
274
280
275
281
template <typename U>
276
282
static char test (SameType<Signature_input, &U::input> *,
@@ -495,28 +501,66 @@ inline bool isBool(StringRef S) {
495
501
S.equals (" false" ) || S.equals (" False" ) || S.equals (" FALSE" );
496
502
}
497
503
498
- inline bool needsQuotes (StringRef S) {
504
+ // 5.1. Character Set
505
+ // The allowed character range explicitly excludes the C0 control block #x0-#x1F
506
+ // (except for TAB #x9, LF #xA, and CR #xD which are allowed), DEL #x7F, the C1
507
+ // control block #x80-#x9F (except for NEL #x85 which is allowed), the surrogate
508
+ // block #xD800-#xDFFF, #xFFFE, and #xFFFF.
509
+ inline QuotingType needsQuotes (StringRef S) {
499
510
if (S.empty ())
500
- return true ;
511
+ return QuotingType::Single ;
501
512
if (isspace (S.front ()) || isspace (S.back ()))
502
- return true ;
513
+ return QuotingType::Single ;
503
514
if (S.front () == ' ,' )
504
- return true ;
505
-
506
- static const char ScalarSafeChars[] =
507
- " abcdefghijklmnopqrstuvwxyz"
508
- " ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-/^., \t " ;
509
- if (S.find_first_not_of (ScalarSafeChars) != StringRef::npos)
510
- return true ;
511
-
515
+ return QuotingType::Single;
512
516
if (isNull (S))
513
- return true ;
517
+ return QuotingType::Single ;
514
518
if (isBool (S))
515
- return true ;
519
+ return QuotingType::Single ;
516
520
if (isNumeric (S))
517
- return true ;
521
+ return QuotingType::Single;
522
+
523
+ QuotingType MaxQuotingNeeded = QuotingType::None;
524
+ for (unsigned char C : S) {
525
+ // Alphanum is safe.
526
+ if (isAlnum (C))
527
+ continue ;
528
+
529
+ switch (C) {
530
+ // Safe scalar characters.
531
+ case ' _' :
532
+ case ' -' :
533
+ case ' /' :
534
+ case ' ^' :
535
+ case ' .' :
536
+ case ' ,' :
537
+ case ' ' :
538
+ // TAB (0x9), LF (0xA), CR (0xD) and NEL (0x85) are allowed.
539
+ case 0x9 :
540
+ case 0xA :
541
+ case 0xD :
542
+ case 0x85 :
543
+ continue ;
544
+ // DEL (0x7F) are excluded from the allowed character range.
545
+ case 0x7F :
546
+ return QuotingType::Double;
547
+ default : {
548
+ // C0 control block (0x0 - 0x1F) is excluded from the allowed character
549
+ // range.
550
+ if (C <= 0x1F )
551
+ return QuotingType::Double;
552
+ // C1 control block (0x80 - 0x9F) is excluded from the allowed character
553
+ // range.
554
+ if (C >= 0x80 && C <= 0x9F )
555
+ return QuotingType::Double;
556
+
557
+ // The character is not safe, at least simple quoting needed.
558
+ MaxQuotingNeeded = QuotingType::Single;
559
+ }
560
+ }
561
+ }
518
562
519
- return false ;
563
+ return MaxQuotingNeeded ;
520
564
}
521
565
522
566
template <typename T, typename Context>
@@ -581,7 +625,7 @@ class IO {
581
625
virtual bool bitSetMatch (const char *, bool ) = 0;
582
626
virtual void endBitSetScalar () = 0;
583
627
584
- virtual void scalarString (StringRef &, bool ) = 0;
628
+ virtual void scalarString (StringRef &, QuotingType ) = 0;
585
629
virtual void blockScalarString (StringRef &) = 0;
586
630
587
631
virtual void setError (const Twine &) = 0;
@@ -911,91 +955,91 @@ template<>
911
955
struct ScalarTraits <bool > {
912
956
static void output (const bool &, void * , raw_ostream &);
913
957
static StringRef input (StringRef, void *, bool &);
914
- static bool mustQuote (StringRef) { return false ; }
958
+ static QuotingType mustQuote (StringRef) { return QuotingType::None ; }
915
959
};
916
960
917
961
template <>
918
962
struct ScalarTraits <StringRef> {
919
963
static void output (const StringRef &, void *, raw_ostream &);
920
964
static StringRef input (StringRef, void *, StringRef &);
921
- static bool mustQuote (StringRef S) { return needsQuotes (S); }
965
+ static QuotingType mustQuote (StringRef S) { return needsQuotes (S); }
922
966
};
923
967
924
968
template <>
925
969
struct ScalarTraits <std::string> {
926
970
static void output (const std::string &, void *, raw_ostream &);
927
971
static StringRef input (StringRef, void *, std::string &);
928
- static bool mustQuote (StringRef S) { return needsQuotes (S); }
972
+ static QuotingType mustQuote (StringRef S) { return needsQuotes (S); }
929
973
};
930
974
931
975
template <>
932
976
struct ScalarTraits <uint8_t > {
933
977
static void output (const uint8_t &, void *, raw_ostream &);
934
978
static StringRef input (StringRef, void *, uint8_t &);
935
- static bool mustQuote (StringRef) { return false ; }
979
+ static QuotingType mustQuote (StringRef) { return QuotingType::None ; }
936
980
};
937
981
938
982
template <>
939
983
struct ScalarTraits <uint16_t > {
940
984
static void output (const uint16_t &, void *, raw_ostream &);
941
985
static StringRef input (StringRef, void *, uint16_t &);
942
- static bool mustQuote (StringRef) { return false ; }
986
+ static QuotingType mustQuote (StringRef) { return QuotingType::None ; }
943
987
};
944
988
945
989
template <>
946
990
struct ScalarTraits <uint32_t > {
947
991
static void output (const uint32_t &, void *, raw_ostream &);
948
992
static StringRef input (StringRef, void *, uint32_t &);
949
- static bool mustQuote (StringRef) { return false ; }
993
+ static QuotingType mustQuote (StringRef) { return QuotingType::None ; }
950
994
};
951
995
952
996
template <>
953
997
struct ScalarTraits <uint64_t > {
954
998
static void output (const uint64_t &, void *, raw_ostream &);
955
999
static StringRef input (StringRef, void *, uint64_t &);
956
- static bool mustQuote (StringRef) { return false ; }
1000
+ static QuotingType mustQuote (StringRef) { return QuotingType::None ; }
957
1001
};
958
1002
959
1003
template <>
960
1004
struct ScalarTraits <int8_t > {
961
1005
static void output (const int8_t &, void *, raw_ostream &);
962
1006
static StringRef input (StringRef, void *, int8_t &);
963
- static bool mustQuote (StringRef) { return false ; }
1007
+ static QuotingType mustQuote (StringRef) { return QuotingType::None ; }
964
1008
};
965
1009
966
1010
template <>
967
1011
struct ScalarTraits <int16_t > {
968
1012
static void output (const int16_t &, void *, raw_ostream &);
969
1013
static StringRef input (StringRef, void *, int16_t &);
970
- static bool mustQuote (StringRef) { return false ; }
1014
+ static QuotingType mustQuote (StringRef) { return QuotingType::None ; }
971
1015
};
972
1016
973
1017
template <>
974
1018
struct ScalarTraits <int32_t > {
975
1019
static void output (const int32_t &, void *, raw_ostream &);
976
1020
static StringRef input (StringRef, void *, int32_t &);
977
- static bool mustQuote (StringRef) { return false ; }
1021
+ static QuotingType mustQuote (StringRef) { return QuotingType::None ; }
978
1022
};
979
1023
980
1024
template <>
981
1025
struct ScalarTraits <int64_t > {
982
1026
static void output (const int64_t &, void *, raw_ostream &);
983
1027
static StringRef input (StringRef, void *, int64_t &);
984
- static bool mustQuote (StringRef) { return false ; }
1028
+ static QuotingType mustQuote (StringRef) { return QuotingType::None ; }
985
1029
};
986
1030
987
1031
template <>
988
1032
struct ScalarTraits <float > {
989
1033
static void output (const float &, void *, raw_ostream &);
990
1034
static StringRef input (StringRef, void *, float &);
991
- static bool mustQuote (StringRef) { return false ; }
1035
+ static QuotingType mustQuote (StringRef) { return QuotingType::None ; }
992
1036
};
993
1037
994
1038
template <>
995
1039
struct ScalarTraits <double > {
996
1040
static void output (const double &, void *, raw_ostream &);
997
1041
static StringRef input (StringRef, void *, double &);
998
- static bool mustQuote (StringRef) { return false ; }
1042
+ static QuotingType mustQuote (StringRef) { return QuotingType::None ; }
999
1043
};
1000
1044
1001
1045
// For endian types, we just use the existing ScalarTraits for the underlying
@@ -1019,7 +1063,7 @@ struct ScalarTraits<support::detail::packed_endian_specific_integral<
1019
1063
return R;
1020
1064
}
1021
1065
1022
- static bool mustQuote (StringRef Str) {
1066
+ static QuotingType mustQuote (StringRef Str) {
1023
1067
return ScalarTraits<value_type>::mustQuote (Str);
1024
1068
}
1025
1069
};
@@ -1148,7 +1192,7 @@ class Input : public IO {
1148
1192
bool beginBitSetScalar (bool &) override ;
1149
1193
bool bitSetMatch (const char *, bool ) override ;
1150
1194
void endBitSetScalar () override ;
1151
- void scalarString (StringRef &, bool ) override ;
1195
+ void scalarString (StringRef &, QuotingType ) override ;
1152
1196
void blockScalarString (StringRef &) override ;
1153
1197
void setError (const Twine &message) override ;
1154
1198
bool canElideEmptySequence () override ;
@@ -1293,7 +1337,7 @@ class Output : public IO {
1293
1337
bool beginBitSetScalar (bool &) override ;
1294
1338
bool bitSetMatch (const char *, bool ) override ;
1295
1339
void endBitSetScalar () override ;
1296
- void scalarString (StringRef &, bool ) override ;
1340
+ void scalarString (StringRef &, QuotingType ) override ;
1297
1341
void blockScalarString (StringRef &) override ;
1298
1342
void setError (const Twine &message) override ;
1299
1343
bool canElideEmptySequence () override ;
@@ -1371,28 +1415,28 @@ template<>
1371
1415
struct ScalarTraits<Hex8> {
1372
1416
static void output (const Hex8 &, void *, raw_ostream &);
1373
1417
static StringRef input (StringRef, void *, Hex8 &);
1374
- static bool mustQuote (StringRef) { return false ; }
1418
+ static QuotingType mustQuote (StringRef) { return QuotingType::None ; }
1375
1419
};
1376
1420
1377
1421
template <>
1378
1422
struct ScalarTraits <Hex16> {
1379
1423
static void output (const Hex16 &, void *, raw_ostream &);
1380
1424
static StringRef input (StringRef, void *, Hex16 &);
1381
- static bool mustQuote (StringRef) { return false ; }
1425
+ static QuotingType mustQuote (StringRef) { return QuotingType::None ; }
1382
1426
};
1383
1427
1384
1428
template <>
1385
1429
struct ScalarTraits <Hex32> {
1386
1430
static void output (const Hex32 &, void *, raw_ostream &);
1387
1431
static StringRef input (StringRef, void *, Hex32 &);
1388
- static bool mustQuote (StringRef) { return false ; }
1432
+ static QuotingType mustQuote (StringRef) { return QuotingType::None ; }
1389
1433
};
1390
1434
1391
1435
template <>
1392
1436
struct ScalarTraits <Hex64> {
1393
1437
static void output (const Hex64 &, void *, raw_ostream &);
1394
1438
static StringRef input (StringRef, void *, Hex64 &);
1395
- static bool mustQuote (StringRef) { return false ; }
1439
+ static QuotingType mustQuote (StringRef) { return QuotingType::None ; }
1396
1440
};
1397
1441
1398
1442
// Define non-member operator>> so that Input can stream in a document list.
@@ -1681,7 +1725,7 @@ template <typename T> struct StdMapStringCustomMappingTraitsImpl {
1681
1725
template <> struct ScalarTraits <Type> { \
1682
1726
static void output (const Type &Value, void *ctx, raw_ostream &Out); \
1683
1727
static StringRef input (StringRef Scalar, void *ctxt, Type &Value); \
1684
- static bool mustQuote (StringRef) { return MustQuote; } \
1728
+ static QuotingType mustQuote (StringRef) { return MustQuote; } \
1685
1729
}; \
1686
1730
} \
1687
1731
}
0 commit comments