llvm.org GIT mirror llvm / b8b7cba
[dsymutil][NFC] Replace calls to CoreFoundation with LLVM equivalent. This patch replaces a block of logic that was implemented using CoreFoundations calls with functionally equivalent logic that makes use of LLVM libraries. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@321522 91177308-0d34-0410-b5e6-96231b3b80d8 Jonas Devlieghere 2 years ago
1 changed file(s) with 34 addition(s) and 54 deletion(s). Raw diff Collapse all Expand all
1010
1111 #ifdef __APPLE__
1212 #include "llvm/Support/FileSystem.h"
13 #include "llvm/Support/Path.h"
1314 #include "llvm/Support/raw_ostream.h"
1415 #include
1516 #include
5556 static const char *UTF8(CFStringRef CFStr, std::string &Str);
5657 };
5758
58 /// Static function that puts a copy of the UTF8 contents of CFStringRef into
59 /// Static function that puts a copy of the UTF-8 contents of CFStringRef into
5960 /// std::string and returns the C string pointer that is contained in the
6061 /// std::string when successful, nullptr otherwise.
6162 ///
8485 /// RAII wrapper around CFBundleRef.
8586 class CFBundle : public CFReleaser {
8687 public:
87 CFBundle(const char *Path = nullptr) : CFReleaser() {
88 if (Path && Path[0])
89 SetFromPath(Path);
90 }
88 CFBundle(StringRef Path) : CFReleaser() { SetFromPath(Path); }
9189
92 CFBundle(CFURLRef url)
93 : CFReleaser(url ? ::CFBundleCreate(nullptr, url)
90 CFBundle(CFURLRef Url)
91 : CFReleaser(Url ? ::CFBundleCreate(nullptr, Url)
9492 : nullptr) {}
9593
9694 /// Return the bundle identifier.
108106 }
109107
110108 private:
111 /// Update this instance with a new bundle created from the given path.
112 bool SetFromPath(const char *Path);
109 /// Helper to initialize this instance with a new bundle created from the
110 /// given path. This function will recursively remove components from the
111 /// path in its search for the nearest Info.plist.
112 void SetFromPath(StringRef Path);
113113 };
114114
115 bool CFBundle::SetFromPath(const char *InPath) {
116 // Release our old bundle and URL.
115 void CFBundle::SetFromPath(StringRef Path) {
116 // Start from an empty/invalid CFBundle.
117117 reset();
118118
119 if (InPath && InPath[0]) {
120 char ResolvedPath[PATH_MAX];
121 const char *Path = ::realpath(InPath, ResolvedPath);
122 if (Path == nullptr)
123 Path = InPath;
119 if (Path.empty() || !sys::fs::exists(Path))
120 return;
124121
125 CFAllocatorRef Allocator = kCFAllocatorDefault;
126 // Make our Bundle URL.
122 SmallString<256> RealPath;
123 sys::fs::real_path(Path, RealPath, /*expand_tilde*/ true);
124
125 do {
126 // Create a CFURL from the current path and use it to create a CFBundle.
127127 CFReleaser BundleURL(::CFURLCreateFromFileSystemRepresentation(
128 Allocator, (const UInt8 *)Path, strlen(Path), false));
129 if (BundleURL.get()) {
130 CFIndex LastLength = LONG_MAX;
128 kCFAllocatorDefault, (const UInt8 *)RealPath.data(), RealPath.size(),
129 false));
130 reset(::CFBundleCreate(kCFAllocatorDefault, BundleURL.get()));
131131
132 while (BundleURL.get() != nullptr) {
133 // Check the Path range and make sure we didn't make it to just "/",
134 // ".", or "..".
135 CFRange rangeIncludingSeparators;
136 CFRange range = ::CFURLGetByteRangeForComponent(
137 BundleURL.get(), kCFURLComponentPath, &rangeIncludingSeparators);
138 if (range.length > LastLength)
139 break;
132 // If we have a valid bundle and find its identifier we are done.
133 if (get() != nullptr) {
134 if (GetIdentifier() != nullptr)
135 return;
136 reset();
137 }
140138
141 reset(::CFBundleCreate(Allocator, BundleURL.get()));
142 if (get() != nullptr) {
143 if (GetIdentifier() != nullptr)
144 break;
145 reset();
146 }
147 BundleURL.reset(::CFURLCreateCopyDeletingLastPathComponent(
148 Allocator, BundleURL.get()));
149
150 LastLength = range.length;
151 }
152 }
153 }
154
155 return get() != nullptr;
139 // Remove the last component of the path and try again until there's
140 // nothing left but the root.
141 sys::path::remove_filename(RealPath);
142 } while (RealPath != sys::path::root_name(RealPath));
156143 }
157
158144 #endif
159145
160 /// On Darwin, try and find the original executable's Info.plist information
161 /// using CoreFoundation calls by creating a URL for the executable and
162 /// chopping off the last Path component. The CFBundle can then get the
163 /// identifier and grab any needed information from it directly. Return default
164 /// CFBundleInfo on other platforms.
146 /// On Darwin, try and find the original executable's Info.plist to extract
147 /// information about the bundle. Return default values on other platforms.
165148 CFBundleInfo getBundleInfo(StringRef ExePath) {
166149 CFBundleInfo BundleInfo;
167150
168151 #ifdef __APPLE__
169 if (ExePath.empty() || !sys::fs::exists(ExePath))
170 return BundleInfo;
171
172152 auto PrintError = [&](CFTypeID TypeID) {
173153 CFString TypeIDCFStr(::CFCopyTypeIDDescription(TypeID));
174154 std::string TypeIDStr;
177157 << ", but it should be a string in: " << ExePath << ".\n";
178158 };
179159
180 CFBundle Bundle(ExePath.data());
160 CFBundle Bundle(ExePath);
181161 if (CFStringRef BundleID = Bundle.GetIdentifier()) {
182162 CFString::UTF8(BundleID, BundleInfo.IDStr);
183163 if (CFTypeRef TypeRef =