File: LuaParser.h

package info (click to toggle)
spring 106.0%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 55,260 kB
  • sloc: cpp: 543,946; ansic: 44,800; python: 12,575; java: 12,201; awk: 5,889; sh: 1,796; asm: 1,546; xml: 655; perl: 405; php: 211; objc: 194; makefile: 76; sed: 2
file content (217 lines) | stat: -rw-r--r-- 7,276 bytes parent folder | download | duplicates (3)
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
211
212
213
214
215
216
217
/* 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;


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

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 std::string& key) const;
	LuaTable SubTableExpr(const std::string& expr) const;

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

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

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

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

	bool GetPairs(std::vector<std::pair<int, float>>& data) const { return false; } // TODO
	bool GetPairs(std::vector<std::pair<int, std::string>>& data) const;
	bool GetPairs(std::vector<std::pair<std::string, float>>& data) const;
	bool GetPairs(std::vector<std::pair<std::string, std::string>>& data) const;

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

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

	enum DataType {
		NIL     = -1,
		NUMBER  = 1,
		STRING  = 2,
		BOOLEAN = 3,
		TABLE   = 4
	};
	DataType GetType(int key) const;
	DataType GetType(const std::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;
	std::string Get(int key, const std::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 std::string& key, T def) const;
	int    Get(const std::string& key, int def) const;
	bool   Get(const std::string& key, bool def) const;
	float  Get(const std::string& key, float def) const;
	float3 Get(const std::string& key, const float3& def) const;
	float4 Get(const std::string& key, const float4& def) const;
	std::string Get(const std::string& key, const std::string& def) const;
	unsigned int Get(const std::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> std::string GetString(T key, const std::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 std::string& key, const float3& def) const;
	float4 GetFloat4(const std::string& key, const float4& def) const;

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

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

private:
	std::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() = default;
	LuaParser(const std::string& fileName, const std::string& fileModes, const std::string& accessModes, const boolean& synced = {false}, const boolean& setup = {true});
	LuaParser(const std::string& textChunk, const std::string& accessModes, int = 0, const boolean& synced = {false}, const boolean& setup = {true});
	~LuaParser();

	void SetupLua(bool isSyncedCtxt, bool isDefsParser);

	bool Execute();
	bool IsValid() const { return (L != nullptr); } // true if nothing failed during Execute
	bool NoTable() const { return (errorLog.find("no return table") == 0); } // parser is still valid if true

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

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

	// for setting up the initial params table
	void GetTable(int index,               bool overwrite = false);
	void GetTable(const std::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 std::string& value);
	void AddFunc(const std::string& key, int (*func)(lua_State*));
	void AddInt(const std::string& key, int value);
	void AddBool(const std::string& key, bool value);
	void AddFloat(const std::string& key, float value);
	void AddString(const std::string& key, const std::string& value);

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

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

private:
	void SetupEnv(bool isSyncedCtxt, bool isDefsParser);
	void PushParam();

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

private:
	lua_State* L = nullptr;
	luaContextData D;

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

	std::string errorLog;

	int initDepth = -1;
	int rootRef = -1;
	int currentRef = -1;

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

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 */