Doxygen
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. */
28{
29 FindFileCacheElem(FileDef *fd,bool ambig) : fileDef(fd), isAmbig(ambig) {}
31 bool isAmbig;
32};
33
35
36static std::mutex g_findFileDefMutex;
37
38FileDef *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
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
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
Definition cache.h:32
A String class for use with Doxygen wrapping std::string and adding some additional functionality off...
Definition dstring.h:84
size_t rfind(char c, size_t pos=npos) const
Definition dstring.h:244
DString mid(size_t index, size_t len=npos) const
Definition dstring.h:318
DString lower() const
Definition dstring.h:326
bool empty() const
Returns true iff the string is empty (std::string compatible alias for isEmpty()).
Definition dstring.h:148
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(size_t len) const
Definition dstring.h:311
DString left(size_t len) const
Definition dstring.h:306
const std::string & str() const
Definition dstring.h:645
bool endsWith(const char *s) const
Definition dstring.h:617
size_t length() const
Returns the length of the string, not counting the 0-terminator.
Definition dstring.h:151
static std::string cleanDirPath(const std::string &path)
Definition dir.cpp:363
A model of a file symbol.
Definition filedef.h:97
virtual DString getPath() const =0
virtual DString absFilePath() const =0
Class representing all files with a certain base name.
Definition filename.h:31
DString showFileDefMatches(const DString &n) const
Returns a list of file definitions in fnMap that match the file name n.
Definition filename.cpp:131
FileDef * findFileDef(const DString &n, bool &ambig) const
Returns the file definition in fnMap that matches the file name n.
Definition filename.cpp:38
static Cache< std::string, FindFileCacheElem > g_findFileDefCache(5000)
static std::mutex g_findFileDefMutex
Definition filename.cpp:36
DString removeLongPathMarker(const DString &path)
Definition portable.cpp:656
bool fileSystemIsCaseSensitive()
Definition portable.cpp:486
Portable versions of functions that are platform dependent.
Cache element for the file name to FileDef mapping cache.
Definition filename.cpp:28
FileDef * fileDef
Definition filename.cpp:30
FindFileCacheElem(FileDef *fd, bool ambig)
Definition filename.cpp:29
DString stripFromIncludePath(const DString &path)
Definition util.cpp:227