~ubuntu-branches/ubuntu/raring/codeblocks/raring-proposed

« back to all changes in this revision

Viewing changes to src/plugins/codecompletion/parser/parser.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Cosme Domínguez Díaz
  • Date: 2010-08-09 04:38:38 UTC
  • mfrom: (1.1.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 4.
  • Revision ID: james.westby@ubuntu.com-20100809043838-a59ygguym4eg0jgw
Tags: 10.05-0ubuntu1
* New upstream release. Closes (LP: #322350)
 - Switch to dpkg-source 3.0 (quilt) format
 - Remove unneeded README.source
 - Add debian/get-source-orig script that removes all
   Windows prebuilt binaries
* Bump Standards-Version to 3.9.1
 - Stop shipping *.la files
* debian/control
 - Add cdbs package as Build-Depend
 - Add libbz2-dev and zlib1g-dev packages as
   Build-Depends (needed by libhelp_plugin.so)
 - Remove dpatch package of Build-Depends
 - Add codeblocks-contrib-debug package
 - Split architecture-independent files of codeblocks
   package in codeblocks-common package
* debian/rules
 - Switch to CDBS rules system
 - Add parallel build support
 - Add a call to debian/get-source-orig script
 - Use lzma compression (saves 23,5 MB of free space)
* debian/patches
 - Refresh 01_codeblocks_plugin_path
 - Add 02_no_Makefiles_in_debian_dir to remove any link
   in codeblocks build system to deleted Makefiles of debian directory
 - Drop 02_ftbfs_gcc44 and 03_ftbfs_glib221 (merged in upstream)
* debian/watch
 - Update to use the new host (berlios.de)

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
 * This file is part of the Code::Blocks IDE and licensed under the GNU General Public License, version 3
3
3
 * http://www.gnu.org/licenses/gpl-3.0.html
4
4
 *
5
 
 * $Revision: 4909 $
6
 
 * $Id: parser.cpp 4909 2008-02-27 13:15:26Z mortenmacfly $
7
 
 * $HeadURL: svn://svn.berlios.de/codeblocks/tags/8.02/src/plugins/codecompletion/parser/parser.cpp $
 
5
 * $Revision: 6099 $
 
6
 * $Id: parser.cpp 6099 2010-01-22 13:45:29Z jenslody $
 
7
 * $HeadURL: svn+ssh://jenslody@svn.berlios.de/svnroot/repos/codeblocks/trunk/src/plugins/codecompletion/parser/parser.cpp $
8
8
 */
9
9
 
10
10
#include <sdk.h>
14
14
#include <wx/intl.h>
15
15
#include <wx/progdlg.h>
16
16
#include "parser.h"
 
17
 
17
18
#include "../classbrowser.h"
18
19
#include "../classbrowserbuilderthread.h"
 
20
 
19
21
#ifndef STANDALONE
20
22
    #include <configmanager.h>
21
23
    #include <logmanager.h>
31
33
      #include "editorbase.h"
32
34
#endif
33
35
 
 
36
#define PARSER_DEBUG_OUTPUT 0
 
37
 
 
38
#if PARSER_DEBUG_OUTPUT
 
39
    #define TRACE(format, args...)\
 
40
    Manager::Get()->GetLogManager()->DebugLog(F( format , ## args))
 
41
#else
 
42
    #define TRACE(format, args...)
 
43
#endif
 
44
 
34
45
static const char CACHE_MAGIC[] = "CCCACHE_1_3";
35
46
static const int batch_timer_delay = 500;
36
47
static const int reparse_timer_delay = 250;
52
63
#endif
53
64
    m_UsingCache(false),
54
65
    m_Pool(this, idPool, 1), // in the meanwhile it'll have to be forced to 1
55
 
    m_pTokens(0),
56
 
    m_pTempTokens(0),
 
66
    m_pTokensTree(0),
 
67
    m_pTempTokensTree(0),
57
68
    m_NeedsReparse(false),
58
69
    m_IsBatch(false),
59
70
    m_pClassBrowser(0),
60
71
    m_TreeBuildingStatus(0),
61
72
    m_TreeBuildingTokenIdx(0),
62
 
    m_timer(this, TIMER_ID),
63
 
    m_batchtimer(this,BATCH_TIMER_ID),
 
73
    m_Timer(this, TIMER_ID),
 
74
    m_BatchTimer(this,BATCH_TIMER_ID),
64
75
    m_StopWatchRunning(false),
65
76
    m_LastStopWatchTime(0),
66
77
    m_IgnoreThreadEvents(false),
67
 
    m_ShuttingDown(false),
68
 
    m_pClassBrowserBuilderThread(0)
 
78
    m_ShuttingDown(false)
69
79
{
70
 
    m_pTokens = new TokensTree;
71
 
    m_pTempTokens = new TokensTree;
 
80
    m_pTokensTree = new TokensTree;
 
81
    m_pTempTokensTree = new TokensTree;
72
82
    m_LocalFiles.clear();
73
83
    m_GlobalIncludes.clear();
74
84
    ReadOptions();
82
92
    m_pImageList->Add(bmp); // PARSER_IMG_CLASS_FOLDER
83
93
    bmp = cbLoadBitmap(prefix + _T("class.png"), wxBITMAP_TYPE_PNG);
84
94
    m_pImageList->Add(bmp); // PARSER_IMG_CLASS
 
95
    bmp = cbLoadBitmap(prefix + _T("class_private.png"), wxBITMAP_TYPE_PNG);
 
96
    m_pImageList->Add(bmp); // PARSER_IMG_CLASS_PRIVATE
 
97
    bmp = cbLoadBitmap(prefix + _T("class_protected.png"), wxBITMAP_TYPE_PNG);
 
98
    m_pImageList->Add(bmp); // PARSER_IMG_CLASS_PROTECTED
 
99
    bmp = cbLoadBitmap(prefix + _T("class_public.png"), wxBITMAP_TYPE_PNG);
 
100
    m_pImageList->Add(bmp); // PARSER_IMG_CLASS_PUBLIC
85
101
    bmp = cbLoadBitmap(prefix + _T("ctor_private.png"), wxBITMAP_TYPE_PNG);
86
102
    m_pImageList->Add(bmp); // PARSER_IMG_CTOR_PRIVATE
87
103
    bmp = cbLoadBitmap(prefix + _T("ctor_protected.png"), wxBITMAP_TYPE_PNG);
110
126
    m_pImageList->Add(bmp); // PARSER_IMG_PREPROCESSOR
111
127
    bmp = cbLoadBitmap(prefix + _T("enum.png"), wxBITMAP_TYPE_PNG);
112
128
    m_pImageList->Add(bmp); // PARSER_IMG_ENUM
 
129
    bmp = cbLoadBitmap(prefix + _T("enum_private.png"), wxBITMAP_TYPE_PNG);
 
130
    m_pImageList->Add(bmp); // PARSER_IMG_ENUM_PRIVATE
 
131
    bmp = cbLoadBitmap(prefix + _T("enum_protected.png"), wxBITMAP_TYPE_PNG);
 
132
    m_pImageList->Add(bmp); // PARSER_IMG_ENUM_PROTECTED
 
133
    bmp = cbLoadBitmap(prefix + _T("enum_public.png"), wxBITMAP_TYPE_PNG);
 
134
    m_pImageList->Add(bmp); // PARSER_IMG_ENUM_PUBLIC
113
135
    bmp = cbLoadBitmap(prefix + _T("enumerator.png"), wxBITMAP_TYPE_PNG);
114
136
    m_pImageList->Add(bmp); // PARSER_IMG_ENUMERATOR
115
137
    bmp = cbLoadBitmap(prefix + _T("namespace.png"), wxBITMAP_TYPE_PNG);
116
138
    m_pImageList->Add(bmp); // PARSER_IMG_NAMESPACE
117
139
    bmp = cbLoadBitmap(prefix + _T("typedef.png"), wxBITMAP_TYPE_PNG);
118
140
    m_pImageList->Add(bmp); // PARSER_IMG_TYPEDEF
 
141
    bmp = cbLoadBitmap(prefix + _T("typedef_private.png"), wxBITMAP_TYPE_PNG);
 
142
    m_pImageList->Add(bmp); // PARSER_IMG_TYPEDEF_PRIVATE
 
143
    bmp = cbLoadBitmap(prefix + _T("typedef_protected.png"), wxBITMAP_TYPE_PNG);
 
144
    m_pImageList->Add(bmp); // PARSER_IMG_TYPEDEF_PROTECTED
 
145
    bmp = cbLoadBitmap(prefix + _T("typedef_public.png"), wxBITMAP_TYPE_PNG);
 
146
    m_pImageList->Add(bmp); // PARSER_IMG_TYPEDEF_PUBLIC
119
147
    bmp = cbLoadBitmap(prefix + _T("symbols_folder.png"), wxBITMAP_TYPE_PNG);
120
148
    m_pImageList->Add(bmp); // PARSER_IMG_SYMBOLS_FOLDER
 
149
    bmp = cbLoadBitmap(prefix + _T("vars_folder.png"), wxBITMAP_TYPE_PNG);
 
150
    m_pImageList->Add(bmp); // PARSER_IMG_VARS_FOLDER
 
151
    bmp = cbLoadBitmap(prefix + _T("funcs_folder.png"), wxBITMAP_TYPE_PNG);
 
152
    m_pImageList->Add(bmp); // PARSER_IMG_FUNCS_FOLDER
121
153
    bmp = cbLoadBitmap(prefix + _T("enums_folder.png"), wxBITMAP_TYPE_PNG);
122
154
    m_pImageList->Add(bmp); // PARSER_IMG_ENUMS_FOLDER
123
155
    bmp = cbLoadBitmap(prefix + _T("preproc_folder.png"), wxBITMAP_TYPE_PNG);
126
158
    m_pImageList->Add(bmp); // PARSER_IMG_OTHERS_FOLDER
127
159
    bmp = cbLoadBitmap(prefix + _T("typedefs_folder.png"), wxBITMAP_TYPE_PNG);
128
160
    m_pImageList->Add(bmp); // PARSER_IMG_TYPEDEF_FOLDER
 
161
    bmp = cbLoadBitmap(prefix + _T("macro.png"), wxBITMAP_TYPE_PNG);
 
162
    m_pImageList->Add(bmp); // PARSER_IMG_MACRO
 
163
    bmp = cbLoadBitmap(prefix + _T("macro_private.png"), wxBITMAP_TYPE_PNG);
 
164
    m_pImageList->Add(bmp); // PARSER_IMG_MACRO_PRIVATE
 
165
    bmp = cbLoadBitmap(prefix + _T("macro_protected.png"), wxBITMAP_TYPE_PNG);
 
166
    m_pImageList->Add(bmp); // PARSER_IMG_MACRO_PROTECTED
 
167
    bmp = cbLoadBitmap(prefix + _T("macro_public.png"), wxBITMAP_TYPE_PNG);
 
168
    m_pImageList->Add(bmp); // PARSER_IMG_MACRO_PUBLIC
 
169
    bmp = cbLoadBitmap(prefix + _T("macro_folder.png"), wxBITMAP_TYPE_PNG);
 
170
    m_pImageList->Add(bmp); // PARSER_IMG_MACRO_FOLDER
129
171
#endif // STANDALONE
130
172
    ConnectEvents();
131
173
}
133
175
Parser::~Parser()
134
176
{
135
177
    m_ShuttingDown = true;
136
 
    if(m_pClassBrowser && m_pClassBrowser->GetParserPtr() == this)
 
178
    if (m_pClassBrowser && m_pClassBrowser->GetParserPtr() == this)
137
179
        m_pClassBrowser->UnlinkParser();
138
180
    m_TreeBuildingStatus = 0;
139
 
    m_pClassBrowser = NULL;
 
181
    m_pClassBrowser = 0;
140
182
 
141
183
    Clear(); // Clear also disconnects the events
142
184
#ifndef STANDALONE
143
185
    Delete(m_pImageList);
144
 
    Delete(m_pTempTokens);
145
 
    Delete(m_pTokens);
 
186
    Delete(m_pTempTokensTree);
 
187
    Delete(m_pTokensTree);
146
188
#endif // STANDALONE
147
189
}
148
190
 
149
191
void Parser::ConnectEvents()
150
192
{
151
 
    Connect(-1,-1,cbEVT_THREADTASK_ALLDONE,
 
193
    Connect(-1, -1, cbEVT_THREADTASK_ALLDONE,
152
194
            (wxObjectEventFunction)(wxEventFunction)(wxCommandEventFunction)
153
195
            &Parser::OnAllThreadsDone);
154
 
    Connect(TIMER_ID,-1, wxEVT_TIMER,(wxObjectEventFunction)
155
 
            (wxEventFunction)(wxTimerEventFunction)&Parser::OnTimer);
156
 
    Connect(BATCH_TIMER_ID,-1,wxEVT_TIMER,(wxObjectEventFunction)
157
 
            (wxEventFunction)(wxTimerEventFunction)&Parser::OnBatchTimer);
 
196
    Connect(TIMER_ID, -1, wxEVT_TIMER,
 
197
            (wxObjectEventFunction)(wxEventFunction)(wxTimerEventFunction)
 
198
            &Parser::OnTimer);
 
199
    Connect(BATCH_TIMER_ID, -1, wxEVT_TIMER,
 
200
            (wxObjectEventFunction)(wxEventFunction)(wxTimerEventFunction)
 
201
            &Parser::OnBatchTimer);
158
202
}
159
203
 
160
204
void Parser::DisconnectEvents()
167
211
void Parser::ReadOptions()
168
212
{
169
213
#ifdef STANDALONE
170
 
    m_Options.followLocalIncludes = true;
171
 
    m_Options.followGlobalIncludes = false;
172
 
    m_Options.caseSensitive = true;
173
 
    m_Options.wantPreprocessor = false;
174
 
    m_Options.useSmartSense = true;
 
214
    m_Options.followLocalIncludes    = true;
 
215
    m_Options.followGlobalIncludes   = false;
 
216
    m_Options.caseSensitive          = true;
 
217
    m_Options.wantPreprocessor       = false;
 
218
    m_Options.useSmartSense          = true;
 
219
    m_Options.whileTyping            = true;
175
220
    m_BrowserOptions.showInheritance = false;
176
 
    m_BrowserOptions.expandNS = false;
177
 
    m_BrowserOptions.viewFlat = false;
178
 
    m_BrowserOptions.displayFilter = bdfWorkspace;
 
221
    m_BrowserOptions.expandNS        = false;
 
222
    m_BrowserOptions.viewFlat        = false;
 
223
    m_BrowserOptions.displayFilter   = bdfWorkspace;
179
224
#else // !STANDALONE
180
225
    ConfigManager* cfg = Manager::Get()->GetConfigManager(_T("code_completion"));
181
226
 
191
236
    }
192
237
 
193
238
    //m_Pool.SetConcurrentThreads(cfg->ReadInt(_T("/max_threads"), 1)); // Ignore it in the meanwhile
194
 
    m_Options.followLocalIncludes = cfg->ReadBool(_T("/parser_follow_local_includes"), true);
 
239
 
 
240
    m_Options.followLocalIncludes  = cfg->ReadBool(_T("/parser_follow_local_includes"), true);
195
241
    m_Options.followGlobalIncludes = cfg->ReadBool(_T("/parser_follow_global_includes"), true);
196
 
    m_Options.caseSensitive = cfg->ReadBool(_T("/case_sensitive"), false);
197
 
    m_Options.useSmartSense = cfg->ReadBool(_T("/use_SmartSense"), true);
198
 
    m_Options.wantPreprocessor = cfg->ReadBool(_T("/want_preprocessor"), true);
 
242
    m_Options.caseSensitive        = cfg->ReadBool(_T("/case_sensitive"), false);
 
243
    m_Options.useSmartSense        = cfg->ReadBool(_T("/use_SmartSense"), true);
 
244
    m_Options.whileTyping          = cfg->ReadBool(_T("/while_typing"), true);
 
245
    m_Options.wantPreprocessor     = cfg->ReadBool(_T("/want_preprocessor"), true);
 
246
 
199
247
    m_BrowserOptions.showInheritance = cfg->ReadBool(_T("/browser_show_inheritance"), false);
200
 
    m_BrowserOptions.expandNS = cfg->ReadBool(_T("/browser_expand_ns"), false);
201
 
    m_BrowserOptions.displayFilter = (BrowserDisplayFilter)cfg->ReadInt(_T("/browser_display_filter"), bdfWorkspace);
 
248
    m_BrowserOptions.expandNS        = cfg->ReadBool(_T("/browser_expand_ns"), false);
 
249
    m_BrowserOptions.treeMembers     = cfg->ReadBool(_T("/browser_tree_members"), true);
 
250
    m_BrowserOptions.displayFilter   = (BrowserDisplayFilter)cfg->ReadInt(_T("/browser_display_filter"), bdfWorkspace);
 
251
    m_BrowserOptions.sortType        = (BrowserSortType)cfg->ReadInt(_T("/browser_sort_type"), bstKind);
202
252
#endif // STANDALONE
203
253
}
204
254
 
207
257
#ifndef STANDALONE
208
258
    ConfigManager* cfg = Manager::Get()->GetConfigManager(_T("code_completion"));
209
259
 
210
 
    cfg->Write(_T("/max_threads"), (int)GetMaxThreads());
211
 
    cfg->Write(_T("/parser_follow_local_includes"), m_Options.followLocalIncludes);
 
260
    cfg->Write(_T("/max_threads"),                   (int)GetMaxThreads());
 
261
    cfg->Write(_T("/parser_follow_local_includes"),  m_Options.followLocalIncludes);
212
262
    cfg->Write(_T("/parser_follow_global_includes"), m_Options.followGlobalIncludes);
213
 
    cfg->Write(_T("/case_sensitive"), m_Options.caseSensitive);
214
 
    cfg->Write(_T("/use_SmartSense"), m_Options.useSmartSense);
215
 
    cfg->Write(_T("/want_preprocessor"), m_Options.wantPreprocessor);
216
 
    cfg->Write(_T("/browser_show_inheritance"), m_BrowserOptions.showInheritance);
217
 
    cfg->Write(_T("/browser_expand_ns"), m_BrowserOptions.expandNS);
218
 
    cfg->Write(_T("/browser_display_filter"), m_BrowserOptions.displayFilter);
 
263
    cfg->Write(_T("/case_sensitive"),                m_Options.caseSensitive);
 
264
    cfg->Write(_T("/use_SmartSense"),                m_Options.useSmartSense);
 
265
    cfg->Write(_T("/while_typing"),                  m_Options.whileTyping);
 
266
    cfg->Write(_T("/want_preprocessor"),             m_Options.wantPreprocessor);
 
267
 
 
268
    cfg->Write(_T("/browser_show_inheritance"),      m_BrowserOptions.showInheritance);
 
269
    cfg->Write(_T("/browser_expand_ns"),             m_BrowserOptions.expandNS);
 
270
    cfg->Write(_T("/browser_tree_members"),          m_BrowserOptions.treeMembers);
 
271
    cfg->Write(_T("/browser_display_filter"),        m_BrowserOptions.displayFilter);
 
272
    cfg->Write(_T("/browser_sort_type"),             m_BrowserOptions.sortType);
219
273
#endif // STANDALONE
220
274
}
221
275
 
224
278
    if (m_UsingCache)
225
279
    {
226
280
        wxCriticalSectionLocker lock(s_MutexProtection);
227
 
        return m_pTokens->m_modified;
 
281
        return m_pTokensTree->m_Modified;
228
282
    }
229
283
    return true;
230
284
}
232
286
unsigned int Parser::GetFilesCount()
233
287
{
234
288
    wxCriticalSectionLocker lock(s_MutexProtection);
235
 
    return m_pTokens->m_FilesMap.size();
 
289
    return m_pTokensTree->m_FilesMap.size();
236
290
}
237
291
 
238
292
bool Parser::Done()
272
326
 
273
327
    switch (token->m_TokenKind)
274
328
    {
275
 
        case tkPreprocessor: return PARSER_IMG_PREPROCESSOR;
276
 
 
277
 
        case tkEnum: return PARSER_IMG_ENUM;
278
 
 
279
 
        case tkEnumerator: return PARSER_IMG_ENUMERATOR;
280
 
 
281
 
        case tkClass: return PARSER_IMG_CLASS;
282
 
 
283
 
        case tkNamespace: return PARSER_IMG_NAMESPACE;
284
 
 
285
 
        case tkTypedef: return PARSER_IMG_TYPEDEF;
 
329
        case tkPreprocessor:      return PARSER_IMG_PREPROCESSOR;
 
330
 
 
331
        case tkEnum:
 
332
            switch (token->m_Scope)
 
333
            {
 
334
                case tsPublic:    return PARSER_IMG_ENUM_PUBLIC;
 
335
                case tsProtected: return PARSER_IMG_ENUM_PROTECTED;
 
336
                case tsPrivate:   return PARSER_IMG_ENUM_PRIVATE;
 
337
                default:          return PARSER_IMG_ENUM;
 
338
            }
 
339
 
 
340
        case tkEnumerator:        return PARSER_IMG_ENUMERATOR;
 
341
 
 
342
        case tkClass:
 
343
            switch (token->m_Scope)
 
344
            {
 
345
                case tsPublic:    return PARSER_IMG_CLASS_PUBLIC;
 
346
                case tsProtected: return PARSER_IMG_CLASS_PROTECTED;
 
347
                case tsPrivate:   return PARSER_IMG_CLASS_PRIVATE;
 
348
                default:          return PARSER_IMG_CLASS_PUBLIC;
 
349
            }
 
350
 
 
351
        case tkNamespace:         return PARSER_IMG_NAMESPACE;
 
352
 
 
353
        case tkTypedef:
 
354
            switch (token->m_Scope)
 
355
            {
 
356
                case tsPublic:    return PARSER_IMG_TYPEDEF_PUBLIC;
 
357
                case tsProtected: return PARSER_IMG_TYPEDEF_PROTECTED;
 
358
                case tsPrivate:   return PARSER_IMG_TYPEDEF_PRIVATE;
 
359
                default:          return PARSER_IMG_TYPEDEF;
 
360
            }
 
361
 
 
362
        case tkMacro:
 
363
            switch (token->m_Scope)
 
364
            {
 
365
                case tsPublic:    return PARSER_IMG_MACRO_PUBLIC;
 
366
                case tsProtected: return PARSER_IMG_MACRO_PROTECTED;
 
367
                case tsPrivate:   return PARSER_IMG_MACRO_PRIVATE;
 
368
                default:          return PARSER_IMG_MACRO;
 
369
            }
286
370
 
287
371
        case tkConstructor:
288
372
            switch (token->m_Scope)
289
373
            {
290
374
                case tsProtected: return PARSER_IMG_CTOR_PROTECTED;
291
 
                case tsPrivate: return PARSER_IMG_CTOR_PRIVATE;
292
 
                default: return PARSER_IMG_CTOR_PUBLIC;
 
375
                case tsPrivate:   return PARSER_IMG_CTOR_PRIVATE;
 
376
                default:          return PARSER_IMG_CTOR_PUBLIC;
293
377
            }
294
378
 
295
379
        case tkDestructor:
296
380
            switch (token->m_Scope)
297
381
            {
298
382
                case tsProtected: return PARSER_IMG_DTOR_PROTECTED;
299
 
                case tsPrivate: return PARSER_IMG_DTOR_PRIVATE;
300
 
                default: return PARSER_IMG_DTOR_PUBLIC;
 
383
                case tsPrivate:   return PARSER_IMG_DTOR_PRIVATE;
 
384
                default:          return PARSER_IMG_DTOR_PUBLIC;
301
385
            }
302
386
 
303
387
        case tkFunction:
304
388
            switch (token->m_Scope)
305
389
            {
306
390
                case tsProtected: return PARSER_IMG_FUNC_PROTECTED;
307
 
                case tsPrivate: return PARSER_IMG_FUNC_PRIVATE;
308
 
                default: return PARSER_IMG_FUNC_PUBLIC;
 
391
                case tsPrivate:   return PARSER_IMG_FUNC_PRIVATE;
 
392
                default:          return PARSER_IMG_FUNC_PUBLIC;
309
393
            }
310
394
 
311
395
        case tkVariable:
312
396
            switch (token->m_Scope)
313
397
            {
314
398
                case tsProtected: return PARSER_IMG_VAR_PROTECTED;
315
 
                case tsPrivate: return PARSER_IMG_VAR_PRIVATE;
316
 
                default: return PARSER_IMG_VAR_PUBLIC;
 
399
                case tsPrivate:   return PARSER_IMG_VAR_PRIVATE;
 
400
                default:          return PARSER_IMG_VAR_PUBLIC;
317
401
            }
318
402
 
319
 
        default: return PARSER_IMG_NONE;
 
403
        default:                  return PARSER_IMG_NONE;
320
404
    }
321
405
}
322
406
#endif // STANDALONE
324
408
Token* Parser::FindTokenByName(const wxString& name, bool globalsOnly, short int kindMask) const
325
409
{
326
410
    wxCriticalSectionLocker lock(s_MutexProtection);
327
 
    int result = m_pTokens->TokenExists(name,-1,kindMask);
328
 
    return m_pTokens->at(result);
 
411
    int result = m_pTokensTree->TokenExists(name, -1, kindMask);
 
412
    return m_pTokensTree->at(result);
329
413
}
330
414
 
331
415
Token* Parser::FindChildTokenByName(Token* parent, const wxString& name, bool useInheritance, short int kindMask) const
332
416
{
333
417
    if (!parent)
334
418
        return FindTokenByName(name, false, kindMask);
 
419
 
335
420
    Token* result = 0;
336
 
    wxCriticalSectionLocker *lock = 0;
337
421
    {
338
 
        lock = new wxCriticalSectionLocker(s_MutexProtection);
339
 
        result = m_pTokens->at(m_pTokens->TokenExists(name,parent->GetSelf(),kindMask));
340
 
        delete lock;
 
422
        wxCriticalSectionLocker lock(s_MutexProtection);
 
423
        result = m_pTokensTree->at(m_pTokensTree->TokenExists(name, parent->GetSelf(), kindMask));
341
424
    }
342
 
    if(!result && useInheritance)
 
425
 
 
426
    if (!result && useInheritance)
343
427
    {
344
428
        // no reason for a critical section here:
345
429
        // it will only recurse to itself.
346
430
        // the critical section above is sufficient
347
431
        TokenIdxSet::iterator it;
348
 
        for(it = parent->m_DirectAncestors.begin();it != parent->m_DirectAncestors.end();++it)
 
432
        for (it = parent->m_DirectAncestors.begin(); it != parent->m_DirectAncestors.end(); ++it)
349
433
        {
350
 
            Token* ancestor = m_pTokens->at(*it);
 
434
            Token* ancestor = m_pTokensTree->at(*it);
351
435
            result = FindChildTokenByName(ancestor, name, true, kindMask);
352
 
            if(result)
 
436
            if (result)
353
437
                break;
354
438
        }
355
439
    }
356
440
    return result;
357
441
}
358
442
 
359
 
size_t Parser::FindMatches(const wxString& s,TokenList& result,bool caseSensitive,bool is_prefix)
 
443
size_t Parser::FindMatches(const wxString& s, TokenList& result, bool caseSensitive, bool is_prefix)
360
444
{
361
445
    result.clear();
362
446
    TokenIdxSet tmpresult;
363
447
    wxCriticalSectionLocker lock(s_MutexProtection);
364
 
    if(!m_pTokens->FindMatches(s,tmpresult,caseSensitive,is_prefix))
 
448
    if (!m_pTokensTree->FindMatches(s, tmpresult, caseSensitive, is_prefix))
365
449
        return 0;
366
450
 
367
451
    TokenIdxSet::iterator it;
368
 
    for(it = tmpresult.begin();it!=tmpresult.end();++it)
 
452
    for (it = tmpresult.begin(); it != tmpresult.end(); ++it)
369
453
    {
370
 
        Token* token = m_pTokens->at(*it);
371
 
        if(token)
 
454
        Token* token = m_pTokensTree->at(*it);
 
455
        if (token)
372
456
        result.push_back(token);
373
457
    }
374
458
    return result.size();
375
459
}
376
460
 
 
461
size_t Parser::FindMatches(const wxString& s, TokenIdxSet& result, bool caseSensitive, bool is_prefix)
 
462
{
 
463
    result.clear();
 
464
    TokenIdxSet tmpresult;
 
465
    wxCriticalSectionLocker lock(s_MutexProtection);
 
466
    if (!m_pTokensTree->FindMatches(s, tmpresult, caseSensitive, is_prefix))
 
467
        return 0;
 
468
 
 
469
    TokenIdxSet::iterator it;
 
470
    for (it = tmpresult.begin(); it != tmpresult.end(); ++it)
 
471
    {
 
472
        Token* token = m_pTokensTree->at(*it);
 
473
        if (token)
 
474
        //result.push_back(token);
 
475
        result.insert(*it);
 
476
    }
 
477
    return result.size();
 
478
}
 
479
 
377
480
void Parser::LinkInheritance(bool tempsOnly)
378
481
{
379
482
    wxCriticalSectionLocker lock(s_MutexProtection);
380
 
    (tempsOnly ? m_pTempTokens :  m_pTokens)->RecalcData();
 
483
    (tempsOnly ? m_pTempTokensTree :  m_pTokensTree)->RecalcData();
381
484
}
382
485
 
383
486
void Parser::MarkFileTokensAsLocal(const wxString& filename, bool local, void* userData)
384
487
{
385
488
    wxCriticalSectionLocker lock(s_MutexProtection);
386
 
    m_pTokens->MarkFileTokensAsLocal(filename, local, userData);
 
489
    m_pTokensTree->MarkFileTokensAsLocal(filename, local, userData);
387
490
}
388
491
 
389
492
bool Parser::ParseBuffer(const wxString& buffer, bool isLocal, bool bufferSkipBlocks, bool isTemp)
390
493
{
391
494
    ParserThreadOptions opts;
392
 
    opts.wantPreprocessor = m_Options.wantPreprocessor;
393
 
    opts.followLocalIncludes = m_Options.followLocalIncludes;
 
495
    opts.wantPreprocessor     = m_Options.wantPreprocessor;
 
496
    opts.followLocalIncludes  = m_Options.followLocalIncludes;
394
497
    opts.followGlobalIncludes = m_Options.followGlobalIncludes;
395
 
    opts.useBuffer = true;
396
 
    opts.isTemp = isTemp;
397
 
    opts.bufferSkipBlocks = bufferSkipBlocks;
398
 
    opts.handleFunctions = false;
 
498
    opts.useBuffer            = true;
 
499
    opts.isTemp               = isTemp;
 
500
    opts.bufferSkipBlocks     = bufferSkipBlocks;
 
501
    opts.handleFunctions      = false;
 
502
 
399
503
    return Parse(buffer, isLocal, opts);
400
504
}
401
505
 
402
506
void Parser::BatchParse(const wxArrayString& filenames)
403
507
{
404
 
    m_batchtimer.Stop();
 
508
    m_BatchTimer.Stop();
405
509
    m_IsBatch = true;
406
510
    m_Pool.BatchBegin();
 
511
 
 
512
    Manager::Get()->GetLogManager()->DebugLog(F(_T("Batch-parsing %d file(s)..."), filenames.GetCount()));
407
513
    for (unsigned int i = 0; i < filenames.GetCount(); ++i)
408
 
    {
409
 
        LoaderBase* loader = NULL; //defer loading until later
410
 
        Parse(filenames[i], true, loader);
411
 
    }
 
514
        Parse(filenames[i]); // defer loading until later
412
515
 
413
516
    // Allow future parses to take place in this same run
414
 
    m_batchtimer.Start(batch_timer_delay,wxTIMER_ONE_SHOT);
 
517
    m_BatchTimer.Start(batch_timer_delay,wxTIMER_ONE_SHOT);
415
518
}
416
519
 
417
520
bool Parser::Parse(const wxString& filename, bool isLocal, LoaderBase* loader)
418
521
{
419
522
    ParserThreadOptions opts;
420
 
    opts.wantPreprocessor = m_Options.wantPreprocessor;
421
 
    opts.useBuffer = false;
422
 
    opts.bufferSkipBlocks = false;
 
523
    opts.wantPreprocessor      = m_Options.wantPreprocessor;
 
524
    opts.useBuffer             = false;
 
525
    opts.bufferSkipBlocks      = false;
423
526
    opts.bufferSkipOuterBlocks = false;
424
 
    opts.followLocalIncludes = m_Options.followLocalIncludes;
425
 
    opts.followGlobalIncludes = m_Options.followGlobalIncludes;
426
 
    opts.loader = loader;
427
 
 
428
 
    // feature incomplete
429
 
//    bool isSource = FileTypeOf(filename) == ftSource;
430
 
//    opts.handleClasses = !isSource;
431
 
//    opts.handleEnums = !isSource;
432
 
////    opts.handleFunctions = !isSource; // always true, so we can get the implementation info
433
 
//    opts.handleTypedefs = !isSource;
434
 
//    opts.handleVars = !isSource;
 
527
    opts.followLocalIncludes   = m_Options.followLocalIncludes;
 
528
    opts.followGlobalIncludes  = m_Options.followGlobalIncludes;
 
529
    opts.loader                = loader; // maybe 0 at this point
435
530
 
436
531
    return Parse(UnixFilename(filename), isLocal, opts);
437
532
}
442
537
    bool result = false;
443
538
    do
444
539
    {
445
 
        if(!opts.useBuffer)
 
540
        if (!opts.useBuffer)
446
541
        {
447
542
            wxCriticalSectionLocker lock(s_MutexProtection);
448
 
            bool canparse = !m_pTokens->IsFileParsed(buffOrFile);
449
 
            if(canparse)
450
 
                canparse = m_pTokens->ReserveFileForParsing(buffOrFile,true) != 0;
 
543
 
 
544
            bool canparse = !m_pTokensTree->IsFileParsed(buffOrFile);
 
545
            if (canparse)
 
546
                canparse = m_pTokensTree->ReserveFileForParsing(buffOrFile, true) != 0;
 
547
 
451
548
            if (!canparse)
452
549
            {
453
 
               if(opts.loader) // if a loader is already open at this point, the caller must clean it up
454
 
                   Manager::Get()->GetLogManager()->DebugLog(_T("CodeCompletion Plugin: FileLoader memory leak likely loading file ")+bufferOrFilename);
 
550
               if (opts.loader) // if a loader is already open at this point, the caller must clean it up
 
551
                   Manager::Get()->GetLogManager()->DebugLog(_T("Parse() : CodeCompletion Plugin: FileLoader memory leak likely while loading file ")+bufferOrFilename);
455
552
               break;
456
553
            }
457
 
            if(!opts.loader) //this should always be true (memory will leak if a loader has already been initialized before this point)
458
 
                opts.loader=Manager::Get()->GetFileManager()->Load(bufferOrFilename, false);
 
554
 
 
555
            if (!opts.loader) // this should always be true (memory will leak if a loader has already been initialized before this point)
 
556
                opts.loader = Manager::Get()->GetFileManager()->Load(bufferOrFilename, true);
459
557
        }
460
558
 
461
 
//        Manager::Get()->GetLogManager()->DebugLog(_T("Creating task for: %s"), buffOrFile.c_str());
 
559
        TRACE(_T("Parse() : Creating task for: %s"), buffOrFile.wx_str());
462
560
        ParserThread* thread = new ParserThread(this,
463
561
                                                buffOrFile,
464
562
                                                isLocal,
465
563
                                                opts,
466
 
                                                m_pTokens);
 
564
                                                m_pTokensTree);
467
565
        if (opts.useBuffer)
468
566
        {
469
567
            result = thread->Parse();
472
570
            break;
473
571
        }
474
572
 
475
 
        bool use_timer = m_batchtimer.IsRunning();
476
 
        if(!m_IsBatch && wxThread::IsMain())
 
573
        bool use_timer = m_BatchTimer.IsRunning();
 
574
        if (!m_IsBatch && wxThread::IsMain())
477
575
        {
478
576
            use_timer = true;
479
577
            m_IsBatch = true;
480
578
            m_Pool.BatchBegin();
481
579
        }
482
 
//        Manager::Get()->GetLogManager()->DebugLog(_T("parsing %s"),buffOrFile.c_str());
483
 
        if(m_IgnoreThreadEvents)
 
580
 
 
581
        TRACE(_T("Parse() : Parsing %s"), buffOrFile.wx_str());
 
582
 
 
583
        if (m_IgnoreThreadEvents)
484
584
            m_IgnoreThreadEvents = false;
 
585
 
485
586
        #ifdef CODECOMPLETION_PROFILING
486
587
        StartStopWatch();
487
 
        m_batchtimer.Stop();
 
588
        m_BatchTimer.Stop();
488
589
        thread->Parse();
489
590
        #else
490
591
        m_Pool.AddTask(thread, true);
492
593
 
493
594
        // For every parse, reset the countdown to -batch_timer_delay.
494
595
        // This will give us a tolerance period before the next parse job is queued.
495
 
        if(use_timer)
496
 
            m_batchtimer.Start(batch_timer_delay,wxTIMER_ONE_SHOT);
 
596
        if (use_timer)
 
597
            m_BatchTimer.Start(batch_timer_delay, wxTIMER_ONE_SHOT);
497
598
        result = true;
498
 
    }while(false);
 
