1 /**
2  * @file
3  * @brief Shared code for unittests
4  */
5 
6 /*
7 Copyright (C) 2002-2013 UFO: Alien Invasion.
8 
9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the GNU General Public License
11 as published by the Free Software Foundation; either version 2
12 of the License, or (at your option) any later version.
13 
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 
18 See the GNU General Public License for more details.
19 
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
23 
24 */
25 
26 #include "test_shared.h"
27 #include "../client/cl_renderer.h"
28 #include "../client/battlescape/cl_particle.h"
29 #include <stdio.h>
30 #include <stdarg.h>
31 
TEST_Shutdown(void)32 void TEST_Shutdown (void)
33 {
34 	PTL_InitStartup();
35 	R_ShutdownImages();
36 	SV_Shutdown("test shutdown", false);
37 	FS_Shutdown();
38 	Cmd_Shutdown();
39 	developer = nullptr;
40 	Cvar_Shutdown();
41 	Mem_Shutdown();
42 	Com_Shutdown();
43 	Cbuf_Shutdown();
44 	NET_Shutdown();
45 
46 	com_aliasSysPool = nullptr;
47 	com_cmdSysPool = nullptr;
48 	com_cmodelSysPool = nullptr;
49 	com_cvarSysPool = nullptr;
50 	com_fileSysPool = nullptr;
51 	com_genericPool = nullptr;
52 }
53 
TEST_vPrintf(const char * fmt,va_list argptr)54 void TEST_vPrintf (const char* fmt, va_list argptr)
55 {
56 	char text[1024];
57 	Q_vsnprintf(text, sizeof(text), fmt, argptr);
58 
59 	fprintf(stderr, "%s", text);
60 
61 	fflush(stderr);
62 }
63 
TEST_Init(void)64 void TEST_Init (void)
65 {
66 	try {
67 		com_aliasSysPool  = Mem_CreatePool("Common: Alias system");
68 		com_cmdSysPool    = Mem_CreatePool("Common: Command system");
69 		com_cmodelSysPool = Mem_CreatePool("Common: Collision model");
70 		com_cvarSysPool   = Mem_CreatePool("Common: Cvar system");
71 		com_fileSysPool   = Mem_CreatePool("Common: File system");
72 		com_genericPool   = Mem_CreatePool("Generic");
73 
74 		Mem_Init();
75 		Cbuf_Init();
76 		Cmd_Init();
77 		Cvar_Init();
78 		FS_InitFilesystem(true);
79 		FS_AddGameDirectory("./unittest", false);
80 		FS_AddHomeAsGameDirectory("unittest", true);
81 		Swap_Init();
82 		SV_Init();
83 		NET_Init();
84 
85 		FS_ExecAutoexec();
86 
87 		OBJZERO(csi);
88 	} catch (comDrop_t const&) {
89 		Sys_Error("Error during initialization");
90 	}
91 
92 	http_timeout = Cvar_Get("noname");
93 	http_proxy = Cvar_Get("noname");
94 	hwclass = Cvar_Get("hwclass", "5");
95 }
96 
97 
98 #define PROPERTY_HASH_SIZE	32
99 
100 #define	MAX_PROPERTY_NAME	32
101 
102 typedef struct test_property_s {
103 	char name[MAX_PROPERTY_NAME];
104 	const char* value;
105 	struct test_property_s* hash_next;
106 	struct test_property_s* next;
107 } test_property_t;
108 
109 static test_property_t* test_property;
110 static test_property_t* test_property_hash[PROPERTY_HASH_SIZE];
111 
112 /**
113  * Register a property name-value to a global structure for all tests
114  * @param name Name of the property
115  * @param value Value of the property. Only the pointer of the value is used. Use it ONLY with stable memory.
116  */
TEST_RegisterProperty(const char * name,const char * value)117 void TEST_RegisterProperty (const char* name, const char* value)
118 {
119 	unsigned int hash;
120 	test_property_t* element;
121 
122 	/* if the alias already exists, reuse it */
123 	hash = Com_HashKey(name, PROPERTY_HASH_SIZE);
124 	for (element = test_property_hash[hash]; element; element = element->hash_next) {
125 		if (Q_streq(name, element->name)) {
126 			break;
127 		}
128 	}
129 
130 	if (!element) {
131 		element = (test_property_t*) malloc(sizeof(*element));
132 		Q_strncpyz(element->name, name, sizeof(element->name));
133 		/** TODO maybe copy the value instead of copying the pointer of the value */
134 		element->value = value;
135 		element->next = test_property;
136 		element->hash_next = test_property_hash[hash];
137 		test_property_hash[hash] = element;
138 		test_property = element;
139 		Com_Printf("Register test property \"%s\" = \"%s\"\n", name, value);
140 	}
141 }
142 
143 /**
144  * Get a property name from global test structure
145  * @param name Name of the property
146  * @return A property element, else nullptr if property not found.
147  */
TEST_GetProperty(const char * name)148 static const test_property_t* TEST_GetProperty (const char* name)
149 {
150 	unsigned int hash;
151 	const test_property_t* element;
152 
153 	hash = Com_HashKey(name, PROPERTY_HASH_SIZE);
154 	for (element = test_property_hash[hash]; element; element = element->hash_next) {
155 		if (!Q_strcasecmp(name, element->name)) {
156 			return element;
157 		}
158 	}
159 	return nullptr;
160 }
161 
162 /**
163  * Test if a property from global test structure exists
164  * @param name Name of the property
165  * @return True if the property exists
166  */
TEST_ExistsProperty(const char * name)167 bool TEST_ExistsProperty (const char* name)
168 {
169 	return TEST_GetProperty(name) != nullptr;
170 }
171 
172 /**
173  * Get a property value from global test structure
174  * @param name Name of the property
175  * @return A property value, else nullptr if property not found.
176  */
TEST_GetStringProperty(const char * name)177 const char* TEST_GetStringProperty (const char* name)
178 {
179 	const test_property_t* element = TEST_GetProperty(name);
180 	if (element == nullptr) {
181 		Com_Printf("WARNING: Test property \"%s\" not found. nullptr returned.\n", name);
182 		return nullptr;
183 	}
184 	return element->value;
185 }
186 
187 /**
188  * Get a property value from global test structure
189  * @param name Name of the property
190  * @return A property value, else 0 if property not found.
191  */
TEST_GetIntProperty(const char * name)192 int TEST_GetIntProperty (const char* name)
193 {
194 	const test_property_t* element = TEST_GetProperty(name);
195 	if (element == nullptr) {
196 		Com_Printf("WARNING: Test property \"%s\" not found. 0 returned.\n", name);
197 		return 0;
198 	}
199 	return atoi(element->value);
200 }
201 
202 /**
203  * Get a property value from global test structure
204  * @param name Name of the property
205  * @return A property value, else 0 if property not found.
206  */
TEST_GetLongProperty(const char * name)207 long TEST_GetLongProperty (const char* name)
208 {
209 	const test_property_t* element = TEST_GetProperty(name);
210 	if (element == nullptr) {
211 		Com_Printf("WARNING: Test property \"%s\" not found. 0 returned.\n", name);
212 		return 0;
213 	}
214 	return atol(element->value);
215 }
216