aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSyoyo Fujita <syoyo@lighttransport.com>2020-11-19 16:26:11 +0900
committerSyoyo Fujita <syoyo@lighttransport.com>2020-11-19 16:26:11 +0900
commitea74ce1cd5ea0cdb4132abdabf5d3f308105b764 (patch)
treed1a830dbacf284bdfb57c30c95d6d99ffda72928
parent4f1099a341baa31a0e562d6e098c0014a0b2ee19 (diff)
parent350d32a5739e567d700dde2326673f134676b7d1 (diff)
downloadtinyobjloader-ea74ce1cd5ea0cdb4132abdabf5d3f308105b764.tar.gz
Merge branch 'chapulina/whitespace' of https://github.com/chapulina/tinyobjloader into chapulina-chapulina/whitespace
-rw-r--r--examples/viewer/README.md2
-rw-r--r--models/mtl filename with whitespace issue46.mtl4
-rw-r--r--models/mtl filename with whitespace issue46.obj31
-rw-r--r--tests/tester.cc26
-rw-r--r--tiny_obj_loader.h35
5 files changed, 88 insertions, 10 deletions
diff --git a/examples/viewer/README.md b/examples/viewer/README.md
index 83392f0..76207bf 100644
--- a/examples/viewer/README.md
+++ b/examples/viewer/README.md
@@ -5,6 +5,8 @@
* premake5
* glfw3
* glew
+* xcursor
+* xinerama
## Build on MaCOSX
diff --git a/models/mtl filename with whitespace issue46.mtl b/models/mtl filename with whitespace issue46.mtl
new file mode 100644
index 0000000..b79d99b
--- /dev/null
+++ b/models/mtl filename with whitespace issue46.mtl
@@ -0,0 +1,4 @@
+newmtl green
+Ka 0 0 0
+Kd 0 1 0
+Ks 0 0 0
diff --git a/models/mtl filename with whitespace issue46.obj b/models/mtl filename with whitespace issue46.obj
new file mode 100644
index 0000000..72d1dc9
--- /dev/null
+++ b/models/mtl filename with whitespace issue46.obj
@@ -0,0 +1,31 @@
+mtllib invalid-file-without-spaces.mtl invalid\ file\ with\ spaces.mtl mtl\ filename\ with\ whitespace\ issue46.mtl
+
+v 0.000000 2.000000 2.000000
+v 0.000000 0.000000 2.000000
+v 2.000000 0.000000 2.000000
+v 2.000000 2.000000 2.000000
+v 0.000000 2.000000 0.000000
+v 0.000000 0.000000 0.000000
+v 2.000000 0.000000 0.000000
+v 2.000000 2.000000 0.000000
+# 8 vertices
+
+g front cube
+usemtl green
+f 1 2 3 4
+g back cube
+usemtl green
+f 8 7 6 5
+g right cube
+usemtl green
+f 4 3 7 8
+g left cube
+usemtl green
+f 5 6 2 1
+g top cube
+usemtl green
+f 5 1 4 8
+g bottom cube
+usemtl green
+f 2 6 7 3
+# 6 elements
diff --git a/tests/tester.cc b/tests/tester.cc
index 7538c74..0fd0dbc 100644
--- a/tests/tester.cc
+++ b/tests/tester.cc
@@ -1308,6 +1308,30 @@ void test_texres_texopt_issue248() {
TEST_CHECK("input.jpg" == materials[0].diffuse_texname);
}
+void test_mtl_filename_with_whitespace_issue46() {
+ tinyobj::attrib_t attrib;
+ std::vector<tinyobj::shape_t> shapes;
+ std::vector<tinyobj::material_t> materials;
+
+ std::string warn;
+ std::string err;
+ bool ret =
+ tinyobj::LoadObj(&attrib, &shapes, &materials, &warn, &err,
+ "../models/mtl filename with whitespace issue46.obj",
+ gMtlBasePath);
+
+ if (!warn.empty()) {
+ std::cout << "WARN: " << warn << std::endl;
+ }
+
+ if (!err.empty()) {
+ std::cerr << "ERR: " << err << std::endl;
+ }
+ TEST_CHECK(true == ret);
+ TEST_CHECK(1 == materials.size());
+ TEST_CHECK("green" == materials[0].name);
+}
+
// Fuzzer test.
// Just check if it does not crash.
// Disable by default since Windows filesystem can't create filename of afl
@@ -1407,4 +1431,6 @@ TEST_LIST = {
test_usemtl_whitespace_issue246},
{"texres_texopt_issue248",
test_texres_texopt_issue248},
+ {"test_mtl_filename_with_whitespace_issue46",
+ test_mtl_filename_with_whitespace_issue46},
{NULL, NULL}};
diff --git a/tiny_obj_loader.h b/tiny_obj_loader.h
index edd18f5..bbb35ca 100644
--- a/tiny_obj_loader.h
+++ b/tiny_obj_loader.h
@@ -1658,16 +1658,31 @@ static bool exportGroupsToShape(shape_t *shape, const PrimGroup &prim_group,
return true;
}
-// Split a string with specified delimiter character.
-// http://stackoverflow.com/questions/236129/split-a-string-in-c
-static void SplitString(const std::string &s, char delim,
+// Split a string with specified delimiter character and escape character.
+// https://rosettacode.org/wiki/Tokenize_a_string_with_escaping#C.2B.2B
+static void SplitString(const std::string &s, char delim, char escape,
std::vector<std::string> &elems) {
- std::stringstream ss;
- ss.str(s);
- std::string item;
- while (std::getline(ss, item, delim)) {
- elems.push_back(item);
+ std::string token;
+
+ bool escaping = false;
+ for (int i = 0; i < s.size(); ++i) {
+ char ch = s[i];
+ if (escaping) {
+ escaping = false;
+ } else if (ch == escape) {
+ escaping = true;
+ continue;
+ } else if (ch == delim) {
+ if (!token.empty()) {
+ elems.push_back(token);
+ }
+ token.clear();
+ continue;
+ }
+ token += ch;
}
+
+ elems.push_back(token);
}
static std::string JoinPath(const std::string &dir,
@@ -2483,7 +2498,7 @@ bool LoadObj(attrib_t *attrib, std::vector<shape_t> *shapes,
token += 7;
std::vector<std::string> filenames;
- SplitString(std::string(token), ' ', filenames);
+ SplitString(std::string(token), ' ', '\\', filenames);
if (filenames.empty()) {
if (warn) {
@@ -2891,7 +2906,7 @@ bool LoadObjWithCallback(std::istream &inStream, const callback_t &callback,
token += 7;
std::vector<std::string> filenames;
- SplitString(std::string(token), ' ', filenames);
+ SplitString(std::string(token), ' ', '\\', filenames);
if (filenames.empty()) {
if (warn) {