2
* This file is part of lib_finder plugin for Code::Blocks Studio
3
* Copyright (C) 2006-2008 Bartlomiej Swiecki
5
* wxSmith is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation; either version 2 of the License, or
8
* (at your option) any later version.
10
* wxSmith is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with wxSmith; if not, write to the Free Software
17
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
20
* $Id: wxsmithpluginregistrants.cpp 4504 2007-10-02 21:52:30Z byo $
21
* $HeadURL: svn+ssh://byo@svn.berlios.de/svnroot/repos/codeblocks/trunk/src/plugins/contrib/wxSmith/plugin/wxsmithpluginregistrants.cpp $
24
#include <tinyxml/tinyxml.h>
25
#include <tinyxml/tinywxuni.h>
27
#include <wx/arrstr.h>
29
#include <wx/filename.h>
30
#include <wx/string.h>
33
#include <configmanager.h>
35
#include "librarydetectionmanager.h"
37
LibraryDetectionManager::LibraryDetectionManager(TypedResults& CurrentResults): m_CurrentResults(CurrentResults)
41
LibraryDetectionManager::~LibraryDetectionManager()
46
void LibraryDetectionManager::Clear()
48
for ( size_t i=0; i<Libraries.Count(); ++i )
55
int LibraryDetectionManager::LoadXmlConfig(const wxString& Path)
59
if ( !Dir.IsOpened() ) return 0;
62
if ( Dir.GetFirst(&Name,wxEmptyString,wxDIR_DIRS|wxDIR_HIDDEN) )
66
loaded += LoadXmlConfig(Path+wxFileName::GetPathSeparator()+Name);
68
while ( Dir.GetNext(&Name) );
71
if ( Dir.GetFirst(&Name,wxEmptyString,wxDIR_FILES|wxDIR_HIDDEN) )
75
loaded += LoadXmlFile(Path+wxFileName::GetPathSeparator()+Name) ? 1 : 0;
77
while ( Dir.GetNext(&Name) );
83
int LibraryDetectionManager::LoadXmlFile(const wxString& Name)
86
if ( !TinyXML::LoadDocument( Name, &Doc ) || Doc.Error() ) return 0;
87
return LoadXmlDoc( Doc );
90
int LibraryDetectionManager::LoadXmlDoc( TiXmlDocument& Doc )
93
for ( TiXmlElement* Elem = Doc.FirstChildElement("library");
95
Elem = Elem->NextSiblingElement("library") )
97
// Load the version of this set
99
if ( Elem->QueryIntAttribute( "version", &version ) != TIXML_SUCCESS )
105
wxString ShortCode = wxString(Elem->Attribute("short_code"),wxConvUTF8);
106
if ( ShortCode.IsEmpty() )
112
wxString Name = wxString( Elem->Attribute("name"), wxConvUTF8 );
113
if ( Name.IsEmpty() )
118
// Check if we already have setting of this library
119
// I'm to lazy to firbid const_cast here ;)
120
LibraryDetectionConfigSet* OldSet = const_cast< LibraryDetectionConfigSet* > ( GetLibrary( ShortCode ) );
121
LibraryDetectionConfigSet* NewSet = 0;
125
// There are detection settings yet, we override only when there's newer
126
// or same version already
127
if ( OldSet->Version > version )
133
OldSet->Categories.Clear();
134
OldSet->Configurations.clear();
135
OldSet->LibraryName.Clear();
140
NewSet = new LibraryDetectionConfigSet;
141
Libraries.Add( NewSet );
144
// Setup configuration set
145
NewSet->ShortCode = ShortCode;
146
NewSet->Version = version;
147
NewSet->LibraryName = Name;
149
// Read categories of library
150
for ( TiXmlAttribute* attr = Elem->FirstAttribute();
152
attr = attr->Next() )
154
// if ( !strncasecmp(attr->Name(),"category",8) )
155
if ( !strncmp(attr->Name(),"category",8) )
157
NewSet->Categories.Add( wxString( attr->Value(),wxConvUTF8 ) );
161
// Check if there's corresponding pkg-config entry
162
if ( IsPkgConfigEntry(ShortCode) )
164
LibraryDetectionConfig Config;
165
Config.PkgConfigVar = ShortCode;
166
Config.Description = NewSet->LibraryName + _T(" (pkg-config)");
167
LibraryDetectionFilter Filter;
168
Filter.Type = LibraryDetectionFilter::PkgConfig;
169
Filter.Value = ShortCode;
170
Config.Filters.push_back(Filter);
171
loaded += AddConfig(Config,NewSet) ? 1 : 0;
175
LibraryDetectionConfig Initial;
176
loaded += LoadXml( Elem, Initial, NewSet );
181
int LibraryDetectionManager::LoadXml(TiXmlElement* Elem,LibraryDetectionConfig& Config,LibraryDetectionConfigSet* ConfigSet,bool Filters,bool Settings)
183
wxString Description = wxString(Elem->Attribute("description"),wxConvUTF8);
184
if ( !Description.empty() ) Config.Description = Description;
187
for ( TiXmlElement* Data = Elem->FirstChildElement();
189
Data = Data->NextSiblingElement() )
191
wxString Node = wxString(Data->Value(),wxConvUTF8).MakeLower();
193
if ( Filters && Settings )
196
if ( Node == _T("filters") )
198
loaded += LoadXml(Data,Config,ConfigSet,true,false);
202
if ( Node == _T("settings") )
204
loaded += LoadXml(Data,Config,ConfigSet,false,true);
208
// pkgconfig does define both filter and setting
209
if ( Node == _T("pkgconfig") )
211
Config.PkgConfigVar = wxString(Data->Attribute("name"),wxConvUTF8);
212
LibraryDetectionFilter Filter;
213
Filter.Type = LibraryDetectionFilter::PkgConfig;
214
Filter.Value = Config.PkgConfigVar;
215
Config.Filters.push_back(Filter);
223
LibraryDetectionFilter::FilterType Type = LibraryDetectionFilter::None;
225
if ( Node == _T("platform") ) Type = LibraryDetectionFilter::Platform; else
226
if ( Node == _T("file") ) Type = LibraryDetectionFilter::File; else
227
if ( Node == _T("exec") ) Type = LibraryDetectionFilter::Exec; else
228
if ( Node == _T("compiler") ) Type = LibraryDetectionFilter::Compiler;
230
if ( Type != LibraryDetectionFilter::None )
232
LibraryDetectionFilter Filter;
234
Filter.Value = wxString(Data->Attribute("name"),wxConvUTF8);
235
if ( !Filter.Value.IsEmpty() )
237
Config.Filters.push_back(Filter);
246
if ( Node==_T("path") )
248
wxString Include = wxString(Data->Attribute("include"),wxConvUTF8);
249
wxString Lib = wxString(Data->Attribute("lib"),wxConvUTF8);
250
wxString Obj = wxString(Data->Attribute("obj"),wxConvUTF8);
251
if ( !Include.empty() ) Config.IncludePaths.Add(Include);
252
if ( !Lib.empty() ) Config.LibPaths.Add(Lib);
253
if ( !Obj.empty() ) Config.ObjPaths.Add(Obj);
257
if ( Node==_T("flags") )
259
wxString cFlags = wxString(Data->Attribute("cflags"),wxConvUTF8);
260
wxString lFlags = wxString(Data->Attribute("lflags"),wxConvUTF8);
261
if ( !cFlags.empty() ) Config.CFlags.Add(cFlags);
262
if ( !lFlags.empty() ) Config.LFlags.Add(lFlags);
266
if ( Node==_T("add") )
268
wxString cFlags = wxString(Data->Attribute("cflags"),wxConvUTF8);
269
wxString lFlags = wxString(Data->Attribute("lflags"),wxConvUTF8);
270
wxString Lib = wxString(Data->Attribute("lib") ,wxConvUTF8);
271
wxString Define = wxString(Data->Attribute("define"),wxConvUTF8);
272
if ( !cFlags.empty() ) Config.CFlags.Add(cFlags);
273
if ( !lFlags.empty() ) Config.LFlags.Add(lFlags);
274
if ( !Lib.empty() ) Config.Libs.Add(Lib);
275
if ( !Define.empty() ) Config.Defines.Add(Define);
278
if ( Node==_T("header") )
280
wxString file = wxString(Data->Attribute("file"),wxConvUTF8);
281
if ( !file.empty() ) Config.Headers.Add(file);
284
if ( Node==_T("require") )
286
wxString lib = wxString(Data->Attribute("library"),wxConvUTF8);
287
if ( !lib.empty() ) Config.Require.Add(lib);
292
if ( Settings && Filters )
294
TiXmlElement* Cfg = Elem->FirstChildElement("config");
297
// If there are any sub-configurations, let's
298
// iterate through them and load config-specific settings
299
for ( ;Cfg; Cfg = Cfg->NextSiblingElement("config") )
301
// Append sub-configuration data
302
LibraryDetectionConfig Copy(Config);
303
loaded += LoadXml(Cfg,Copy,ConfigSet);
308
// No sub-config entry, so let's add this one
309
loaded += AddConfig(Config,ConfigSet) ? 1 : 0;
315
bool LibraryDetectionManager::CheckConfig(const LibraryDetectionConfig& Cfg) const
317
if ( Cfg.Filters.empty() ) return false;
321
const LibraryDetectionConfigSet* LibraryDetectionManager::GetLibrary(int Index)
323
if ( Index < 0 ) return NULL;
324
if ( Index >= GetLibraryCount() ) return NULL;
325
return Libraries[Index];
328
const LibraryDetectionConfigSet* LibraryDetectionManager::GetLibrary(const wxString& ShortCode)
330
for ( int i=0; i<GetLibraryCount(); i++ )
332
if ( Libraries[i]->ShortCode == ShortCode )
340
bool LibraryDetectionManager::IsPkgConfigEntry(const wxString& Name)
342
return m_CurrentResults[rtPkgConfig].IsShortCode(Name);
345
bool LibraryDetectionManager::AddConfig(LibraryDetectionConfig& Cfg,LibraryDetectionConfigSet* Set)
347
if ( CheckConfig(Cfg) )
349
Set->Configurations.push_back(Cfg);
355
bool LibraryDetectionManager::LoadSearchFilters()
357
wxString Sep = wxFileName::GetPathSeparator();
360
loaded += LoadXmlConfig(ConfigManager::GetFolder(sdDataGlobal) + Sep + _T("lib_finder"));
361
loaded += LoadXmlConfig(ConfigManager::GetFolder(sdDataUser) + Sep + _T("lib_finder"));
366
int LibraryDetectionManager::StoreNewSettingsFile( const wxString& shortcut, const std::vector< char >& content )
368
// Try to parse file's content
370
if ( !doc.Parse( &content[0] ) ) return -1;
372
// Ensure that this file contains required shortcut
373
if ( !doc.RootElement() ) return -1;
374
if ( !doc.RootElement()->Attribute("short_code") ) return -1;
375
if ( strcmp( doc.RootElement()->Attribute("short_code"), cbU2C(shortcut) ) ) return -1;
377
// Finally load new data - this will make sure that we have valid xml structure
378
int AddedConfigs = LoadXmlDoc( doc );
379
if ( !AddedConfigs ) return -1;
381
// Search for not-yet existing file name
383
wxString BaseName = ConfigManager::GetFolder(sdDataUser) + wxFileName::GetPathSeparator() + _T("lib_finder") + wxFileName::GetPathSeparator();
384
if ( !wxFileName::Mkdir( BaseName, 0777, wxPATH_MKDIR_FULL ) )
388
wxString FileName = BaseName + shortcut + _T(".xml");
389
while ( wxFileName::FileExists( FileName ) || wxFileName::DirExists( FileName ) )
391
FileName = BaseName + shortcut + wxString::Format(_T("%d.xml"),i++);
395
wxFile fl( FileName, wxFile::write_excl );
396
if ( !fl.IsOpened() )
400
const char* ptr = &content[0];
401
size_t len = strlen(ptr);
402
if ( fl.Write( ptr, len ) != len )