1 /* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */
2 
3 #ifndef LUA_PARSER_H
4 #define LUA_PARSER_H
5 
6 #include "System/FileSystem/VFSModes.h"
7 
8 #include <string>
9 #include <vector>
10 #include <map>
11 #include <set>
12 
13 class float3;
14 struct float4;
15 class LuaTable;
16 class LuaParser;
17 struct lua_State;
18 
19 using std::string;
20 using std::vector;
21 using std::map;
22 using std::set;
23 
24 
25 /******************************************************************************/
26 
27 class LuaTable {
28 
29 	friend class LuaParser;
30 
31 	public:
32 		LuaTable();
33 		LuaTable(const LuaTable& tbl);
34 		LuaTable& operator=(const LuaTable& tbl);
35 		~LuaTable();
36 
37 		LuaTable SubTable(int key) const;
38 		LuaTable SubTable(const string& key) const;
39 		LuaTable SubTableExpr(const string& expr) const;
40 
IsValid()41 		bool IsValid() const { return (parser != NULL); }
42 
GetPath()43 		const string& GetPath() const { return path; }
44 
45 		int GetLength() const;                  // lua '#' operator
46 		int GetLength(int key) const;           // lua '#' operator
47 		int GetLength(const string& key) const; // lua '#' operator
48 
49 		bool GetKeys(vector<int>& data) const;
50 		bool GetKeys(vector<string>& data) const;
51 
52 		bool GetMap(map<int, float>& data) const;
53 		bool GetMap(map<int, string>& data) const;
54 		bool GetMap(map<string, float>& data) const;
55 		bool GetMap(map<string, string>& data) const;
56 
57 		bool KeyExists(int key) const;
58 		bool KeyExists(const string& key) const;
59 
60 		enum DataType {
61 			NIL     = -1,
62 			NUMBER  = 1,
63 			STRING  = 2,
64 			BOOLEAN = 3,
65 			TABLE   = 4
66 		};
67 		DataType GetType(int key) const;
68 		DataType GetType(const string& key) const;
69 
70 		// numeric keys
71 		template<typename T> T Get(int key, T def) const;
72 		int    Get(int key, int def) const;
73 		bool   Get(int key, bool def) const;
74 		float  Get(int key, float def) const;
75 		float3 Get(int key, const float3& def) const;
76 		float4 Get(int key, const float4& def) const;
77 		string Get(int key, const string& def) const;
Get(int key,unsigned int def)78 		unsigned int Get(int key, unsigned int def) const { return (unsigned int)Get(key, (int)def); }
79 
80 		// string keys  (always lowercase)
81 		template<typename T> T Get(const string& key, T def) const;
82 		int    Get(const string& key, int def) const;
83 		bool   Get(const string& key, bool def) const;
84 		float  Get(const string& key, float def) const;
85 		float3 Get(const string& key, const float3& def) const;
86 		float4 Get(const string& key, const float4& def) const;
87 		string Get(const string& key, const string& def) const;
Get(const string & key,unsigned int def)88 		unsigned int Get(const string& key, unsigned int def) const { return (unsigned int)Get(key, (int)def); }
89 
GetInt(T key,int def)90 		template<typename T> int    GetInt(T key, int def) const { return Get(key, def); }
GetBool(T key,bool def)91 		template<typename T> bool   GetBool(T key, bool def) const { return Get(key, def); }
GetFloat(T key,float def)92 		template<typename T> float  GetFloat(T key, float def) const { return Get(key, def); }
GetString(T key,const string & def)93 		template<typename T> string GetString(T key, const string& def) const { return Get(key, def); }
94 		// we cannot use templates for float3/4 cause then we would need to #include "float3.h" in this header
95 		//template<typename T> float3 GetFloat3(T key, const float3& def) const { return Get(key, def); }
96 		//template<typename T> float4 GetFloat4(T key, const float4& def) const { return Get(key, def); }
97 		float3 GetFloat3(int key, const float3& def) const;
98 		float4 GetFloat4(int key, const float4& def) const;
99 		float3 GetFloat3(const string& key, const float3& def) const;
100 		float4 GetFloat4(const string& key, const float4& def) const;
101 
102 	private:
103 		LuaTable(LuaParser* parser); // for LuaParser::GetRoot()
104 
105 		bool PushTable() const;
106 		bool PushValue(int key) const;
107 		bool PushValue(const string& key) const;
108 
109 	private:
110 		string path;
111 		mutable bool isValid;
112 		LuaParser* parser;
113 		lua_State* L;
114 		int refnum;
115 };
116 
117 
118 /******************************************************************************/
119 
120 class LuaParser {
121 
122 	friend class LuaTable;
123 
124 	public:
125 		LuaParser(const string& fileName,
126 		          const string& fileModes,
127 		          const string& accessModes);
128 		LuaParser(const string& textChunk,
129 		          const string& accessModes);
130 		~LuaParser();
131 
132 		bool Execute();
133 
IsValid()134 		bool IsValid() const { return (L != NULL); }
135 
136 		LuaTable GetRoot();
137 
SubTableExpr(const string & expr)138 		LuaTable SubTableExpr(const string& expr) {
139 			return GetRoot().SubTableExpr(expr);
140 		}
141 
GetErrorLog()142 		const string& GetErrorLog() const { return errorLog; }
143 
GetAccessedFiles()144 		const set<string>& GetAccessedFiles() const { return accessedFiles; }
145 
146 		// for setting up the initial params table
147 		void GetTable(int index,          bool overwrite = false);
148 		void GetTable(const string& name, bool overwrite = false);
149 		void EndTable();
150 		void AddFunc(int key, int (*func)(lua_State*));
151 		void AddInt(int key, int value);
152 		void AddBool(int key, bool value);
153 		void AddFloat(int key, float value);
154 		void AddString(int key, const string& value);
155 		void AddFunc(const string& key, int (*func)(lua_State*));
156 		void AddInt(const string& key, int value);
157 		void AddBool(const string& key, bool value);
158 		void AddFloat(const string& key, float value);
159 		void AddString(const string& key, const string& value);
160 
SetLowerKeys(bool state)161 		void SetLowerKeys(bool state) { lowerKeys = state; }
SetLowerCppKeys(bool state)162 		void SetLowerCppKeys(bool state) { lowerCppKeys = state; }
163 
164 	public:
165 		const string fileName;
166 		const string fileModes;
167 		const string textChunk;
168 		const string accessModes;
169 
170 	private:
171 		void SetupEnv();
172 
173 		void PushParam();
174 
175 		void AddTable(LuaTable* tbl);
176 		void RemoveTable(LuaTable* tbl);
177 
178 	private:
179 		bool valid;
180 		int initDepth;
181 
182 		lua_State* L;
183 		set<LuaTable*> tables;
184 		int rootRef;
185 		int currentRef;
186 
187 		bool lowerKeys; // convert all returned keys to lower case
188 		bool lowerCppKeys; // convert strings in arguments keys to lower case
189 
190 		string errorLog;
191 		set<string> accessedFiles;
192 
193 	private:
194 		// Weird call-outs
195 		static int DontMessWithMyCase(lua_State* L);
196 
197 		// Spring call-outs
198 		static int TimeCheck(lua_State* L);
199 
200 		// VFS call-outs
201 		static int DirList(lua_State* L);
202 		static int SubDirs(lua_State* L);
203 		static int Include(lua_State* L);
204 		static int LoadFile(lua_State* L);
205 		static int FileExists(lua_State* L);
206 
207 	private:
208 		static LuaParser* currentParser;
209 };
210 
211 
212 /******************************************************************************/
213 
214 #endif /* LUA_PARSER_H */
215