blob: 9287ed9d78c95e1864fb79192c724535b77aa617 [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
**/
#include "utility/Glob.hpp"
#include "utility/UtilityConfig.h"
#if defined(QUICKSTEP_HAVE_GLOB)
#include <glob.h>
#elif defined(QUICKSTEP_HAVE_WINDOWS)
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif
#include <cstddef>
#include <functional>
#include <string>
#include <vector>
#include "glog/logging.h"
namespace quickstep {
namespace utility {
namespace file {
std::size_t GlobForEach(const std::string &pattern,
std::function<void(const char *)> functor) {
#if defined(QUICKSTEP_HAVE_GLOB)
glob_t glob_result;
const int ret = glob(pattern.c_str(), 0, nullptr, &glob_result);
std::size_t num_matches = 0;
if (ret == GLOB_ABORTED) {
LOG(ERROR) << "An error occurred during glob.";
} else if (ret == GLOB_NOMATCH) {
LOG(WARNING) << "Glob function made zero matches.";
} else if (ret == GLOB_NOSPACE) {
LOG(ERROR) << "Glob function failed to allocate memory.";
} else {
// There should be no errors at this point.
DCHECK_EQ(ret, 0);
num_matches = glob_result.gl_pathc;
}
for (std::size_t i = 0; i < num_matches; ++i) {
functor(glob_result.gl_pathv[i]);
}
globfree(&glob_result);
return num_matches;
#elif defined(QUICKSTEP_HAVE_WINDOWS)
std::size_t num_matches = 0;
WIN32_FIND_DATA find_data;
HANDLE find_handle = INVALID_HANDLE_VALUE;
DWORD error_code = 0;
find_handle = FindFirstFile(pattern.c_str(), &find_data);
if (find_handle == INVALID_HANDLE_VALUE) {
error_code = GetLastError();
if (error_code != ERROR_FILE_NOT_FOUND) {
LOG(ERROR) << "Failed to retrieve blockfiles with error_code: " << error_code;
}
return 0;
}
do {
functor(find_data.cFileName);
++num_matches;
} while (FindNextFile(find_handle, &find_data) != 0);
error_code = GetLastError();
if (error_code != ERROR_NO_MORE_FILES) {
LOG(ERROR) << "Failed to FindNextFile with error_code: " << error_code;
}
if (FindClose(find_handle) == 0) {
LOG(ERROR) << "Failed to close the file with error_code: " << GetLastError();
}
return num_matches;
#else
#error "No implementation for Glob in this platform."
#endif
}
std::vector<std::string> GlobExpand(const std::string &pattern) {
std::vector<std::string> matches;
GlobForEach(pattern, [&matches](const char *path) {
matches.emplace_back(path);
});
return matches;
}
} // namespace file
} // namespace utility
} // namespace quickstep