simplekey.cpp 2.58 KB
Newer Older
beder's avatar
beder committed
1
2
3
4
5
6
7
#include "scanner.h"
#include "token.h"
#include "exceptions.h"
#include "exp.h"

namespace YAML
{
8
	Scanner::SimpleKey::SimpleKey(int pos_, int line_, int column_, int flowLevel_)
9
		: pos(pos_), line(line_), column(column_), flowLevel(flowLevel_), pMapStart(0), pKey(0)
beder's avatar
beder committed
10
11
12
13
14
15
	{
	}

	void Scanner::SimpleKey::Validate()
	{
		if(pMapStart)
16
			pMapStart->status = TS_VALID;
beder's avatar
beder committed
17
		if(pKey)
18
			pKey->status = TS_VALID;
beder's avatar
beder committed
19
20
21
22
23
	}

	void Scanner::SimpleKey::Invalidate()
	{
		if(pMapStart)
24
			pMapStart->status = TS_INVALID;
beder's avatar
beder committed
25
		if(pKey)
26
			pKey->status = TS_INVALID;
beder's avatar
beder committed
27
28
29
30
31
32
33
	}

	// InsertSimpleKey
	// . Adds a potential simple key to the queue,
	//   and saves it on a stack.
	void Scanner::InsertSimpleKey()
	{
34
		SimpleKey key(INPUT.pos(), INPUT.line, INPUT.column, m_flowLevel);
beder's avatar
beder committed
35
36

		// first add a map start, if necessary
37
		key.pMapStart = PushIndentTo(INPUT.column, false);
beder's avatar
beder committed
38
		if(key.pMapStart)
39
			key.pMapStart->status = TS_UNVERIFIED;
beder's avatar
beder committed
40

41
		// then add the (now unverified) key
42
		key.pKey = new Token(TT_KEY, INPUT.line, INPUT.column);
43
		key.pKey->status = TS_UNVERIFIED;
beder's avatar
beder committed
44
45
46
47
48
		m_tokens.push(key.pKey);

		m_simpleKeys.push(key);
	}

49
	// VerifySimpleKey
beder's avatar
beder committed
50
51
	// . Determines whether the latest simple key to be added is valid,
	//   and if so, makes it valid.
52
	bool Scanner::VerifySimpleKey()
beder's avatar
beder committed
53
	{
54
		m_isLastKeyValid = false;
beder's avatar
beder committed
55
		if(m_simpleKeys.empty())
56
			return m_isLastKeyValid;
beder's avatar
beder committed
57
58
59

		// grab top key
		SimpleKey key = m_simpleKeys.top();
60
61
62
63
64

		// only validate if we're in the correct flow level
		if(key.flowLevel != m_flowLevel)
			return false;

beder's avatar
beder committed
65
66
67
68
69
70
71
72
73
74
75
		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
76
		if(INPUT.line != key.line || INPUT.pos() - key.pos > 1024)
beder's avatar
beder committed
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
			isValid = false;

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

		// In block style, remember that we've pushed an indent for this potential simple key (if it was starting).
		// If it was invalid, then we need to pop it off.
		// Note: we're guaranteed to be popping the right one (i.e., there couldn't have been anything in
		//       between) since keys have to be inline, and will be invalidated immediately on a newline.
		if(!isValid && m_flowLevel == 0)
			m_indents.pop();

92
		m_isLastKeyValid = isValid;
beder's avatar
beder committed
93
94
95
		return isValid;
	}

96
	void Scanner::VerifyAllSimpleKeys()
beder's avatar
beder committed
97
98
	{
		while(!m_simpleKeys.empty())
99
			VerifySimpleKey();
beder's avatar
beder committed
100
101
	}
}