diff options
Diffstat (limited to 'source/blender/blenlib')
-rw-r--r-- | source/blender/blenlib/BLI_blenlib.h | 1 | ||||
-rw-r--r-- | source/blender/blenlib/intern/storage.c | 2 | ||||
-rw-r--r-- | source/blender/blenlib/intern/util.c | 49 |
3 files changed, 51 insertions, 1 deletions
diff --git a/source/blender/blenlib/BLI_blenlib.h b/source/blender/blenlib/BLI_blenlib.h index 13d5b5fe829..c131dd93c72 100644 --- a/source/blender/blenlib/BLI_blenlib.h +++ b/source/blender/blenlib/BLI_blenlib.h @@ -387,6 +387,7 @@ void BLI_setInterruptCallBack(int (*f)(void)); char *BLI_strcasestr(const char *s, const char *find); int BLI_strcasecmp(const char *s1, const char *s2); int BLI_strncasecmp(const char *s1, const char *s2, int n); +int BLI_natstrcmp(const char *s1, const char *s2); void BLI_timestr(double _time, char *str); /* time var is global */ /** diff --git a/source/blender/blenlib/intern/storage.c b/source/blender/blenlib/intern/storage.c index 8ba03ad1343..088b5e40a51 100644 --- a/source/blender/blenlib/intern/storage.c +++ b/source/blender/blenlib/intern/storage.c @@ -153,7 +153,7 @@ int BLI_compare(struct direntry *entry1, struct direntry *entry2) if( strcmp(entry2->relname, ".")==0 ) return (1); if( strcmp(entry1->relname, "..")==0 ) return (-1); - return (BLI_strcasecmp(entry1->relname,entry2->relname)); + return (BLI_natstrcmp(entry1->relname,entry2->relname)); } diff --git a/source/blender/blenlib/intern/util.c b/source/blender/blenlib/intern/util.c index 013b9e0bb1b..842ebc4c0a9 100644 --- a/source/blender/blenlib/intern/util.c +++ b/source/blender/blenlib/intern/util.c @@ -1985,6 +1985,55 @@ int BLI_strncasecmp(const char *s1, const char *s2, int n) { return 0; } +/* natural string compare, keeping numbers in order */ +int BLI_natstrcmp(const char *s1, const char *s2) +{ + int d1= 0, d2= 0; + + /* if both chars are numeric, to a strtol(). + then increase string deltas as long they are + numeric, else do a tolower and char compare */ + + while(1) { + char c1 = tolower(s1[d1]); + char c2 = tolower(s2[d2]); + + if( isdigit(c1) && isdigit(c2) ) { + int val1, val2; + + val1= (int)strtol(s1+d1, (char **)NULL, 10); + val2= (int)strtol(s2+d2, (char **)NULL, 10); + + if (val1<val2) { + return -1; + } else if (val1>val2) { + return 1; + } + d1++; + while( isdigit(s1[d1]) ) + d1++; + d2++; + while( isdigit(s2[d2]) ) + d2++; + + c1 = tolower(s1[d1]); + c2 = tolower(s2[d2]); + } + + if (c1<c2) { + return -1; + } else if (c1>c2) { + return 1; + } else if (c1==0) { + break; + } + d1++; + d2++; + } + +} + + #ifdef WITH_ICONV #include "iconv.h" |