Files.cpp revision 52364f7ae31716d7827ea8f8566f4a28bd30a921
1a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown/* 2a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown * Copyright (C) 2015 The Android Open Source Project 3a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown * 4a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown * Licensed under the Apache License, Version 2.0 (the "License"); 5a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown * you may not use this file except in compliance with the License. 6a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown * You may obtain a copy of the License at 7a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown * 8a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown * http://www.apache.org/licenses/LICENSE-2.0 9a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown * 10a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown * Unless required by applicable law or agreed to in writing, software 11a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown * distributed under the License is distributed on an "AS IS" BASIS, 12a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown * See the License for the specific language governing permissions and 14a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown * limitations under the License. 15a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown */ 16a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown 17a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown#include "util/Files.h" 18a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown#include "util/Util.h" 19a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown 20a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown#include <cerrno> 21a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown#include <cstdio> 22a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown#include <dirent.h> 23a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown#include <string> 24a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown#include <sys/stat.h> 25a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown 26a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown#ifdef _WIN32 27a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown// Windows includes. 28a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown#include <direct.h> 29a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown#endif 30a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown 31a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brownnamespace aapt { 32a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brownnamespace file { 33a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown 34a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff BrownFileType getFileType(const StringPiece& path) { 35a95a3b494fd88f83c9f5d32e001452575ba235ecJeff Brown struct stat sb; 36a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown if (stat(path.data(), &sb) < 0) { 37a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown if (errno == ENOENT || errno == ENOTDIR) { 38a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown return FileType::kNonexistant; 39a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown } 40a95a3b494fd88f83c9f5d32e001452575ba235ecJeff Brown return FileType::kUnknown; 41a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown } 42a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown 43a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown if (S_ISREG(sb.st_mode)) { 44a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown return FileType::kRegular; 45a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown } else if (S_ISDIR(sb.st_mode)) { 46a95a3b494fd88f83c9f5d32e001452575ba235ecJeff Brown return FileType::kDirectory; 47a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown } else if (S_ISCHR(sb.st_mode)) { 48a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown return FileType::kCharDev; 49a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown } else if (S_ISBLK(sb.st_mode)) { 50a95a3b494fd88f83c9f5d32e001452575ba235ecJeff Brown return FileType::kBlockDev; 51a95a3b494fd88f83c9f5d32e001452575ba235ecJeff Brown } else if (S_ISFIFO(sb.st_mode)) { 52a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown return FileType::kFifo; 53a95a3b494fd88f83c9f5d32e001452575ba235ecJeff Brown#if defined(S_ISLNK) 54a95a3b494fd88f83c9f5d32e001452575ba235ecJeff Brown } else if (S_ISLNK(sb.st_mode)) { 55a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown return FileType::kSymlink; 56a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown#endif 57a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown#if defined(S_ISSOCK) 58a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown } else if (S_ISSOCK(sb.st_mode)) { 59a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown return FileType::kSocket; 60a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown#endif 61a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown } else { 62a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown return FileType::kUnknown; 63a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown } 64a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown} 65a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown 66a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brownstd::vector<std::string> listFiles(const StringPiece& root, std::string* outError) { 67a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown DIR* dir = opendir(root.data()); 68a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown if (dir == nullptr) { 69a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown if (outError) { 70a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown std::stringstream errorStr; 71a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown errorStr << "unable to open file: " << strerror(errno); 72a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown *outError = errorStr.str(); 73a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown return {}; 74a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown } 75a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown } 76a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown 77a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown std::vector<std::string> files; 78a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown dirent* entry; 79a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown while ((entry = readdir(dir))) { 80a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown files.emplace_back(entry->d_name); 81a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown } 82a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown 83a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown closedir(dir); 84a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown return files; 85a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown} 86a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown 87a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Browninline static int mkdirImpl(const StringPiece& path) { 88a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown#ifdef _WIN32 89a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown return _mkdir(path.toString().c_str()); 90a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown#else 91a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown return mkdir(path.toString().c_str(), S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP); 92a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown#endif 93a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown} 94a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown 95a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brownbool mkdirs(const StringPiece& path) { 96a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown const char* start = path.begin(); 97a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown const char* end = path.end(); 98a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown for (const char* current = start; current != end; ++current) { 99a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown if (*current == sDirSep) { 100a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown StringPiece parentPath(start, current - start); 101a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown int result = mkdirImpl(parentPath); 102a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown if (result < 0 && errno != EEXIST) { 103a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown return false; 104a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown } 105a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown } 106a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown } 107a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown return mkdirImpl(path) == 0 || errno == EEXIST; 108a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown} 109a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown 110a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff BrownStringPiece getStem(const StringPiece& path) { 111a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown const char* start = path.begin(); 112a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown const char* end = path.end(); 113a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown for (const char* current = end - 1; current != start - 1; --current) { 114a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown if (*current == sDirSep) { 115a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown return StringPiece(start, current - start); 116a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown } 117a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown } 118a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown return {}; 119a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown} 120a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown 121a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff BrownStringPiece getFilename(const StringPiece& path) { 122a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown const char* end = path.end(); 123a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown const char* lastDirSep = path.begin(); 124a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown for (const char* c = path.begin(); c != end; ++c) { 125a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown if (*c == sDirSep) { 126a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown lastDirSep = c + 1; 127a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown } 128a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown } 129a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown return StringPiece(lastDirSep, end - lastDirSep); 130a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown} 131a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown 132a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff BrownStringPiece getExtension(const StringPiece& path) { 133a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown StringPiece filename = getFilename(path); 134a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown const char* const end = filename.end(); 135a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown const char* c = std::find(filename.begin(), end, '.'); 136a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown if (c != end) { 137a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown return StringPiece(c, end - c); 138a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown } 139a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown return {}; 140a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown} 141a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown 142a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brownstd::string packageToPath(const StringPiece& package) { 143a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown std::string outPath; 144a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown for (StringPiece part : util::tokenize<char>(package, '.')) { 145a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown appendPath(&outPath, part); 146a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown } 147a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown return outPath; 148a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown} 149a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown 150a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff BrownMaybe<android::FileMap> mmapPath(const StringPiece& path, std::string* outError) { 151a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown std::unique_ptr<FILE, decltype(fclose)*> f = { fopen(path.data(), "rb"), fclose }; 152a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown if (!f) { 153a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown if (outError) *outError = strerror(errno); 154a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown return {}; 155a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown } 156a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown 157a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown int fd = fileno(f.get()); 158a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown 159a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown struct stat fileStats = {}; 160a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown if (fstat(fd, &fileStats) != 0) { 161a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown if (outError) *outError = strerror(errno); 162a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown return {}; 163a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown } 164a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown 165a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown android::FileMap fileMap; 166a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown if (fileStats.st_size == 0) { 167a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown // mmap doesn't like a length of 0. Instead we return an empty FileMap. 168a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown return std::move(fileMap); 169a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown } 170a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown 171a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown if (!fileMap.create(path.data(), fd, 0, fileStats.st_size, true)) { 172a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown if (outError) *outError = strerror(errno); 173a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown return {}; 174a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown } 175a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown return std::move(fileMap); 176a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown} 177a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown 178a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brownbool FileFilter::setPattern(const StringPiece& pattern) { 179a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown mPatternTokens = util::splitAndLowercase(pattern, ':'); 180a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown return true; 181a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown} 182a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown 183a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brownbool FileFilter::operator()(const std::string& filename, FileType type) const { 184a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown if (filename == "." || filename == "..") { 185a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown return false; 186a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown } 187a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown 188a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown const char kDir[] = "dir"; 189a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown const char kFile[] = "file"; 190a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown const size_t filenameLen = filename.length(); 191a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown bool chatty = true; 192a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown for (const std::string& token : mPatternTokens) { 193a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown const char* tokenStr = token.c_str(); 194a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown if (*tokenStr == '!') { 195a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown chatty = false; 196a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown tokenStr++; 197a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown } 198a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown 199a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown if (strncasecmp(tokenStr, kDir, sizeof(kDir)) == 0) { 200a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown if (type != FileType::kDirectory) { 201a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown continue; 202a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown } 203a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown tokenStr += sizeof(kDir); 204a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown } 205a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown 206a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown if (strncasecmp(tokenStr, kFile, sizeof(kFile)) == 0) { 207a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown if (type != FileType::kRegular) { 208a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown continue; 209a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown } 210a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown tokenStr += sizeof(kFile); 211a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown } 212a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown 213a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown bool ignore = false; 214a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown size_t n = strlen(tokenStr); 215a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown if (*tokenStr == '*') { 216a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown // Math suffix. 217a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown tokenStr++; 218a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown n--; 219a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown if (n <= filenameLen) { 220a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown ignore = strncasecmp(tokenStr, filename.c_str() + filenameLen - n, n) == 0; 221a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown } 222a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown } else if (n > 1 && tokenStr[n - 1] == '*') { 223a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown // Match prefix. 224a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown ignore = strncasecmp(tokenStr, filename.c_str(), n - 1) == 0; 225a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown } else { 226a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown ignore = strcasecmp(tokenStr, filename.c_str()) == 0; 227a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown } 228a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown 229a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown if (ignore) { 230a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown if (chatty) { 231a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown mDiag->warn(DiagMessage() << "skipping " 232a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown << (type == FileType::kDirectory ? "dir '" : "file '") 233a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown << filename << "' due to ignore pattern '" 234a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown << token << "'"); 235a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown } 236a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown return false; 237a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown } 238a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown } 239a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown return true; 240a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown} 241a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown 242a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown} // namespace file 243a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown} // namespace aapt 244a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown