]> icculus.org git repositories - icculus/iodoom3.git/blob - neo/tools/debugger/DebuggerScript.cpp
hello world
[icculus/iodoom3.git] / neo / tools / debugger / DebuggerScript.cpp
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 "../../idlib/precompiled.h"
30 #pragma hdrstop
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 */
43 rvDebuggerScript::rvDebuggerScript ( void )
44 {
45         mContents  = NULL;
46         mProgram   = NULL;
47         mInterface = NULL;
48 }
49
50 /*
51 ================
52 rvDebuggerScript::~rvDebuggerScript
53 ================
54 */
55 rvDebuggerScript::~rvDebuggerScript ( void )
56 {
57         Unload ( );
58 }
59
60 /*
61 ================
62 rvDebuggerScript::Unload
63
64 Unload the script from memory
65 ================
66 */
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 */
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 */
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 */
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 */
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 }