599
    } while(false);
 
600
 
499
601
    return result;
500
602
}
501
603
 
503
605
{
504
606
    ParserThreadOptions opts;
505
607
    opts.wantPreprocessor = m_Options.wantPreprocessor;
506
 
    opts.useBuffer = true;
 
608
    opts.useBuffer        = true;
507
609
    opts.bufferSkipBlocks = true;
508
 
    opts.handleFunctions = true;
509
 
    ParserThread* thread = new ParserThread(this,
510
 
                                            buffer,
511
 
                                            false,
512
 
                                            opts,
513
 
                                            m_pTempTokens);
514
 
    bool result = thread->Parse();
515
 
    delete thread;
516
 
    return result;
 
610
    opts.handleFunctions  = true;
 
611
 
 
612
    ParserThread thread(this,
 
613
                        buffer,
 
614
                        false,
 
615
                        opts,
 
616
                        m_pTempTokensTree);
 
617
 
 
618
    return thread.Parse();
517
619
}
518
620
 
519
621
bool Parser::ParseBufferForUsingNamespace(const wxString& buffer, wxArrayString& result)
520
622
{
521
623
    ParserThreadOptions opts;
522
 
//    opts.wantPreprocessor = m_Options.wantPreprocessor; // ignored
523
 
//    opts.useBuffer = false; // ignored
524
 
//    opts.bufferSkipBlocks = false; // ignored
525
 
    ParserThread* thread = new ParserThread(this,
526
 
                                            wxEmptyString,
527
 
                                            false,
528
 
                                            opts,
529
 
                                            m_pTempTokens);
530
 
    bool bresult = thread->ParseBufferForUsingNamespace(buffer, result);
531
 
    delete thread;
532
 
    return bresult;
 
624
 
 
625
    ParserThread thread(this,
 
626
                        wxEmptyString,
 
627
                        false,
 
628
                        opts,
 
629
                        m_pTempTokensTree);
 
630
 
 
631
    return thread.ParseBufferForUsingNamespace(buffer, result);
533
632
}
534
633
 
