From 33e0ee7162f439817e09d3a473cf314e1c4c6512 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Sun, 13 Aug 2023 10:08:29 -0700 Subject: [PATCH] Trim trailing whitespace for names Some .obj files have extra whitespace after usemtl and other statements; this may interfere with parsing, for example by adding a space to the material name which can result in inability to find it in .mtl file. For consistency, we replace all uses of is_end_of_name with skip_name that handles this by leaving trailing whitespace alone. It will be skipped in the parsing flow when we skip the newline, which is similar to the behavior of trailing whitespace after numeric data (which parse_float/int leave alone). --- fast_obj.h | 50 ++++++++++++++++++++++++-------------------------- 1 file changed, 24 insertions(+), 26 deletions(-) diff --git a/fast_obj.h b/fast_obj.h index b39c0f6..777f8dc 100644 --- a/fast_obj.h +++ b/fast_obj.h @@ -297,7 +297,7 @@ void* file_open(const char* path, void* user_data) static void file_close(void* file, void* user_data) { - FILE* f; + FILE* f; (void)(user_data); f = (FILE*)(file); @@ -308,7 +308,7 @@ void file_close(void* file, void* user_data) static size_t file_read(void* file, void* dst, size_t bytes, void* user_data) { - FILE* f; + FILE* f; (void)(user_data); f = (FILE*)(file); @@ -323,7 +323,7 @@ unsigned long file_size(void* file, void* user_data) long p; long n; (void)(user_data); - + f = (FILE*)(file); p = ftell(f); @@ -413,12 +413,6 @@ int is_whitespace(char c) return (c == ' ' || c == '\t' || c == '\r'); } -static -int is_end_of_name(char c) -{ - return (c == '\t' || c == '\r' || c == '\n'); -} - static int is_newline(char c) { @@ -440,6 +434,21 @@ int is_exponent(char c) } +static +const char* skip_name(const char* ptr) +{ + const char* s = ptr; + + while (!is_newline(*ptr)) + ptr++; + + while (ptr > s && is_whitespace(*(ptr - 1))) + ptr--; + + return ptr; +} + + static const char* skip_whitespace(const char* ptr) { @@ -791,9 +800,7 @@ const char* parse_object(fastObjData* data, const char* ptr) ptr = skip_whitespace(ptr); s = ptr; - while (!is_end_of_name(*ptr)) - ptr++; - + ptr = skip_name(ptr); e = ptr; flush_object(data); @@ -813,9 +820,7 @@ const char* parse_group(fastObjData* data, const char* ptr) ptr = skip_whitespace(ptr); s = ptr; - while (!is_end_of_name(*ptr)) - ptr++; - + ptr = skip_name(ptr); e = ptr; flush_group(data); @@ -894,9 +899,7 @@ const char* parse_usemtl(fastObjData* data, const char* ptr) /* Parse the material name */ s = ptr; - while (!is_end_of_name(*ptr)) - ptr++; - + ptr = skip_name(ptr); e = ptr; /* Find an existing material with the same name */ @@ -992,9 +995,7 @@ const char* read_map(fastObjData* data, const char* ptr, fastObjTexture* map) /* Read name */ s = ptr; - while (!is_end_of_name(*ptr)) - ptr++; - + ptr = skip_name(ptr); e = ptr; name = string_copy(s, e); @@ -1068,8 +1069,7 @@ int read_mtllib(fastObjData* data, void* file, const fastObjCallbacks* callbacks p++; s = p; - while (!is_end_of_name(*p)) - p++; + p = skip_name(p); mtl.name = string_copy(s, p); } @@ -1211,9 +1211,7 @@ const char* parse_mtllib(fastObjData* data, const char* ptr, const fastObjCallba ptr = skip_whitespace(ptr); s = ptr; - while (!is_end_of_name(*ptr)) - ptr++; - + ptr = skip_name(ptr); e = ptr; lib = string_concat(data->base, s, e);