File: LuaParser.h

package info (click to toggle)
spring 104.0%2Bdfsg-3
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 47,512 kB
  • sloc: cpp: 391,093; ansic: 79,943; python: 12,356; java: 12,201; awk: 5,889; sh: 1,826; xml: 655; makefile: 486; perl: 405; php: 211; objc: 194; sed: 2
file content (210 lines) | stat: -rw-r--r-- 6,359 bytes parent folder | download
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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
/* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */

#ifndef LUA_PARSER_H
#define LUA_PARSER_H

#include <string>
#include <vector>

#include "LuaContextData.h"

#include "System/FileSystem/VFSModes.h"
#include "System/UnorderedMap.hpp"

class float3;
struct float4;
class LuaTable;
class LuaParser;
struct lua_State;

using std::string;


/******************************************************************************/

class LuaTable {
friend class LuaParser;

public:
	LuaTable();
	LuaTable(const LuaTable& tbl);
	LuaTable& operator=(const LuaTable& tbl);
	~LuaTable();

	LuaTable SubTable(int key) const;
	LuaTable SubTable(const string& key) const;
	LuaTable SubTableExpr(const string& expr) const;

	bool IsValid() const { return (parser != nullptr); }

	const string& GetPath() const { return path; }

	int GetLength() const;                  // lua '#' operator
	int GetLength(int key) const;           // lua '#' operator
	int GetLength(const string& key) const; // lua '#' operator

	bool GetKeys(std::vector<int>& data) const;
	bool GetKeys(std::vector<string>& data) const;

	bool GetMap(spring::unordered_map<int, float>& data) const;
	bool GetMap(spring::unordered_map<int, string>& data) const;
	bool GetMap(spring::unordered_map<string, float>& data) const;
	bool GetMap(spring::unordered_map<string, string>& data) const;

	bool KeyExists(int key) const;
	bool KeyExists(const string& key) const;

	enum DataType {
		NIL     = -1,
		NUMBER  = 1,
		STRING  = 2,
		BOOLEAN = 3,
		TABLE   = 4
	};
	DataType GetType(int key) const;
	DataType GetType(const string& key) const;

	// numeric keys
	template<typename T> T Get(int key, T def) const;
	int    Get(int key, int def) const;
	bool   Get(int key, bool def) const;
	float  Get(int key, float def) const;
	float3 Get(int key, const float3& def) const;
	float4 Get(int key, const float4& def) const;
	string Get(int key, const string& def) const;
	unsigned int Get(int key, unsigned int def) const { return (unsigned int)Get(key, (int)def); }

	// string keys  (always lowercase)
	template<typename T> T Get(const string& key, T def) const;
	int    Get(const string& key, int def) const;
	bool   Get(const string& key, bool def) const;
	float  Get(const string& key, float def) const;
	float3 Get(const string& key, const float3& def) const;
	float4 Get(const string& key, const float4& def) const;
	string Get(const string& key, const string& def) const;
	unsigned int Get(const string& key, unsigned int def) const { return (unsigned int)Get(key, (int)def); }

	template<typename T> int    GetInt(T key, int def) const { return Get(key, def); }
	template<typename T> bool   GetBool(T key, bool def) const { return Get(key, def); }
	template<typename T> float  GetFloat(T key, float def) const { return Get(key, def); }
	template<typename T> string GetString(T key, const string& def) const { return Get(key, def); }
	// we cannot use templates for float3/4 cause then we would need to #include "float3.h" in this header
	//template<typename T> float3 GetFloat3(T key, const float3& def) const { return Get(key, def); }
	//template<typename T> float4 GetFloat4(T key, const float4& def) const { return Get(key, def); }
	float3 GetFloat3(int key, const float3& def) const;
	float4 GetFloat4(int key, const float4& def) const;
	float3 GetFloat3(const string& key, const float3& def) const;
	float4 GetFloat4(const string& key, const float4& def) const;

private:
	LuaTable(LuaParser* parser); // for LuaParser::GetRoot()

	bool PushTable() const;
	bool PushValue(int key) const;
	bool PushValue(const string& key) const;

private:
	string path;
	mutable bool isValid;
	LuaParser* parser;
	lua_State* L;
	int refnum;
};


/******************************************************************************/

class LuaParser {
private:
	friend class LuaTable;
	// prevent implicit bool-to-string conversion
	struct boolean { bool b; };

public:
	LuaParser(const string& fileName, const string& fileModes, const string& accessModes, const boolean& synced = {false});
	LuaParser(const string& textChunk, const string& accessModes, const boolean& synced = {false});
	~LuaParser();

	bool Execute();
	bool IsValid() const { return (L != nullptr); }

	LuaTable GetRoot();
	LuaTable SubTableExpr(const string& expr) {
		return GetRoot().SubTableExpr(expr);
	}

	const string& GetErrorLog() const { return errorLog; }

	// for setting up the initial params table
	void GetTable(int index,          bool overwrite = false);
	void GetTable(const string& name, bool overwrite = false);
	void EndTable();
	void AddFunc(int key, int (*func)(lua_State*));
	void AddInt(int key, int value);
	void AddBool(int key, bool value);
	void AddFloat(int key, float value);
	void AddString(int key, const string& value);
	void AddFunc(const string& key, int (*func)(lua_State*));
	void AddInt(const string& key, int value);
	void AddBool(const string& key, bool value);
	void AddFloat(const string& key, float value);
	void AddString(const string& key, const string& value);

	void SetLowerKeys(bool state) { lowerKeys = state; }
	void SetLowerCppKeys(bool state) { lowerCppKeys = state; }

public:
	const string fileName;
	const string fileModes;
	const string textChunk;
	const string accessModes;

private:
	void SetupEnv(bool synced);
	void PushParam();

	void AddTable(LuaTable* tbl);
	void RemoveTable(LuaTable* tbl);

private:
	lua_State* L;
	luaContextData D;

	// NOTE: holds *stack* pointers
	std::vector<LuaTable*> tables;
	// unused
	std::vector<string> accessedFiles;

	int initDepth;
	int rootRef;
	int currentRef;

	bool valid;
	bool lowerKeys; // convert all returned keys to lower case
	bool lowerCppKeys; // convert strings in arguments keys to lower case

	string errorLog;

private:
	// Weird call-outs
	static int DontMessWithMyCase(lua_State* L);

	// Spring call-outs
	static int RandomSeed(lua_State* L);
	static int Random(lua_State* L);
	static int DummyRandomSeed(lua_State* L);
	static int DummyRandom(lua_State* L);
	static int TimeCheck(lua_State* L);

	// VFS call-outs
	static int DirList(lua_State* L);
	static int SubDirs(lua_State* L);
	static int Include(lua_State* L);
	static int LoadFile(lua_State* L);
	static int FileExists(lua_State* L);
};


/******************************************************************************/

#endif /* LUA_PARSER_H */