Bugfix #18637
authorTon Roosendaal <ton@blender.org>
Tue, 28 Apr 2009 17:25:50 +0000 (17:25 +0000)
committerTon Roosendaal <ton@blender.org>
Tue, 28 Apr 2009 17:25:50 +0000 (17:25 +0000)
Sorting of files didn't take numbers into account propertly, so it
ordered files like;

10.jpg
300.jpg
89.jpg
9.jpg

Quite simple to solve, almost moved report to the 'todo', but too
fun to leave this. :)

function name is BLI_natstrcmp() "natural string compare".

source/blender/blenlib/BLI_blenlib.h
source/blender/blenlib/intern/storage.c
source/blender/blenlib/intern/util.c
source/blender/src/filesel.c

index 13d5b5fe8290aea17a1186dceb401e9a5506cd1f..c131dd93c720c3201eb2787d57163f8440a82b98 100644 (file)
@@ -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 */
 
 /** 
index 8ba03ad1343ac7e593b353fd5233c02c021a7671..088b5e40a517c70f95476955bbd244b5d3a3c5e5 100644 (file)
@@ -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));
 }
 
 
index 013b9e0bb1b49fde7ffa8c615e793edfd48eacbc..842ebc4c0a96b4d9955e1d7f97f07d62af1a481f 100644 (file)
@@ -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"
index 9800c80b57d15637f63e04386481ef3b6634b6b9..36427fce36b35f7f4fb2a768422d0e1d624e4b6a 100644 (file)
@@ -196,7 +196,7 @@ static int compare_name(const void *a1, const void *a2)
        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));
 }
 
 static int compare_date(const void *a1, const void *a2)