535
634
bool Parser::RemoveFile(const wxString& filename)
536
635
{
537
 
    if(!Done())
 
636
    if (!Done())
538
637
        return false; // Can't alter the tokens tree if parsing has not finished
 
638
 
539
639
    bool result = false;
540
640
    wxString file = UnixFilename(filename);
541
641
    {
542
642
        wxCriticalSectionLocker lock(s_MutexProtection);
543
 
        size_t index = m_pTokens->GetFileIndex(file);
544
 
        result = m_pTokens->m_FilesStatus.count(index);
 
643
        size_t index = m_pTokensTree->GetFileIndex(file);
 
644
        result = m_pTokensTree->m_FilesStatus.count(index);
545
645
 
546
 
        m_pTokens->RemoveFile(filename);
547
 
        m_pTokens->m_FilesMap.erase(index);
548
 
        m_pTokens->m_FilesStatus.erase(index);
549
 
        m_pTokens->m_FilesToBeReparsed.erase(index);
550
 
        m_pTokens->m_modified = true;
 
646
        m_pTokensTree->RemoveFile(filename);
 
647
        m_pTokensTree->m_FilesMap.erase(index);
 
648
        m_pTokensTree->m_FilesStatus.erase(index);
 
649
        m_pTokensTree->m_FilesToBeReparsed.erase(index);
 
650
        m_pTokensTree->m_Modified = true;
551
651
    }
 
652
 
552
653
    return result;
553
654
}
554
655
 
