fix [#29098] File save dialog cannot handle extra periods in file name
authorCampbell Barton <ideasman42@gmail.com>
Mon, 31 Oct 2011 00:23:42 +0000 (00:23 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Mon, 31 Oct 2011 00:23:42 +0000 (00:23 +0000)
source/blender/blenkernel/intern/image.c
source/blender/blenlib/BLI_path_util.h
source/blender/blenlib/intern/path_util.c
source/blender/windowmanager/intern/wm_operators.c

index 8bce751..9aeacb9 100644 (file)
@@ -981,7 +981,7 @@ int BKE_add_image_extension(char *string, int imtype)
                                  || (G.have_quicktime && BLI_testextensie_array(string, imb_ext_image_qt))) {
                        return BLI_replace_extension(string, FILE_MAX, extension);
                } else {
-                       strcat(string, extension);
+                       return BLI_ensure_extension(string, FILE_MAX, extension);
                        return TRUE;
                }
                
index dd4bc86..68bb1a7 100644 (file)
@@ -102,6 +102,7 @@ int BLI_testextensie(const char *str, const char *ext);
 int BLI_testextensie_array(const char *str, const char **ext_array);
 int BLI_testextensie_glob(const char *str, const char *ext_fnmatch);
 int BLI_replace_extension(char *path, size_t maxlen, const char *ext);
+int BLI_ensure_extension(char *path, size_t maxlen, const char *ext);
 void BLI_uniquename(struct ListBase *list, void *vlink, const char defname[], char delim, short name_offs, short len);
 int BLI_uniquename_cb(int (*unique_check)(void *, const char *), void *arg, const char defname[], char delim, char *name, short name_len);
 void BLI_newname(char * name, int add);
index e03a7ba..bbb62db 100644 (file)
@@ -1397,22 +1397,51 @@ int BLI_testextensie_glob(const char *str, const char *ext_fnmatch)
 
 int BLI_replace_extension(char *path, size_t maxlen, const char *ext)
 {
+       size_t path_len= strlen(path);
+       size_t ext_len= strlen(ext);
        size_t a;
 
-       for(a=strlen(path); a>0; a--) {
-               if(path[a-1] == '.' || path[a-1] == '/' || path[a-1] == '\\') {
-                       a--;
+       for(a= path_len - 1; a >= 0; a--) {
+               if (ELEM3(path[a], '.', '/', '\\')) {
                        break;
                }
        }
-       
-       if(path[a] != '.')
-               a= strlen(path);
 
-       if(a + strlen(ext) >= maxlen)
+       if(a + ext_len >= maxlen)
+               return 0;
+
+       memcpy(path+a, ext, ext_len + 1);
+       return 1;
+}
+
+/* strip's trailing '.'s and adds the extension only when needed */
+int BLI_ensure_extension(char *path, size_t maxlen, const char *ext)
+{
+       size_t path_len= strlen(path);
+       size_t ext_len= strlen(ext);
+       size_t a;
+
+       /* first check the extension is alread there */
+       if (    (ext_len <= path_len) &&
+               (strcmp(path + (path_len - ext_len), ext) == 0))
+       {
+               return 1;
+       }
+
+       for(a= path_len - 1; a >= 0; a--) {
+               if (path[a] == '.') {
+                       path[a]= '\0';
+               }
+               else {
+                       break;
+               }
+       }
+       a++;
+
+       if(a + ext_len >= maxlen)
                return 0;
 
-       strcpy(path+a, ext);
+       memcpy(path+a, ext, ext_len + 1);
        return 1;
 }
 
index 32d4ba8..acd5df7 100644 (file)
@@ -1949,7 +1949,10 @@ static int blend_save_check(bContext *UNUSED(C), wmOperator *op)
 {
        char filepath[FILE_MAX];
        RNA_string_get(op->ptr, "filepath", filepath);
-       if(BLI_replace_extension(filepath, sizeof(filepath), ".blend")) {
+       if(!BLO_has_bfile_extension(filepath)) {
+               /* some users would prefer BLI_replace_extension(),
+                * we keep getting knit-picking bug reports about this - campbell */
+               BLI_ensure_extension(filepath, FILE_MAX, ".blend");
                RNA_string_set(op->ptr, "filepath", filepath);
                return TRUE;
        }