rapidyaml  0.16.0
parseandemitYAML,anddoitfast
scalar_style.cpp
Go to the documentation of this file.
1 #ifndef C4_YML_SCALAR_STYLE_HPP_
3 #endif
4 #ifndef C4_YML_SCALAR_CHARCONV_HPP_
6 #endif
7 #ifndef C4_YML_ERROR_HPP_
8 #include "c4/yml/error.hpp"
9 #endif
10 
11 
12 namespace c4 {
13 namespace yml {
14 
15 bool scalar_style_query_squo(csubstr scalar) noexcept
16 {
17  // see https://www.yaml.info/learn/quote.html#noplain
18  // cannot have leading whitespace after a newline
19  for(size_t i = 0; i < scalar.len; ++i)
20  {
21  if(scalar.str[i] == '\n' && i + 1 < scalar.len)
22  {
23  char next = scalar.str[i + 1];
24  if(next == ' ' || next == '\t')
25  return false;
26  }
27  }
28  return true;
29 }
30 
31 
32 namespace {
33 bool is_wsnl_(char c) noexcept
34 {
35  return c == ' ' || c == '\n' || c == '\t' || c == '\r';
36 }
37 bool is_valid_bulk_(csubstr s, size_t i)
38 {
39  C4_ASSERT(i >= 1 && i+1 < s.len);
40  C4_ASSERT(s.str[i] == ':' || s.str[i] == '#');
41  switch(s.str[i])
42  {
43  case ':': return !is_wsnl_(s.str[i+1]);
44  case '#': return !is_wsnl_(s.str[i-1]);
45  }
46  C4_UNREACHABLE(); // LCOV_EXCL_LINE
47 }
48 } // namespace
49 
50 
52 {
53  // see https://www.yaml.info/learn/quote.html#noplain
54  if(!scalar.len)
55  return !scalar.str;
56  // first
57  switch(scalar.str[0])
58  {
59  case ' ': case '\n': case '\t': case '\r':
60  case '!': case '&': case '*': case ',':
61  case '"': case '\'': case '|': case '>':
62  case '{': case '}': case '[': case ']':
63  case '#': case '`': case '%': case '@':
64  return false;
65  case '-': case ':': case '?':
66  if(scalar.len == 1 || (scalar.str[1] == ' ' || scalar.str[1] == '\t'))
67  return false;
68  break;
69  }
70  // bulk
71  for(size_t i = 1; i + 1 < scalar.len; ++i)
72  {
73  switch(scalar.str[i])
74  {
75  case ',': case '{': case '}': case '[': case ']':
76  return false;
77  case ':': case '#':
78  if(!is_valid_bulk_(scalar, i))
79  return false;
80  break;
81  }
82  }
83  // last
84  if(scalar.len > 1)
85  {
86  switch(scalar.back())
87  {
88  case ' ': case '\n': case '\t': case '\r':
89  case ',':
90  case '{': case '}':
91  case '[': case ']':
92  case '#':
93  case ':':
94  return false;
95  }
96  }
97  return true;
98 }
99 
100 
102 {
103  // see https://www.yaml.info/learn/quote.html#noplain
104  if(!scalar.len)
105  return !scalar.str;
106  // first
107  switch(scalar.str[0])
108  {
109  case ' ': case '\n': case '\t': case '\r':
110  case '!': case '&': case '*': case ',':
111  case '"': case '\'': case '|': case '>':
112  case '{': case '}': case '[': case ']':
113  case '#': case '`': case '%': case '@':
114  return false;
115  case '-': case ':': case '?':
116  if (scalar.len == 1 || (scalar.str[1] == ' ' || scalar.str[1] == '\t'))
117  return false;
118  break;
119  }
120  // bulk
121  for(size_t i = 1; i + 1 < scalar.len; ++i)
122  {
123  switch(scalar.str[i])
124  {
125  case ':': case '#':
126  if(!is_valid_bulk_(scalar, i))
127  return false;
128  break;
129  }
130  }
131  // last
132  if(scalar.len > 1)
133  {
134  switch(scalar.back())
135  {
136  case ' ': case '\n': case '\t': case '\r':
137  case '#':
138  case ':':
139  return false;
140  }
141  }
142  return true;
143 }
144 
145 
147 {
148  if(scalar.len)
149  {
151  return SCALAR_PLAIN;
152  RYML_ASSERT_BASIC_(scalar_style_query_squo(scalar)
153  && "if this assertion fires, please submit an issue!");
154  return SCALAR_SQUO;
155  }
156  return scalar.str ? SCALAR_SQUO : SCALAR_PLAIN;
157 }
158 
159 
161 {
162  // do not quote numbers or special scalars
163  return scalar_is_plain_number_json(scalar)
165 }
166 
167 } // namespace yml
168 } // namespace c4
bool scalar_style_query_plain_block(csubstr scalar) noexcept
query whether a scalar can be encoded using plain style while in block mode.
bool scalar_style_query_squo(csubstr scalar) noexcept
query whether a scalar can be encoded using single quotes.
NodeType scalar_style_choose_json(csubstr scalar) noexcept
choose a json scalar style based on the scalar's contents
bool scalar_is_plain_number_json(csubstr s) noexcept
JSON-sense query of plain number.
mask of KEY_SQUO|VAL_SQUO,
Definition: node_type.hpp:171
basic_substring< const char > csubstr
an immutable string view
Definition: substr.hpp:2356
mask of KEY_PLAIN|VAL_PLAIN,
Definition: node_type.hpp:173
bool scalar_is_special_json(csubstr s) noexcept
Query if a scalar is plain, eg, true, false, null, +-.inf or .nan.
Error utilities used by ryml.
mask of KEY_DQUO|VAL_DQUO,
Definition: node_type.hpp:172
NodeType scalar_style_choose_block(csubstr scalar) noexcept
choose a YAML scalar style based on the scalar's contents, while in block mode.
Wraps a type_bits mask of NodeTypeBits flags with some syntactic sugar and predicates.
Definition: node_type.hpp:213
bool scalar_style_query_plain_flow(csubstr scalar) noexcept
query whether a scalar can be encoded using plain style while in flow mode.