556
657
{
557
658
    if (!Done())
558
659
        return false; // if still parsing, exit with error
 
660
 
559
661
    wxString file = UnixFilename(filename);
560
 
    if(isLocal)
 
662
    if (isLocal)
561
663
        m_LocalFiles.insert(filename);
562
664
    else
563
665
        m_LocalFiles.erase(filename);
 
666
 
564
667
    {
565
668
        wxCriticalSectionLocker lock(s_MutexProtection);
566
 
        m_pTokens->FlagFileForReparsing(file);
 
669
        m_pTokensTree->FlagFileForReparsing(file);
567
670
    }
 
671
 
568
672
    m_NeedsReparse = true;
569
 
    m_timer.Start(reparse_timer_delay,wxTIMER_ONE_SHOT);
 
673
    m_Timer.Start(reparse_timer_delay,wxTIMER_ONE_SHOT);
 
674
 
570
675
    return true;
571
676
}
572
677
 
573
678
void Parser::Clear()
574
679
{
575
680
    DisconnectEvents();
576
 
//    if(m_ShuttingDown)
577
 
//    {
578
 
//        Manager::Get()->GetLogManager()->DebugLog(_T("Terminating threads..."));
579
 
//    }
580
 
    TerminateAllThreads(); //
581
 
//    if(m_ShuttingDown)
582
 
//    {
583
 
//        Manager::Get()->GetLogManager()->DebugLog(_T("Done."));
584
 
//    }
585
 
 
 
681
    TerminateAllThreads();
586
682
    Manager::ProcessPendingEvents();
587
683
 
588
684
    m_IncludeDirs.Clear();
589
 
    m_pTokens->clear();
590
 
    m_pTempTokens->clear();
 
685
    m_pTokensTree->clear();
 
686
    m_pTempTokensTree->clear();
591
687
 
592
688
    m_LocalFiles.clear();
593
689
    m_GlobalIncludes.clear();
594
690
 
595
 
    if(!m_ShuttingDown)
 
691
    if (!m_ShuttingDown)
596
692
    {
597
693
        Manager::ProcessPendingEvents();
598
694
        ConnectEvents();
607
703
    wxCriticalSectionLocker lock(s_MutexProtection);
608
704
 
609
705
    char CACHE_MAGIC_READ[] = "           ";
610
 
    m_pTokens->clear(); // Clear data
 
706
    m_pTokensTree->clear(); // Clear data
611
707
 
612
708
    // File format is like this:
613
709
    //
647
743
            int i;
648
744
            for (i = 0; i < fcount && !f->Eof(); ++i)
649
745
            {
650
 
                if(!LoadIntFromFile(f,&idx)) // Filename index
651
 
                    break;
652
 
                if(idx != i)
653
 
                    break;
654
 
                if(!LoadStringFromFile(f,file)) // Filename data
655
 
                    break;
656
 
                if(!idx)
 
746
                if (!LoadIntFromFile(f,&idx)) // Filename index
 
747
                    break;
 
748
                if (idx != i)
 
749
                    break;
 
750
                if (!LoadStringFromFile(f,file)) // Filename data
 
751
                    break;
 
752
                if (!idx)
657
753
                    file.Clear();
658
 
                if(file.IsEmpty())
 
754
                if (file.IsEmpty())
659
755
                    idx = 0;
660
 
                m_pTokens->m_FilenamesMap.insert(file);
 
756
                m_pTokensTree->m_FilenamesMap.insert(file);
661
757
                actual_fcount++;
662
758
            }
663
759
            result = (actual_fcount == fcount);
664
 
            if(!result)
 
760
            if (!result)
665
761
                break;
666
 
            if(tcount)
667
 
                m_pTokens->m_Tokens.resize(tcount,0);
 
762
            if (tcount)
 
763
                m_pTokensTree->m_Tokens.resize(tcount,0);
668
764
            // Tokens
669
765
            for (i = 0; i < tcount && !f->Eof(); ++i)
670
766
            {
671
767
                token = 0;
672
768
                if (!LoadIntFromFile(f, &nonempty_token))
673
769
                break;
674
 
                if(nonempty_token != 0)
 
770
                if (nonempty_token != 0)
675
771
                {
676
772
                    token = new Token();
677
773
                    if (!token->SerializeIn(f))
680
776
                        token = 0;
681
777
                        break;
682
778
                    }
683
 
                    m_pTokens->insert(i,token);
 
779
                    m_pTokensTree->insert(i,token);
684
780
                }
685
781
                ++actual_tcount;
686
782
            }
687
 
            if(actual_tcount != tcount)
 
783
            if (actual_tcount != tcount)
688
784
                break;
689
 
            m_pTokens->RecalcFreeList();
 
785
            m_pTokensTree->RecalcFreeList();
690
786
            result = true;
691
 
        }while(false);
 
