aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/yaml-cpp/src/simplekey.cpp
blob: 4d8835c6e68a3a6509d3ef514c1cbfa14f56a151 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#include "scanner.h" 
#include "token.h" 
 
namespace YAML { 
struct Mark; 
 
Scanner::SimpleKey::SimpleKey(const Mark& mark_, std::size_t flowLevel_) 
    : mark(mark_), flowLevel(flowLevel_), pIndent(0), pMapStart(0), pKey(0) {} 
 
void Scanner::SimpleKey::Validate() { 
  // Note: pIndent will *not* be garbage here; 
  //       we "garbage collect" them so we can 
  //       always refer to them 
  if (pIndent) 
    pIndent->status = IndentMarker::VALID; 
  if (pMapStart) 
    pMapStart->status = Token::VALID; 
  if (pKey) 
    pKey->status = Token::VALID; 
} 
 
void Scanner::SimpleKey::Invalidate() { 
  if (pIndent) 
    pIndent->status = IndentMarker::INVALID; 
  if (pMapStart) 
    pMapStart->status = Token::INVALID; 
  if (pKey) 
    pKey->status = Token::INVALID; 
} 
 
// CanInsertPotentialSimpleKey 
bool Scanner::CanInsertPotentialSimpleKey() const { 
  if (!m_simpleKeyAllowed) 
    return false; 
 
  return !ExistsActiveSimpleKey(); 
} 
 
// ExistsActiveSimpleKey 
// . Returns true if there's a potential simple key at our flow level 
//   (there's allowed at most one per flow level, i.e., at the start of the flow 
// start token) 
bool Scanner::ExistsActiveSimpleKey() const { 
  if (m_simpleKeys.empty()) 
    return false; 
 
  const SimpleKey& key = m_simpleKeys.top(); 
  return key.flowLevel == GetFlowLevel(); 
} 
 
// InsertPotentialSimpleKey 
// . If we can, add a potential simple key to the queue, 
//   and save it on a stack. 
void Scanner::InsertPotentialSimpleKey() { 
  if (!CanInsertPotentialSimpleKey()) 
    return; 
 
  SimpleKey key(INPUT.mark(), GetFlowLevel()); 
 
  // first add a map start, if necessary 
  if (InBlockContext()) { 
    key.pIndent = PushIndentTo(INPUT.column(), IndentMarker::MAP); 
    if (key.pIndent) { 
      key.pIndent->status = IndentMarker::UNKNOWN; 
      key.pMapStart = key.pIndent->pStartToken; 
      key.pMapStart->status = Token::UNVERIFIED; 
    } 
  } 
 
  // then add the (now unverified) key 
  m_tokens.push(Token(Token::KEY, INPUT.mark())); 
  key.pKey = &m_tokens.back(); 
  key.pKey->status = Token::UNVERIFIED; 
 
  m_simpleKeys.push(key); 
} 
 
// InvalidateSimpleKey 
// . Automatically invalidate the simple key in our flow level 
void Scanner::InvalidateSimpleKey() { 
  if (m_simpleKeys.empty()) 
    return; 
 
  // grab top key 
  SimpleKey& key = m_simpleKeys.top(); 
  if (key.flowLevel != GetFlowLevel()) 
    return; 
 
  key.Invalidate(); 
  m_simpleKeys.pop(); 
} 
 
// VerifySimpleKey 
// . Determines whether the latest simple key to be added is valid, 
//   and if so, makes it valid. 
bool Scanner::VerifySimpleKey() { 
  if (m_simpleKeys.empty()) 
    return false; 
 
  // grab top key 
  SimpleKey key = m_simpleKeys.top(); 
 
  // only validate if we're in the correct flow level 
  if (key.flowLevel != GetFlowLevel()) 
    return false; 
 
  m_simpleKeys.pop(); 
 
  bool isValid = true; 
 
  // needs to be less than 1024 characters and inline 
  if (INPUT.line() != key.mark.line || INPUT.pos() - key.mark.pos > 1024) 
    isValid = false; 
 
  // invalidate key 
  if (isValid) 
    key.Validate(); 
  else 
    key.Invalidate(); 
 
  return isValid; 
} 
 
void Scanner::PopAllSimpleKeys() { 
  while (!m_simpleKeys.empty()) 
    m_simpleKeys.pop(); 
} 
}