mirror of
https://github.com/lighttransport/tinyusdz.git
synced 2026-01-18 01:11:17 +01:00
Add ghc::filesystem and glob.
Update tinygltf. Fix Android app build.
This commit is contained in:
@@ -324,3 +324,5 @@ TinyUSDZ is licensed under MIT license.
|
|||||||
* nanobind : BSD-3 license. https://github.com/wjakob/nanobind
|
* nanobind : BSD-3 license. https://github.com/wjakob/nanobind
|
||||||
* pybind11 : BSD-3 license. https://github.com/pybind/pybind11
|
* pybind11 : BSD-3 license. https://github.com/pybind/pybind11
|
||||||
* pystring : BSD-3 license. https://github.com/imageworks/pystring
|
* pystring : BSD-3 license. https://github.com/imageworks/pystring
|
||||||
|
* gulrak/filesytem : MIT license. https://github.com/gulrak/filesystem
|
||||||
|
* p-ranav/glob : MIT license. https://github.com/p-ranav/glob
|
||||||
|
|||||||
@@ -14,9 +14,10 @@ set(TINYUSDZ_SOURCES
|
|||||||
${PROJECT_SOURCE_DIR}/../../../../../src/crate-pprint.cc
|
${PROJECT_SOURCE_DIR}/../../../../../src/crate-pprint.cc
|
||||||
${PROJECT_SOURCE_DIR}/../../../../../src/io-util.cc
|
${PROJECT_SOURCE_DIR}/../../../../../src/io-util.cc
|
||||||
${PROJECT_SOURCE_DIR}/../../../../../src/pprinter.cc
|
${PROJECT_SOURCE_DIR}/../../../../../src/pprinter.cc
|
||||||
${PROJECT_SOURCE_DIR}/../../../../../src/value-type.cc
|
${PROJECT_SOURCE_DIR}/../../../../../src/value-types.cc
|
||||||
${PROJECT_SOURCE_DIR}/../../../../../src/value-pprint.cc
|
${PROJECT_SOURCE_DIR}/../../../../../src/value-pprint.cc
|
||||||
${PROJECT_SOURCE_DIR}/../../../../../src/primvar.cc
|
${PROJECT_SOURCE_DIR}/../../../../../src/primvar.cc
|
||||||
|
${PROJECT_SOURCE_DIR}/../../../../../src/image-loader.cc
|
||||||
${PROJECT_SOURCE_DIR}/../../../../../src/usda-writer.cc)
|
${PROJECT_SOURCE_DIR}/../../../../../src/usda-writer.cc)
|
||||||
|
|
||||||
if(TINYUSDZ_USE_USDOBJ)
|
if(TINYUSDZ_USE_USDOBJ)
|
||||||
@@ -29,7 +30,7 @@ endif()
|
|||||||
set(TINYUSDZ_DEP_SOURCES
|
set(TINYUSDZ_DEP_SOURCES
|
||||||
${PROJECT_SOURCE_DIR}/../../../../../src/integerCoding.cpp
|
${PROJECT_SOURCE_DIR}/../../../../../src/integerCoding.cpp
|
||||||
${PROJECT_SOURCE_DIR}/../../../../../src/lz4-compression.cc
|
${PROJECT_SOURCE_DIR}/../../../../../src/lz4-compression.cc
|
||||||
${PROJECT_SOURCE_DIR}/../../../../../src/pxrLZ4/lz4.cpp
|
${PROJECT_SOURCE_DIR}/../../../../../src/lz4/lz4.c
|
||||||
${PROJECT_SOURCE_DIR}/../../../../../src/external/string_id/database.cpp
|
${PROJECT_SOURCE_DIR}/../../../../../src/external/string_id/database.cpp
|
||||||
${PROJECT_SOURCE_DIR}/../../../../../src/external/string_id/string_id.cpp
|
${PROJECT_SOURCE_DIR}/../../../../../src/external/string_id/string_id.cpp
|
||||||
${PROJECT_SOURCE_DIR}/../../../../../src/external/string_id/error.cpp
|
${PROJECT_SOURCE_DIR}/../../../../../src/external/string_id/error.cpp
|
||||||
|
|||||||
@@ -123,10 +123,10 @@ Java_com_example_hellotinyusdz_MainActivity_touchMove(JNIEnv *env, jobject obj,
|
|||||||
tinyusdz::USDLoadOptions options;
|
tinyusdz::USDLoadOptions options;
|
||||||
|
|
||||||
// load from Android asset folder
|
// load from Android asset folder
|
||||||
example::g_gui_ctx.scene = tinyusdz::HighLevelScene(); // reset
|
example::g_gui_ctx.stage = tinyusdz::Stage(); // reset
|
||||||
|
|
||||||
std::string warn, err;
|
std::string warn, err;
|
||||||
bool ret = LoadUSDCFromFile(filename, &example::g_gui_ctx.scene, &warn, &err, options);
|
bool ret = LoadUSDCFromFile(filename, &example::g_gui_ctx.stage, &warn, &err, options);
|
||||||
|
|
||||||
if (warn.size()) {
|
if (warn.size()) {
|
||||||
__android_log_print(ANDROID_LOG_WARN, "tinyusdz", "USD load warning: %s", warn.c_str());
|
__android_log_print(ANDROID_LOG_WARN, "tinyusdz", "USD load warning: %s", warn.c_str());
|
||||||
@@ -140,7 +140,7 @@ Java_com_example_hellotinyusdz_MainActivity_touchMove(JNIEnv *env, jobject obj,
|
|||||||
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
// TODO
|
// TODO
|
||||||
//__android_log_print(ANDROID_LOG_INFO, "tinyusdz", "USD loaded. #of geom_meshes: %d", int(example::g_gui_ctx.scene.geom_meshes.size()));
|
//__android_log_print(ANDROID_LOG_INFO, "tinyusdz", "USD loaded. #of geom_meshes: %d", int(example::g_gui_ctx.stage.geom_meshes.size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = example::SetupScene(example::g_gui_ctx);
|
ret = example::SetupScene(example::g_gui_ctx);
|
||||||
@@ -151,7 +151,7 @@ Java_com_example_hellotinyusdz_MainActivity_touchMove(JNIEnv *env, jobject obj,
|
|||||||
|
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
//return int(example::g_gui_ctx.scene.geom_meshes.size()); // OK
|
//return int(example::g_gui_ctx.stage.geom_meshes.size()); // OK
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,7 +57,8 @@ inline uint8_t ftouc(float f) {
|
|||||||
bool SetupScene(GUIContext &ctx) {
|
bool SetupScene(GUIContext &ctx) {
|
||||||
|
|
||||||
__android_log_print(ANDROID_LOG_INFO, "tinyusdz", "SetupScene");
|
__android_log_print(ANDROID_LOG_INFO, "tinyusdz", "SetupScene");
|
||||||
if (ctx.scene.root_nodes.empty()) {
|
#if 0 // TODO
|
||||||
|
if (ctx.stage.root_nodes.empty()) {
|
||||||
__android_log_print(ANDROID_LOG_ERROR, "tinyusdz", "No GeomMesh");
|
__android_log_print(ANDROID_LOG_ERROR, "tinyusdz", "No GeomMesh");
|
||||||
// No GeomMesh in the scene
|
// No GeomMesh in the scene
|
||||||
return false;
|
return false;
|
||||||
@@ -78,6 +79,7 @@ bool SetupScene(GUIContext &ctx) {
|
|||||||
__android_log_print(ANDROID_LOG_ERROR, "tinyusdz", "Scene::Setup failed");
|
__android_log_print(ANDROID_LOG_ERROR, "tinyusdz", "Scene::Setup failed");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// init camera matrix
|
// init camera matrix
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ struct GUIContext {
|
|||||||
int render_height = 512;
|
int render_height = 512;
|
||||||
|
|
||||||
// scene reload
|
// scene reload
|
||||||
tinyusdz::HighLevelScene scene;
|
tinyusdz::Stage stage;
|
||||||
std::atomic<bool> request_reload{false};
|
std::atomic<bool> request_reload{false};
|
||||||
std::string filename;
|
std::string filename;
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
path_classifiers:
|
path_classifiers:
|
||||||
legacy:
|
legacy:
|
||||||
- exclude: src/stb_image.h "src/dr_*"
|
- exclude: src/miniz.c
|
||||||
|
- exclude: src/miniz.h
|
||||||
|
|||||||
19
src/external/filesystem/LICENSE
vendored
Normal file
19
src/external/filesystem/LICENSE
vendored
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
Copyright (c) 2018, Steffen Schümann <s.schuemann@pobox.com>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
1074
src/external/filesystem/README.md
vendored
Normal file
1074
src/external/filesystem/README.md
vendored
Normal file
File diff suppressed because it is too large
Load Diff
6065
src/external/filesystem/include/ghc/filesystem.hpp
vendored
Normal file
6065
src/external/filesystem/include/ghc/filesystem.hpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
38
src/external/filesystem/include/ghc/fs_fwd.hpp
vendored
Normal file
38
src/external/filesystem/include/ghc/fs_fwd.hpp
vendored
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
//---------------------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// ghc::filesystem - A C++17-like filesystem implementation for C++11/C++14
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Copyright (c) 2018, Steffen Schümann <s.schuemann@pobox.com>
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
// SOFTWARE.
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------------------
|
||||||
|
// fs_fwd.hpp - The forwarding header for the header/implementation seperated usage of
|
||||||
|
// ghc::filesystem.
|
||||||
|
// This file can be include at any place, where ghc::filesystem api is needed while
|
||||||
|
// not bleeding implementation details (e.g. system includes) into the global namespace,
|
||||||
|
// as long as one cpp includes fs_impl.hpp to deliver the matching implementations.
|
||||||
|
//---------------------------------------------------------------------------------------
|
||||||
|
#ifndef GHC_FILESYSTEM_FWD_H
|
||||||
|
#define GHC_FILESYSTEM_FWD_H
|
||||||
|
#define GHC_FILESYSTEM_FWD
|
||||||
|
#include <ghc/filesystem.hpp>
|
||||||
|
#endif // GHC_FILESYSTEM_FWD_H
|
||||||
35
src/external/filesystem/include/ghc/fs_impl.hpp
vendored
Normal file
35
src/external/filesystem/include/ghc/fs_impl.hpp
vendored
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
//---------------------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// ghc::filesystem - A C++17-like filesystem implementation for C++11/C++14
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Copyright (c) 2018, Steffen Schümann <s.schuemann@pobox.com>
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
// SOFTWARE.
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------------------
|
||||||
|
// fs_impl.hpp - The implementation header for the header/implementation seperated usage of
|
||||||
|
// ghc::filesystem.
|
||||||
|
// This file can be used to hide the implementation of ghc::filesystem into a single cpp.
|
||||||
|
// The cpp has to include this before including fs_fwd.hpp directly or via a different
|
||||||
|
// header to work.
|
||||||
|
//---------------------------------------------------------------------------------------
|
||||||
|
#define GHC_FILESYSTEM_IMPLEMENTATION
|
||||||
|
#include <ghc/filesystem.hpp>
|
||||||
60
src/external/filesystem/include/ghc/fs_std.hpp
vendored
Normal file
60
src/external/filesystem/include/ghc/fs_std.hpp
vendored
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
//---------------------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// ghc::filesystem - A C++17-like filesystem implementation for C++11/C++14
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Copyright (c) 2018, Steffen Schümann <s.schuemann@pobox.com>
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
// SOFTWARE.
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------------------
|
||||||
|
// fs_std.hpp - The dynamic switching header that includes std::filesystem if detected
|
||||||
|
// or ghc::filesystem if not, and makes the resulting API available in the
|
||||||
|
// namespace fs.
|
||||||
|
//---------------------------------------------------------------------------------------
|
||||||
|
#ifndef GHC_FILESYSTEM_STD_H
|
||||||
|
#define GHC_FILESYSTEM_STD_H
|
||||||
|
#if defined(__APPLE__)
|
||||||
|
#include <Availability.h>
|
||||||
|
#endif
|
||||||
|
#if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || (defined(__cplusplus) && __cplusplus >= 201703L)) && defined(__has_include)
|
||||||
|
#if __has_include(<filesystem>) && (!defined(__MAC_OS_X_VERSION_MIN_REQUIRED) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 101500)
|
||||||
|
#define GHC_USE_STD_FS
|
||||||
|
#include <filesystem>
|
||||||
|
namespace fs {
|
||||||
|
using namespace std::filesystem;
|
||||||
|
using ifstream = std::ifstream;
|
||||||
|
using ofstream = std::ofstream;
|
||||||
|
using fstream = std::fstream;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#ifndef GHC_USE_STD_FS
|
||||||
|
//#define GHC_WIN_DISABLE_WSTRING_STORAGE_TYPE
|
||||||
|
#include <ghc/filesystem.hpp>
|
||||||
|
namespace fs {
|
||||||
|
using namespace ghc::filesystem;
|
||||||
|
using ifstream = ghc::filesystem::ifstream;
|
||||||
|
using ofstream = ghc::filesystem::ofstream;
|
||||||
|
using fstream = ghc::filesystem::fstream;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif // GHC_FILESYSTEM_STD_H
|
||||||
|
|
||||||
63
src/external/filesystem/include/ghc/fs_std_fwd.hpp
vendored
Normal file
63
src/external/filesystem/include/ghc/fs_std_fwd.hpp
vendored
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
//---------------------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// ghc::filesystem - A C++17-like filesystem implementation for C++11/C++14
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Copyright (c) 2018, Steffen Schümann <s.schuemann@pobox.com>
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
// SOFTWARE.
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------------------
|
||||||
|
// fs_std_fwd.hpp - The forwarding header for the header/implementation seperated usage of
|
||||||
|
// ghc::filesystem that uses std::filesystem if it detects it.
|
||||||
|
// This file can be include at any place, where fs::filesystem api is needed while
|
||||||
|
// not bleeding implementation details (e.g. system includes) into the global namespace,
|
||||||
|
// as long as one cpp includes fs_std_impl.hpp to deliver the matching implementations.
|
||||||
|
//---------------------------------------------------------------------------------------
|
||||||
|
#ifndef GHC_FILESYSTEM_STD_FWD_H
|
||||||
|
#define GHC_FILESYSTEM_STD_FWD_H
|
||||||
|
#if defined(__APPLE__)
|
||||||
|
#include <Availability.h>
|
||||||
|
#endif
|
||||||
|
#if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || (defined(__cplusplus) && __cplusplus >= 201703L)) && defined(__has_include)
|
||||||
|
#if __has_include(<filesystem>) && (!defined(__MAC_OS_X_VERSION_MIN_REQUIRED) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 101500)
|
||||||
|
#define GHC_USE_STD_FS
|
||||||
|
#include <filesystem>
|
||||||
|
namespace fs {
|
||||||
|
using namespace std::filesystem;
|
||||||
|
using ifstream = std::ifstream;
|
||||||
|
using ofstream = std::ofstream;
|
||||||
|
using fstream = std::fstream;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#ifndef GHC_USE_STD_FS
|
||||||
|
//#define GHC_WIN_DISABLE_WSTRING_STORAGE_TYPE
|
||||||
|
#define GHC_FILESYSTEM_FWD
|
||||||
|
#include <ghc/filesystem.hpp>
|
||||||
|
namespace fs {
|
||||||
|
using namespace ghc::filesystem;
|
||||||
|
using ifstream = ghc::filesystem::ifstream;
|
||||||
|
using ofstream = ghc::filesystem::ofstream;
|
||||||
|
using fstream = ghc::filesystem::fstream;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif // GHC_FILESYSTEM_STD_FWD_H
|
||||||
|
|
||||||
46
src/external/filesystem/include/ghc/fs_std_impl.hpp
vendored
Normal file
46
src/external/filesystem/include/ghc/fs_std_impl.hpp
vendored
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
//---------------------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// ghc::filesystem - A C++17-like filesystem implementation for C++11/C++14
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Copyright (c) 2018, Steffen Schümann <s.schuemann@pobox.com>
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
// SOFTWARE.
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------------------
|
||||||
|
// fs_std_impl.hpp - The implementation header for the header/implementation seperated usage of
|
||||||
|
// ghc::filesystem that does nothing if std::filesystem is detected.
|
||||||
|
// This file can be used to hide the implementation of ghc::filesystem into a single cpp.
|
||||||
|
// The cpp has to include this before including fs_std_fwd.hpp directly or via a different
|
||||||
|
// header to work.
|
||||||
|
//---------------------------------------------------------------------------------------
|
||||||
|
#if defined(__APPLE__)
|
||||||
|
#include <Availability.h>
|
||||||
|
#endif
|
||||||
|
#if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || (defined(__cplusplus) && __cplusplus >= 201703L)) && defined(__has_include)
|
||||||
|
#if __has_include(<filesystem>) && (!defined(__MAC_OS_X_VERSION_MIN_REQUIRED) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 101500)
|
||||||
|
#define GHC_USE_STD_FS
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#ifndef GHC_USE_STD_FS
|
||||||
|
//#define GHC_WIN_DISABLE_WSTRING_STORAGE_TYPE
|
||||||
|
#define GHC_FILESYSTEM_IMPLEMENTATION
|
||||||
|
#include <ghc/filesystem.hpp>
|
||||||
|
#endif
|
||||||
21
src/external/glob/LICENSE
vendored
Normal file
21
src/external/glob/LICENSE
vendored
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2019 Pranav
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
283
src/external/glob/README.md
vendored
Normal file
283
src/external/glob/README.md
vendored
Normal file
@@ -0,0 +1,283 @@
|
|||||||
|
<p align="center">
|
||||||
|
<img height="90" src="img/logo.png"/>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
Unix-style pathname pattern expansion
|
||||||
|
</p>
|
||||||
|
|
||||||
|
## Table of Contents
|
||||||
|
|
||||||
|
- [Quick Start](#quick-start)
|
||||||
|
* [Build Library and Standalone Sample](#build-library-and-standalone-sample)
|
||||||
|
- [Usage](#usage)
|
||||||
|
- [API](#api)
|
||||||
|
- [Wildcards](#wildcards)
|
||||||
|
- [Examples](#examples)
|
||||||
|
* [Match file extensions](#match-file-extensions)
|
||||||
|
* [Match files in absolute pathnames](#match-files-in-absolute-pathnames)
|
||||||
|
* [Wildcards: Match a range of characters listed in brackets ('[]')](#wildcards-match-a-range-of-characters-listed-in-brackets-)
|
||||||
|
* [Exclude files from the matching](#exclude-files-from-the-matching)
|
||||||
|
* [Wildcards: Match any one character with question mark ('?')](#wildcards-match-any-one-character-with-question-mark-)
|
||||||
|
* [Case sensitivity](#case-sensitivity)
|
||||||
|
* [Tilde expansion](#tilde-expansion)
|
||||||
|
- [Contributing](#contributing)
|
||||||
|
- [License](#license)
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
* This library is available in two flavors:
|
||||||
|
1. Two file version: `glob.h` and `glob.cpp`
|
||||||
|
2. Single header file version in `single_include/`
|
||||||
|
* No external dependencies - just the standard library
|
||||||
|
* Requires C++17 `std::filesystem`
|
||||||
|
- If you can't use `C++17`, you can integrate [gulrak/filesystem](https://github.com/gulrak/filesystem) with minimal effort.
|
||||||
|
* MIT License
|
||||||
|
|
||||||
|
### Build Library and Standalone Sample
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cmake -Hall -Bbuild
|
||||||
|
cmake --build build
|
||||||
|
|
||||||
|
# run standalone `glob` sample
|
||||||
|
./build/standalone/glob --help
|
||||||
|
```
|
||||||
|
|
||||||
|
### Usage
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
// Match on a single pattern
|
||||||
|
for (auto& p : glob::glob("~/.b*")) { // e.g., .bash_history, .bashrc
|
||||||
|
// do something with `p`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Match on multiple patterns
|
||||||
|
for (auto& p : glob::glob({"*.png", "*.jpg"})) { // e.g., foo.png, bar.jpg
|
||||||
|
// do something with `p`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Match recursively with `rglob`
|
||||||
|
for (auto& p : glob::rglob("**/*.hpp")) { // e.g., include/foo.hpp, include/foo/bar.hpp
|
||||||
|
// do something with `p`
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## API
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
/// e.g., glob("*.hpp")
|
||||||
|
/// e.g., glob("**/*.cpp")
|
||||||
|
/// e.g., glob("test_files_02/[0-9].txt")
|
||||||
|
/// e.g., glob("/usr/local/include/nc*.h")
|
||||||
|
/// e.g., glob("test_files_02/?.txt")
|
||||||
|
vector<filesystem::path> glob(string pathname);
|
||||||
|
|
||||||
|
/// Globs recursively
|
||||||
|
/// e.g., rglob("Documents/Projects/Foo/**/*.hpp")
|
||||||
|
/// e.g., rglob("test_files_02/*[0-9].txt")
|
||||||
|
vector<filesystem::path> rglob(string pathname);
|
||||||
|
```
|
||||||
|
|
||||||
|
There are also two convenience functions to `glob` on a list of patterns:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
/// e.g., glob({"*.png", "*.jpg"})
|
||||||
|
vector<filesystem::path> glob(vector<string> pathnames);
|
||||||
|
|
||||||
|
/// Globs recursively
|
||||||
|
/// e.g., rglob({"**/*.h", "**/*.hpp", "**/*.cpp"})
|
||||||
|
vector<filesystem::path> rglob(vector<string> pathnames);
|
||||||
|
```
|
||||||
|
|
||||||
|
## Wildcards
|
||||||
|
|
||||||
|
| Wildcard | Matches | Example
|
||||||
|
|--- |--- |--- |
|
||||||
|
| `*` | any characters | `*.txt` matches all files with the txt extension |
|
||||||
|
| `?` | any one character | `???` matches files with 3 characters long |
|
||||||
|
| `[]` | any character listed in the brackets | `[ABC]*` matches files starting with A,B or C |
|
||||||
|
| `[-]` | any character in the range listed in brackets | `[A-Z]*` matches files starting with capital letters |
|
||||||
|
| `[!]` | any character not listed in the brackets | `[!ABC]*` matches files that do not start with A,B or C |
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
The following examples use the [standalone](standalone/source/main.cpp) sample that is part of this repository to illustrate the library functionality.
|
||||||
|
|
||||||
|
```console
|
||||||
|
foo@bar:~$ ./build/standalone/glob -h
|
||||||
|
Run glob to find all the pathnames matching a specified pattern
|
||||||
|
Usage:
|
||||||
|
./build/standalone/glob [OPTION...]
|
||||||
|
|
||||||
|
-h, --help Show help
|
||||||
|
-v, --version Print the current version number
|
||||||
|
-r, --recursive Run glob recursively
|
||||||
|
-i, --input arg Patterns to match
|
||||||
|
```
|
||||||
|
|
||||||
|
### Match file extensions
|
||||||
|
|
||||||
|
```console
|
||||||
|
foo@bar:~$ tree
|
||||||
|
.
|
||||||
|
├── include
|
||||||
|
│ └── foo
|
||||||
|
│ ├── bar.hpp
|
||||||
|
│ ├── baz.hpp
|
||||||
|
│ └── foo.hpp
|
||||||
|
└── test
|
||||||
|
├── bar.cpp
|
||||||
|
├── doctest.hpp
|
||||||
|
├── foo.cpp
|
||||||
|
└── main.cpp
|
||||||
|
|
||||||
|
3 directories, 7 files
|
||||||
|
|
||||||
|
foo@bar:~$ ./glob -i "**/*.hpp"
|
||||||
|
"test/doctest.hpp"
|
||||||
|
|
||||||
|
foo@bar:~$ ./glob -i "**/**/*.hpp"
|
||||||
|
"include/foo/baz.hpp"
|
||||||
|
"include/foo/foo.hpp"
|
||||||
|
"include/foo/bar.hpp"
|
||||||
|
```
|
||||||
|
|
||||||
|
***NOTE*** If you run glob recursively, i.e., using `rglob`:
|
||||||
|
|
||||||
|
```console
|
||||||
|
foo@bar:~$ ./glob -r -i "**/*.hpp"
|
||||||
|
"test/doctest.hpp"
|
||||||
|
"include/foo/baz.hpp"
|
||||||
|
"include/foo/foo.hpp"
|
||||||
|
"include/foo/bar.hpp"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Match files in absolute pathnames
|
||||||
|
|
||||||
|
```console
|
||||||
|
foo@bar:~$ ./glob -i '/usr/local/include/nc*.h'
|
||||||
|
"/usr/local/include/ncCheck.h"
|
||||||
|
"/usr/local/include/ncGroupAtt.h"
|
||||||
|
"/usr/local/include/ncUshort.h"
|
||||||
|
"/usr/local/include/ncByte.h"
|
||||||
|
"/usr/local/include/ncString.h"
|
||||||
|
"/usr/local/include/ncUint64.h"
|
||||||
|
"/usr/local/include/ncGroup.h"
|
||||||
|
"/usr/local/include/ncUbyte.h"
|
||||||
|
"/usr/local/include/ncvalues.h"
|
||||||
|
"/usr/local/include/ncInt.h"
|
||||||
|
"/usr/local/include/ncAtt.h"
|
||||||
|
"/usr/local/include/ncVar.h"
|
||||||
|
"/usr/local/include/ncUint.h"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Wildcards: Match a range of characters listed in brackets ('[]')
|
||||||
|
|
||||||
|
```console
|
||||||
|
foo@bar:~$ ls test_files_02
|
||||||
|
1.txt 2.txt 3.txt 4.txt
|
||||||
|
|
||||||
|
foo@bar:~$ ./glob -i 'test_files_02/[0-9].txt'
|
||||||
|
"test_files_02/4.txt"
|
||||||
|
"test_files_02/3.txt"
|
||||||
|
"test_files_02/2.txt"
|
||||||
|
"test_files_02/1.txt"
|
||||||
|
|
||||||
|
foo@bar:~$ ./glob -i 'test_files_02/[1-2]*'
|
||||||
|
"test_files_02/2.txt"
|
||||||
|
"test_files_02/1.txt"
|
||||||
|
```
|
||||||
|
|
||||||
|
```console
|
||||||
|
foo@bar:~$ ls test_files_03
|
||||||
|
file1.txt file2.txt file3.txt file4.txt
|
||||||
|
|
||||||
|
foo@bar:~$ ./glob -i 'test_files_03/file[0-9].*'
|
||||||
|
"test_files_03/file2.txt"
|
||||||
|
"test_files_03/file3.txt"
|
||||||
|
"test_files_03/file1.txt"
|
||||||
|
"test_files_03/file4.txt"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Exclude files from the matching
|
||||||
|
|
||||||
|
```console
|
||||||
|
foo@bar:~$ ls test_files_01
|
||||||
|
__init__.py bar.py foo.py
|
||||||
|
|
||||||
|
foo@bar:~$ ./glob -i 'test_files_01/*[!__init__].py'
|
||||||
|
"test_files_01/bar.py"
|
||||||
|
"test_files_01/foo.py"
|
||||||
|
|
||||||
|
foo@bar:~$ ./glob -i 'test_files_01/*[!__init__][!bar].py'
|
||||||
|
"test_files_01/foo.py"
|
||||||
|
|
||||||
|
foo@bar:~$ ./glob -i 'test_files_01/[!_]*.py'
|
||||||
|
"test_files_01/bar.py"
|
||||||
|
"test_files_01/foo.py"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Wildcards: Match any one character with question mark ('?')
|
||||||
|
|
||||||
|
```console
|
||||||
|
foo@bar:~$ ls test_files_02
|
||||||
|
1.txt 2.txt 3.txt 4.txt
|
||||||
|
|
||||||
|
foo@bar:~$ ./glob -i 'test_files_02/?.txt'
|
||||||
|
"test_files_02/4.txt"
|
||||||
|
"test_files_02/3.txt"
|
||||||
|
"test_files_02/2.txt"
|
||||||
|
"test_files_02/1.txt"
|
||||||
|
```
|
||||||
|
|
||||||
|
```console
|
||||||
|
foo@bar:~$ ls test_files_03
|
||||||
|
file1.txt file2.txt file3.txt file4.txt
|
||||||
|
|
||||||
|
foo@bar:~$ ./glob -i 'test_files_03/????[3-4].txt'
|
||||||
|
"test_files_03/file3.txt"
|
||||||
|
"test_files_03/file4.txt"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Case sensitivity
|
||||||
|
|
||||||
|
`glob` matching is case-sensitive:
|
||||||
|
|
||||||
|
```console
|
||||||
|
foo@bar:~$ ls test_files_05
|
||||||
|
file1.png file2.png file3.PNG file4.PNG
|
||||||
|
|
||||||
|
foo@bar:~$ ./glob -i 'test_files_05/*.png'
|
||||||
|
"test_files_05/file2.png"
|
||||||
|
"test_files_05/file1.png"
|
||||||
|
|
||||||
|
foo@bar:~$ ./glob -i 'test_files_05/*.PNG'
|
||||||
|
"test_files_05/file3.PNG"
|
||||||
|
"test_files_05/file4.PNG"
|
||||||
|
|
||||||
|
foo@bar:~$ ./glob -i "test_files_05/*.png","test_files_05/*.PNG"
|
||||||
|
"test_files_05/file2.png"
|
||||||
|
"test_files_05/file1.png"
|
||||||
|
"test_files_05/file3.PNG"
|
||||||
|
"test_files_05/file4.PNG"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Tilde expansion
|
||||||
|
|
||||||
|
```console
|
||||||
|
foo@bar:~$ ./glob -i "~/.b*"
|
||||||
|
"/Users/pranav/.bashrc"
|
||||||
|
"/Users/pranav/.bash_sessions"
|
||||||
|
"/Users/pranav/.bash_profile"
|
||||||
|
"/Users/pranav/.bash_history"
|
||||||
|
|
||||||
|
foo@bar:~$ ./glob -i "~/Documents/Projects/glob/**/glob/*.h"
|
||||||
|
"/Users/pranav/Documents/Projects/glob/include/glob/glob.h"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
Contributions are welcome, have a look at the [CONTRIBUTING.md](CONTRIBUTING.md) document for more information.
|
||||||
|
|
||||||
|
## License
|
||||||
|
The project is available under the [MIT](https://opensource.org/licenses/MIT) license.
|
||||||
40
src/external/glob/include/glob/glob.h
vendored
Normal file
40
src/external/glob/include/glob/glob.h
vendored
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include <filesystem>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace glob {
|
||||||
|
|
||||||
|
/// \param pathname string containing a path specification
|
||||||
|
/// \return vector of paths that match the pathname
|
||||||
|
///
|
||||||
|
/// Pathnames can be absolute (/usr/src/Foo/Makefile) or relative (../../Tools/*/*.gif)
|
||||||
|
/// Pathnames can contain shell-style wildcards
|
||||||
|
/// Broken symlinks are included in the results (as in the shell)
|
||||||
|
std::vector<std::filesystem::path> glob(const std::string &pathname);
|
||||||
|
|
||||||
|
/// \param pathnames string containing a path specification
|
||||||
|
/// \return vector of paths that match the pathname
|
||||||
|
///
|
||||||
|
/// Globs recursively.
|
||||||
|
/// The pattern “**” will match any files and zero or more directories, subdirectories and
|
||||||
|
/// symbolic links to directories.
|
||||||
|
std::vector<std::filesystem::path> rglob(const std::string &pathname);
|
||||||
|
|
||||||
|
/// Runs `glob` against each pathname in `pathnames` and accumulates the results
|
||||||
|
std::vector<std::filesystem::path> glob(const std::vector<std::string> &pathnames);
|
||||||
|
|
||||||
|
/// Runs `rglob` against each pathname in `pathnames` and accumulates the results
|
||||||
|
std::vector<std::filesystem::path> rglob(const std::vector<std::string> &pathnames);
|
||||||
|
|
||||||
|
/// Initializer list overload for convenience
|
||||||
|
std::vector<std::filesystem::path> glob(const std::initializer_list<std::string> &pathnames);
|
||||||
|
|
||||||
|
/// Initializer list overload for convenience
|
||||||
|
std::vector<std::filesystem::path> rglob(const std::initializer_list<std::string> &pathnames);
|
||||||
|
|
||||||
|
/// Returns true if the input path matche the glob pattern
|
||||||
|
bool fnmatch(const std::filesystem::path &name, const std::string &pattern);
|
||||||
|
|
||||||
|
} // namespace glob
|
||||||
447
src/external/glob/single_include/glob/glob.hpp
vendored
Normal file
447
src/external/glob/single_include/glob/glob.hpp
vendored
Normal file
@@ -0,0 +1,447 @@
|
|||||||
|
//
|
||||||
|
// TinyUSDZ modification:
|
||||||
|
// - Disable exception
|
||||||
|
// - Use GHC filesystem
|
||||||
|
//
|
||||||
|
#pragma once
|
||||||
|
#include <cassert>
|
||||||
|
// Assume ghc filesystem header is included(with NO_EXCEPTION version)
|
||||||
|
//#include <filesystem>
|
||||||
|
#include <functional>
|
||||||
|
#include <iostream>
|
||||||
|
#include <map>
|
||||||
|
#include <regex>
|
||||||
|
#include <string>
|
||||||
|
#include <system_error>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
namespace fs = std::filesystem;
|
||||||
|
#else
|
||||||
|
namespace fs = ghc::filesystem;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace glob {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
static inline
|
||||||
|
bool string_replace(std::string &str, const std::string &from, const std::string &to) {
|
||||||
|
std::size_t start_pos = str.find(from);
|
||||||
|
if (start_pos == std::string::npos)
|
||||||
|
return false;
|
||||||
|
str.replace(start_pos, from.length(), to);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
std::string translate(const std::string &pattern) {
|
||||||
|
std::size_t i = 0, n = pattern.size();
|
||||||
|
std::string result_string;
|
||||||
|
|
||||||
|
while (i < n) {
|
||||||
|
auto c = pattern[i];
|
||||||
|
i += 1;
|
||||||
|
if (c == '*') {
|
||||||
|
result_string += ".*";
|
||||||
|
} else if (c == '?') {
|
||||||
|
result_string += ".";
|
||||||
|
} else if (c == '[') {
|
||||||
|
auto j = i;
|
||||||
|
if (j < n && pattern[j] == '!') {
|
||||||
|
j += 1;
|
||||||
|
}
|
||||||
|
if (j < n && pattern[j] == ']') {
|
||||||
|
j += 1;
|
||||||
|
}
|
||||||
|
while (j < n && pattern[j] != ']') {
|
||||||
|
j += 1;
|
||||||
|
}
|
||||||
|
if (j >= n) {
|
||||||
|
result_string += "\\[";
|
||||||
|
} else {
|
||||||
|
auto stuff = std::string(pattern.begin() + i, pattern.begin() + j);
|
||||||
|
if (stuff.find("--") == std::string::npos) {
|
||||||
|
string_replace(stuff, std::string{"\\"}, std::string{R"(\\)"});
|
||||||
|
} else {
|
||||||
|
std::vector<std::string> chunks;
|
||||||
|
std::size_t k = 0;
|
||||||
|
if (pattern[i] == '!') {
|
||||||
|
k = i + 2;
|
||||||
|
} else {
|
||||||
|
k = i + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
k = pattern.find("-", k, j);
|
||||||
|
if (k == std::string::npos) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
chunks.push_back(std::string(pattern.begin() + i, pattern.begin() + k));
|
||||||
|
i = k + 1;
|
||||||
|
k = k + 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
chunks.push_back(std::string(pattern.begin() + i, pattern.begin() + j));
|
||||||
|
// Escape backslashes and hyphens for set difference (--).
|
||||||
|
// Hyphens that create ranges shouldn't be escaped.
|
||||||
|
bool first = false;
|
||||||
|
for (auto &s : chunks) {
|
||||||
|
string_replace(s, std::string{"\\"}, std::string{R"(\\)"});
|
||||||
|
string_replace(s, std::string{"-"}, std::string{R"(\-)"});
|
||||||
|
if (first) {
|
||||||
|
stuff += s;
|
||||||
|
first = false;
|
||||||
|
} else {
|
||||||
|
stuff += "-" + s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Escape set operations (&&, ~~ and ||).
|
||||||
|
std::string result;
|
||||||
|
std::regex_replace(std::back_inserter(result), // result
|
||||||
|
stuff.begin(), stuff.end(), // string
|
||||||
|
std::regex(std::string{R"([&~|])"}), // pattern
|
||||||
|
std::string{R"(\\\1)"}); // repl
|
||||||
|
stuff = result;
|
||||||
|
i = j + 1;
|
||||||
|
if (stuff[0] == '!') {
|
||||||
|
stuff = "^" + std::string(stuff.begin() + 1, stuff.end());
|
||||||
|
} else if (stuff[0] == '^' || stuff[0] == '[') {
|
||||||
|
stuff = "\\\\" + stuff;
|
||||||
|
}
|
||||||
|
result_string = result_string + "[" + stuff + "]";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// SPECIAL_CHARS
|
||||||
|
// closing ')', '}' and ']'
|
||||||
|
// '-' (a range in character set)
|
||||||
|
// '&', '~', (extended character set operations)
|
||||||
|
// '#' (comment) and WHITESPACE (ignored) in verbose mode
|
||||||
|
static std::string special_characters = "()[]{}?*+-|^$\\.&~# \t\n\r\v\f";
|
||||||
|
static std::map<int, std::string> special_characters_map;
|
||||||
|
if (special_characters_map.empty()) {
|
||||||
|
for (auto &sc : special_characters) {
|
||||||
|
special_characters_map.insert(
|
||||||
|
std::make_pair(static_cast<int>(sc), std::string{"\\"} + std::string(1, sc)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (special_characters.find(c) != std::string::npos) {
|
||||||
|
result_string += special_characters_map[static_cast<int>(c)];
|
||||||
|
} else {
|
||||||
|
result_string += c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return std::string{"(("} + result_string + std::string{R"()|[\r\n])$)"};
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
std::regex compile_pattern(const std::string &pattern) {
|
||||||
|
return std::regex(translate(pattern), std::regex::ECMAScript);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
bool fnmatch(const fs::path &name, const std::string &pattern) {
|
||||||
|
return std::regex_match(name.string(), compile_pattern(pattern));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
std::vector<fs::path> filter(const std::vector<fs::path> &names,
|
||||||
|
const std::string &pattern) {
|
||||||
|
// std::cout << "Pattern: " << pattern << "\n";
|
||||||
|
std::vector<fs::path> result;
|
||||||
|
for (auto &name : names) {
|
||||||
|
// std::cout << "Checking for " << name.string() << "\n";
|
||||||
|
if (fnmatch(name, pattern)) {
|
||||||
|
result.push_back(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
fs::path expand_tilde(fs::path path) {
|
||||||
|
if (path.empty()) return path;
|
||||||
|
#ifdef _WIN32
|
||||||
|
char* home;
|
||||||
|
size_t sz;
|
||||||
|
_dupenv_s(&home, &sz, "USERPROFILE");
|
||||||
|
#else
|
||||||
|
const char * home = std::getenv("HOME");
|
||||||
|
#endif
|
||||||
|
if (home == nullptr) {
|
||||||
|
//throw std::invalid_argument("error: Unable to expand `~` - HOME environment variable not set.");
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string s = path.string();
|
||||||
|
if (s[0] == '~') {
|
||||||
|
s = std::string(home) + s.substr(1, s.size() - 1);
|
||||||
|
return fs::path(s);
|
||||||
|
} else {
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
bool has_magic(const std::string &pathname) {
|
||||||
|
static const auto magic_check = std::regex("([*?[])");
|
||||||
|
return std::regex_search(pathname, magic_check);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
bool is_hidden(const std::string &pathname) {
|
||||||
|
return std::regex_match(pathname, std::regex("^(.*\\/)*\\.[^\\.\\/]+\\/*$"));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
bool is_recursive(const std::string &pattern) { return pattern == "**"; }
|
||||||
|
|
||||||
|
static inline
|
||||||
|
std::vector<fs::path> iter_directory(const fs::path &dirname, bool dironly) {
|
||||||
|
std::vector<fs::path> result;
|
||||||
|
|
||||||
|
std::error_code ec;
|
||||||
|
|
||||||
|
auto current_directory = dirname;
|
||||||
|
if (current_directory.empty()) {
|
||||||
|
current_directory = fs::current_path(ec);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fs::exists(current_directory, ec)) {
|
||||||
|
#if 0
|
||||||
|
try {
|
||||||
|
for (auto &entry : fs::directory_iterator(
|
||||||
|
current_directory, fs::directory_options::follow_directory_symlink |
|
||||||
|
fs::directory_options::skip_permission_denied, ec)) {
|
||||||
|
if (!dironly || entry.is_directory()) {
|
||||||
|
if (dirname.is_absolute()) {
|
||||||
|
result.push_back(entry.path());
|
||||||
|
} else {
|
||||||
|
result.push_back(fs::relative(entry.path()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (std::exception&) {
|
||||||
|
// not a directory
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
auto it = fs::directory_iterator(current_directory, ec);
|
||||||
|
auto itE = fs::end(it);
|
||||||
|
for (; it != itE; it.increment(ec)) {
|
||||||
|
|
||||||
|
if (ec) {
|
||||||
|
// TODO: Report error
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!dironly || it->is_directory(ec)) {
|
||||||
|
if (dirname.is_absolute()) {
|
||||||
|
result.push_back(it->path());
|
||||||
|
} else {
|
||||||
|
result.push_back(fs::relative(it->path(), ec));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recursively yields relative pathnames inside a literal directory.
|
||||||
|
static inline
|
||||||
|
std::vector<fs::path> rlistdir(const fs::path &dirname, bool dironly) {
|
||||||
|
std::vector<fs::path> result;
|
||||||
|
auto names = iter_directory(dirname, dironly);
|
||||||
|
for (auto &x : names) {
|
||||||
|
if (!is_hidden(x.string())) {
|
||||||
|
result.push_back(x);
|
||||||
|
for (auto &y : rlistdir(x, dironly)) {
|
||||||
|
result.push_back(y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This helper function recursively yields relative pathnames inside a literal
|
||||||
|
// directory.
|
||||||
|
static inline
|
||||||
|
std::vector<fs::path> glob2(const fs::path &dirname, [[maybe_unused]] const std::string &pattern,
|
||||||
|
bool dironly) {
|
||||||
|
// std::cout << "In glob2\n";
|
||||||
|
std::vector<fs::path> result;
|
||||||
|
assert(is_recursive(pattern));
|
||||||
|
for (auto &dir : rlistdir(dirname, dironly)) {
|
||||||
|
result.push_back(dir);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// These 2 helper functions non-recursively glob inside a literal directory.
|
||||||
|
// They return a list of basenames. _glob1 accepts a pattern while _glob0
|
||||||
|
// takes a literal basename (so it only has to check for its existence).
|
||||||
|
static inline
|
||||||
|
std::vector<fs::path> glob1(const fs::path &dirname, const std::string &pattern,
|
||||||
|
bool dironly) {
|
||||||
|
// std::cout << "In glob1\n";
|
||||||
|
auto names = iter_directory(dirname, dironly);
|
||||||
|
std::vector<fs::path> filtered_names;
|
||||||
|
for (auto &n : names) {
|
||||||
|
if (!is_hidden(n.string())) {
|
||||||
|
filtered_names.push_back(n.filename());
|
||||||
|
// if (n.is_relative()) {
|
||||||
|
// // std::cout << "Filtered (Relative): " << n << "\n";
|
||||||
|
// filtered_names.push_back(fs::relative(n));
|
||||||
|
// } else {
|
||||||
|
// // std::cout << "Filtered (Absolute): " << n << "\n";
|
||||||
|
// filtered_names.push_back(n.filename());
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return filter(filtered_names, pattern);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
std::vector<fs::path> glob0(const fs::path &dirname, const fs::path &basename,
|
||||||
|
bool /*dironly*/) {
|
||||||
|
// std::cout << "In glob0\n";
|
||||||
|
std::vector<fs::path> result;
|
||||||
|
std::error_code ec;
|
||||||
|
if (basename.empty()) {
|
||||||
|
// 'q*x/' should match only directories.
|
||||||
|
if (fs::is_directory(dirname, ec)) {
|
||||||
|
result = {basename};
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (fs::exists(dirname / basename, ec)) {
|
||||||
|
result = {basename};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
std::vector<fs::path> glob(const std::string &pathname, bool recursive = false,
|
||||||
|
bool dironly = false) {
|
||||||
|
std::vector<fs::path> result;
|
||||||
|
|
||||||
|
auto path = fs::path(pathname);
|
||||||
|
std::error_code ec;
|
||||||
|
|
||||||
|
if (pathname[0] == '~') {
|
||||||
|
// expand tilde
|
||||||
|
path = expand_tilde(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto dirname = path.parent_path();
|
||||||
|
const auto basename = path.filename();
|
||||||
|
|
||||||
|
if (!has_magic(pathname)) {
|
||||||
|
assert(!dironly);
|
||||||
|
if (!basename.empty()) {
|
||||||
|
if (fs::exists(path, ec)) {
|
||||||
|
result.push_back(path);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Patterns ending with a slash should match only directories
|
||||||
|
if (fs::is_directory(dirname, ec)) {
|
||||||
|
result.push_back(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dirname.empty()) {
|
||||||
|
if (recursive && is_recursive(basename.string())) {
|
||||||
|
return glob2(dirname, basename.string(), dironly);
|
||||||
|
} else {
|
||||||
|
return glob1(dirname, basename.string(), dironly);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<fs::path> dirs;
|
||||||
|
if (dirname != fs::path(pathname) && has_magic(dirname.string())) {
|
||||||
|
dirs = glob(dirname.string(), recursive, true);
|
||||||
|
} else {
|
||||||
|
dirs = {dirname};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::function<std::vector<fs::path>(const fs::path &, const std::string &, bool)>
|
||||||
|
glob_in_dir;
|
||||||
|
if (has_magic(basename.string())) {
|
||||||
|
if (recursive && is_recursive(basename.string())) {
|
||||||
|
glob_in_dir = glob2;
|
||||||
|
} else {
|
||||||
|
glob_in_dir = glob1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
glob_in_dir = glob0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto &d : dirs) {
|
||||||
|
for (auto &name : glob_in_dir(d, basename.string(), dironly)) {
|
||||||
|
fs::path subresult = name;
|
||||||
|
if (name.parent_path().empty()) {
|
||||||
|
subresult = d / name;
|
||||||
|
}
|
||||||
|
result.push_back(subresult);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace end
|
||||||
|
|
||||||
|
static inline
|
||||||
|
std::vector<fs::path> glob(const std::string &pathname) {
|
||||||
|
return glob(pathname, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
std::vector<fs::path> rglob(const std::string &pathname) {
|
||||||
|
return glob(pathname, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
std::vector<fs::path> glob(const std::vector<std::string> &pathnames) {
|
||||||
|
std::vector<fs::path> result;
|
||||||
|
for (auto &pathname : pathnames) {
|
||||||
|
for (auto &match : glob(pathname, false)) {
|
||||||
|
result.push_back(std::move(match));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
std::vector<fs::path> rglob(const std::vector<std::string> &pathnames) {
|
||||||
|
std::vector<fs::path> result;
|
||||||
|
for (auto &pathname : pathnames) {
|
||||||
|
for (auto &match : glob(pathname, true)) {
|
||||||
|
result.push_back(std::move(match));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
std::vector<fs::path>
|
||||||
|
glob(const std::initializer_list<std::string> &pathnames) {
|
||||||
|
return glob(std::vector<std::string>(pathnames));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
std::vector<fs::path>
|
||||||
|
rglob(const std::initializer_list<std::string> &pathnames) {
|
||||||
|
return rglob(std::vector<std::string>(pathnames));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace glob
|
||||||
381
src/external/glob/source/glob.cpp
vendored
Normal file
381
src/external/glob/source/glob.cpp
vendored
Normal file
@@ -0,0 +1,381 @@
|
|||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
#include <functional>
|
||||||
|
#include <glob/glob.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <map>
|
||||||
|
#include <regex>
|
||||||
|
namespace fs = std::filesystem;
|
||||||
|
|
||||||
|
namespace glob {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
bool string_replace(std::string &str, const std::string &from, const std::string &to) {
|
||||||
|
std::size_t start_pos = str.find(from);
|
||||||
|
if (start_pos == std::string::npos)
|
||||||
|
return false;
|
||||||
|
str.replace(start_pos, from.length(), to);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string translate(const std::string &pattern) {
|
||||||
|
std::size_t i = 0, n = pattern.size();
|
||||||
|
std::string result_string;
|
||||||
|
|
||||||
|
while (i < n) {
|
||||||
|
auto c = pattern[i];
|
||||||
|
i += 1;
|
||||||
|
if (c == '*') {
|
||||||
|
result_string += ".*";
|
||||||
|
} else if (c == '?') {
|
||||||
|
result_string += ".";
|
||||||
|
} else if (c == '[') {
|
||||||
|
auto j = i;
|
||||||
|
if (j < n && pattern[j] == '!') {
|
||||||
|
j += 1;
|
||||||
|
}
|
||||||
|
if (j < n && pattern[j] == ']') {
|
||||||
|
j += 1;
|
||||||
|
}
|
||||||
|
while (j < n && pattern[j] != ']') {
|
||||||
|
j += 1;
|
||||||
|
}
|
||||||
|
if (j >= n) {
|
||||||
|
result_string += "\\[";
|
||||||
|
} else {
|
||||||
|
auto stuff = std::string(pattern.begin() + i, pattern.begin() + j);
|
||||||
|
if (stuff.find("--") == std::string::npos) {
|
||||||
|
string_replace(stuff, std::string{"\\"}, std::string{R"(\\)"});
|
||||||
|
} else {
|
||||||
|
std::vector<std::string> chunks;
|
||||||
|
std::size_t k = 0;
|
||||||
|
if (pattern[i] == '!') {
|
||||||
|
k = i + 2;
|
||||||
|
} else {
|
||||||
|
k = i + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
k = pattern.find("-", k, j);
|
||||||
|
if (k == std::string::npos) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
chunks.push_back(std::string(pattern.begin() + i, pattern.begin() + k));
|
||||||
|
i = k + 1;
|
||||||
|
k = k + 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
chunks.push_back(std::string(pattern.begin() + i, pattern.begin() + j));
|
||||||
|
// Escape backslashes and hyphens for set difference (--).
|
||||||
|
// Hyphens that create ranges shouldn't be escaped.
|
||||||
|
bool first = true;
|
||||||
|
for (auto &s : chunks) {
|
||||||
|
string_replace(s, std::string{"\\"}, std::string{R"(\\)"});
|
||||||
|
string_replace(s, std::string{"-"}, std::string{R"(\-)"});
|
||||||
|
if (first) {
|
||||||
|
stuff += s;
|
||||||
|
first = false;
|
||||||
|
} else {
|
||||||
|
stuff += "-" + s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Escape set operations (&&, ~~ and ||).
|
||||||
|
std::string result;
|
||||||
|
std::regex_replace(std::back_inserter(result), // ressult
|
||||||
|
stuff.begin(), stuff.end(), // string
|
||||||
|
std::regex(std::string{R"([&~|])"}), // pattern
|
||||||
|
std::string{R"(\\\1)"}); // repl
|
||||||
|
stuff = result;
|
||||||
|
i = j + 1;
|
||||||
|
if (stuff[0] == '!') {
|
||||||
|
stuff = "^" + std::string(stuff.begin() + 1, stuff.end());
|
||||||
|
} else if (stuff[0] == '^' || stuff[0] == '[') {
|
||||||
|
stuff = "\\\\" + stuff;
|
||||||
|
}
|
||||||
|
result_string = result_string + "[" + stuff + "]";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// SPECIAL_CHARS
|
||||||
|
// closing ')', '}' and ']'
|
||||||
|
// '-' (a range in character set)
|
||||||
|
// '&', '~', (extended character set operations)
|
||||||
|
// '#' (comment) and WHITESPACE (ignored) in verbose mode
|
||||||
|
static std::string special_characters = "()[]{}?*+-|^$\\.&~# \t\n\r\v\f";
|
||||||
|
static std::map<int, std::string> special_characters_map;
|
||||||
|
if (special_characters_map.empty()) {
|
||||||
|
for (auto &sc : special_characters) {
|
||||||
|
special_characters_map.insert(
|
||||||
|
std::make_pair(static_cast<int>(sc), std::string{"\\"} + std::string(1, sc)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (special_characters.find(c) != std::string::npos) {
|
||||||
|
result_string += special_characters_map[static_cast<int>(c)];
|
||||||
|
} else {
|
||||||
|
result_string += c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return std::string{"(("} + result_string + std::string{R"()|[\r\n])$)"};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::regex compile_pattern(const std::string &pattern) {
|
||||||
|
return std::regex(translate(pattern), std::regex::ECMAScript);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool fnmatch(const fs::path &name, const std::string &pattern) {
|
||||||
|
return std::regex_match(name.string(), compile_pattern(pattern));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<fs::path> filter(const std::vector<fs::path> &names,
|
||||||
|
const std::string &pattern) {
|
||||||
|
// std::cout << "Pattern: " << pattern << "\n";
|
||||||
|
std::vector<fs::path> result;
|
||||||
|
for (auto &name : names) {
|
||||||
|
// std::cout << "Checking for " << name.string() << "\n";
|
||||||
|
if (fnmatch(name, pattern)) {
|
||||||
|
result.push_back(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
fs::path expand_tilde(fs::path path) {
|
||||||
|
if (path.empty()) return path;
|
||||||
|
|
||||||
|
const char * home = std::getenv("HOME");
|
||||||
|
if (home == nullptr) {
|
||||||
|
throw std::invalid_argument("error: Unable to expand `~` - HOME environment variable not set.");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string s = path.string();
|
||||||
|
if (s[0] == '~') {
|
||||||
|
s = std::string(home) + s.substr(1, s.size() - 1);
|
||||||
|
return fs::path(s);
|
||||||
|
} else {
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool has_magic(const std::string &pathname) {
|
||||||
|
static const auto magic_check = std::regex("([*?[])");
|
||||||
|
return std::regex_search(pathname, magic_check);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_hidden(const std::string &pathname) { return pathname[0] == '.'; }
|
||||||
|
|
||||||
|
bool is_recursive(const std::string &pattern) { return pattern == "**"; }
|
||||||
|
|
||||||
|
std::vector<fs::path> iter_directory(const fs::path &dirname, bool dironly) {
|
||||||
|
std::vector<fs::path> result;
|
||||||
|
|
||||||
|
auto current_directory = dirname;
|
||||||
|
if (current_directory.empty()) {
|
||||||
|
current_directory = fs::current_path();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fs::exists(current_directory)) {
|
||||||
|
try {
|
||||||
|
for (auto &entry : fs::directory_iterator(
|
||||||
|
current_directory, fs::directory_options::follow_directory_symlink |
|
||||||
|
fs::directory_options::skip_permission_denied)) {
|
||||||
|
if (!dironly || entry.is_directory()) {
|
||||||
|
if (dirname.is_absolute()) {
|
||||||
|
result.push_back(entry.path());
|
||||||
|
} else {
|
||||||
|
result.push_back(fs::relative(entry.path()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (std::exception&) {
|
||||||
|
// not a directory
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recursively yields relative pathnames inside a literal directory.
|
||||||
|
std::vector<fs::path> rlistdir(const fs::path &dirname, bool dironly) {
|
||||||
|
std::vector<fs::path> result;
|
||||||
|
auto names = iter_directory(dirname, dironly);
|
||||||
|
for (auto &x : names) {
|
||||||
|
if (!is_hidden(x.string())) {
|
||||||
|
result.push_back(x);
|
||||||
|
for (auto &y : rlistdir(x, dironly)) {
|
||||||
|
result.push_back(y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This helper function recursively yields relative pathnames inside a literal
|
||||||
|
// directory.
|
||||||
|
std::vector<fs::path> glob2(const fs::path &dirname, [[maybe_unused]] const fs::path &pattern,
|
||||||
|
bool dironly) {
|
||||||
|
// std::cout << "In glob2\n";
|
||||||
|
std::vector<fs::path> result;
|
||||||
|
assert(is_recursive(pattern.string()));
|
||||||
|
for (auto &dir : rlistdir(dirname, dironly)) {
|
||||||
|
result.push_back(dir);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// These 2 helper functions non-recursively glob inside a literal directory.
|
||||||
|
// They return a list of basenames. _glob1 accepts a pattern while _glob0
|
||||||
|
// takes a literal basename (so it only has to check for its existence).
|
||||||
|
|
||||||
|
std::vector<fs::path> glob1(const fs::path &dirname, const fs::path &pattern,
|
||||||
|
bool dironly) {
|
||||||
|
// std::cout << "In glob1\n";
|
||||||
|
auto names = iter_directory(dirname, dironly);
|
||||||
|
std::vector<fs::path> filtered_names;
|
||||||
|
for (auto &n : names) {
|
||||||
|
if (!is_hidden(n.string())) {
|
||||||
|
filtered_names.push_back(n.filename());
|
||||||
|
// if (n.is_relative()) {
|
||||||
|
// // std::cout << "Filtered (Relative): " << n << "\n";
|
||||||
|
// filtered_names.push_back(fs::relative(n));
|
||||||
|
// } else {
|
||||||
|
// // std::cout << "Filtered (Absolute): " << n << "\n";
|
||||||
|
// filtered_names.push_back(n.filename());
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return filter(filtered_names, pattern.string());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<fs::path> glob0(const fs::path &dirname, const fs::path &basename,
|
||||||
|
bool /*dironly*/) {
|
||||||
|
// std::cout << "In glob0\n";
|
||||||
|
std::vector<fs::path> result;
|
||||||
|
if (basename.empty()) {
|
||||||
|
// 'q*x/' should match only directories.
|
||||||
|
if (fs::is_directory(dirname)) {
|
||||||
|
result = {basename};
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (fs::exists(dirname / basename)) {
|
||||||
|
result = {basename};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<fs::path> glob(const fs::path &inpath, bool recursive = false,
|
||||||
|
bool dironly = false) {
|
||||||
|
std::vector<fs::path> result;
|
||||||
|
|
||||||
|
const auto pathname = inpath.string();
|
||||||
|
auto path = fs::path(pathname);
|
||||||
|
|
||||||
|
if (pathname[0] == '~') {
|
||||||
|
// expand tilde
|
||||||
|
path = expand_tilde(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto dirname = path.parent_path();
|
||||||
|
const auto basename = path.filename();
|
||||||
|
|
||||||
|
if (!has_magic(pathname)) {
|
||||||
|
assert(!dironly);
|
||||||
|
if (!basename.empty()) {
|
||||||
|
if (fs::exists(path)) {
|
||||||
|
result.push_back(path);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Patterns ending with a slash should match only directories
|
||||||
|
if (fs::is_directory(dirname)) {
|
||||||
|
result.push_back(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dirname.empty()) {
|
||||||
|
if (recursive && is_recursive(basename.string())) {
|
||||||
|
return glob2(dirname, basename, dironly);
|
||||||
|
} else {
|
||||||
|
return glob1(dirname, basename, dironly);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<fs::path> dirs;
|
||||||
|
if (dirname != fs::path(pathname) && has_magic(dirname.string())) {
|
||||||
|
dirs = glob(dirname, recursive, true);
|
||||||
|
} else {
|
||||||
|
dirs = {dirname};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::function<std::vector<fs::path>(const fs::path &, const fs::path &, bool)>
|
||||||
|
glob_in_dir;
|
||||||
|
if (has_magic(basename.string())) {
|
||||||
|
if (recursive && is_recursive(basename.string())) {
|
||||||
|
glob_in_dir = glob2;
|
||||||
|
} else {
|
||||||
|
glob_in_dir = glob1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
glob_in_dir = glob0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto &d : dirs) {
|
||||||
|
for (auto &name : glob_in_dir(d, basename, dironly)) {
|
||||||
|
fs::path subresult = name;
|
||||||
|
if (name.parent_path().empty()) {
|
||||||
|
subresult = d / name;
|
||||||
|
}
|
||||||
|
result.push_back(subresult);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace end
|
||||||
|
|
||||||
|
std::vector<fs::path> glob(const std::string &pathname) {
|
||||||
|
return glob(pathname, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<fs::path> rglob(const std::string &pathname) {
|
||||||
|
return glob(pathname, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::filesystem::path> glob(const std::vector<std::string> &pathnames) {
|
||||||
|
std::vector<std::filesystem::path> result;
|
||||||
|
for (auto &pathname : pathnames) {
|
||||||
|
for (auto &match : glob(pathname, false)) {
|
||||||
|
result.push_back(std::move(match));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::filesystem::path> rglob(const std::vector<std::string> &pathnames) {
|
||||||
|
std::vector<std::filesystem::path> result;
|
||||||
|
for (auto &pathname : pathnames) {
|
||||||
|
for (auto &match : glob(pathname, true)) {
|
||||||
|
result.push_back(std::move(match));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::filesystem::path>
|
||||||
|
glob(const std::initializer_list<std::string> &pathnames) {
|
||||||
|
return glob(std::vector<std::string>(pathnames));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::filesystem::path>
|
||||||
|
rglob(const std::initializer_list<std::string> &pathnames) {
|
||||||
|
return rglob(std::vector<std::string>(pathnames));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace glob
|
||||||
123
src/external/tiny_gltf.h
vendored
123
src/external/tiny_gltf.h
vendored
@@ -26,6 +26,8 @@
|
|||||||
// THE SOFTWARE.
|
// THE SOFTWARE.
|
||||||
|
|
||||||
// Version:
|
// Version:
|
||||||
|
// - v2.6.0 Disable expanding file path for security(no use of awkward `wordexp` anymore).
|
||||||
|
// Support serializing sparse accessor(Thanks to @fynv).
|
||||||
// - v2.5.0 Add SetPreserveImageChannels() option to load image data as is.
|
// - v2.5.0 Add SetPreserveImageChannels() option to load image data as is.
|
||||||
// - v2.4.3 Fix null object output when when material has all default
|
// - v2.4.3 Fix null object output when when material has all default
|
||||||
// parameters.
|
// parameters.
|
||||||
@@ -108,7 +110,11 @@ namespace tinygltf {
|
|||||||
#define TINYGLTF_COMPONENT_TYPE_INT (5124)
|
#define TINYGLTF_COMPONENT_TYPE_INT (5124)
|
||||||
#define TINYGLTF_COMPONENT_TYPE_UNSIGNED_INT (5125)
|
#define TINYGLTF_COMPONENT_TYPE_UNSIGNED_INT (5125)
|
||||||
#define TINYGLTF_COMPONENT_TYPE_FLOAT (5126)
|
#define TINYGLTF_COMPONENT_TYPE_FLOAT (5126)
|
||||||
#define TINYGLTF_COMPONENT_TYPE_DOUBLE (5130) // OpenGL double type. Note that some of glTF 2.0 validator does not support double type even the schema seems allow any value of integer: https://github.com/KhronosGroup/glTF/blob/b9884a2fd45130b4d673dd6c8a706ee21ee5c5f7/specification/2.0/schema/accessor.schema.json#L22
|
#define TINYGLTF_COMPONENT_TYPE_DOUBLE \
|
||||||
|
(5130) // OpenGL double type. Note that some of glTF 2.0 validator does not
|
||||||
|
// support double type even the schema seems allow any value of
|
||||||
|
// integer:
|
||||||
|
// https://github.com/KhronosGroup/glTF/blob/b9884a2fd45130b4d673dd6c8a706ee21ee5c5f7/specification/2.0/schema/accessor.schema.json#L22
|
||||||
|
|
||||||
#define TINYGLTF_TEXTURE_FILTER_NEAREST (9728)
|
#define TINYGLTF_TEXTURE_FILTER_NEAREST (9728)
|
||||||
#define TINYGLTF_TEXTURE_FILTER_LINEAR (9729)
|
#define TINYGLTF_TEXTURE_FILTER_LINEAR (9729)
|
||||||
@@ -613,7 +619,8 @@ struct Sampler {
|
|||||||
int wrapT =
|
int wrapT =
|
||||||
TINYGLTF_TEXTURE_WRAP_REPEAT; // ["CLAMP_TO_EDGE", "MIRRORED_REPEAT",
|
TINYGLTF_TEXTURE_WRAP_REPEAT; // ["CLAMP_TO_EDGE", "MIRRORED_REPEAT",
|
||||||
// "REPEAT"], default "REPEAT"
|
// "REPEAT"], default "REPEAT"
|
||||||
//int wrapR = TINYGLTF_TEXTURE_WRAP_REPEAT; // TinyGLTF extension. currently not used.
|
// int wrapR = TINYGLTF_TEXTURE_WRAP_REPEAT; // TinyGLTF extension. currently
|
||||||
|
// not used.
|
||||||
|
|
||||||
Value extras;
|
Value extras;
|
||||||
ExtensionMap extensions;
|
ExtensionMap extensions;
|
||||||
@@ -1302,8 +1309,10 @@ class TinyGLTF {
|
|||||||
///
|
///
|
||||||
/// Loads glTF ASCII asset from string(memory).
|
/// Loads glTF ASCII asset from string(memory).
|
||||||
/// `length` = strlen(str);
|
/// `length` = strlen(str);
|
||||||
/// Set warning message to `warn` for example it fails to load asserts.
|
/// `base_dir` is a search path of glTF asset(e.g. images). Path Must be an
|
||||||
/// Returns false and set error string to `err` if there's an error.
|
/// expanded path (e.g. no tilde(`~`), no environment variables). Set warning
|
||||||
|
/// message to `warn` for example it fails to load asserts. Returns false and
|
||||||
|
/// set error string to `err` if there's an error.
|
||||||
///
|
///
|
||||||
bool LoadASCIIFromString(Model *model, std::string *err, std::string *warn,
|
bool LoadASCIIFromString(Model *model, std::string *err, std::string *warn,
|
||||||
const char *str, const unsigned int length,
|
const char *str, const unsigned int length,
|
||||||
@@ -1322,6 +1331,8 @@ class TinyGLTF {
|
|||||||
///
|
///
|
||||||
/// Loads glTF binary asset from memory.
|
/// Loads glTF binary asset from memory.
|
||||||
/// `length` = strlen(str);
|
/// `length` = strlen(str);
|
||||||
|
/// `base_dir` is a search path of glTF asset(e.g. images). Path Must be an
|
||||||
|
/// expanded path (e.g. no tilde(`~`), no environment variables).
|
||||||
/// Set warning message to `warn` for example it fails to load asserts.
|
/// Set warning message to `warn` for example it fails to load asserts.
|
||||||
/// Returns false and set error string to `err` if there's an error.
|
/// Returns false and set error string to `err` if there's an error.
|
||||||
///
|
///
|
||||||
@@ -1424,6 +1435,10 @@ class TinyGLTF {
|
|||||||
bool preserve_image_channels_ = false; /// Default false(expand channels to
|
bool preserve_image_channels_ = false; /// Default false(expand channels to
|
||||||
/// RGBA) for backward compatibility.
|
/// RGBA) for backward compatibility.
|
||||||
|
|
||||||
|
// Warning & error messages
|
||||||
|
std::string warn_;
|
||||||
|
std::string err_;
|
||||||
|
|
||||||
FsCallbacks fs = {
|
FsCallbacks fs = {
|
||||||
#ifndef TINYGLTF_NO_FS
|
#ifndef TINYGLTF_NO_FS
|
||||||
&tinygltf::FileExists, &tinygltf::ExpandFilePath,
|
&tinygltf::FileExists, &tinygltf::ExpandFilePath,
|
||||||
@@ -1605,10 +1620,10 @@ class TinyGLTF {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#elif !defined(__ANDROID__) && !defined(__OpenBSD__)
|
#elif !defined(__ANDROID__) && !defined(__OpenBSD__)
|
||||||
#include <wordexp.h>
|
//#include <wordexp.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__sparcv9)
|
#if defined(__sparcv9) || defined(__powerpc__)
|
||||||
// Big endian
|
// Big endian
|
||||||
#else
|
#else
|
||||||
#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || MINIZ_X86_OR_X64_CPU
|
#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || MINIZ_X86_OR_X64_CPU
|
||||||
@@ -1933,10 +1948,9 @@ bool Sampler::operator==(const Sampler &other) const {
|
|||||||
return this->extensions == other.extensions && this->extras == other.extras &&
|
return this->extensions == other.extensions && this->extras == other.extras &&
|
||||||
this->magFilter == other.magFilter &&
|
this->magFilter == other.magFilter &&
|
||||||
this->minFilter == other.minFilter && this->name == other.name &&
|
this->minFilter == other.minFilter && this->name == other.name &&
|
||||||
this->wrapS == other.wrapS &&
|
this->wrapS == other.wrapS && this->wrapT == other.wrapT;
|
||||||
this->wrapT == other.wrapT;
|
|
||||||
|
|
||||||
//this->wrapR == other.wrapR
|
// this->wrapR == other.wrapR
|
||||||
}
|
}
|
||||||
bool Scene::operator==(const Scene &other) const {
|
bool Scene::operator==(const Scene &other) const {
|
||||||
return this->extensions == other.extensions && this->extras == other.extras &&
|
return this->extensions == other.extensions && this->extras == other.extras &&
|
||||||
@@ -2042,8 +2056,7 @@ static std::string GetBaseDir(const std::string &filepath) {
|
|||||||
|
|
||||||
static std::string GetBaseFilename(const std::string &filepath) {
|
static std::string GetBaseFilename(const std::string &filepath) {
|
||||||
auto idx = filepath.find_last_of("/\\");
|
auto idx = filepath.find_last_of("/\\");
|
||||||
if (idx != std::string::npos)
|
if (idx != std::string::npos) return filepath.substr(idx + 1);
|
||||||
return filepath.substr(idx + 1);
|
|
||||||
return filepath;
|
return filepath;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2605,6 +2618,18 @@ bool FileExists(const std::string &abs_filename, void *) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string ExpandFilePath(const std::string &filepath, void *) {
|
std::string ExpandFilePath(const std::string &filepath, void *) {
|
||||||
|
// https://github.com/syoyo/tinygltf/issues/368
|
||||||
|
//
|
||||||
|
// No file path expansion in built-in FS function anymore, since glTF URI
|
||||||
|
// should not contain tilde('~') and environment variables, and for security
|
||||||
|
// reason(`wordexp`).
|
||||||
|
//
|
||||||
|
// Users need to supply `base_dir`(in `LoadASCIIFromString`,
|
||||||
|
// `LoadBinaryFromMemory`) in expanded absolute path.
|
||||||
|
|
||||||
|
return filepath;
|
||||||
|
|
||||||
|
#if 0
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
// Assume input `filepath` is encoded in UTF-8
|
// Assume input `filepath` is encoded in UTF-8
|
||||||
std::wstring wfilepath = UTF8ToWchar(filepath);
|
std::wstring wfilepath = UTF8ToWchar(filepath);
|
||||||
@@ -2652,6 +2677,7 @@ std::string ExpandFilePath(const std::string &filepath, void *) {
|
|||||||
|
|
||||||
return s;
|
return s;
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ReadWholeFile(std::vector<unsigned char> *out, std::string *err,
|
bool ReadWholeFile(std::vector<unsigned char> *out, std::string *err,
|
||||||
@@ -3092,11 +3118,17 @@ std::string JsonToString(const json &o, int spacing = -1) {
|
|||||||
StringBuffer buffer;
|
StringBuffer buffer;
|
||||||
if (spacing == -1) {
|
if (spacing == -1) {
|
||||||
Writer<StringBuffer> writer(buffer);
|
Writer<StringBuffer> writer(buffer);
|
||||||
o.Accept(writer);
|
// TODO: Better error handling.
|
||||||
|
// https://github.com/syoyo/tinygltf/issues/332
|
||||||
|
if (!o.Accept(writer)) {
|
||||||
|
return "tiny_gltf::JsonToString() failed rapidjson conversion";
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
PrettyWriter<StringBuffer> writer(buffer);
|
PrettyWriter<StringBuffer> writer(buffer);
|
||||||
writer.SetIndent(' ', uint32_t(spacing));
|
writer.SetIndent(' ', uint32_t(spacing));
|
||||||
o.Accept(writer);
|
if (!o.Accept(writer)) {
|
||||||
|
return "tiny_gltf::JsonToString() failed rapidjson conversion";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return buffer.GetString();
|
return buffer.GetString();
|
||||||
#else
|
#else
|
||||||
@@ -4236,20 +4268,20 @@ static bool ParseSparseAccessor(Accessor *accessor, std::string *err,
|
|||||||
const json &values_obj = GetValue(values_iterator);
|
const json &values_obj = GetValue(values_iterator);
|
||||||
|
|
||||||
int indices_buffer_view = 0, indices_byte_offset = 0, component_type = 0;
|
int indices_buffer_view = 0, indices_byte_offset = 0, component_type = 0;
|
||||||
if (!ParseIntegerProperty(&indices_buffer_view, err, indices_obj, "bufferView",
|
if (!ParseIntegerProperty(&indices_buffer_view, err, indices_obj,
|
||||||
true, "SparseAccessor")) {
|
"bufferView", true, "SparseAccessor")) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ParseIntegerProperty(&indices_byte_offset, err, indices_obj, "byteOffset",
|
ParseIntegerProperty(&indices_byte_offset, err, indices_obj, "byteOffset",
|
||||||
false);
|
false);
|
||||||
if (!ParseIntegerProperty(&component_type, err, indices_obj, "componentType",
|
if (!ParseIntegerProperty(&component_type, err, indices_obj, "componentType",
|
||||||
true, "SparseAccessor")) {
|
true, "SparseAccessor")) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int values_buffer_view = 0, values_byte_offset = 0;
|
int values_buffer_view = 0, values_byte_offset = 0;
|
||||||
if (!ParseIntegerProperty(&values_buffer_view, err, values_obj, "bufferView",
|
if (!ParseIntegerProperty(&values_buffer_view, err, values_obj, "bufferView",
|
||||||
true, "SparseAccessor")) {
|
true, "SparseAccessor")) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ParseIntegerProperty(&values_byte_offset, err, values_obj, "byteOffset",
|
ParseIntegerProperty(&values_byte_offset, err, values_obj, "byteOffset",
|
||||||
@@ -5088,12 +5120,13 @@ static bool ParseSampler(Sampler *sampler, std::string *err, const json &o,
|
|||||||
int magFilter = -1;
|
int magFilter = -1;
|
||||||
int wrapS = TINYGLTF_TEXTURE_WRAP_REPEAT;
|
int wrapS = TINYGLTF_TEXTURE_WRAP_REPEAT;
|
||||||
int wrapT = TINYGLTF_TEXTURE_WRAP_REPEAT;
|
int wrapT = TINYGLTF_TEXTURE_WRAP_REPEAT;
|
||||||
//int wrapR = TINYGLTF_TEXTURE_WRAP_REPEAT;
|
// int wrapR = TINYGLTF_TEXTURE_WRAP_REPEAT;
|
||||||
ParseIntegerProperty(&minFilter, err, o, "minFilter", false);
|
ParseIntegerProperty(&minFilter, err, o, "minFilter", false);
|
||||||
ParseIntegerProperty(&magFilter, err, o, "magFilter", false);
|
ParseIntegerProperty(&magFilter, err, o, "magFilter", false);
|
||||||
ParseIntegerProperty(&wrapS, err, o, "wrapS", false);
|
ParseIntegerProperty(&wrapS, err, o, "wrapS", false);
|
||||||
ParseIntegerProperty(&wrapT, err, o, "wrapT", false);
|
ParseIntegerProperty(&wrapT, err, o, "wrapT", false);
|
||||||
//ParseIntegerProperty(&wrapR, err, o, "wrapR", false); // tinygltf extension
|
// ParseIntegerProperty(&wrapR, err, o, "wrapR", false); // tinygltf
|
||||||
|
// extension
|
||||||
|
|
||||||
// TODO(syoyo): Check the value is alloed one.
|
// TODO(syoyo): Check the value is alloed one.
|
||||||
// (e.g. we allow 9728(NEAREST), but don't allow 9727)
|
// (e.g. we allow 9728(NEAREST), but don't allow 9727)
|
||||||
@@ -5102,7 +5135,7 @@ static bool ParseSampler(Sampler *sampler, std::string *err, const json &o,
|
|||||||
sampler->magFilter = magFilter;
|
sampler->magFilter = magFilter;
|
||||||
sampler->wrapS = wrapS;
|
sampler->wrapS = wrapS;
|
||||||
sampler->wrapT = wrapT;
|
sampler->wrapT = wrapT;
|
||||||
//sampler->wrapR = wrapR;
|
// sampler->wrapR = wrapR;
|
||||||
|
|
||||||
ParseExtensionsProperty(&(sampler->extensions), err, o);
|
ParseExtensionsProperty(&(sampler->extensions), err, o);
|
||||||
ParseExtrasProperty(&(sampler->extras), o);
|
ParseExtrasProperty(&(sampler->extras), o);
|
||||||
@@ -6683,6 +6716,27 @@ static void SerializeGltfAccessor(Accessor &accessor, json &o) {
|
|||||||
if (accessor.extras.Type() != NULL_TYPE) {
|
if (accessor.extras.Type() != NULL_TYPE) {
|
||||||
SerializeValue("extras", accessor.extras, o);
|
SerializeValue("extras", accessor.extras, o);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// sparse
|
||||||
|
if (accessor.sparse.isSparse)
|
||||||
|
{
|
||||||
|
json sparse;
|
||||||
|
SerializeNumberProperty<int>("count", accessor.sparse.count, sparse);
|
||||||
|
{
|
||||||
|
json indices;
|
||||||
|
SerializeNumberProperty<int>("bufferView", accessor.sparse.indices.bufferView, indices);
|
||||||
|
SerializeNumberProperty<int>("byteOffset", accessor.sparse.indices.byteOffset, indices);
|
||||||
|
SerializeNumberProperty<int>("componentType", accessor.sparse.indices.componentType, indices);
|
||||||
|
JsonAddMember(sparse, "indices", std::move(indices));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
json values;
|
||||||
|
SerializeNumberProperty<int>("bufferView", accessor.sparse.values.bufferView, values);
|
||||||
|
SerializeNumberProperty<int>("byteOffset", accessor.sparse.values.byteOffset, values);
|
||||||
|
JsonAddMember(sparse, "values", std::move(values));
|
||||||
|
}
|
||||||
|
JsonAddMember(o, "sparse", std::move(sparse));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SerializeGltfAnimationChannel(AnimationChannel &channel, json &o) {
|
static void SerializeGltfAnimationChannel(AnimationChannel &channel, json &o) {
|
||||||
@@ -7165,7 +7219,7 @@ static void SerializeGltfSampler(Sampler &sampler, json &o) {
|
|||||||
if (sampler.minFilter != -1) {
|
if (sampler.minFilter != -1) {
|
||||||
SerializeNumberProperty("minFilter", sampler.minFilter, o);
|
SerializeNumberProperty("minFilter", sampler.minFilter, o);
|
||||||
}
|
}
|
||||||
//SerializeNumberProperty("wrapR", sampler.wrapR, o);
|
// SerializeNumberProperty("wrapR", sampler.wrapR, o);
|
||||||
SerializeNumberProperty("wrapS", sampler.wrapS, o);
|
SerializeNumberProperty("wrapS", sampler.wrapS, o);
|
||||||
SerializeNumberProperty("wrapT", sampler.wrapT, o);
|
SerializeNumberProperty("wrapT", sampler.wrapT, o);
|
||||||
|
|
||||||
@@ -7519,7 +7573,7 @@ static bool WriteGltfFile(const std::string &output,
|
|||||||
return WriteGltfStream(gltfFile, content);
|
return WriteGltfStream(gltfFile, content);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void WriteBinaryGltfStream(std::ostream &stream,
|
static bool WriteBinaryGltfStream(std::ostream &stream,
|
||||||
const std::string &content,
|
const std::string &content,
|
||||||
const std::vector<unsigned char> &binBuffer) {
|
const std::vector<unsigned char> &binBuffer) {
|
||||||
const std::string header = "glTF";
|
const std::string header = "glTF";
|
||||||
@@ -7528,8 +7582,10 @@ static void WriteBinaryGltfStream(std::ostream &stream,
|
|||||||
const uint32_t content_size = uint32_t(content.size());
|
const uint32_t content_size = uint32_t(content.size());
|
||||||
const uint32_t binBuffer_size = uint32_t(binBuffer.size());
|
const uint32_t binBuffer_size = uint32_t(binBuffer.size());
|
||||||
// determine number of padding bytes required to ensure 4 byte alignment
|
// determine number of padding bytes required to ensure 4 byte alignment
|
||||||
const uint32_t content_padding_size = content_size % 4 == 0 ? 0 : 4 - content_size % 4;
|
const uint32_t content_padding_size =
|
||||||
const uint32_t bin_padding_size = binBuffer_size % 4 == 0 ? 0 : 4 - binBuffer_size % 4;
|
content_size % 4 == 0 ? 0 : 4 - content_size % 4;
|
||||||
|
const uint32_t bin_padding_size =
|
||||||
|
binBuffer_size % 4 == 0 ? 0 : 4 - binBuffer_size % 4;
|
||||||
|
|
||||||
// 12 bytes for header, JSON content length, 8 bytes for JSON chunk info.
|
// 12 bytes for header, JSON content length, 8 bytes for JSON chunk info.
|
||||||
// Chunk data must be located at 4-byte boundary, which may require padding
|
// Chunk data must be located at 4-byte boundary, which may require padding
|
||||||
@@ -7573,9 +7629,12 @@ static void WriteBinaryGltfStream(std::ostream &stream,
|
|||||||
std::streamsize(padding.size()));
|
std::streamsize(padding.size()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Check error on stream.write
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void WriteBinaryGltfFile(const std::string &output,
|
static bool WriteBinaryGltfFile(const std::string &output,
|
||||||
const std::string &content,
|
const std::string &content,
|
||||||
const std::vector<unsigned char> &binBuffer) {
|
const std::vector<unsigned char> &binBuffer) {
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
@@ -7593,7 +7652,7 @@ static void WriteBinaryGltfFile(const std::string &output,
|
|||||||
#else
|
#else
|
||||||
std::ofstream gltfFile(output.c_str(), std::ios::binary);
|
std::ofstream gltfFile(output.c_str(), std::ios::binary);
|
||||||
#endif
|
#endif
|
||||||
WriteBinaryGltfStream(gltfFile, content, binBuffer);
|
return WriteBinaryGltfStream(gltfFile, content, binBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TinyGLTF::WriteGltfSceneToStream(Model *model, std::ostream &stream,
|
bool TinyGLTF::WriteGltfSceneToStream(Model *model, std::ostream &stream,
|
||||||
@@ -7632,7 +7691,7 @@ bool TinyGLTF::WriteGltfSceneToStream(Model *model, std::ostream &stream,
|
|||||||
// UpdateImageObject need baseDir but only uses it if embeddedImages is
|
// UpdateImageObject need baseDir but only uses it if embeddedImages is
|
||||||
// enabled, since we won't write separate images when writing to a stream
|
// enabled, since we won't write separate images when writing to a stream
|
||||||
// we
|
// we
|
||||||
UpdateImageObject(model->images[i], dummystring, int(i), false,
|
UpdateImageObject(model->images[i], dummystring, int(i), true,
|
||||||
&this->WriteImageData, this->write_image_user_data_);
|
&this->WriteImageData, this->write_image_user_data_);
|
||||||
SerializeGltfImage(model->images[i], image);
|
SerializeGltfImage(model->images[i], image);
|
||||||
JsonPushBack(images, std::move(image));
|
JsonPushBack(images, std::move(image));
|
||||||
@@ -7641,12 +7700,11 @@ bool TinyGLTF::WriteGltfSceneToStream(Model *model, std::ostream &stream,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (writeBinary) {
|
if (writeBinary) {
|
||||||
WriteBinaryGltfStream(stream, JsonToString(output), binBuffer);
|
return WriteBinaryGltfStream(stream, JsonToString(output), binBuffer);
|
||||||
} else {
|
} else {
|
||||||
WriteGltfStream(stream, JsonToString(output, prettyPrint ? 2 : -1));
|
return WriteGltfStream(stream, JsonToString(output, prettyPrint ? 2 : -1));
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TinyGLTF::WriteGltfSceneToFile(Model *model, const std::string &filename,
|
bool TinyGLTF::WriteGltfSceneToFile(Model *model, const std::string &filename,
|
||||||
@@ -7731,12 +7789,11 @@ bool TinyGLTF::WriteGltfSceneToFile(Model *model, const std::string &filename,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (writeBinary) {
|
if (writeBinary) {
|
||||||
WriteBinaryGltfFile(filename, JsonToString(output), binBuffer);
|
return WriteBinaryGltfFile(filename, JsonToString(output), binBuffer);
|
||||||
} else {
|
} else {
|
||||||
WriteGltfFile(filename, JsonToString(output, (prettyPrint ? 2 : -1)));
|
return WriteGltfFile(filename, JsonToString(output, (prettyPrint ? 2 : -1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace tinygltf
|
} // namespace tinygltf
|
||||||
|
|||||||
@@ -44,8 +44,21 @@
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#endif // _WIN32
|
#endif // _WIN32
|
||||||
|
|
||||||
|
#ifdef __clang__
|
||||||
|
#pragma clang diagnostic push
|
||||||
|
#pragma clang diagnostic ignored "-Weverything"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "external/filesystem/include/ghc/filesystem.hpp"
|
||||||
|
#include "external/glob/single_include/glob/glob.hpp"
|
||||||
|
|
||||||
|
#ifdef __clang__
|
||||||
|
#pragma clang diagnostic pop
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "io-util.hh"
|
#include "io-util.hh"
|
||||||
|
|
||||||
namespace tinyusdz {
|
namespace tinyusdz {
|
||||||
@@ -85,7 +98,8 @@ std::string ExpandFilePath(const std::string &filepath, void *) {
|
|||||||
// Quote the string to keep any spaces in filepath intact.
|
// Quote the string to keep any spaces in filepath intact.
|
||||||
std::string quoted_path = "\"" + filepath + "\"";
|
std::string quoted_path = "\"" + filepath + "\"";
|
||||||
// char** w;
|
// char** w;
|
||||||
int ret = wordexp(quoted_path.c_str(), &p, 0);
|
// TODO: Implement our own file path expansion routine.
|
||||||
|
int ret = wordexp(quoted_path.c_str(), &p, WRDE_NOCMD);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
// err
|
// err
|
||||||
s = filepath;
|
s = filepath;
|
||||||
|
|||||||
Reference in New Issue
Block a user