Doxygen
Toggle main menu visibility
Loading...
Searching...
No Matches
filename.cpp
Go to the documentation of this file.
1
/******************************************************************************
2
*
3
* Copyright (C) 1997-2026 by Dimitri van Heesch.
4
*
5
* Permission to use, copy, modify, and distribute this software and its
6
* documentation under the terms of the GNU General Public License is hereby
7
* granted. No representations are made about the suitability of this software
8
* for any purpose. It is provided "as is" without express or implied warranty.
9
* See the GNU General Public License for more details.
10
*
11
* Documents produced by Doxygen are derivative works derived from the
12
* input used in their production; they are not affected by this license.
13
*
14
*/
15
16
// own include
17
#include "
filename.h
"
18
19
#include <mutex>
20
21
#include "
cache.h
"
22
#include "
dir.h
"
23
#include "
filedef.h
"
24
#include "
portable.h
"
25
26
/** Cache element for the file name to FileDef mapping cache. */
27
struct
FindFileCacheElem
28
{
29
FindFileCacheElem
(
FileDef
*fd,
bool
ambig) :
fileDef
(fd),
isAmbig
(ambig) {}
30
FileDef
*
fileDef
;
31
bool
isAmbig
;
32
};
33
34
static
Cache<std::string,FindFileCacheElem>
g_findFileDefCache
(5000);
35
36
static
std::mutex
g_findFileDefMutex
;
37
38
FileDef
*
FileNameLinkedMap::findFileDef
(
const
DString
&n,
bool
&ambig)
const
39
{
40
ambig=
false
;
41
if
(n.
empty
())
return
nullptr
;
42
43
44
const
int
maxAddrSize = 20;
45
char
addr[maxAddrSize];
46
snprintf(addr,maxAddrSize,
"%p:"
,
reinterpret_cast<
const
void
*
>
(
this
));
47
DString
key = addr;
48
key+=n;
49
50
std::lock_guard<std::mutex> lock(
g_findFileDefMutex
);
51
FindFileCacheElem
*cachedResult =
g_findFileDefCache
.find(key.
str
());
52
//printf("key=%s cachedResult=%p\n",qPrint(key),cachedResult);
53
if
(cachedResult)
54
{
55
ambig = cachedResult->
isAmbig
;
56
//printf("cached: fileDef=%p\n",cachedResult->fileDef);
57
return
cachedResult->
fileDef
;
58
}
59
else
60
{
61
cachedResult =
g_findFileDefCache
.insert(key.
str
(),
FindFileCacheElem
(
nullptr
,
false
));
62
}
63
64
DString
name=
Dir::cleanDirPath
(n.
str
());
65
DString
path;
66
if
(name.
empty
())
return
nullptr
;
67
size_t
sp0 = name.
rfind
(
'/'
);
68
size_t
sp1 = name.
rfind
(
'\\'
);
69
size_t
slashPos = sp0!=
DString::npos
&& sp1!=
DString::npos
? std::max(sp0,sp1) :
70
sp0!=
DString::npos
? sp0 : sp1;
71
if
(slashPos!=
DString::npos
)
72
{
73
path=
Portable::removeLongPathMarker
(name.
left
(slashPos+1));
74
name=name.
mid
(slashPos+1);
75
}
76
if
(name.
empty
())
return
nullptr
;
77
const
FileName
*fn = this->
find
(name);
78
if
(fn)
79
{
80
//printf("fn->size()=%zu\n",fn->size());
81
if
(fn->size()==1)
82
{
83
const
std::unique_ptr<FileDef> &fd = fn->front();
84
bool
isSamePath =
Portable::fileSystemIsCaseSensitive
() ?
85
fd->getPath().right(path.
length
())==path :
86
fd->getPath().
right
(path.
length
()).
lower
()==path.
lower
();
87
if
(path.
empty
() || isSamePath)
88
{
89
cachedResult->
fileDef
= fd.get();
90
return
fd.get();
91
}
92
}
93
else
// file name alone is ambiguous
94
{
95
int
count=0;
96
FileDef
*lastMatch=
nullptr
;
97
DString
pathStripped =
stripFromIncludePath
(path);
98
for
(
const
auto
&fd_p : *fn)
99
{
100
FileDef
*fd = fd_p.get();
101
DString
fdStripPath =
stripFromIncludePath
(fd->
getPath
());
102
if
(fdStripPath == pathStripped)
103
{
104
// if the stripped paths are equal, we have a perfect match
105
count = 1;
106
lastMatch=fd;
107
break
;
108
}
109
if
(path.
empty
() ||
110
(!pathStripped.
empty
() && fdStripPath.
endsWith
(pathStripped)) ||
111
(pathStripped.
empty
() && fdStripPath.
empty
()))
112
{
113
count++;
114
lastMatch=fd;
115
}
116
}
117
118
ambig=(count>1);
119
cachedResult->
isAmbig
= ambig;
120
cachedResult->
fileDef
= lastMatch;
121
return
lastMatch;
122
}
123
}
124
else
125
{
126
//printf("not found!\n");
127
}
128
return
nullptr
;
129
}
130
131
DString
FileNameLinkedMap::showFileDefMatches
(
const
DString
&n)
const
132
{
133
DString
result;
134
DString
name=
Dir::cleanDirPath
(n.
str
());
135
DString
path;
136
size_t
sp0 = name.
rfind
(
'/'
);
137
size_t
sp1 = name.
rfind
(
'\\'
);
138
size_t
slashPos = sp0!=
DString::npos
&& sp1!=
DString::npos
? std::max(sp0,sp1) :
139
sp0!=
DString::npos
? sp0 : sp1;
140
if
(slashPos!=
DString::npos
)
141
{
142
path=
Portable::removeLongPathMarker
(name.
left
(slashPos+1));
143
name=name.
mid
(slashPos+1);
144
}
145
const
FileName
*fn=this->
find
(name);
146
if
(fn)
147
{
148
bool
first =
true
;
149
DString
pathStripped =
stripFromIncludePath
(path);
150
for
(
const
auto
&fd_p : *fn)
151
{
152
FileDef
*fd = fd_p.get();
153
DString
fdStripPath =
stripFromIncludePath
(fd->
getPath
());
154
if
(path.
empty
() ||
155
(!pathStripped.
empty
() && fdStripPath.
endsWith
(pathStripped)) ||
156
(pathStripped.
empty
() && fdStripPath.
empty
()))
157
{
158
if
(!first) result +=
"\n"
;
159
else
first =
false
;
160
result+=
" "
+fd->
absFilePath
();
161
}
162
}
163
164
}
165
return
result;
166
}
167
168
cache.h
Cache
Definition
cache.h:32
DString
A String class for use with Doxygen wrapping std::string and adding some additional functionality off...
Definition
dstring.h:84
DString::rfind
size_t rfind(char c, size_t pos=npos) const
Definition
dstring.h:244
DString::mid
DString mid(size_t index, size_t len=npos) const
Definition
dstring.h:318
DString::lower
DString lower() const
Definition
dstring.h:326
DString::empty
bool empty() const
Returns true iff the string is empty (std::string compatible alias for isEmpty()).
Definition
dstring.h:148
DString::npos
static constexpr size_t npos
value used to indicate 'not found' or 'to the end of the string', matching std::string::npos
Definition
dstring.h:178
DString::right
DString right(size_t len) const
Definition
dstring.h:311
DString::left
DString left(size_t len) const
Definition
dstring.h:306
DString::str
const std::string & str() const
Definition
dstring.h:645
DString::endsWith
bool endsWith(const char *s) const
Definition
dstring.h:617
DString::length
size_t length() const
Returns the length of the string, not counting the 0-terminator.
Definition
dstring.h:151
Dir::cleanDirPath
static std::string cleanDirPath(const std::string &path)
Definition
dir.cpp:363
FileDef
A model of a file symbol.
Definition
filedef.h:97
FileDef::getPath
virtual DString getPath() const =0
FileDef::absFilePath
virtual DString absFilePath() const =0
FileName
Class representing all files with a certain base name.
Definition
filename.h:31
FileNameLinkedMap::showFileDefMatches
DString showFileDefMatches(const DString &n) const
Returns a list of file definitions in fnMap that match the file name n.
Definition
filename.cpp:131
FileNameLinkedMap::findFileDef
FileDef * findFileDef(const DString &n, bool &ambig) const
Returns the file definition in fnMap that matches the file name n.
Definition
filename.cpp:38
LinkedMap< FileName, FileNameFn, FileNameFn, std::unordered_multimap< std::string, FileName *, FileNameFn, FileNameFn > >::find
const FileName * find(const std::string &key) const
Definition
linkedmap.h:47
dir.h
filedef.h
g_findFileDefCache
static Cache< std::string, FindFileCacheElem > g_findFileDefCache(5000)
g_findFileDefMutex
static std::mutex g_findFileDefMutex
Definition
filename.cpp:36
filename.h
Portable::removeLongPathMarker
DString removeLongPathMarker(const DString &path)
Definition
portable.cpp:656
Portable::fileSystemIsCaseSensitive
bool fileSystemIsCaseSensitive()
Definition
portable.cpp:486
portable.h
Portable versions of functions that are platform dependent.
FindFileCacheElem
Cache element for the file name to FileDef mapping cache.
Definition
filename.cpp:28
FindFileCacheElem::isAmbig
bool isAmbig
Definition
filename.cpp:31
FindFileCacheElem::fileDef
FileDef * fileDef
Definition
filename.cpp:30
FindFileCacheElem::FindFileCacheElem
FindFileCacheElem(FileDef *fd, bool ambig)
Definition
filename.cpp:29
stripFromIncludePath
DString stripFromIncludePath(const DString &path)
Definition
util.cpp:227
src
filename.cpp
Generated by
1.19.0