787
        } while(false);
692
788
 
693
 
    }
694
 
    while(false);
 
789
    } while(false);
695
790
 
696
791
//  End loading process
697
792
 
698
 
    if(result)
 
793
    if (result)
699
794
        m_UsingCache = true;
700
795
    else
701
 
        m_pTokens->clear();
702
 
    m_pTokens->m_modified = false;
 
796
        m_pTokensTree->clear();
 
797
 
 
798
    m_pTokensTree->m_Modified = false;
 
799
 
703
800
    return result;
704
801
}
705
802
 
709
806
    wxCriticalSectionLocker lock(s_MutexProtection);
710
807
//  Begin saving process
711
808
 
712
 
    size_t tcount = m_pTokens->m_Tokens.size();
713
 
    size_t fcount = m_pTokens->m_FilenamesMap.size();
 
809
    size_t tcount = m_pTokensTree->m_Tokens.size();
 
810
    size_t fcount = m_pTokensTree->m_FilenamesMap.size();
714
811
    size_t i = 0;
715
812
 
716
813
    // write cache magic
720
817
    SaveIntToFile(f, tcount); // num tokens
721
818
 
722
819
    // Filenames
723
 
    for(i = 0; i < fcount; ++i)
 
820
    for (i = 0; i < fcount; ++i)
