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-2018 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 <trace_helpers.h>
28 #include <wx/tokenzr.h>
29 #include <wx/log.h>
30 
31 
32 #if defined(__MINGW32__)
33  #define PATH_SEPS wxT( ";\r\n" )
34 #else
35  #define PATH_SEPS wxT( ":;\r\n" ) // unix == linux | mac
36 #endif
37 
38 
39 int SEARCH_STACK::Split( wxArrayString* aResult, const wxString& aPathString )
40 {
41  wxStringTokenizer tokenizer( aPathString, PATH_SEPS, wxTOKEN_STRTOK );
42 
43  while( tokenizer.HasMoreTokens() )
44  {
45  wxString path = tokenizer.GetNextToken();
46 
47  aResult->Add( path );
48  }
49 
50  return aResult->GetCount();
51 }
52 
53 
54 // Convert aRelativePath to an absolute path based on aBaseDir
55 static wxString base_dir( const wxString& aRelativePath, const wxString& aBaseDir )
56 {
57  wxFileName fn = aRelativePath;
58 
59  if( !fn.IsAbsolute() && !!aBaseDir )
60  {
61  wxASSERT_MSG( wxFileName( aBaseDir ).IsAbsolute(), wxT( "Must pass absolute path in aBaseDir" ) );
62  fn.MakeRelativeTo( aBaseDir );
63  }
64 
65  return fn.GetFullPath();
66 }
67 
68 
70  const wxString& aFullFilename, const wxString& aBaseDir )
71 {
72  wxFileName fn = aFullFilename;
73  wxString filename = aFullFilename;
74 
75  unsigned pathlen = fn.GetPath().Len(); // path len, used to find the better (shortest)
76  // subpath within defaults paths
77 
78  for( unsigned kk = 0; kk < GetCount(); kk++ )
79  {
80  fn = aFullFilename;
81 
82  // Search for the shortest subpath within 'this':
83  if( fn.MakeRelativeTo( base_dir( (*this)[kk], aBaseDir ) ) )
84  {
85  if( fn.GetPathWithSep().StartsWith( wxT("..") ) ) // Path outside kicad libs paths
86  continue;
87 
88  if( pathlen > fn.GetPath().Len() ) // A better (shortest) subpath is found
89  {
90  filename = fn.GetPathWithSep() + fn.GetFullName();
91  pathlen = fn.GetPath().Len();
92  }
93  }
94  }
95 
96  return filename;
97 }
98 
99 
100 void SEARCH_STACK::RemovePaths( const wxString& aPaths )
101 {
102  bool isCS = wxFileName::IsCaseSensitive();
103  wxArrayString paths;
104 
105  Split( &paths, aPaths );
106 
107  for( unsigned i=0; i<paths.GetCount(); ++i )
108  {
109  wxString path = paths[i];
110 
111  if( Index( path, isCS ) != wxNOT_FOUND )
112  {
113  Remove( path );
114  }
115  }
116 }
117 
118 
119 void SEARCH_STACK::AddPaths( const wxString& aPaths, int aIndex )
120 {
121  bool isCS = wxFileName::IsCaseSensitive();
122  wxArrayString paths;
123 
124  Split( &paths, aPaths );
125 
126  // appending all of them, on large or negative aIndex
127  if( unsigned( aIndex ) >= GetCount() )
128  {
129  for( unsigned i=0; i<paths.GetCount(); ++i )
130  {
131  wxString path = paths[i];
132 
133  if( wxFileName::IsDirReadable( path )
134  && Index( path, isCS ) == wxNOT_FOUND )
135  {
136  Add( path );
137  }
138  }
139  }
140 
141  // inserting all of them:
142  else
143  {
144  for( unsigned i=0; i<paths.GetCount(); ++i )
145  {
146  wxString path = paths[i];
147 
148  if( wxFileName::IsDirReadable( path )
149  && Index( path, isCS ) == wxNOT_FOUND )
150  {
151  Insert( path, aIndex );
152  aIndex++;
153  }
154  }
155  }
156 }
157 
158 
159 #if 1 // this function is too convoluted for words.
160 
161 const wxString SEARCH_STACK::LastVisitedPath( const wxString& aSubPathToSearch )
162 {
163  wxString path;
164 
165  // Initialize default path to the main default lib path
166  // this is the second path in list (the first is the project path).
167  unsigned pcount = GetCount();
168 
169  if( pcount )
170  {
171  unsigned ipath = 0;
172 
173  if( (*this)[0] == wxGetCwd() )
174  ipath = 1;
175 
176  // First choice of path:
177  if( ipath < pcount )
178  path = (*this)[ipath];
179 
180  // Search a sub path matching this SEARCH_PATH
181  if( !IsEmpty() )
182  {
183  for( ; ipath < pcount; ipath++ )
184  {
185  if( (*this)[ipath].Contains( aSubPathToSearch ) )
186  {
187  path = (*this)[ipath];
188  break;
189  }
190  }
191  }
192  }
193 
194  if( path.IsEmpty() )
195  path = wxGetCwd();
196 
197  return path;
198 }
199 #endif
200 
201 
202 #if defined(DEBUG)
203 void SEARCH_STACK::Show( const wxString& aPrefix ) const
204 {
205  wxLogTrace( tracePathsAndFiles, "%s SEARCH_STACK:", aPrefix );
206 
207  for( unsigned i=0; i<GetCount(); ++i )
208  {
209  wxLogTrace( tracePathsAndFiles, " [%2u]:%s", i, TO_UTF8( (*this)[i] ) );
210  }
211 }
212 #endif
void RemovePaths(const wxString &aPaths)
Function RemovePaths removes the given path(s) from the library path list.
const wxChar *const tracePathsAndFiles
Flag to enable path and file name debug output.
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:95
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)
wxLogTrace helper definitions.
#define PATH_SEPS
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...