KiCad PCB EDA Suite
search_stack.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2014 CERN
5  * Copyright (C) 2014-2015 KiCad Developers, see CHANGELOG.TXT for contributors.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, you may find one here:
19  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20  * or you may search the http://www.gnu.org website for the version 2 license,
21  * or you may write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23  */
24 
25 #include <macros.h>
26 #include <search_stack.h>
27 #include <wx/tokenzr.h>
28 
29 
30 #if defined(__MINGW32__)
31  #define PATH_SEPS wxT( ";\r\n" )
32 #else
33  #define PATH_SEPS wxT( ":;\r\n" ) // unix == linux | mac
34 #endif
35 
36 
37 int SEARCH_STACK::Split( wxArrayString* aResult, const wxString aPathString )
38 {
39  wxStringTokenizer tokenizer( aPathString, PATH_SEPS, wxTOKEN_STRTOK );
40 
41  while( tokenizer.HasMoreTokens() )
42  {
43  wxString path = tokenizer.GetNextToken();
44 
45  aResult->Add( path );
46  }
47 
48  return aResult->GetCount();
49 }
50 
51 
52 // Convert aRelativePath to an absolute path based on aBaseDir
53 static wxString base_dir( const wxString& aRelativePath, const wxString& aBaseDir )
54 {
55  wxFileName fn = aRelativePath;
56 
57  if( !fn.IsAbsolute() && !!aBaseDir )
58  {
59  wxASSERT_MSG( wxFileName( aBaseDir ).IsAbsolute(), wxT( "Must pass absolute path in aBaseDir" ) );
60  fn.MakeRelativeTo( aBaseDir );
61  }
62 
63  return fn.GetFullPath();
64 }
65 
66 
68  const wxString& aFullFilename, const wxString& aBaseDir )
69 {
70  wxFileName fn = aFullFilename;
71  wxString filename = aFullFilename;
72 
73  unsigned pathlen = fn.GetPath().Len(); // path len, used to find the better (shortest)
74  // subpath within defaults paths
75 
76  for( unsigned kk = 0; kk < GetCount(); kk++ )
77  {
78  fn = aFullFilename;
79 
80  // Search for the shortest subpath within 'this':
81  if( fn.MakeRelativeTo( base_dir( (*this)[kk], aBaseDir ) ) )
82  {
83  if( fn.GetPathWithSep().StartsWith( wxT("..") ) ) // Path outside kicad libs paths
84  continue;
85 
86  if( pathlen > fn.GetPath().Len() ) // A better (shortest) subpath is found
87  {
88  filename = fn.GetPathWithSep() + fn.GetFullName();
89  pathlen = fn.GetPath().Len();
90  }
91  }
92  }
93 
94  return filename;
95 }
96 
97 
98 void SEARCH_STACK::RemovePaths( const wxString& aPaths )
99 {
100  bool isCS = wxFileName::IsCaseSensitive();
101  wxArrayString paths;
102 
103  Split( &paths, aPaths );
104 
105  for( unsigned i=0; i<paths.GetCount(); ++i )
106  {
107  wxString path = paths[i];
108 
109  if( Index( path, isCS ) != wxNOT_FOUND )
110  {
111  Remove( path );
112  }
113  }
114 }
115 
116 
117 void SEARCH_STACK::AddPaths( const wxString& aPaths, int aIndex )
118 {
119  bool isCS = wxFileName::IsCaseSensitive();
120  wxArrayString paths;
121 
122  Split( &paths, aPaths );
123 
124  // appending all of them, on large or negative aIndex
125  if( unsigned( aIndex ) >= GetCount() )
126  {
127  for( unsigned i=0; i<paths.GetCount(); ++i )
128  {
129  wxString path = paths[i];
130 
131  if( wxFileName::IsDirReadable( path )
132  && Index( path, isCS ) == wxNOT_FOUND )
133  {
134  Add( path );
135  }
136  }
137  }
138 
139  // inserting all of them:
140  else
141  {
142  for( unsigned i=0; i<paths.GetCount(); ++i )
143  {
144  wxString path = paths[i];
145 
146  if( wxFileName::IsDirReadable( path )
147  && Index( path, isCS ) == wxNOT_FOUND )
148  {
149  Insert( path, aIndex );
150  aIndex++;
151  }
152  }
153  }
154 }
155 
156 
157 #if 1 // this function is too convoluted for words.
158 
159 const wxString SEARCH_STACK::LastVisitedPath( const wxString& aSubPathToSearch )
160 {
161  wxString path;
162 
163  // Initialize default path to the main default lib path
164  // this is the second path in list (the first is the project path).
165  unsigned pcount = GetCount();
166 
167  if( pcount )
168  {
169  unsigned ipath = 0;
170 
171  if( (*this)[0] == wxGetCwd() )
172  ipath = 1;
173 
174  // First choice of path:
175  if( ipath < pcount )
176  path = (*this)[ipath];
177 
178  // Search a sub path matching this SEARCH_PATH
179  if( !IsEmpty() )
180  {
181  for( ; ipath < pcount; ipath++ )
182  {
183  if( (*this)[ipath].Contains( aSubPathToSearch ) )
184  {
185  path = (*this)[ipath];
186  break;
187  }
188  }
189  }
190  }
191 
192  if( path.IsEmpty() )
193  path = wxGetCwd();
194 
195  return path;
196 }
197 #endif
198 
199 
200 #if defined(DEBUG)
201 void SEARCH_STACK::Show( const wxString& aPrefix ) const
202 {
203  wxLogDebug( wxT( "%s SEARCH_STACK:" ), GetChars( aPrefix ) );
204 
205  for( unsigned i=0; i<GetCount(); ++i )
206  {
207  wxLogDebug( wxT( " [%2u]:%s" ), i, TO_UTF8( (*this)[i] ) );
208  }
209 }
210 #endif
void RemovePaths(const wxString &aPaths)
Function RemovePaths removes the given path(s) from the library path list.
This file contains miscellaneous commonly used macros and functions.
#define TO_UTF8(wxstring)
Macro TO_UTF8 converts a wxString to a UTF8 encoded C string for all wxWidgets build modes...
Definition: macros.h:47
static int Split(wxArrayString *aResult, const wxString aPathString)
Function Split separates aPathString into individual paths.
static wxString base_dir(const wxString &aRelativePath, const wxString &aBaseDir)
#define PATH_SEPS
static const wxChar * GetChars(const wxString &s)
Function GetChars returns a wxChar* to the actual wxChar* data within a wxString, and is helpful for ...
Definition: macros.h:92
const wxString LastVisitedPath(const wxString &aSubPathToSearch=wxEmptyString)
Function LastVisitedPath is a quirky function inherited from old code that seems to serve particular ...
void AddPaths(const wxString &aPaths, int aIndex=-1)
Function AddPaths insert or append path(s)
wxString FilenameWithRelativePathInSearchList(const wxString &aFullFilename, const wxString &aBaseDir)
Function FilenameWithRelativePathInSearchList returns the shortest possible path which can be use lat...