724
821
    {
725
822
        SaveIntToFile(f,i);
726
 
        SaveStringToFile(f,m_pTokens->m_FilenamesMap.GetString(i));
 
823
        SaveStringToFile(f,m_pTokensTree->m_FilenamesMap.GetString(i));
727
824
    }
728
825
 
729
826
    // Tokens
730
827
 
731
828
    for (i = 0; i < tcount; ++i)
732
829
    {
733
 
        // Manager::Get()->GetLogManager()->DebugLog(_T("Token #%d, offset %d"),i,f->TellO());
734
 
        Token* token = m_pTokens->at(i);
 
830
        TRACE(_T("WriteToCache() : Token #%d, offset %d"),i,f->TellO());
 
831
        Token* token = m_pTokensTree->at(i);
735
832
        SaveIntToFile(f,(token!=0) ? 1 : 0);
736
 
        if(token)
 
833
        if (token)
737
834
            token->SerializeOut(f);
738
835
    }
739
836
 
740
837
    result = true;
741
838
 
742
 
    if(result)
743
 
        m_pTokens->m_modified = false;
744
 
    return result;
 
839
    if (result)
 
840
        m_pTokensTree->m_Modified = false;
 
841
 
745
842
//  End saving process
746
843
    return result;
747
844
}
758
855
    if (base.Last() == wxFILE_SEP_PATH)
