1 /*
2 ===========================================================================
3 
4 Doom 3 GPL Source Code
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
6 
7 This file is part of the Doom 3 GPL Source Code ("Doom 3 Source Code").
8 
9 Doom 3 Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13 
14 Doom 3 Source Code 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.  See the
17 GNU General Public License for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with Doom 3 Source Code.  If not, see <http://www.gnu.org/licenses/>.
21 
22 In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code.  If not, please request a copy in writing from id Software at the address below.
23 
24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
25 
26 ===========================================================================
27 */
28 
29 #include "tools/edit_gui_common.h"
30 
31 
32 #include "DebuggerApp.h"
33 #include "DebuggerScript.h"
34 #include "../../game/script/Script_Program.h"
35 #include "../../ui/Window.h"
36 #include "../../ui/UserInterfaceLocal.h"
37 
38 /*
39 ================
40 rvDebuggerScript::rvDebuggerScript
41 ================
42 */
rvDebuggerScript(void)43 rvDebuggerScript::rvDebuggerScript ( void )
44 {
45 	mContents  = NULL;
46 	mProgram   = NULL;
47 	mInterface = NULL;
48 }
49 
50 /*
51 ================
52 rvDebuggerScript::~rvDebuggerScript
53 ================
54 */
~rvDebuggerScript(void)55 rvDebuggerScript::~rvDebuggerScript ( void )
56 {
57 	Unload ( );
58 }
59 
60 /*
61 ================
62 rvDebuggerScript::Unload
63 
64 Unload the script from memory
65 ================
66 */
Unload(void)67 void rvDebuggerScript::Unload ( void )
68 {
69 	delete[] mContents;
70 
71 	if ( mInterface )
72 	{
73 		delete mInterface;
74 	}
75 	else
76 	{
77 		delete mProgram;
78 	}
79 
80 	mContents  = NULL;
81 	mProgram   = NULL;
82 	mInterface = NULL;
83 }
84 
85 /*
86 ================
87 rvDebuggerScript::Load
88 
89 Loads the debugger script and attempts to compile it using the method
90 appropriate for the file being loaded.  If the script cant be compiled
91 the loading of the script fails
92 ================
93 */
Load(const char * filename)94 bool rvDebuggerScript::Load ( const char* filename )
95 {
96 	void* buffer;
97 	int	  size;
98 
99 	// Unload the script before reloading it
100 	Unload ( );
101 
102 	// Cache the filename used to load the script
103 	mFilename = filename;
104 
105 	// Read in the file
106 	size = fileSystem->ReadFile ( filename, &buffer, &mModifiedTime );
107 	if ( buffer == NULL )
108 	{
109 		return false;
110 	}
111 
112 	// Copy the buffer over
113 	mContents = new char [ size + 1 ];
114 	memcpy ( mContents, buffer, size );
115 	mContents[size] = 0;
116 
117 	// Cleanup
118 	fileSystem->FreeFile ( buffer );
119 
120 	// Now compile the script so we can tell what a valid line is, etc..  If its
121 	// a gui file then we need to parse it using the userinterface system rather
122 	// than the normal script compiler.
123 	try
124 	{
125 		// Parse the script using the script compiler
126 		mProgram = new idProgram;
127 		mProgram->BeginCompilation ( );
128 		mProgram->CompileFile ( SCRIPT_DEFAULT );
129 
130 		//BSM Nerve: Loads a game specific main script file
131 		idStr gamedir = cvarSystem->GetCVarString( "fs_game" );
132 		if(gamedir.Length() > 0) {
133 
134 			idStr scriptFile = va("script/%s_main.script", gamedir.c_str());
135 			if(fileSystem->ReadFile(scriptFile.c_str(), NULL) > 0) {
136 				mProgram.CompileFile(scriptFile.c_str());
137 			}
138 
139 		}
140 
141 		// Make sure the file isnt already compiled before trying to compile it again
142 		for ( int f = mProgram->NumFilenames() - 1; f >= 0; f -- )
143 		{
144 			idStr qpath;
145 			qpath = fileSystem->OSPathToRelativePath ( mProgram->GetFilename ( f ) );
146 			qpath.BackSlashesToSlashes ( );
147 			if ( !qpath.Cmp ( filename ) )
148 			{
149 				break;
150 			}
151 		}
152 
153 		if ( f < 0 )
154 		{
155 			mProgram->CompileText ( filename, mContents, false );
156 		}
157 
158 		mProgram->FinishCompilation ( );
159 	}
160 	catch ( idException& )
161 	{
162 		// Failed to parse the script so fail to load the file
163 		delete mProgram;
164 		mProgram = NULL;
165 		delete[] mContents;
166 		mContents = NULL;
167 
168 		// TODO: Should cache the error for the dialog box
169 
170 		return false;
171 	}
172 
173 	return true;
174 }
175 
176 /*
177 ================
178 rvDebuggerScript::Reload
179 
180 Reload the contents of the script
181 ================
182 */
Reload(void)183 bool rvDebuggerScript::Reload ( void )
184 {
185 	return Load ( mFilename );
186 }
187 
188 /*
189 ================
190 rvDebuggerScript::IsValidLine
191 
192 Determines whether or not the given line number within the script is a valid line of code
193 ================
194 */
IsLineCode(int linenumber)195 bool rvDebuggerScript::IsLineCode ( int linenumber )
196 {
197 	int i;
198 
199 	assert ( mProgram );
200 
201 	// Run through all the statements in the program and see if any match the
202 	// linenumber that we are checking.
203 	for ( i	= 0; i < mProgram->NumStatements ( ); i ++ )
204 	{
205 		if ( mProgram->GetStatement ( i ).linenumber == linenumber )
206 		{
207 			return true;
208 		}
209 	}
210 
211 	return false;
212 }
213 
214 /*
215 ================
216 rvDebuggerScript::IsFileModified
217 
218 Determines whether or not the file loaded for this script has been modified since
219 it was loaded.
220 ================
221 */
IsFileModified(bool updateTime)222 bool rvDebuggerScript::IsFileModified ( bool updateTime )
223 {
224 	ID_TIME_T	t;
225 	bool	result = false;
226 
227 	// Grab the filetime and shut the file down
228 	fileSystem->ReadFile ( mFilename, NULL, &t );
229 
230 	// Has the file been modified?
231 	if ( t > mModifiedTime )
232 	{
233 		result = true;
234 	}
235 
236 	// If updateTime is true then we will update the modified time
237 	// stored in the script with the files current modified time
238 	if ( updateTime )
239 	{
240 		mModifiedTime = t;
241 	}
242 
243 	return result;
244 }
245