diff --git a/main.cpp b/main.cpp index fe8ea292..45da2f3e 100644 --- a/main.cpp +++ b/main.cpp @@ -239,6 +239,9 @@ int main(int argc, char **argv) case simplecpp::Output::DUI_ERROR: std::cerr << "dui error: "; break; + case simplecpp::Output::CACHE_ERROR: + std::cerr << "cache error: "; + break; } std::cerr << output.msg << std::endl; } diff --git a/simplecpp.cpp b/simplecpp.cpp index ef891eb1..5d6a1a0b 100644 --- a/simplecpp.cpp +++ b/simplecpp.cpp @@ -53,8 +53,10 @@ #include #ifdef _WIN32 +# include # include #else +# include # include #endif @@ -3051,8 +3053,18 @@ std::pair simplecpp::FileDataCache::tryload(FileDat const std::string &path = name_it->first; FileID fileId; - if (!getFileId(path, fileId)) + std::string errmsg; + if (!getFileId(path, fileId, errmsg)) { + if (outputList && !errmsg.empty()) { + simplecpp::Output err = { + Output::CACHE_ERROR, + Location{filenames}, + "Failed to get ID for " + path + " (" + errmsg + ")" + }; + outputList->push_back(std::move(err)); + } return {nullptr, false}; + } const auto id_it = mIdMap.find(fileId); if (id_it != mIdMap.end()) { @@ -3118,15 +3130,23 @@ std::pair simplecpp::FileDataCache::get(const std:: return {nullptr, false}; } -bool simplecpp::FileDataCache::getFileId(const std::string &path, FileID &id) -{ +bool simplecpp::FileDataCache::getFileId(const std::string &path, FileID &id, std::string& errmsg) { + errmsg = ""; + #ifdef _WIN32 HANDLE hFile = CreateFileA(path.c_str(), 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - - if (hFile == INVALID_HANDLE_VALUE) + if (hFile == INVALID_HANDLE_VALUE) { + const DWORD err = GetLastError(); + if (err != ERROR_FILE_NOT_FOUND) + errmsg = "CreateFileA() failed with '" + std::system_category().message(err) + "'"; return false; + } const BOOL ret = GetFileInformationByHandleEx(hFile, FileIdInfo, &id.fileIdInfo, sizeof(id.fileIdInfo)); + if (!ret) { + const DWORD err = GetLastError(); + errmsg = "GetFileInformationByHandleEx() failed with '" + std::system_category().message(err) + "'"; + } CloseHandle(hFile); @@ -3134,8 +3154,12 @@ bool simplecpp::FileDataCache::getFileId(const std::string &path, FileID &id) #else struct stat statbuf; - if (stat(path.c_str(), &statbuf) != 0) + if (stat(path.c_str(), &statbuf) == -1) { + const int err = errno; + if (err != ENOENT) + errmsg = std::string("stat() failed with '") + strerror(err) + "'"; return false; + } id.dev = statbuf.st_dev; id.ino = statbuf.st_ino; diff --git a/simplecpp.h b/simplecpp.h index 22f3c19f..cf57e48d 100644 --- a/simplecpp.h +++ b/simplecpp.h @@ -211,7 +211,8 @@ namespace simplecpp { UNHANDLED_CHAR_ERROR, EXPLICIT_INCLUDE_NOT_FOUND, FILE_NOT_FOUND, - DUI_ERROR + DUI_ERROR, + CACHE_ERROR } type; Output(Type type, const Location& loc, std::string msg) : type(type), location(loc), msg(std::move(msg)) {} Location location; @@ -501,7 +502,7 @@ namespace simplecpp { using name_map_type = std::unordered_map; using id_map_type = std::unordered_map; - static bool getFileId(const std::string &path, FileID &id); + static bool getFileId(const std::string &path, FileID &id, std::string& errmsg); std::pair tryload(name_map_type::iterator &name_it, const DUI &dui, std::vector &filenames, OutputList *outputList); diff --git a/test.cpp b/test.cpp index 69e08781..828dd169 100644 --- a/test.cpp +++ b/test.cpp @@ -167,6 +167,9 @@ static std::string toString(const simplecpp::OutputList &outputList) case simplecpp::Output::Type::DUI_ERROR: ostr << "dui_error,"; break; + case simplecpp::Output::Type::CACHE_ERROR: + ostr << "cache_error,"; + break; } ostr << output.msg << '\n';