759
856
        base.RemoveLast();
760
857
 
761
 
    if(m_IncludeDirs.Index(base) == wxNOT_FOUND)
 
858
    if (m_IncludeDirs.Index(base) == wxNOT_FOUND)
762
859
    {
763
 
//        Manager::Get()->GetLogManager()->DebugLog(_T("Adding %s"), base.c_str());
 
860
        TRACE(_T("AddIncludeDir() : Adding %s"), base.wx_str());
764
861
        m_IncludeDirs.Add(base);
765
862
    }
766
 
} // end of AddIncludeDir
 
863
}
767
864
 
768
865
wxString Parser::FindFirstFileInIncludeDirs(const wxString& file)
769
866
{
770
867
    wxString FirstFound = m_GlobalIncludes.GetItem(file);
771
 
    if(FirstFound.IsEmpty())
 
868
    if (FirstFound.IsEmpty())
772
869
    {
773
870
        wxArrayString FoundSet = FindFileInIncludeDirs(file,true);
774
 
        if(FoundSet.GetCount())
 
871
        if (FoundSet.GetCount())
775
872
        {
776
873
            FirstFound = UnixFilename(FoundSet[0]);
777
 
            m_GlobalIncludes.AddItem(file,FirstFound);
 
874
            m_GlobalIncludes.AddItem(file, FirstFound);
778
875
        }
779
876
    }
780
877
    return FirstFound;
781
878
}
782
879
 
783
 
wxArrayString Parser::FindFileInIncludeDirs(const wxString& file,bool firstonly)
 
880
wxArrayString Parser::FindFileInIncludeDirs(const wxString& file, bool firstonly)
784
881
{
785
882
    wxArrayString FoundSet;
786
 
    for(size_t idxSearch = 0; idxSearch < m_IncludeDirs.GetCount(); ++idxSearch)
 
883
    for (size_t idxSearch = 0; idxSearch < m_IncludeDirs.GetCount(); ++idxSearch)
787
884
    {
788
885
        wxString base = m_IncludeDirs[idxSearch];
789
886
        wxFileName tmp = file;
790
887
        NormalizePath(tmp,base);
791
888
        wxString fullname = tmp.GetFullPath();
792
 
        if(wxFileExists(fullname))
 
889
        if (wxFileExists(fullname))
793
890
        {
794
891
            FoundSet.Add(fullname);
795
 
            if(firstonly)
 
892
            if (firstonly)
796
893
                break;
797
894
        }
798
 
    } // end for : idx : idxSearch
799
 
//    Manager::Get()->GetLogManager()->DebugLog(_T("Searching %s"), file.c_str());
800
 
//    Manager::Get()->GetLogManager()->DebugLog(_T("Found %d"), FoundSet.GetCount());
 
895
    }
 
896
 
 
897
    TRACE(_T("FindFileInIncludeDirs() : Searching %s"), file.wx_str());
 
898
    TRACE(_T("FindFileInIncludeDirs() : Found %d"), FoundSet.GetCount());
 
899
 
801
900
    return FoundSet;
802
 
} // end of FindFileInIncludeDirs
 
