Commit: 16ed20ff3cc68589a5fe48075d2b80692d3c90ea
Author: Bastien Montagne
Date:   Sat Jan 3 10:13:02 2015 +0100
Branches: master
https://developer.blender.org/rB16ed20ff3cc68589a5fe48075d2b80692d3c90ea

Add some BLI helpers needed by asset branch.

`BLI_strncpy_ensure_pad()` is also useful with current master code.

The two others (`BLI_strcmp_ignore_pad()` and `BLI_filelist_duplicate()`)
are only used in asset branch currently, but think they could be useful
in other places too, and simplifies handling of asset branch & future patch 
review.

Reviewers: campbellbarton

Reviewed By: campbellbarton

Differential Revision: https://developer.blender.org/D965

===================================================================

M       source/blender/blenlib/BLI_fileops.h
M       source/blender/blenlib/BLI_string.h
M       source/blender/blenlib/intern/storage.c
M       source/blender/blenlib/intern/string.c
M       source/blender/editors/interface/interface_templates.c
M       source/blender/editors/space_outliner/outliner_tree.c
M       tests/gtests/blenlib/BLI_path_util_test.cc

===================================================================

diff --git a/source/blender/blenlib/BLI_fileops.h 
b/source/blender/blenlib/BLI_fileops.h
index 4f451a6..8e05665 100644
--- a/source/blender/blenlib/BLI_fileops.h
+++ b/source/blender/blenlib/BLI_fileops.h
@@ -89,6 +89,9 @@ double BLI_dir_free_space(const char *dir);
 char  *BLI_current_working_dir(char *dir, const size_t maxlen);
 
 unsigned int BLI_dir_contents(const char *dir, struct direntry **filelist);
+void BLI_filelist_duplicate(
+        struct direntry **dest_filelist, struct direntry *src_filelist, 
unsigned int nrentries,
+        void *(*dup_poin)(void *));
 void BLI_free_filelist(struct direntry *filelist, unsigned int nrentries);
 
 /* Files */
diff --git a/source/blender/blenlib/BLI_string.h 
b/source/blender/blenlib/BLI_string.h
index b249bc7..a390b41 100644
--- a/source/blender/blenlib/BLI_string.h
+++ b/source/blender/blenlib/BLI_string.h
@@ -48,6 +48,8 @@ char *BLI_strdupcat(const char *__restrict str1, const char 
*__restrict str2) AT
 
 char *BLI_strncpy(char *__restrict dst, const char *__restrict src, const 
size_t maxncpy) ATTR_NONNULL();
 
+char *BLI_strncpy_ensure_pad(char *dst, const char *src, const char pad, 
size_t maxncpy) ATTR_NONNULL();
+
 size_t BLI_strncpy_rlen(char *__restrict dst, const char *__restrict src, 
const size_t maxncpy) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
 
 size_t BLI_strcpy_rlen(char *__restrict dst, const char *__restrict src) 
ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
@@ -71,6 +73,8 @@ char *BLI_strcasestr(const char *s, const char *find) 
ATTR_WARN_UNUSED_RESULT AT
 int BLI_strcasecmp(const char *s1, const char *s2) ATTR_WARN_UNUSED_RESULT 
ATTR_NONNULL();
 int BLI_strncasecmp(const char *s1, const char *s2, size_t len) 
ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
 int BLI_natstrcmp(const char *s1, const char *s2) ATTR_WARN_UNUSED_RESULT 
ATTR_NONNULL();
+int BLI_strcmp_ignore_pad(const char *str1, const char *str2, const char pad) 
ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+
 size_t BLI_strnlen(const char *str, const size_t maxlen) 
ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
 void BLI_timestr(double _time, char *str, size_t maxlen) ATTR_NONNULL();
 
diff --git a/source/blender/blenlib/intern/storage.c 
b/source/blender/blenlib/intern/storage.c
index c062d62..78057b1 100644
--- a/source/blender/blenlib/intern/storage.c
+++ b/source/blender/blenlib/intern/storage.c
@@ -409,7 +409,40 @@ unsigned int BLI_dir_contents(const char *dirname,  struct 
direntry **filelist)
        return dir_ctx.nrfiles;
 }
 
