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
#include <mutex>
17
18
#include "
cache.h
"
19
#include "
filename.h
"
20
#include "
filedef.h
"
21
#include "
dir.h
"
22
#include "
portable.h
"
23
24
/** Cache element for the file name to FileDef mapping cache. */
25
struct
FindFileCacheElem
26
{
27
FindFileCacheElem
(
FileDef
*fd,
bool
ambig) :
fileDef
(fd),
isAmbig
(ambig) {}
28
FileDef
*
fileDef
;
29
bool
isAmbig
;
30
};
31
32
static
Cache<std::string,FindFileCacheElem>
g_findFileDefCache
(5000);
33
34
static
std::mutex
g_findFileDefMutex
;
35
36
FileDef
*
FileNameLinkedMap::findFileDef
(
const
DString
&n,
bool
&ambig)
const
37
{
38
ambig=
false
;
39
if
(n.
empty
())
return
nullptr
;
40
41
42
const
int
maxAddrSize = 20;
43
char
addr[maxAddrSize];
44
snprintf(addr,maxAddrSize,
"%p:"
,
reinterpret_cast<
const
void
*
>
(
this
));
45
DString
key = addr;
46
key+=n;
47
48
std::lock_guard<std::mutex> lock(
g_findFileDefMutex
);
49
FindFileCacheElem
*cachedResult =
g_findFileDefCache
.find(key.
str
());
50
//printf("key=%s cachedResult=%p\n",qPrint(key),cachedResult);
51
if
(cachedResult)
52
{
53
ambig = cachedResult->
isAmbig
;
54
//printf("cached: fileDef=%p\n",cachedResult->fileDef);
55
return
cachedResult->
fileDef
;
56
}
57
else
58
{
59
cachedResult =
g_findFileDefCache
.insert(key.
str
(),
FindFileCacheElem
(
nullptr
,
false
));
60
}
61
62
DString
name=
Dir::cleanDirPath
(n.
str
());
63
DString
path;
64
if
(name.
empty
())
return
nullptr
;
65
size_t
sp0 = name.
rfind
(
'/'
);
66
size_t
sp1 = name.
rfind
(
'\\'
);
67
size_t
slashPos = sp0!=
DString::npos
&& sp1!=
DString::npos
? std::max(sp0,sp1) :
68
sp0!=
DString::npos
? sp0 : sp1;
69
if
(slashPos!=
DString::npos
)
70
{
71
path=
removeLongPathMarker
(name.
left
(slashPos+1));
72
name=name.
mid
(slashPos+1);
73
}
74
if
(name.
empty
())
return
nullptr
;
75
const
FileName
*fn = this->
find
(name);
76
if
(fn)
77
{
78
//printf("fn->size()=%zu\n",fn->size());
79
if
(fn->size()==1)
80
{
81
const
std::unique_ptr<FileDef> &fd = fn->front();
82
bool
isSamePath =
Portable::fileSystemIsCaseSensitive
() ?
83
fd->getPath().right(path.
length
())==path :
84
fd->getPath().
right
(path.
length
()).
lower
()==path.
lower
();
85
if
(path.
empty
() || isSamePath)
86
{
87
cachedResult->
fileDef
= fd.get();
88
return
fd.get();
89
}
90
}
91
else
// file name alone is ambiguous
92
{
93
int
count=0;
94
FileDef
*lastMatch=
nullptr
;
95
DString
pathStripped =
stripFromIncludePath
(path);
96
for
(
const
auto
&fd_p : *fn)
97
{
98
FileDef
*fd = fd_p.get();
99
DString
fdStripPath =
stripFromIncludePath
(fd->
getPath
());
100
if
(fdStripPath == pathStripped)
101
{
102
// if the stripped paths are equal, we have a perfect match
103
count = 1;
104
lastMatch=fd;
105
break
;
106
}
107
if
(path.
empty
() ||
108
(!pathStripped.
empty
() && fdStripPath.
endsWith
(pathStripped)) ||
109
(pathStripped.
empty
() && fdStripPath.
empty
()))
110
{
111
count++;
112
lastMatch=fd;
113
}
114
}
115
116
ambig=(count>1);
117
cachedResult->
isAmbig
= ambig;
118
cachedResult->
fileDef
= lastMatch;
119
return
lastMatch;
120
}
121
}
122
else
123
{
124
//printf("not found!\n");
125
}
126
return
nullptr
;
127
}
128
129
DString
FileNameLinkedMap::showFileDefMatches
(
const
DString
&n)
const
130
{
131
DString
result;
132
DString
name=
Dir::cleanDirPath
(n.
str
());
133
DString
path;
134
size_t
sp0 = name.
rfind
(
'/'
);
135
size_t
sp1 = name.
rfind
(
'\\'
);
136
size_t
slashPos = sp0!=
DString::npos
&& sp1!=
DString::npos
? std::max(sp0,sp1) :
137
sp0!=
DString::npos
? sp0 : sp1;
138
if
(slashPos!=
DString::npos
)
139
{
140
path=
removeLongPathMarker
(name.
left
(slashPos+1));
141
name=name.
mid
(slashPos+1);
142
}
143
const
FileName
*fn=this->
find
(name);
144
if
(fn)
145
{
146
bool
first =
true
;
147
DString
pathStripped =
stripFromIncludePath
(path);
148
for
(
const
auto
&fd_p : *fn)
149
{
150
FileDef
*fd = fd_p.get();
151
DString
fdStripPath =
stripFromIncludePath
(fd->
getPath
());
152
if
(path.
empty
() ||
153
(!pathStripped.
empty
() && fdStripPath.
endsWith
(pathStripped)) ||
154
(pathStripped.
empty
() && fdStripPath.
empty
()))
155
{
156
if
(!first) result +=
"\n"
;
157
else
first =
false
;
158
result+=
" "
+fd->
absFilePath
();
159
}
160
}
161
162
}
163
return
result;
164
}
165
166
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:89
DString::rfind
size_t rfind(char c, size_t pos=npos) const
Definition
dstring.h:249
DString::mid
DString mid(size_t index, size_t len=npos) const
Definition
dstring.h:323
DString::lower
DString lower() const
Definition
dstring.h:331
DString::empty
bool empty() const
Returns true iff the string is empty (std::string compatible alias for isEmpty()).
Definition
dstring.h:153
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:183
DString::right
DString right(size_t len) const
Definition
dstring.h:316
DString::left
DString left(size_t len) const
Definition
dstring.h:311
DString::str
const std::string & str() const
Definition
dstring.h:634
DString::endsWith
bool endsWith(const char *s) const
Definition
dstring.h:606
DString::length
size_t length() const
Returns the length of the string, not counting the 0-terminator.
Definition
dstring.h:156
Dir::cleanDirPath
static std::string cleanDirPath(const std::string &path)
Definition
dir.cpp:357
FileDef
A model of a file symbol.
Definition
filedef.h:99
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:30
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:129
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:36
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:34
filename.h
Portable::fileSystemIsCaseSensitive
bool fileSystemIsCaseSensitive()
Definition
portable.cpp:470
portable.h
Portable versions of functions that are platform dependent.
FindFileCacheElem
Cache element for the file name to FileDef mapping cache.
Definition
filename.cpp:26
FindFileCacheElem::isAmbig
bool isAmbig
Definition
filename.cpp:29
FindFileCacheElem::fileDef
FileDef * fileDef
Definition
filename.cpp:28
FindFileCacheElem::FindFileCacheElem
FindFileCacheElem(FileDef *fd, bool ambig)
Definition
filename.cpp:27
stripFromIncludePath
DString stripFromIncludePath(const DString &path)
Definition
util.cpp:259
removeLongPathMarker
DString removeLongPathMarker(const DString &path)
Definition
util.cpp:212
src
filename.cpp
Generated by
1.19.0