901
}
803
902
 
804
903
void Parser::OnAllThreadsDone(CodeBlocksEvent& event)
805
904
{
806
 
    if(m_IgnoreThreadEvents)
 
905
    if (m_IgnoreThreadEvents)
807
906
        return;
 
907
 
808
908
    EndStopWatch();
809
 
//    LinkInheritance(false);
 
909
 
810
910
    wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED, PARSER_END);
811
911
    evt.SetClientData(this);
812
912
    wxPostEvent(m_pParent, evt);
813
913
}
814
914
 
815
 
wxString Parser::GetFullFileName(const wxString& src,const wxString& tgt, bool isGlobal)
 
915
wxString Parser::GetFullFileName(const wxString& src, const wxString& tgt, bool isGlobal)
816
916
{
817
917
    wxCriticalSectionLocker lock(s_mutexListProtection);
818
918
    wxString fullname(_T("")); // Initialize with Empty String
840
940
    {
841
941
        wxFileName fname(tgt);
842
942
        wxFileName source(src);
843
 
        if(NormalizePath(fname,source.GetPath(wxPATH_GET_VOLUME)))
 
943
        if (NormalizePath(fname,source.GetPath(wxPATH_GET_VOLUME)))
844
944
        {
845
945
            fullname = fname.GetFullPath();
846
 
            if(!wxFileExists(fullname))
 
946
            if (!wxFileExists(fullname))
847
947
                fullname.Clear();
848
948
        }
849
949
    }
851
951
    return fullname;
852
952
}
853
953
 
854
 
void Parser::OnParseFile(const wxString& filename,int flags)
 
954
void Parser::DoParseFile(const wxString& filename, bool isGlobal)
855
955
{
856
 
    if(m_IgnoreThreadEvents)
857
 
        return;
858
 
    if ((flags == 0 && !m_Options.followLocalIncludes) ||
859
 
        (flags == 1 && !m_Options.followGlobalIncludes))
860
 
        return;
 
956
    if (m_IgnoreThreadEvents)
 
957
        return;
 
958
 
 
959
    if (   (!isGlobal && !m_Options.followLocalIncludes)
 
960
        || ( isGlobal && !m_Options.followGlobalIncludes) )
 
961
        return;
 
962
 
861
963
    if (filename.IsEmpty())
862
964
        return;
863
 
    LoaderBase* loader = NULL; //defer loading until later
864
 
    Parse(filename, flags == 0, loader); // isLocal = (flags==0)
 
965
 
 
966
    LoaderBase* loader = 0; // defer loading until later
 
967
    Parse(filename, !isGlobal, loader);
865
968
}
866
969
 
867
970
void Parser::StartStopWatch()
868
971
{
869
 
    if(!m_StopWatchRunning)
 
972
    if (!m_StopWatchRunning)
870
973
    {
871
974
        m_StopWatchRunning = true;
872
975
        m_StopWatch.Start();
875
978
 
876
979
void Parser::EndStopWatch()
877
980
{
878
 
    if(m_StopWatchRunning)
 
981
    if (m_StopWatchRunning)
879
982
    {
880
983
        m_StopWatch.Pause();
881
984
        m_StopWatchRunning = false;
902
1005
void Parser::OnBatchTimer(wxTimerEvent& event)
903
1006
{
904
1007
#ifndef CODECOMPLETION_PROFILING
905
 
    Manager::Get()->GetLogManager()->DebugLog(_T("Starting batch parsing"));
906
 
    if(m_IsBatch)
 
1008
    Manager::Get()->GetLogManager()->DebugLog(_T("Starting batch parsing..."));
 
1009
    if (m_IsBatch)
907
1010
    {
908
1011
        m_IsBatch = false;
909
1012
        StartStopWatch();
911
1014
    }
912
1015
#else
913
1016
    EndStopWatch();
914
 
    if(m_LastStopWatchTime > batch_timer_delay)
 
1017
    if (m_LastStopWatchTime > batch_timer_delay)
915
1018
        m_LastStopWatchTime -= batch_timer_delay;
916
1019
    else
917
1020
        m_LastStopWatchTime = 0;
922
1025
 
923
1026
bool Parser::ReparseModifiedFiles()
924
1027
{
925
 
    if(!m_NeedsReparse || !m_Pool.Done())
 
1028
    if (!m_NeedsReparse || !m_Pool.Done())
926
1029
        return false;
 
1030
 
927
1031
    Manager::Get()->GetLogManager()->DebugLog(_T("Reparsing saved files..."));
928
1032
    m_NeedsReparse = false;
929
1033
    std::queue<wxString> files_list;
934
1038
        // loop two times so that we reparse modified *header* files first
935
1039
        // because they usually hold definitions which need to exist
936
1040
        // when we parse the normal source files...
937
 
        for(it = m_pTokens->m_FilesToBeReparsed.begin(); it != m_pTokens->m_FilesToBeReparsed.end(); ++it)
 
1041
        for (it = m_pTokensTree->m_FilesToBeReparsed.begin(); it != m_pTokensTree->m_FilesToBeReparsed.end(); ++it)
938
1042
        {
939
 
            m_pTokens->RemoveFile(*it);
940
 
            wxString filename = m_pTokens->m_FilenamesMap.GetString(*it);
 
1043
            m_pTokensTree->RemoveFile(*it);
 
1044
            wxString filename = m_pTokensTree->m_FilenamesMap.GetString(*it);
941
1045
            if (FileTypeOf(filename) == ftSource) // ignore source files (*.cpp etc)
942
1046
                continue;
943
1047
            files_list.push(filename);
944
1048
        }
945
 
        for(it = m_pTokens->m_FilesToBeReparsed.begin(); it != m_pTokens->m_FilesToBeReparsed.end(); ++it)
 
1049
        for (it = m_pTokensTree->m_FilesToBeReparsed.begin(); it != m_pTokensTree->m_FilesToBeReparsed.end(); ++it)
946
1050
        {
947
 
            m_pTokens->RemoveFile(*it);
948
 
            wxString filename = m_pTokens->m_FilenamesMap.GetString(*it);
 
1051
            m_pTokensTree->RemoveFile(*it);
 
1052
            wxString filename = m_pTokensTree->m_FilenamesMap.GetString(*it);
949
1053
            if (FileTypeOf(filename) != ftSource) // ignore non-source files (*.h etc)
950
1054
                continue;
951
1055
            files_list.push(filename);
960
1064
    }
961
1065
    return true;
962
1066
}
 
1067
 
 
1068
size_t Parser::FindTokensInFile(const wxString& fileName, TokenIdxSet& result, short int kindMask)
 
1069
{
 
1070
    result.clear();
 
1071
    wxString file = UnixFilename(fileName);
 
1072
    TokenIdxSet tmpresult;
 
1073
 
 
1074
    wxCriticalSectionLocker lock(s_MutexProtection);
 
1075
    TRACE(_T("Parser::FindTokensInFile() : Searching for file '%s' in tokens tree..."), file.wx_str());
 
1076
    if ( !m_pTokensTree->FindTokensInFile(file, tmpresult, kindMask) )
 
1077
        return 0;
 
1078
 
 
1079
    for (TokenIdxSet::iterator it = tmpresult.begin(); it != tmpresult.end(); ++it)
 
1080
    {
 
1081
        Token* token = m_pTokensTree->at(*it);
 
1082
        if (token)
 
1083
            result.insert(*it);
 
1084
    }
 
1085
    return result.size();
 
1086
}