diff options
author | Aras Pranckevicius <aras@nesnausk.org> | 2022-07-10 18:27:07 +0300 |
---|---|---|
committer | Aras Pranckevicius <aras@nesnausk.org> | 2022-07-10 18:27:38 +0300 |
commit | 4114ace6169282390b199ea593c93445af748903 (patch) | |
tree | 275f169dbe8c9712ffbd46dc0194d13ce38987a5 /source/blender/io/wavefront_obj/importer/obj_import_string_utils.cc | |
parent | 443690604f4ed5bdcf05cca40c8d6f1f88a1c29a (diff) |
Fix T99536: new 3.2 OBJ importer fails with trailing space after wrapped lines
Address the issue by re-working line continuation handling: stop
trying to parse sequences like "backslash, newline" (which is the
bug: it should also handle "backslash, possible whitespace, newline")
during parsing. Instead, fixup line continuations after reading chunks
of input file data - turn backslash and the following newline into
spaces. The rest of parsing code does not have to be aware of them
at all then.
Makes the file attached to T99536 load correctly now. Also will extend
one of the test files in subversion tests repo to contain backslashes
followed by newlines.
Diffstat (limited to 'source/blender/io/wavefront_obj/importer/obj_import_string_utils.cc')
-rw-r--r-- | source/blender/io/wavefront_obj/importer/obj_import_string_utils.cc | 26 |
1 files changed, 22 insertions, 4 deletions
diff --git a/source/blender/io/wavefront_obj/importer/obj_import_string_utils.cc b/source/blender/io/wavefront_obj/importer/obj_import_string_utils.cc index bc9006e1051..9a457167fca 100644 --- a/source/blender/io/wavefront_obj/importer/obj_import_string_utils.cc +++ b/source/blender/io/wavefront_obj/importer/obj_import_string_utils.cc @@ -18,14 +18,12 @@ StringRef read_next_line(StringRef &buffer) const char *start = buffer.begin(); const char *end = buffer.end(); size_t len = 0; - char prev = 0; const char *ptr = start; while (ptr < end) { char c = *ptr++; - if (c == '\n' && prev != '\\') { + if (c == '\n') { break; } - prev = c; ++len; } @@ -35,7 +33,27 @@ StringRef read_next_line(StringRef &buffer) static bool is_whitespace(char c) { - return c <= ' ' || c == '\\'; + return c <= ' '; +} + +void fixup_line_continuations(char *p, char *end) +{ + while (true) { + /* Find next backslash, if any. */ + char *backslash = std::find(p, end, '\\'); + if (backslash == end) + break; + /* Skip over possible whitespace right after it. */ + p = backslash + 1; + while (p < end && is_whitespace(*p) && *p != '\n') + ++p; + /* If then we have a newline, turn both backslash + * and the newline into regular spaces. */ + if (p < end && *p == '\n') { + *backslash = ' '; + *p = ' '; + } + } } const char *drop_whitespace(const char *p, const char *end) |