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

namespace YAML
{
8
9
	Scanner::SimpleKey::SimpleKey(int pos_, int line_, int column_, int flowLevel_)
		: pos(pos_), line(line_), column(column_), flowLevel(flowLevel_), required(false), pMapStart(0), pKey(0)
Jesse Beder's avatar
Jesse Beder committed
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
	{
	}

	void Scanner::SimpleKey::Validate()
	{
		if(pMapStart)
			pMapStart->isValid = true;
		if(pKey)
			pKey->isValid = true;
	}

	void Scanner::SimpleKey::Invalidate()
	{
		if(required)
			throw RequiredSimpleKeyNotFound();

		if(pMapStart)
			pMapStart->isPossible = false;
		if(pKey)
			pKey->isPossible = false;
	}

	// InsertSimpleKey
	// . Adds a potential simple key to the queue,
	//   and saves it on a stack.
	void Scanner::InsertSimpleKey()
	{
37
		SimpleKey key(INPUT.tellg(), m_line, m_column, m_flowLevel);
Jesse Beder's avatar
Jesse Beder committed
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59

		// first add a map start, if necessary
		key.pMapStart = PushIndentTo(m_column, false);
		if(key.pMapStart)
			key.pMapStart->isValid = false;
//		else
//			key.required = true;	// TODO: is this correct?

		// then add the (now invalid) key
		key.pKey = new KeyToken;
		key.pKey->isValid = false;

		m_tokens.push(key.pKey);

		m_simpleKeys.push(key);
	}

	// ValidateSimpleKey
	// . Determines whether the latest simple key to be added is valid,
	//   and if so, makes it valid.
	bool Scanner::ValidateSimpleKey()
	{
60
		m_isLastKeyValid = false;
Jesse Beder's avatar
Jesse Beder committed
61
		if(m_simpleKeys.empty())
62
			return m_isLastKeyValid;
Jesse Beder's avatar
Jesse Beder committed
63
64
65

		// grab top key
		SimpleKey key = m_simpleKeys.top();
66
67
68
69
70

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

Jesse Beder's avatar
Jesse Beder committed
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
		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
		if(m_line != key.line || (int) INPUT.tellg() - key.pos > 1024)
			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();

98
		m_isLastKeyValid = isValid;
Jesse Beder's avatar
Jesse Beder committed
99
100
101
102
103
104
105
106
107
		return isValid;
	}

	void Scanner::ValidateAllSimpleKeys()
	{
		while(!m_simpleKeys.empty())
			ValidateSimpleKey();
	}
}