-/* frees storage for an array of direntries, including the array itself. */
+/**
+ * Deep-duplicate of an array of direntries, including the array itself.
+ *
+ * \param dup_poin If given, called for each non-NULL direntry->poin. 
Otherwise, pointer is always simply copied over.
+ */
+void BLI_filelist_duplicate(
+        struct direntry **dest_filelist, struct direntry *src_filelist, 
unsigned int nrentries,
+        void *(*dup_poin)(void *))
+{
+       unsigned int i;
+
+       *dest_filelist = malloc(sizeof(**dest_filelist) * (size_t)(nrentries));
+       for (i = 0; i < nrentries; ++i) {
+               struct direntry * const src = &src_filelist[i];
+               struct direntry *dest = &(*dest_filelist)[i];
+               *dest = *src;
+               if (dest->image) {
+                       dest->image = IMB_dupImBuf(src->image);
+               }
+               if (dest->relname) {
+                       dest->relname = MEM_dupallocN(src->relname);
+               }
+               if (dest->path) {
+                       dest->path = MEM_dupallocN(src->path);
+               }
+               if (dest->poin && dup_poin) {
+                       dest->poin = dup_poin(src->poin);
+               }
+       }
+}
+
+/**
+ * frees storage for an array of direntries, including the array itself.
+ */
 void BLI_free_filelist(struct direntry *filelist, unsigned int nrentries)
 {
        unsigned int i;
diff --git a/source/blender/blenlib/intern/string.c 
b/source/blender/blenlib/intern/string.c
index eeafc1a..765e2ea 100644
--- a/source/blender/blenlib/intern/string.c
+++ b/source/blender/blenlib/intern/string.c
@@ -126,6 +126,54 @@ char *BLI_strncpy(char *__restrict dst, const char 
*__restrict src, const size_t
 }
 
 /**
+ * Like BLI_strncpy but ensures dst is always padded by given char, on both 
sides (unless src is empty).
+ *
+ * \param dst Destination for copy
+ * \param src Source string to copy
+ * \param pad the char to use for padding
+ * \param maxncpy Maximum number of characters to copy (generally the size of 
dst)
+ * \retval Returns dst
+ */
+char *BLI_strncpy_ensure_pad(char *__restrict dst, const char *__restrict src, 
const char pad, size_t maxncpy)
+{
+       BLI_assert(maxncpy != 0);
+
+#ifdef DEBUG_STRSIZE
+       memset(dst, 0xff, sizeof(*dst) * maxncpy);
+#endif
+
+       if (src[0] == '\0') {
+               dst[0] = '\0';
+       }
+       else {
+               /* Add heading/trailing wildcards if needed. */
+               size_t idx = 0;
+               size_t srclen;
+
+               if (src[idx] != pad) {
+                       dst[idx++] = pad;
+                       maxncpy--;
+               }
+               maxncpy--;  /* trailing '\0' */
+
+               srclen = BLI_strnlen(src, maxncpy);
+               if ((src[srclen - 1] != pad) && (srclen == maxncpy)) {
+                       srclen--;
+               }
+
+               memcpy(&dst[idx], src, srclen);
+               idx += srclen;
+
+               if (dst[idx - 1] != pad) {
+                       dst[idx++] = pad;
+               }
+               dst[idx] = '\0';
+       }
+
+       return dst;
+}
+
+/**
  * Like strncpy but ensures dst is always
  * '\0' terminated.
  *
@@ -566,6 +614,50 @@ int BLI_natstrcmp(const char *s1, const char *s2)
        return strcmp(s1, s2);
 }
 
+/**
+ * Like strcmp, but will ignore any heading/trailing pad char for comparison.
+ * So e.g. if pad is '*', '*world' and 'world*' will compare equal.
+ */
+int BLI_strcmp_ignore_pad(const char *str1, const char *str2, const char pad)
+{
+       size_t str1_len, str2_len;
+
+       while (*str1 == pad) {
+               str1++;
+       }
+       while (*str2 == pad) {
+               str2++;
+       }
+
+       str1_len = strlen(str1);
+       str2_len = strlen(str2);
+
+       while (str1_len && (str1[str1_len - 1] == pad)) {
+               str1_len--;
+       }
+       while (str2_len && (str2[str2_len - 1] == pad)) {
+               str2_len--;
+       }
+
+       if (str1_len == str2_len) {
+               return strncmp(str1, str2, str2_len);
+       }
+       else if (str1_len > str2_len) {
+               int ret = strncmp(str1, str2, str2_len);
+               if (ret == 0) {
+                       ret = 1;
+               }
+               return ret;
+       }
+       else {
+               int ret = strncmp(str1, str2, str1_len);
+               if (ret == 0) {
+                       ret = -1;
+               }
+               return ret;
+       }
+}
+
 void BLI_timestr(double _time, char *str, size_t maxlen)
 {
        /* format 00:00:00.00 (hr:min:sec) string has to be 12 long */
diff --git a/source/blender/editors/interface/interface_templates.c 
b/source/blender/editors/interface/interface_templates.c
index 214fcfa..e3fa591 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -2684,15 +2684,7 @@ static void uilist_filter_items_default(struct uiList 
*ui_list, struct bContext
                        else {
                                filter = filter_dyn = MEM_mallocN((slen + 3) * 
sizeof(char), "filter_dyn");
                        }
-                       if (filter_raw[idx] != '*') {
-                               filter[idx++] = '*';
-                       }
-                       memcpy(filter + idx, filter_raw, slen);
-                       idx += slen;
-                       if (filter[idx - 1] != '*') {
-                               filter[idx++] = '*';
-                       }
-                       filter[idx] = '\0';
+                       BLI_strncpy_ensure_pad(filter, filter_raw, '*', slen + 
3);
                }
 
                RNA_PROP_BEGIN (dataptr, itemptr, prop)
diff --git a/source/blender/editors/space_outliner/outliner_tree.c 
b/source/blender/editors/space_outliner/outliner_tree.c
index f8a90c9..10cde8b 100644
--- a/source/blender/editors/space_outliner/outliner_tree.c
+++ b/source/blender/editors/space_outliner/outliner_tree.c
@@ -1371,59 +1371,42 @@ static void outliner_sort(SpaceOops *soops, ListBase 
*lb)
 
 /* Filtering ----------------------------------------------- */
 
-static int outliner_filter_has_name(TreeElement *te, const char *name, int 
flags)
+static bool outliner_filter_has_name(TreeElement *te, const char *name, int 
flags)
 {
-#if 0
-       int found = 0;
-       
-       /* determine if match */
-       if (flags & SO_FIND_CASE_SENSITIVE) {
-               if (flags & SO_FIND_COMPLETE)
-                       found = strcmp(te->name, name) == 0;
-               else
-                       found = strstr(te->name, name) != NULL;
-       }
-       else {
-               if (flags & SO_FIND_COMPLETE)
-                       found = BLI_strcasecmp(te->name, name) == 0;
-               else
-                       found = BLI_strcasestr(te->name, name) != NULL;
-       }
-#else
-       
        int fn_flag = 0;
-       int found = 0;
-       
+
        if ((flags & SO_FIND_CASE_SENSITIVE) == 0)
                fn_flag |= FNM_CASEFOLD;
 
-       if (flags & SO_FIND_COMPLETE) {
-               found = fnmatch(name, te->name, fn_flag) == 0;
-       }
-       else {
-               char fn_name[sizeof(((struct SpaceOops *)NULL)->search_string) 
+ 2];
-               BLI_snprintf(fn_name, sizeof(fn_name), "*%s*", name);
-               found = fnmatch(fn_name, te->name, fn_flag) == 0;
-       }
-       return found;
-#endif
+       return fnmatch(name, te->name, fn_flag) == 0;
 }
 
 static int outliner_filter_tree(SpaceOops *soops, ListBase *lb)
 {
        TreeElement *te, *ten;
        TreeStoreElem *tselem;
-       
+       char search_buff[sizeof(((struct SpaceOops *)NULL)->search_string) + 2];
+       char *search_string;
+
        /* although we don't have any search string, we return true 
         * since the entire tree is ok then...
         */
        if (soops->search_string[0] == 0)
                return 1;
 
+       if (soops->search_flags & SO_FIND_COMPLETE) {
+               search_string = soops->search_string;
+       }
+       else {
+               search_string = search_buff;
+               /* Implicitly add heading/trailing wildcards if needed. */
+               BLI_strncpy_ensure_pad(search_string, soops->search_string, 
'*', sizeof(search_string));
+       }
+
        for (te = lb->first; te; te = ten) {
                ten = te->next;
                
-               if (0 == outliner_filter_has_name(te, soops->search_string, 
soops->search_flags)) {
+               if (!outliner_filter_has_name(te, search_string, 
soops->search_flags)) {
                        /* item isn't something we're looking for, but...
                         *  - if the subtree is expanded, check if there are 
any matches that can be easily found
                         *              so that searching for "cu" in the 
default scene will still match the Cube
diff --git a/tests/gtests/blenlib/BLI_path_util_test.cc 
b/tests/gtests/blenlib/BLI_path_util_test.cc
index ea761bc..c4ef7c2 100644
--- a/tests/gtests/blenlib/BLI_path_util_test.cc
+++ b/tests/gtests/blenlib/BLI_path_util_test.cc
@@ -31,6 +31,7 @@ const char *GHOST_getSystemDir(int version, const char 
*versionstr)
 
 struct ImBuf;
 void IMB_freeImBuf(struct ImBuf *ibuf) {}
+struct ImBuf *IMB_dupImBuf(struct ImBuf *ibuf) {return NULL;}
 
 #ifdef __linux__
 char *zLhm65070058860608_br_find_exe(const char *default_exe)

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to