"test/main.cpp" did not exist on "cc87c83b01b19feeee3f3f9e446d1771110b1dd2"
simplekey.cpp 2.65 KB
Newer Older
1
2
3
4
5
6
7
8
#include "crt.h"
#include "scanner.h"
#include "token.h"
#include "exceptions.h"
#include "exp.h"

namespace YAML
{
9
	Scanner::SimpleKey::SimpleKey(const Mark& mark_, int flowLevel_)
10
		: mark(mark_), flowLevel(flowLevel_), pIndent(0), pMapStart(0), pKey(0)
11
12
13
14
15
	{
	}

	void Scanner::SimpleKey::Validate()
	{
16
17
18
		// Note: pIndent will *not* be garbage here; see below
		if(pIndent)
			pIndent->isValid = true;
19
		if(pMapStart)
jbeder's avatar
jbeder committed
20
			pMapStart->status = Token::VALID;
21
		if(pKey)
jbeder's avatar
jbeder committed
22
			pKey->status = Token::VALID;
23
24
25
26
	}

	void Scanner::SimpleKey::Invalidate()
	{
27
28
		// Note: pIndent might be a garbage pointer here, but that's ok
		//       An indent will only be popped if the simple key is invalid
29
		if(pMapStart)
jbeder's avatar
jbeder committed
30
			pMapStart->status = Token::INVALID;
31
		if(pKey)
jbeder's avatar
jbeder committed
32
			pKey->status = Token::INVALID;
33
34
35
36
37
38
39
	}

	// InsertSimpleKey
	// . Adds a potential simple key to the queue,
	//   and saves it on a stack.
	void Scanner::InsertSimpleKey()
	{
40
		SimpleKey key(INPUT.mark(), m_flowLevel);
41
42

		// first add a map start, if necessary
43
44
45
46
		key.pIndent = PushIndentTo(INPUT.column(), IndentMarker::MAP);
		if(key.pIndent) {
			key.pIndent->isValid = false;
			key.pMapStart = key.pIndent->pStartToken;
jbeder's avatar
jbeder committed
47
			key.pMapStart->status = Token::UNVERIFIED;
48
		}
49
50

		// then add the (now unverified) key
jbeder's avatar
jbeder committed
51
		m_tokens.push(Token(Token::KEY, INPUT.mark()));
52
		key.pKey = &m_tokens.back();
jbeder's avatar
jbeder committed
53
		key.pKey->status = Token::UNVERIFIED;
54
55
56
57
58
59
60

		m_simpleKeys.push(key);
	}

	// VerifySimpleKey
	// . Determines whether the latest simple key to be added is valid,
	//   and if so, makes it valid.
61
62
	// . If 'force' is true, then we'll pop no matter what (whether we can verify it or not).
	bool Scanner::VerifySimpleKey(bool force)
63
64
65
66
67
68
69
70
71
	{
		m_isLastKeyValid = false;
		if(m_simpleKeys.empty())
			return m_isLastKeyValid;

		// grab top key
		SimpleKey key = m_simpleKeys.top();

		// only validate if we're in the correct flow level
72
73
74
		if(key.flowLevel != m_flowLevel) {
			if(force)
				m_simpleKeys.pop();
75
			return false;
76
		}
77
78
79
80
81
82
83
84
85
86
87
88

		m_simpleKeys.pop();

		bool isValid = true;

		// needs to be followed immediately by a value
		if(m_flowLevel > 0 && !Exp::ValueInFlow.Matches(INPUT))
			isValid = false;
		if(m_flowLevel == 0 && !Exp::Value.Matches(INPUT))
			isValid = false;

		// also needs to be less than 1024 characters and inline
89
		if(INPUT.line() != key.mark.line || INPUT.pos() - key.mark.pos > 1024)
90
91
92
93
94
95
96
97
98
99
100
101
			isValid = false;

		// invalidate key
		if(isValid)
			key.Validate();
		else
			key.Invalidate();

		m_isLastKeyValid = isValid;
		return isValid;
	}

102
103
	// VerifyAllSimplyKeys
	// . Pops all simple keys (with checking, but if we can't verify one, then pop it anyways).
104
105
106
	void Scanner::VerifyAllSimpleKeys()
	{
		while(!m_simpleKeys.empty())
107
			VerifySimpleKey(true);
108
109
	}
}