Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenlib')
-rw-r--r--source/blender/blenlib/BLI_alloca.h46
-rw-r--r--source/blender/blenlib/BLI_array.h42
-rw-r--r--source/blender/blenlib/BLI_bitmap.h4
-rw-r--r--source/blender/blenlib/BLI_buffer.h2
-rw-r--r--source/blender/blenlib/BLI_ghash.h2
-rw-r--r--source/blender/blenlib/BLI_listbase.h2
-rw-r--r--source/blender/blenlib/BLI_math_geom.h3
-rw-r--r--source/blender/blenlib/BLI_math_matrix.h19
-rw-r--r--source/blender/blenlib/BLI_math_vector.h4
-rw-r--r--source/blender/blenlib/BLI_path_util.h13
-rw-r--r--source/blender/blenlib/BLI_string.h6
-rw-r--r--source/blender/blenlib/BLI_string_utf8.h58
-rw-r--r--source/blender/blenlib/BLI_threads.h12
-rw-r--r--source/blender/blenlib/CMakeLists.txt1
-rw-r--r--source/blender/blenlib/intern/BLI_ghash.c16
-rw-r--r--source/blender/blenlib/intern/BLI_kdopbvh.c3
-rw-r--r--source/blender/blenlib/intern/BLI_mempool.c11
-rw-r--r--source/blender/blenlib/intern/DLRB_tree.c8
-rw-r--r--source/blender/blenlib/intern/fileops.c14
-rw-r--r--source/blender/blenlib/intern/listbase.c4
-rw-r--r--source/blender/blenlib/intern/math_color.c4
-rw-r--r--source/blender/blenlib/intern/math_geom.c160
-rw-r--r--source/blender/blenlib/intern/math_matrix.c74
-rw-r--r--source/blender/blenlib/intern/math_rotation.c5
-rw-r--r--source/blender/blenlib/intern/math_vector.c10
-rw-r--r--source/blender/blenlib/intern/math_vector_inline.c15
-rw-r--r--source/blender/blenlib/intern/noise.c10
-rw-r--r--source/blender/blenlib/intern/path_util.c62
-rw-r--r--source/blender/blenlib/intern/storage.c17
-rw-r--r--source/blender/blenlib/intern/string.c99
-rw-r--r--source/blender/blenlib/intern/string_utf8.c79
-rw-r--r--source/blender/blenlib/intern/threads.c46
32 files changed, 576 insertions, 275 deletions
diff --git a/source/blender/blenlib/BLI_alloca.h b/source/blender/blenlib/BLI_alloca.h
new file mode 100644
index 00000000000..b93f5b7123e
--- /dev/null
+++ b/source/blender/blenlib/BLI_alloca.h
@@ -0,0 +1,46 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __BLI_ALLOCA_H__
+
+/** \file BLI_alloca.h
+ * \ingroup bli
+ *
+ * Defines alloca and utility macro BLI_array_alloca
+ */
+
+/* BLI_array_alloca / alloca */
+#ifdef _MSC_VER
+# define alloca _alloca
+#endif
+
+#if defined(__MINGW32__)
+# include <malloc.h> /* mingw needs for alloca() */
+#endif
+
+#if defined(__GNUC__) || defined(__clang__)
+#define BLI_array_alloca(arr, realsize) \
+ (typeof(arr))alloca(sizeof(*arr) * (realsize))
+#else
+#define BLI_array_alloca(arr, realsize) \
+ alloca(sizeof(*arr) * (realsize))
+#endif
+
+#endif /* __BLI_ALLOCA_H__ */
diff --git a/source/blender/blenlib/BLI_array.h b/source/blender/blenlib/BLI_array.h
index 3fb50afdeac..ef5cb8bde04 100644
--- a/source/blender/blenlib/BLI_array.h
+++ b/source/blender/blenlib/BLI_array.h
@@ -40,11 +40,11 @@
#define _bli_array_totalsize_dynamic(arr) ( \
((arr) == NULL) ? \
0 : \
- MEM_allocN_len(arr) / sizeof(*arr) \
+ MEM_allocN_len(arr) / sizeof(*(arr)) \
)
#define _bli_array_totalsize_static(arr) \
- (sizeof(_##arr##_static) / sizeof(*arr))
+ (sizeof(_##arr##_static) / sizeof(*(arr)))
#define _bli_array_totalsize(arr) ( \
(size_t) \
@@ -66,8 +66,9 @@ void _bli_array_grow_func(void **arr_p, const void *arr_static,
/* -------------------------------------------------------------------- */
/* public defines */
+/* use sizeof(*(arr)) to ensure the array exists and is an array */
#define BLI_array_declare(arr) \
- int _##arr##_count = 0; \
+ int _##arr##_count = ((void)(sizeof(*(arr))), 0); \
void *_##arr##_static = NULL
/* this will use stack space, up to maxstatic array elements, before
@@ -95,7 +96,7 @@ void _bli_array_grow_func(void **arr_p, const void *arr_static,
(LIKELY(_bli_array_totalsize(arr) >= _##arr##_count + num) ? \
(void)0 /* do nothing */ : \
_bli_array_grow_func((void **)&(arr), _##arr##_static, \
- sizeof(*arr), _##arr##_count, num, \
+ sizeof(*(arr)), _##arr##_count, num, \
"BLI_array." #arr), \
(void)0) /* msvc2008 needs this */ \
), \
@@ -148,8 +149,8 @@ void _bli_array_grow_func(void **arr_p, const void *arr_static,
/* only to prevent unused warnings */
#define BLI_array_fake_user(arr) \
- (void)_##arr##_count, \
- (void)_##arr##_static
+ ((void)_##arr##_count, \
+ (void)_##arr##_static)
/* -------------------------------------------------------------------- */
@@ -161,7 +162,7 @@ void _bli_array_grow_func(void **arr_p, const void *arr_static,
* but use when the max size is known ahead of time */
#define BLI_array_fixedstack_declare(arr, maxstatic, realsize, allocstr) \
char _##arr##_static[maxstatic * sizeof(*(arr))]; \
- const int _##arr##_is_static = ((void *)_##arr##_static) != ( \
+ const bool _##arr##_is_static = ((void *)_##arr##_static) != ( \
arr = ((realsize) <= maxstatic) ? \
(void *)_##arr##_static : \
MEM_mallocN(sizeof(*(arr)) * (realsize), allocstr) \
@@ -172,31 +173,4 @@ void _bli_array_grow_func(void **arr_p, const void *arr_static,
MEM_freeN(arr); \
} (void)0
-
-/* alloca */
-#ifdef _MSC_VER
-# define alloca _alloca
-#endif
-
-#if defined(__MINGW32__)
-# include <malloc.h> /* mingw needs for alloca() */
-#endif
-
-#if defined(__GNUC__) || defined(__clang__)
-#define BLI_array_alloca(arr, realsize) \
- (typeof(arr))alloca(sizeof(*arr) * (realsize))
-
-#define BLI_array_alloca_and_count(arr, realsize) \
- (typeof(arr))alloca(sizeof(*arr) * (realsize)); \
- const int _##arr##_count = (realsize)
-
-#else
-#define BLI_array_alloca(arr, realsize) \
- alloca(sizeof(*arr) * (realsize))
-
-#define BLI_array_alloca_and_count(arr, realsize) \
- alloca(sizeof(*arr) * (realsize)); \
- const int _##arr##_count = (realsize)
-#endif
-
#endif /* __BLI_ARRAY_H__ */
diff --git a/source/blender/blenlib/BLI_bitmap.h b/source/blender/blenlib/BLI_bitmap.h
index 02e5d6bd797..ca98d28cc40 100644
--- a/source/blender/blenlib/BLI_bitmap.h
+++ b/source/blender/blenlib/BLI_bitmap.h
@@ -26,7 +26,7 @@
#ifndef __BLI_BITMAP_H__
#define __BLI_BITMAP_H__
-typedef unsigned int *BLI_bitmap;
+typedef unsigned int BLI_bitmap;
/* warning: the bitmap does not keep track of its own size or check
* for out-of-bounds access */
@@ -48,7 +48,7 @@ typedef unsigned int *BLI_bitmap;
/* allocate memory for a bitmap with '_tot' bits; free
* with MEM_freeN() */
#define BLI_BITMAP_NEW(_tot, _alloc_string) \
- ((BLI_bitmap)MEM_callocN(BLI_BITMAP_SIZE(_tot), \
+ ((BLI_bitmap *)MEM_callocN(BLI_BITMAP_SIZE(_tot), \
_alloc_string))
/* get the value of a single bit at '_index' */
diff --git a/source/blender/blenlib/BLI_buffer.h b/source/blender/blenlib/BLI_buffer.h
index fe835e7cadc..879ef869653 100644
--- a/source/blender/blenlib/BLI_buffer.h
+++ b/source/blender/blenlib/BLI_buffer.h
@@ -53,7 +53,7 @@ enum {
#define BLI_buffer_declare_static(type_, name_, flag_, static_count_) \
char name_ ## user; /* warn for free only */ \
- type_ *name_ ## _static_[static_count_]; \
+ type_ name_ ## _static_[static_count_]; \
BLI_Buffer name_ = { \
/* clear the static memory if this is a calloc'd array */ \
((void)((flag_ & BLI_BUFFER_USE_CALLOC) ? \
diff --git a/source/blender/blenlib/BLI_ghash.h b/source/blender/blenlib/BLI_ghash.h
index 930715b4bc6..3ad0e18c8d7 100644
--- a/source/blender/blenlib/BLI_ghash.h
+++ b/source/blender/blenlib/BLI_ghash.h
@@ -73,7 +73,7 @@ void *BLI_ghash_lookup(GHash *gh, const void *key);
bool BLI_ghash_remove(GHash *gh, void *key, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp);
void BLI_ghash_clear(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp);
void *BLI_ghash_pop(GHash *gh, void *key, GHashKeyFreeFP keyfreefp);
-bool BLI_ghash_haskey(GHash *gh, const void *key);
+bool BLI_ghash_haskey(GHash *gh, const void *key);
int BLI_ghash_size(GHash *gh);
/* *** */
diff --git a/source/blender/blenlib/BLI_listbase.h b/source/blender/blenlib/BLI_listbase.h
index 767f61b29dd..4c7ddf7ba66 100644
--- a/source/blender/blenlib/BLI_listbase.h
+++ b/source/blender/blenlib/BLI_listbase.h
@@ -72,7 +72,7 @@ void BLI_freelinkN(struct ListBase *listbase, void *vlink);
void BLI_movelisttolist(struct ListBase *dst, struct ListBase *src);
void BLI_duplicatelist(struct ListBase *dst, const struct ListBase *src);
void BLI_reverselist(struct ListBase *lb);
-void BLI_rotatelist(struct ListBase *lb, LinkData *vlink);
+void BLI_rotatelist(struct ListBase *lb, void *vlink);
/* create a generic list node containing link to provided data */
struct LinkData *BLI_genericNodeN(void *data);
diff --git a/source/blender/blenlib/BLI_math_geom.h b/source/blender/blenlib/BLI_math_geom.h
index 96652c0e78d..f9671f57acd 100644
--- a/source/blender/blenlib/BLI_math_geom.h
+++ b/source/blender/blenlib/BLI_math_geom.h
@@ -75,7 +75,8 @@ void closest_to_line_segment_v2(float closest[2], const float p[2], const float
float dist_to_plane_normalized_v3(const float p[3], const float plane_co[3], const float plane_no_unit[3]);
float dist_to_plane_v3(const float p[3], const float plane_co[3], const float plane_no[3]);
-float dist_to_line_segment_v3(const float p[3], const float l1[3], const float l2[3]);
+float dist_squared_to_line_segment_v3(const float p[3], const float l1[3], const float l2[3]);
+float dist_to_line_segment_v3(const float p[3], const float l1[3], const float l2[3]);
float dist_to_line_v3(const float p[3], const float l1[3], const float l2[3]);
float closest_to_line_v3(float r[3], const float p[3], const float l1[3], const float l2[3]);
float closest_to_line_v2(float r[2], const float p[2], const float l1[2], const float l2[2]);
diff --git a/source/blender/blenlib/BLI_math_matrix.h b/source/blender/blenlib/BLI_math_matrix.h
index 723122d7814..c305cc9a030 100644
--- a/source/blender/blenlib/BLI_math_matrix.h
+++ b/source/blender/blenlib/BLI_math_matrix.h
@@ -133,12 +133,12 @@ void normalize_m4_m4(float R[4][4], float A[4][4]);
void orthogonalize_m3(float R[3][3], int axis);
void orthogonalize_m4(float R[4][4], int axis);
-int is_orthogonal_m3(float mat[3][3]);
-int is_orthogonal_m4(float mat[4][4]);
-int is_orthonormal_m3(float mat[3][3]);
-int is_orthonormal_m4(float mat[4][4]);
+bool is_orthogonal_m3(float mat[3][3]);
+bool is_orthogonal_m4(float mat[4][4]);
+bool is_orthonormal_m3(float mat[3][3]);
+bool is_orthonormal_m4(float mat[4][4]);
-int is_uniform_scaled_m3(float mat[3][3]);
+bool is_uniform_scaled_m3(float mat[3][3]);
void adjoint_m2_m2(float R[2][2], float A[2][2]);
void adjoint_m3_m3(float R[3][3], float A[3][3]);
@@ -175,7 +175,7 @@ void mat4_to_size(float r[3], float M[4][4]);
void translate_m4(float mat[4][4], float tx, float ty, float tz);
void rotate_m4(float mat[4][4], const char axis, const float angle);
void rotate_m2(float mat[2][2], const float angle);
-
+void transform_pivot_set_m4(float mat[4][4], const float pivot[3]);
void mat3_to_rot_size(float rot[3][3], float size[3], float mat3[3][3]);
void mat4_to_loc_rot_size(float loc[3], float rot[3][3], float size[3], float wmat[4][4]);
@@ -194,8 +194,11 @@ void loc_axisangle_size_to_mat4(float R[4][4],
void blend_m3_m3m3(float R[3][3], float A[3][3], float B[3][3], const float t);
void blend_m4_m4m4(float R[4][4], float A[4][4], float B[4][4], const float t);
-int is_negative_m3(float mat[3][3]);
-int is_negative_m4(float mat[4][4]);
+bool is_negative_m3(float mat[3][3]);
+bool is_negative_m4(float mat[4][4]);
+
+bool is_zero_m3(float mat[3][3]);
+bool is_zero_m4(float mat[4][4]);
/*********************************** Other ***********************************/
diff --git a/source/blender/blenlib/BLI_math_vector.h b/source/blender/blenlib/BLI_math_vector.h
index 0df4de1f829..38b377c640e 100644
--- a/source/blender/blenlib/BLI_math_vector.h
+++ b/source/blender/blenlib/BLI_math_vector.h
@@ -116,6 +116,9 @@ MINLINE void mul_v3_v3v3(float r[3], const float a[3], const float b[3]);
MINLINE void mul_v4_fl(float r[4], float f);
MINLINE void mul_v4_v4fl(float r[3], const float a[3], float f);
MINLINE float mul_project_m4_v3_zfac(float mat[4][4], const float co[3]);
+MINLINE float dot_m3_v3_row_x(float M[3][3], const float a[3]);
+MINLINE float dot_m3_v3_row_y(float M[3][3], const float a[3]);
+MINLINE float dot_m3_v3_row_z(float M[3][3], const float a[3]);
MINLINE void madd_v3_v3fl(float r[3], const float a[3], float f);
MINLINE void madd_v3_v3v3(float r[3], const float a[3], const float b[3]);
@@ -240,6 +243,7 @@ void rotate_normalized_v3_v3v3fl(float v[3], const float p[3], const float axis[
void print_v2(const char *str, const float a[2]);
void print_v3(const char *str, const float a[3]);
void print_v4(const char *str, const float a[4]);
+void print_vn(const char *str, const float v[], const int n);
MINLINE void normal_short_to_float_v3(float r[3], const short n[3]);
MINLINE void normal_float_to_short_v3(short r[3], const float n[3]);
diff --git a/source/blender/blenlib/BLI_path_util.h b/source/blender/blenlib/BLI_path_util.h
index e0a34e35acc..cb812fe8595 100644
--- a/source/blender/blenlib/BLI_path_util.h
+++ b/source/blender/blenlib/BLI_path_util.h
@@ -89,7 +89,18 @@ void BLI_make_existing_file(const char *name);
void BLI_split_dirfile(const char *string, char *dir, char *file, const size_t dirlen, const size_t filelen);
void BLI_split_dir_part(const char *string, char *dir, const size_t dirlen);
void BLI_split_file_part(const char *string, char *file, const size_t filelen);
-void BLI_join_dirfile(char *string, const size_t maxlen, const char *dir, const char *file);
+void BLI_path_append(char *__restrict dst, const size_t maxlen,
+ const char *__restrict file)
+#ifdef __GNUC__
+__attribute__((nonnull))
+#endif
+;
+void BLI_join_dirfile(char *__restrict string, const size_t maxlen,
+ const char *__restrict dir, const char *__restrict file)
+#ifdef __GNUC__
+__attribute__((nonnull))
+#endif
+;
const char *BLI_path_basename(const char *path);
typedef enum bli_rebase_state {
diff --git a/source/blender/blenlib/BLI_string.h b/source/blender/blenlib/BLI_string.h
index c6f0bc49c9b..4816ac19fce 100644
--- a/source/blender/blenlib/BLI_string.h
+++ b/source/blender/blenlib/BLI_string.h
@@ -86,21 +86,21 @@ __attribute__((nonnull))
#endif
;
-char *BLI_replacestr(char *__restrict str, const char *__restrict oldText, const char *__restrict newText)
+char *BLI_replacestrN(const char *__restrict str, const char *__restrict substr_old, const char *__restrict substr_new)
#ifdef __GNUC__
__attribute__((warn_unused_result))
__attribute__((nonnull))
#endif
;
-size_t BLI_snprintf(char *__restrict buffer, size_t len, const char *__restrict format, ...)
+size_t BLI_snprintf(char *__restrict dst, size_t maxncpy, const char *__restrict format, ...)
#ifdef __GNUC__
__attribute__ ((format(printf, 3, 4)))
__attribute__((nonnull))
#endif
;
-size_t BLI_vsnprintf(char *__restrict buffer, size_t count, const char *__restrict format, va_list arg)
+size_t BLI_vsnprintf(char *__restrict dst, size_t maxncpy, const char *__restrict format, va_list arg)
#ifdef __GNUC__
__attribute__ ((format(printf, 3, 0)))
#endif
diff --git a/source/blender/blenlib/BLI_string_utf8.h b/source/blender/blenlib/BLI_string_utf8.h
index d20cbd2a91c..db32190494a 100644
--- a/source/blender/blenlib/BLI_string_utf8.h
+++ b/source/blender/blenlib/BLI_string_utf8.h
@@ -31,41 +31,57 @@
extern "C" {
#endif
-char *BLI_strncpy_utf8(char *__restrict dst, const char *__restrict src, size_t maxncpy);
-char *BLI_strncat_utf8(char *__restrict dst, const char *__restrict src, size_t maxncpy);
-int BLI_utf8_invalid_byte(const char *str, int length);
-int BLI_utf8_invalid_strip(char *str, int length);
+#ifdef __GNUC__
+# define ATTR_NONULL __attribute__((nonnull))
+# define ATTR_NONULL_FIRST __attribute__((nonnull(1)))
+# define ATTR_UNUSED_RESULT __attribute__((warn_unused_result))
+#else
+# define ATTR_NONULL
+# define ATTR_NONULL_FIRST
+# define ATTR_UNUSED_RESULT
+#endif
+
+char *BLI_strncpy_utf8(char *__restrict dst, const char *__restrict src, size_t maxncpy) ATTR_NONULL;
+char *BLI_strncat_utf8(char *__restrict dst, const char *__restrict src, size_t maxncpy) ATTR_NONULL;
+int BLI_utf8_invalid_byte(const char *str, int length) ATTR_NONULL;
+int BLI_utf8_invalid_strip(char *str, int length) ATTR_NONULL;
-int BLI_str_utf8_size(const char *p); /* warning, can return -1 on bad chars */
-int BLI_str_utf8_size_safe(const char *p);
+int BLI_str_utf8_size(const char *p) ATTR_NONULL; /* warning, can return -1 on bad chars */
+int BLI_str_utf8_size_safe(const char *p) ATTR_NONULL;
/* copied from glib */
-unsigned int BLI_str_utf8_as_unicode(const char *p);
-unsigned int BLI_str_utf8_as_unicode_and_size(const char *__restrict p, size_t *__restrict index);
-unsigned int BLI_str_utf8_as_unicode_and_size_safe(const char *__restrict p, size_t *__restrict index);
-unsigned int BLI_str_utf8_as_unicode_step(const char *__restrict p, size_t *__restrict index);
+unsigned int BLI_str_utf8_as_unicode(const char *p) ATTR_NONULL;
+unsigned int BLI_str_utf8_as_unicode_and_size(const char *__restrict p, size_t *__restrict index) ATTR_NONULL;
+unsigned int BLI_str_utf8_as_unicode_and_size_safe(const char *__restrict p, size_t *__restrict index) ATTR_NONULL;
+unsigned int BLI_str_utf8_as_unicode_step(const char *__restrict p, size_t *__restrict index) ATTR_NONULL;
size_t BLI_str_utf8_from_unicode(unsigned int c, char *outbuf);
-char *BLI_str_find_prev_char_utf8(const char *str, const char *p);
-char *BLI_str_find_next_char_utf8(const char *p, const char *end);
-char *BLI_str_prev_char_utf8(const char *p);
+char *BLI_str_find_prev_char_utf8(const char *str, const char *p) ATTR_NONULL;
+char *BLI_str_find_next_char_utf8(const char *p, const char *end) ATTR_NONULL_FIRST;
+char *BLI_str_prev_char_utf8(const char *p) ATTR_NONULL;
/* wchar_t functions, copied from blenders own font.c originally */
-size_t BLI_wstrlen_utf8(const wchar_t *src);
-size_t BLI_strlen_utf8(const char *strc);
-size_t BLI_strnlen_utf8(const char *start, const size_t maxlen);
-size_t BLI_strncpy_wchar_as_utf8(char *__restrict dst, const wchar_t *__restrict src, const size_t maxcpy);
-size_t BLI_strncpy_wchar_from_utf8(wchar_t *__restrict dst, const char *__restrict src, const size_t maxcpy);
+size_t BLI_wstrlen_utf8(const wchar_t *src) ATTR_NONULL;
+size_t BLI_strlen_utf8_ex(const char *strc, size_t *r_len_bytes) ATTR_NONULL;
+size_t BLI_strlen_utf8(const char *strc) ATTR_NONULL;
+size_t BLI_strnlen_utf8_ex(const char *strc, const size_t maxlen, size_t *r_len_bytes) ATTR_NONULL;
+size_t BLI_strnlen_utf8(const char *strc, const size_t maxlen) ATTR_NONULL;
+size_t BLI_strncpy_wchar_as_utf8(char *__restrict dst, const wchar_t *__restrict src, const size_t maxcpy) ATTR_NONULL;
+size_t BLI_strncpy_wchar_from_utf8(wchar_t *__restrict dst, const char *__restrict src, const size_t maxcpy) ATTR_NONULL;
/* count columns that character/string occupies, based on wcwidth.c */
int BLI_wcwidth(wchar_t ucs);
-int BLI_wcswidth(const wchar_t *pwcs, size_t n);
-int BLI_str_utf8_char_width(const char *p); /* warning, can return -1 on bad chars */
-int BLI_str_utf8_char_width_safe(const char *p);
+int BLI_wcswidth(const wchar_t *pwcs, size_t n) ATTR_NONULL;
+int BLI_str_utf8_char_width(const char *p) ATTR_NONULL; /* warning, can return -1 on bad chars */
+int BLI_str_utf8_char_width_safe(const char *p) ATTR_NONULL;
#define BLI_UTF8_MAX 6 /* mem */
#define BLI_UTF8_WIDTH_MAX 2 /* columns */
#define BLI_UTF8_ERR ((unsigned int)-1)
+#undef ATTR_NONULL
+#undef ATTR_NONULL_FIRST
+#undef ATTR_UNUSED_RESULT
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenlib/BLI_threads.h b/source/blender/blenlib/BLI_threads.h
index 331cac3ed76..154986936a2 100644
--- a/source/blender/blenlib/BLI_threads.h
+++ b/source/blender/blenlib/BLI_threads.h
@@ -131,6 +131,18 @@ void BLI_rw_mutex_free(ThreadRWMutex *mutex);
void BLI_rw_mutex_lock(ThreadRWMutex *mutex, int mode);
void BLI_rw_mutex_unlock(ThreadRWMutex *mutex);
+/* Ticket Mutex Lock
+ *
+ * This is a 'fair' mutex in that it will grant the lock to the first thread
+ * that requests it. */
+
+typedef struct TicketMutex TicketMutex;
+
+TicketMutex *BLI_ticket_mutex_alloc(void);
+void BLI_ticket_mutex_free(TicketMutex *ticket);
+void BLI_ticket_mutex_lock(TicketMutex *ticket);
+void BLI_ticket_mutex_unlock(TicketMutex *ticket);
+
/* ThreadedWorker
*
* A simple tool for dispatching work to a limited number of threads
diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt
index 1d94ca9afbc..b6b69116e67 100644
--- a/source/blender/blenlib/CMakeLists.txt
+++ b/source/blender/blenlib/CMakeLists.txt
@@ -99,6 +99,7 @@ set(SRC
intern/winstuff.c
BLI_args.h
+ BLI_alloca.h
BLI_array.h
BLI_bitmap.h
BLI_blenlib.h
diff --git a/source/blender/blenlib/intern/BLI_ghash.c b/source/blender/blenlib/intern/BLI_ghash.c
index d30d3f3d256..14dfbcffebe 100644
--- a/source/blender/blenlib/intern/BLI_ghash.c
+++ b/source/blender/blenlib/intern/BLI_ghash.c
@@ -34,6 +34,7 @@
#include <string.h>
#include <stdlib.h>
+#include <limits.h>
#include "MEM_guardedalloc.h"
@@ -178,7 +179,8 @@ void BLI_ghash_clear(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfree
gh->nentries = 0;
gh->nbuckets = hashsizes[gh->cursize];
- gh->buckets = MEM_recallocN(gh->buckets, gh->nbuckets * sizeof(*gh->buckets));
+ MEM_freeN(gh->buckets);
+ gh->buckets = MEM_callocN(gh->nbuckets * sizeof(*gh->buckets), "buckets");
}
/* same as above but return the value,
@@ -255,22 +257,14 @@ void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreef
GHashIterator *BLI_ghashIterator_new(GHash *gh)
{
GHashIterator *ghi = MEM_mallocN(sizeof(*ghi), "ghash iterator");
- ghi->gh = gh;
- ghi->curEntry = NULL;
- ghi->curBucket = (unsigned int)-1;
- while (!ghi->curEntry) {
- ghi->curBucket++;
- if (ghi->curBucket == ghi->gh->nbuckets)
- break;
- ghi->curEntry = ghi->gh->buckets[ghi->curBucket];
- }
+ BLI_ghashIterator_init(ghi, gh);
return ghi;
}
void BLI_ghashIterator_init(GHashIterator *ghi, GHash *gh)
{
ghi->gh = gh;
ghi->curEntry = NULL;
- ghi->curBucket = (unsigned int)-1;
+ ghi->curBucket = UINT_MAX; /* wraps to zero */
while (!ghi->curEntry) {
ghi->curBucket++;
if (ghi->curBucket == ghi->gh->nbuckets)
diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c
index cd5c961d982..a4c72aa26b0 100644
--- a/source/blender/blenlib/intern/BLI_kdopbvh.c
+++ b/source/blender/blenlib/intern/BLI_kdopbvh.c
@@ -72,7 +72,7 @@ struct BVHTree {
/* optimization, ensure we stay small */
BLI_STATIC_ASSERT((sizeof(void *) == 8 && sizeof(BVHTree) <= 48) ||
(sizeof(void *) == 4 && sizeof(BVHTree) <= 32),
- "over sized");
+ "over sized")
typedef struct BVHOverlapData {
BVHTree *tree1, *tree2;
@@ -603,6 +603,7 @@ static void build_implicit_tree_helper(BVHTree *tree, BVHBuildHelper *data)
data->branches_on_level[0] = 1;
/* We could stop the loop first (but I am lazy to find out when) */
+ /* note: this often causes integer overflow, may be worth avoiding? - campbell */
for (depth = 1; depth < 32; depth++) {
data->branches_on_level[depth] = data->branches_on_level[depth - 1] * data->tree_type;
data->leafs_per_child[depth] = data->leafs_per_child[depth - 1] / data->tree_type;
diff --git a/source/blender/blenlib/intern/BLI_mempool.c b/source/blender/blenlib/intern/BLI_mempool.c
index 87179a93e83..217a4b9d266 100644
--- a/source/blender/blenlib/intern/BLI_mempool.c
+++ b/source/blender/blenlib/intern/BLI_mempool.c
@@ -437,19 +437,22 @@ void *BLI_mempool_iterstep(BLI_mempool_iter *iter)
void BLI_mempool_destroy(BLI_mempool *pool)
{
BLI_mempool_chunk *mpchunk = NULL;
+ BLI_mempool_chunk *mpchunk_next;
if (pool->flag & BLI_MEMPOOL_SYSMALLOC) {
- for (mpchunk = pool->chunks.first; mpchunk; mpchunk = mpchunk->next) {
+ for (mpchunk = pool->chunks.first; mpchunk; mpchunk = mpchunk_next) {
+ mpchunk_next = mpchunk->next;
free(mpchunk->data);
+ free(mpchunk);
}
- BLI_freelist(&(pool->chunks));
free(pool);
}
else {
- for (mpchunk = pool->chunks.first; mpchunk; mpchunk = mpchunk->next) {
+ for (mpchunk = pool->chunks.first; mpchunk; mpchunk = mpchunk_next) {
+ mpchunk_next = mpchunk->next;
MEM_freeN(mpchunk->data);
+ MEM_freeN(mpchunk);
}
- BLI_freelistN(&(pool->chunks));
MEM_freeN(pool);
}
}
diff --git a/source/blender/blenlib/intern/DLRB_tree.c b/source/blender/blenlib/intern/DLRB_tree.c
index cb47f07574d..31b4b7cd4a5 100644
--- a/source/blender/blenlib/intern/DLRB_tree.c
+++ b/source/blender/blenlib/intern/DLRB_tree.c
@@ -539,9 +539,8 @@ DLRBT_Node *BLI_dlrbTree_add(DLRBT_Tree *tree, DLRBT_Comparator_FP cmp_cb,
parNode->left = node;
node->parent = parNode;
+ break;
}
- break;
-
case 1: /* add new node as right child */
{
node = new_cb(data);
@@ -549,15 +548,14 @@ DLRBT_Node *BLI_dlrbTree_add(DLRBT_Tree *tree, DLRBT_Comparator_FP cmp_cb,
parNode->right = node;
node->parent = parNode;
+ break;
}
- break;
-
default: /* update the duplicate node as appropriate */
{
if (update_cb)
update_cb(parNode, data);
+ break;
}
- break;
}
}
else {
diff --git a/source/blender/blenlib/intern/fileops.c b/source/blender/blenlib/intern/fileops.c
index 26fe0f21cd5..4809ba59aaf 100644
--- a/source/blender/blenlib/intern/fileops.c
+++ b/source/blender/blenlib/intern/fileops.c
@@ -199,7 +199,7 @@ bool BLI_file_touch(const char *file)
{
FILE *f = BLI_fopen(file, "r+b");
if (f != NULL) {
- char c = getc(f);
+ int c = getc(f);
rewind(f);
putc(c, f);
}
@@ -445,7 +445,7 @@ static void join_dirfile_alloc(char **dst, size_t *alloc_len, const char *dir, c
size_t len = strlen(dir) + strlen(file) + 1;
if (*dst == NULL)
- *dst = MEM_callocN(len + 1, "join_dirfile_alloc path");
+ *dst = MEM_mallocN(len + 1, "join_dirfile_alloc path");
else if (*alloc_len < len)
*dst = MEM_reallocN(*dst, len + 1);
@@ -911,18 +911,15 @@ void BLI_dir_create_recursive(const char *dirname)
char static_buf[MAXPATHLEN];
#endif
char *tmp;
- int needs_free;
if (BLI_exists(dirname)) return;
#ifdef MAXPATHLEN
size = MAXPATHLEN;
tmp = static_buf;
- needs_free = 0;
#else
size = strlen(dirname) + 1;
- tmp = MEM_callocN(size, "BLI_dir_create_recursive tmp");
- needs_free = 1;
+ tmp = MEM_callocN(size, __func__);
#endif
BLI_strncpy(tmp, dirname, size);
@@ -934,8 +931,9 @@ void BLI_dir_create_recursive(const char *dirname)
BLI_dir_create_recursive(tmp);
}
- if (needs_free)
- MEM_freeN(tmp);
+#ifndef MAXPATHLEN
+ MEM_freeN(tmp);
+#endif
mkdir(dirname, 0777);
}
diff --git a/source/blender/blenlib/intern/listbase.c b/source/blender/blenlib/intern/listbase.c
index f060a2771fe..ded4f31ae05 100644
--- a/source/blender/blenlib/intern/listbase.c
+++ b/source/blender/blenlib/intern/listbase.c
@@ -557,14 +557,14 @@ void BLI_reverselist(ListBase *lb)
/**
* \param vlink Link to make first.
*/
-void BLI_rotatelist(ListBase *lb, LinkData *vlink)
+void BLI_rotatelist(ListBase *lb, void *vlink)
{
/* make circular */
((LinkData *)lb->first)->prev = lb->last;
((LinkData *)lb->last)->next = lb->first;
lb->first = vlink;
- lb->last = vlink->prev;
+ lb->last = ((LinkData *)vlink)->prev;
((LinkData *)lb->first)->prev = NULL;
((LinkData *)lb->last)->next = NULL;
diff --git a/source/blender/blenlib/intern/math_color.c b/source/blender/blenlib/intern/math_color.c
index 3f802c492c2..8cfe4706937 100644
--- a/source/blender/blenlib/intern/math_color.c
+++ b/source/blender/blenlib/intern/math_color.c
@@ -150,6 +150,7 @@ void rgb_to_ycc(float r, float g, float b, float *ly, float *lcb, float *lcr, in
break;
default:
assert(!"invalid colorspace");
+ break;
}
*ly = y;
@@ -183,7 +184,8 @@ void ycc_to_rgb(float y, float cb, float cr, float *lr, float *lg, float *lb, in
b = y + 1.772f * cb - 226.816f;
break;
default:
- assert(!"invalid colorspace");
+ BLI_assert(0);
+ break;
}
*lr = r / 255.0f;
*lg = g / 255.0f;
diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c
index ddf1c598a1c..0e7ff521ce8 100644
--- a/source/blender/blenlib/intern/math_geom.c
+++ b/source/blender/blenlib/intern/math_geom.c
@@ -324,21 +324,26 @@ float dist_to_plane_v3(const float p[3], const float plane_co[3], const float pl
return line_point_factor_v3(p, plane_co, plane_co_other);
}
-/* distance v1 to line-piece v2-v3 in 3D */
-float dist_to_line_segment_v3(const float v1[3], const float v2[3], const float v3[3])
+/* distance v1 to line-piece l1-l2 in 3D */
+float dist_squared_to_line_segment_v3(const float p[3], const float l1[3], const float l2[3])
{
float closest[3];
- closest_to_line_segment_v3(closest, v1, v2, v3);
+ closest_to_line_segment_v3(closest, p, l1, l2);
- return len_v3v3(closest, v1);
+ return len_squared_v3v3(closest, p);
+}
+
+float dist_to_line_segment_v3(const float p[3], const float l1[3], const float l2[3])
+{
+ return sqrtf(dist_squared_to_line_segment_v3(p, l1, l2));
}
-float dist_to_line_v3(const float v1[3], const float v2[3], const float v3[3])
+float dist_to_line_v3(const float v1[3], const float l1[3], const float l2[3])
{
float closest[3];
- closest_to_line_v3(closest, v1, v2, v3);
+ closest_to_line_v3(closest, v1, l1, l2);
return len_v3v3(closest, v1);
}
@@ -489,6 +494,7 @@ int isect_seg_seg_v2_point(const float v1[2], const float v2[2], const float v3[
float a1, a2, b1, b2, c1, c2, d;
float u, v;
const float eps = 0.000001f;
+ const float eps_sq = eps * eps;
a1 = v2[0] - v1[0];
b1 = v4[0] - v3[0];
@@ -505,8 +511,8 @@ int isect_seg_seg_v2_point(const float v1[2], const float v2[2], const float v3[
float a[2], b[2], c[2];
float u2;
- if (len_v2v2(v1, v2) == 0.0f) {
- if (len_v2v2(v3, v4) > eps) {
+ if (equals_v2v2(v1, v2)) {
+ if (len_squared_v2v2(v3, v4) > eps_sq) {
/* use non-point segment as basis */
SWAP(const float *, v1, v3);
SWAP(const float *, v2, v4);
@@ -1452,7 +1458,7 @@ bool isect_axial_line_tri_v3(const int axis, const float p1[3], const float p2[3
int isect_line_line_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3], float i1[3], float i2[3])
{
float a[3], b[3], c[3], ab[3], cb[3], dir1[3], dir2[3];
- float d;
+ float d, div;
sub_v3_v3v3(c, v3, v1);
sub_v3_v3v3(a, v2, v1);
@@ -1468,12 +1474,17 @@ int isect_line_line_v3(const float v1[3], const float v2[3], const float v3[3],
cross_v3_v3v3(ab, a, b);
d = dot_v3v3(c, ab);
+ div = dot_v3v3(ab, ab);
+ /* test zero length line */
+ if (UNLIKELY(div == 0.0f)) {
+ return 0;
+ }
/* test if the two lines are coplanar */
- if (d > -0.000001f && d < 0.000001f) {
+ else if (d > -0.000001f && d < 0.000001f) {
cross_v3_v3v3(cb, c, b);
- mul_v3_fl(a, dot_v3v3(cb, ab) / dot_v3v3(ab, ab));
+ mul_v3_fl(a, dot_v3v3(cb, ab) / div);
add_v3_v3v3(i1, v1, a);
copy_v3_v3(i2, i1);
@@ -1518,7 +1529,7 @@ bool isect_line_line_strict_v3(const float v1[3], const float v2[3],
float vi[3], float *r_lambda)
{
float a[3], b[3], c[3], ab[3], cb[3], ca[3], dir1[3], dir2[3];
- float d;
+ float d, div;
sub_v3_v3v3(c, v3, v1);
sub_v3_v3v3(a, v2, v1);
@@ -1534,15 +1545,20 @@ bool isect_line_line_strict_v3(const float v1[3], const float v2[3],
cross_v3_v3v3(ab, a, b);
d = dot_v3v3(c, ab);
+ div = dot_v3v3(ab, ab);
+ /* test zero length line */
+ if (UNLIKELY(div == 0.0f)) {
+ return 0;
+ }
/* test if the two lines are coplanar */
- if (d > -0.000001f && d < 0.000001f) {
+ else if (d > -0.000001f && d < 0.000001f) {
float f1, f2;
cross_v3_v3v3(cb, c, b);
cross_v3_v3v3(ca, c, a);
- f1 = dot_v3v3(cb, ab) / dot_v3v3(ab, ab);
- f2 = dot_v3v3(ca, ab) / dot_v3v3(ab, ab);
+ f1 = dot_v3v3(cb, ab) / div;
+ f2 = dot_v3v3(ca, ab) / div;
if (f1 >= 0 && f1 <= 1 &&
f2 >= 0 && f2 <= 1)
@@ -2588,45 +2604,62 @@ static float mean_value_half_tan_v2(const float v1[2], const float v2[2], const
void interp_weights_poly_v3(float *w, float v[][3], const int n, const float co[3])
{
- /* TODO: t1 and t2 overlap each iter, we could call this only once per iter and reuse previous value */
- float totweight, t1, t2, len, *vmid, *vprev, *vnext;
- int i, i_next, i_curr;
+ const float eps = 0.00001f; /* take care, low values cause [#36105] */
+ const float eps_sq = eps * eps;
+ float *v_curr, *v_next;
+ float ht_prev, ht; /* half tangents */
+ float totweight = 0.0f;
+ int i = 0;
+ bool vert_interp = false;
bool edge_interp = false;
- totweight = 0.0f;
+ v_curr = v[0];
+ v_next = v[1];
- for (i = 0; i < n; i++) {
- i_curr = i;
- i_next = (i == n - 1) ? 0 : i + 1;
+ ht_prev = mean_value_half_tan_v3(co, v[n - 1], v_curr);
- vmid = v[i];
- vprev = (i == 0) ? v[n - 1] : v[i - 1];
- vnext = v[i_next];
+ while (i < n) {
+ const float len_sq = len_squared_v3v3(co, v_curr);
/* Mark Mayer et al algorithm that is used here does not operate well if vertex is close
* to borders of face. In that case, do simple linear interpolation between the two edge vertices */
- if (dist_to_line_segment_v3(co, vmid, vnext) < 10 * FLT_EPSILON) {
+ if (len_sq < eps_sq) {
+ vert_interp = true;
+ break;
+ }
+ else if (dist_squared_to_line_segment_v3(co, v_curr, v_next) < eps_sq) {
edge_interp = true;
break;
}
- t1 = mean_value_half_tan_v3(co, vprev, vmid);
- t2 = mean_value_half_tan_v3(co, vmid, vnext);
-
- len = len_v3v3(co, vmid);
- w[i] = (len != 0.0f) ? (t1 + t2) / len: 0.0f;
+ ht = mean_value_half_tan_v3(co, v_curr, v_next);
+ w[i] = (ht_prev + ht) / sqrtf(len_sq);
totweight += w[i];
+
+ /* step */
+ i++;
+ v_curr = v_next;
+ v_next = v[(i + 1) % n];
+
+ ht_prev = ht;
}
- if (edge_interp) {
- float len_curr = len_v3v3(co, vmid);
- float len_next = len_v3v3(co, vnext);
+ if (vert_interp) {
+ const int i_curr = i;
+ for (i = 0; i < n; i++)
+ w[i] = 0.0;
+ w[i_curr] = 1.0f;
+ }
+ else if (edge_interp) {
+ const int i_curr = i;
+ float len_curr = len_v3v3(co, v_curr);
+ float len_next = len_v3v3(co, v_next);
float edge_len = len_curr + len_next;
for (i = 0; i < n; i++)
w[i] = 0.0;
w[i_curr] = len_next / edge_len;
- w[i_next] = len_curr / edge_len;
+ w[(i_curr + 1) % n] = len_curr / edge_len;
}
else {
if (totweight != 0.0f) {
@@ -2640,45 +2673,62 @@ void interp_weights_poly_v3(float *w, float v[][3], const int n, const float co[
void interp_weights_poly_v2(float *w, float v[][2], const int n, const float co[2])
{
- /* TODO: t1 and t2 overlap each iter, we could call this only once per iter and reuse previous value */
- float totweight, t1, t2, len, *vmid, *vprev, *vnext;
- int i, i_next, i_curr;
+ const float eps = 0.00001f; /* take care, low values cause [#36105] */
+ const float eps_sq = eps * eps;
+ float *v_curr, *v_next;
+ float ht_prev, ht; /* half tangents */
+ float totweight = 0.0f;
+ int i = 0;
+ bool vert_interp = false;
bool edge_interp = false;
- totweight = 0.0f;
+ v_curr = v[0];
+ v_next = v[1];
- for (i = 0; i < n; i++) {
- i_curr = i;
- i_next = (i == n - 1) ? 0 : i + 1;
+ ht_prev = mean_value_half_tan_v2(co, v[n - 1], v_curr);
- vmid = v[i];
- vprev = (i == 0) ? v[n - 1] : v[i - 1];
- vnext = v[i_next];
+ while (i < n) {
+ const float len_sq = len_squared_v2v2(co, v_curr);
/* Mark Mayer et al algorithm that is used here does not operate well if vertex is close
* to borders of face. In that case, do simple linear interpolation between the two edge vertices */
- if (dist_to_line_segment_v2(co, vmid, vnext) < 10 * FLT_EPSILON) {
+ if (len_sq < eps_sq) {
+ vert_interp = true;
+ break;
+ }
+ else if (dist_squared_to_line_segment_v2(co, v_curr, v_next) < eps_sq) {
edge_interp = true;
break;
}
- t1 = mean_value_half_tan_v2(co, vprev, vmid);
- t2 = mean_value_half_tan_v2(co, vmid, vnext);
-
- len = len_v2v2(co, vmid);
- w[i] = (len != 0.0f) ? (t1 + t2) / len: 0.0f;
+ ht = mean_value_half_tan_v2(co, v_curr, v_next);
+ w[i] = (ht_prev + ht) / sqrtf(len_sq);
totweight += w[i];
+
+ /* step */
+ i++;
+ v_curr = v_next;
+ v_next = v[(i + 1) % n];
+
+ ht_prev = ht;
}
- if (edge_interp) {
- float len_curr = len_v2v2(co, vmid);
- float len_next = len_v2v2(co, vnext);
+ if (vert_interp) {
+ const int i_curr = i;
+ for (i = 0; i < n; i++)
+ w[i] = 0.0;
+ w[i_curr] = 1.0f;
+ }
+ else if (edge_interp) {
+ const int i_curr = i;
+ float len_curr = len_v2v2(co, v_curr);
+ float len_next = len_v2v2(co, v_next);
float edge_len = len_curr + len_next;
for (i = 0; i < n; i++)
w[i] = 0.0;
w[i_curr] = len_next / edge_len;
- w[i_next] = len_curr / edge_len;
+ w[(i_curr + 1) % n] = len_curr / edge_len;
}
else {
if (totweight != 0.0f) {
diff --git a/source/blender/blenlib/intern/math_matrix.c b/source/blender/blenlib/intern/math_matrix.c
index 298abfa8c5e..99342c4d6dc 100644
--- a/source/blender/blenlib/intern/math_matrix.c
+++ b/source/blender/blenlib/intern/math_matrix.c
@@ -790,6 +790,7 @@ void orthogonalize_m3(float mat[3][3], int axis)
normalize_v3(mat[2]);
cross_v3_v3v3(mat[1], mat[2], mat[0]);
}
+ break;
case 1:
if (dot_v3v3(mat[1], mat[0]) < 1) {
cross_v3_v3v3(mat[2], mat[0], mat[1]);
@@ -812,6 +813,7 @@ void orthogonalize_m3(float mat[3][3], int axis)
normalize_v3(mat[0]);
cross_v3_v3v3(mat[2], mat[0], mat[1]);
}
+ break;
case 2:
if (dot_v3v3(mat[2], mat[0]) < 1) {
cross_v3_v3v3(mat[1], mat[2], mat[0]);
@@ -834,6 +836,10 @@ void orthogonalize_m3(float mat[3][3], int axis)
normalize_v3(mat[0]);
cross_v3_v3v3(mat[1], mat[2], mat[0]);
}
+ break;
+ default:
+ BLI_assert(0);
+ break;
}
mul_v3_fl(mat[0], size[0]);
mul_v3_fl(mat[1], size[1]);
@@ -868,8 +874,8 @@ void orthogonalize_m4(float mat[4][4], int axis)
normalize_v3(mat[2]);
cross_v3_v3v3(mat[1], mat[2], mat[0]);
}
+ break;
case 1:
- normalize_v3(mat[0]);
if (dot_v3v3(mat[1], mat[0]) < 1) {
cross_v3_v3v3(mat[2], mat[0], mat[1]);
normalize_v3(mat[2]);
@@ -891,6 +897,7 @@ void orthogonalize_m4(float mat[4][4], int axis)
normalize_v3(mat[0]);
cross_v3_v3v3(mat[2], mat[0], mat[1]);
}
+ break;
case 2:
if (dot_v3v3(mat[2], mat[0]) < 1) {
cross_v3_v3v3(mat[1], mat[2], mat[0]);
@@ -913,13 +920,17 @@ void orthogonalize_m4(float mat[4][4], int axis)
normalize_v3(mat[0]);
cross_v3_v3v3(mat[1], mat[2], mat[0]);
}
+ break;
+ default:
+ BLI_assert(0);
+ break;
}
mul_v3_fl(mat[0], size[0]);
mul_v3_fl(mat[1], size[1]);
mul_v3_fl(mat[2], size[2]);
}
-int is_orthogonal_m3(float m[3][3])
+bool is_orthogonal_m3(float m[3][3])
{
int i, j;
@@ -933,7 +944,7 @@ int is_orthogonal_m3(float m[3][3])
return 1;
}
-int is_orthogonal_m4(float m[4][4])
+bool is_orthogonal_m4(float m[4][4])
{
int i, j;
@@ -948,7 +959,7 @@ int is_orthogonal_m4(float m[4][4])
return 1;
}
-int is_orthonormal_m3(float m[3][3])
+bool is_orthonormal_m3(float m[3][3])
{
if (is_orthogonal_m3(m)) {
int i;
@@ -963,7 +974,7 @@ int is_orthonormal_m3(float m[3][3])
return 0;
}
-int is_orthonormal_m4(float m[4][4])
+bool is_orthonormal_m4(float m[4][4])
{
if (is_orthogonal_m4(m)) {
int i;
@@ -978,7 +989,7 @@ int is_orthonormal_m4(float m[4][4])
return 0;
}
-int is_uniform_scaled_m3(float m[3][3])
+bool is_uniform_scaled_m3(float m[3][3])
{
const float eps = 1e-7;
float t[3][3];
@@ -1207,16 +1218,19 @@ void mat4_to_size(float size[3], float mat[4][4])
float mat3_to_scale(float mat[3][3])
{
/* unit length vector */
- float unit_vec[3] = {0.577350269189626f, 0.577350269189626f, 0.577350269189626f};
+ float unit_vec[3];
+ copy_v3_fl(unit_vec, 0.577350269189626f);
mul_m3_v3(mat, unit_vec);
return len_v3(unit_vec);
}
float mat4_to_scale(float mat[4][4])
{
- float tmat[3][3];
- copy_m3_m4(tmat, mat);
- return mat3_to_scale(tmat);
+ /* unit length vector */
+ float unit_vec[3];
+ copy_v3_fl(unit_vec, 0.577350269189626f);
+ mul_mat3_m4_v3(mat, unit_vec);
+ return len_v3(unit_vec);
}
void mat3_to_rot_size(float rot[3][3], float size[3], float mat3[3][3])
@@ -1360,6 +1374,28 @@ void rotate_m2(float mat[2][2], const float angle)
mat[1][0] = -mat[0][1];
}
+/**
+ * Scale or rotate around a pivot point,
+ * a convenience function to avoid having to do inline.
+ *
+ * Since its common to make a scale/rotation matrix that pivots around an arbitrary point.
+ *
+ * Typical use case is to make 3x3 matrix, copy to 4x4, then pass to this function.
+ */
+void transform_pivot_set_m4(float mat[4][4], const float pivot[3])
+{
+ float tmat[4][4];
+
+ unit_m4(tmat);
+
+ copy_v3_v3(tmat[3], pivot);
+ mul_m4_m4m4(mat, tmat, mat);
+
+ /* invert the matrix */
+ negate_v3(tmat[3]);
+ mul_m4_m4m4(mat, mat, tmat);
+}
+
void blend_m3_m3m3(float out[3][3], float dst[3][3], float src[3][3], const float srcweight)
{
float srot[3][3], drot[3][3];
@@ -1405,20 +1441,34 @@ void blend_m4_m4m4(float out[4][4], float dst[4][4], float src[4][4], const floa
loc_quat_size_to_mat4(out, floc, fquat, fsize);
}
-int is_negative_m3(float mat[3][3])
+bool is_negative_m3(float mat[3][3])
{
float vec[3];
cross_v3_v3v3(vec, mat[0], mat[1]);
return (dot_v3v3(vec, mat[2]) < 0.0f);
}
-int is_negative_m4(float mat[4][4])
+bool is_negative_m4(float mat[4][4])
{
float vec[3];
cross_v3_v3v3(vec, mat[0], mat[1]);
return (dot_v3v3(vec, mat[2]) < 0.0f);
}
+bool is_zero_m3(float mat[3][3])
+{
+ return (is_zero_v3(mat[0]) &&
+ is_zero_v3(mat[1]) &&
+ is_zero_v3(mat[2]));
+}
+bool is_zero_m4(float mat[4][4])
+{
+ return (is_zero_v4(mat[0]) &&
+ is_zero_v4(mat[1]) &&
+ is_zero_v4(mat[2]) &&
+ is_zero_v4(mat[3]));
+}
+
/* make a 4x4 matrix out of 3 transform components */
/* matrices are made in the order: scale * rot * loc */
/* TODO: need to have a version that allows for rotation order... */
diff --git a/source/blender/blenlib/intern/math_rotation.c b/source/blender/blenlib/intern/math_rotation.c
index 96664b776f0..9fd8c479d6e 100644
--- a/source/blender/blenlib/intern/math_rotation.c
+++ b/source/blender/blenlib/intern/math_rotation.c
@@ -857,7 +857,8 @@ void single_axis_angle_to_mat3(float mat[3][3], const char axis, const float ang
mat[2][2] = 1.0f;
break;
default:
- assert(0);
+ BLI_assert(0);
+ break;
}
}
@@ -1816,7 +1817,7 @@ static int _axis_convert_lut[23][24] = {
{0x408, 0x810, 0xA20, 0x228, 0x081, 0x891, 0x699, 0x2A9, 0x102, 0x50A,
0x71A, 0xB22, 0x4CB, 0x8D3, 0xAE3, 0x2EB, 0x144, 0x954, 0x75C, 0x36C,
0x045, 0x44D, 0x65D, 0xA65},
- };
+};
// _axis_convert_num = {'X': 0, 'Y': 1, 'Z': 2, '-X': 3, '-Y': 4, '-Z': 5}
diff --git a/source/blender/blenlib/intern/math_vector.c b/source/blender/blenlib/intern/math_vector.c
index 78266c47170..ba0394dbc66 100644
--- a/source/blender/blenlib/intern/math_vector.c
+++ b/source/blender/blenlib/intern/math_vector.c
@@ -542,6 +542,16 @@ void print_v4(const char *str, const float v[4])
printf("%s: %.3f %.3f %.3f %.3f\n", str, v[0], v[1], v[2], v[3]);
}
+void print_vn(const char *str, const float v[], const int n)
+{
+ int i = 0;
+ printf("%s[%d]:", str, n);
+ while (i < n) {
+ printf(" %.3f", v[i++]);
+ }
+ printf("\n");
+}
+
void minmax_v3v3_v3(float min[3], float max[3], const float vec[3])
{
if (min[0] > vec[0]) min[0] = vec[0];
diff --git a/source/blender/blenlib/intern/math_vector_inline.c b/source/blender/blenlib/intern/math_vector_inline.c
index d77b1ecf017..8e5040d983b 100644
--- a/source/blender/blenlib/intern/math_vector_inline.c
+++ b/source/blender/blenlib/intern/math_vector_inline.c
@@ -418,6 +418,21 @@ MINLINE float mul_project_m4_v3_zfac(float mat[4][4], const float co[3])
(mat[2][3] * co[2]) + mat[3][3];
}
+/**
+ * Has the effect of mul_m3_v3(), on a single axis.
+ */
+MINLINE float dot_m3_v3_row_x(float M[3][3], const float a[3])
+{
+ return M[0][0] * a[0] + M[1][0] * a[1] + M[2][0] * a[2];
+}
+MINLINE float dot_m3_v3_row_y(float M[3][3], const float a[3])
+{
+ return M[0][1] * a[0] + M[1][1] * a[1] + M[2][1] * a[2];
+}
+MINLINE float dot_m3_v3_row_z(float M[3][3], const float a[3])
+{
+ return M[0][2] * a[0] + M[1][2] * a[1] + M[2][2] * a[2];
+}
MINLINE void madd_v2_v2fl(float r[2], const float a[2], float f)
{
diff --git a/source/blender/blenlib/intern/noise.c b/source/blender/blenlib/intern/noise.c
index 6e52145c653..2f94e833e9d 100644
--- a/source/blender/blenlib/intern/noise.c
+++ b/source/blender/blenlib/intern/noise.c
@@ -1252,6 +1252,7 @@ void voronoi(float x, float y, float z, float *da, float *pa, float me, int dtyp
case 0:
default:
distfunc = dist_Real;
+ break;
}
xi = (int)(floor(x));
@@ -1467,6 +1468,7 @@ float BLI_gNoise(float noisesize, float x, float y, float z, int hard, int noise
x += 1;
y += 1;
z += 1;
+ break;
}
}
@@ -1522,6 +1524,7 @@ float BLI_gTurbulence(float noisesize, float x, float y, float z, int oct, int h
x += 1;
y += 1;
z += 1;
+ break;
}
if (noisesize != 0.0f) {
@@ -1596,6 +1599,7 @@ float mg_fBm(float x, float y, float z, float H, float lacunarity, float octaves
default:
{
noisefunc = orgBlenderNoiseS;
+ break;
}
}
@@ -1667,6 +1671,7 @@ float mg_MultiFractal(float x, float y, float z, float H, float lacunarity, floa
default:
{
noisefunc = orgBlenderNoiseS;
+ break;
}
}
@@ -1734,6 +1739,7 @@ float mg_HeteroTerrain(float x, float y, float z, float H, float lacunarity, flo
default:
{
noisefunc = orgBlenderNoiseS;
+ break;
}
}
@@ -1808,6 +1814,7 @@ float mg_HybridMultiFractal(float x, float y, float z, float H, float lacunarity
default:
{
noisefunc = orgBlenderNoiseS;
+ break;
}
}
@@ -1884,6 +1891,7 @@ float mg_RidgedMultiFractal(float x, float y, float z, float H, float lacunarity
default:
{
noisefunc = orgBlenderNoiseS;
+ break;
}
}
@@ -1950,6 +1958,7 @@ float mg_VLNoise(float x, float y, float z, float distortion, int nbas1, int nba
default:
{
noisefunc1 = orgBlenderNoiseS;
+ break;
}
}
@@ -1985,6 +1994,7 @@ float mg_VLNoise(float x, float y, float z, float distortion, int nbas1, int nba
default:
{
noisefunc2 = orgBlenderNoiseS;
+ break;
}
}
diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c
index 1e76a7f3164..2c06a812c8a 100644
--- a/source/blender/blenlib/intern/path_util.c
+++ b/source/blender/blenlib/intern/path_util.c
@@ -610,9 +610,8 @@ bool BLI_parent_dir(char *path)
{
static char parent_dir[] = {'.', '.', SEP, '\0'}; /* "../" or "..\\" */
char tmp[FILE_MAX + 4];
- BLI_strncpy(tmp, path, sizeof(tmp) - 4);
- BLI_add_slash(tmp);
- strcat(tmp, parent_dir);
+
+ BLI_join_dirfile(tmp, sizeof(tmp), path, parent_dir);
BLI_cleanup_dir(NULL, tmp); /* does all the work of normalizing the path for us */
if (!BLI_testextensie(tmp, parent_dir)) {
@@ -696,8 +695,10 @@ bool BLI_path_frame(char *path, int frame, int digits)
if (stringframe_chars(path, &ch_sta, &ch_end)) { /* warning, ch_end is the last # +1 */
char tmp[FILE_MAX];
- sprintf(tmp, "%.*s%.*d%s", ch_sta, path, ch_end - ch_sta, frame, path + ch_end);
- strcpy(path, tmp);
+ BLI_snprintf(tmp, sizeof(tmp),
+ "%.*s%.*d%s",
+ ch_sta, path, ch_end - ch_sta, frame, path + ch_end);
+ BLI_strncpy(path, tmp, FILE_MAX);
return true;
}
return false;
@@ -1229,6 +1230,7 @@ const char *BLI_get_folder(int folder_id, const char *subfolder)
default:
BLI_assert(0);
+ break;
}
return path;
@@ -1257,7 +1259,9 @@ const char *BLI_get_user_folder_notest(int folder_id, const char *subfolder)
break;
default:
BLI_assert(0);
+ break;
}
+
if ('\0' == path[0]) {
return NULL;
}
@@ -1307,6 +1311,7 @@ const char *BLI_get_folder_version(const int id, const int ver, const bool do_ch
path[0] = '\0'; /* in case do_check is false */
ok = false;
BLI_assert(!"incorrect ID");
+ break;
}
if (!ok && do_check) {
@@ -1686,6 +1691,26 @@ void BLI_split_file_part(const char *string, char *file, const size_t filelen)
}
/**
+ * Append a filename to a dir, ensuring slash separates.
+ */
+void BLI_path_append(char *dst, const size_t maxlen, const char *file)
+{
+ size_t dirlen = BLI_strnlen(dst, maxlen);
+
+ /* inline BLI_add_slash */
+ if ((dirlen > 0) && (dst[dirlen - 1] != SEP)) {
+ dst[dirlen++] = SEP;
+ dst[dirlen] = '\0';
+ }
+
+ if (dirlen >= maxlen) {
+ return; /* fills the path */
+ }
+
+ BLI_strncpy(dst + dirlen, file, maxlen - dirlen);
+}
+
+/**
* Simple appending of filename to dir, does not check for valid path!
* Puts result into *dst, which may be same area as *dir.
*/
@@ -1693,15 +1718,16 @@ void BLI_join_dirfile(char *dst, const size_t maxlen, const char *dir, const cha
{
size_t dirlen = BLI_strnlen(dir, maxlen);
- if (dst != dir) {
- if (dirlen == maxlen) {
- memcpy(dst, dir, dirlen);
- dst[dirlen - 1] = '\0';
- return; /* dir fills the path */
- }
- else {
- memcpy(dst, dir, dirlen + 1);
- }
+ /* args can't match */
+ BLI_assert(!ELEM(dst, dir, file));
+
+ if (dirlen == maxlen) {
+ memcpy(dst, dir, dirlen);
+ dst[dirlen - 1] = '\0';
+ return; /* dir fills the path */
+ }
+ else {
+ memcpy(dst, dir, dirlen + 1);
}
if (dirlen + 1 >= maxlen) {
@@ -1718,10 +1744,6 @@ void BLI_join_dirfile(char *dst, const size_t maxlen, const char *dir, const cha
return; /* fills the path */
}
- if (file == NULL) {
- return;
- }
-
BLI_strncpy(dst + dirlen, file, maxlen - dirlen);
}
@@ -1837,7 +1859,7 @@ int BLI_rebase_path(char *abs, size_t abs_len,
/* subdirectories relative to blend_dir */
BLI_join_dirfile(dest_path, sizeof(dest_path), dest_dir, rel_dir);
/* same subdirectories relative to dest_dir */
- BLI_join_dirfile(dest_path, sizeof(dest_path), dest_path, base);
+ BLI_path_append(dest_path, sizeof(dest_path), base);
/* keeping original item basename */
}
@@ -2058,7 +2080,7 @@ static void bli_where_am_i(char *fullname, const size_t maxlen, const char *name
else {
strncpy(filename, path, sizeof(filename));
}
- BLI_join_dirfile(fullname, maxlen, fullname, name);
+ BLI_path_append(fullname, maxlen, name);
if (add_win32_extension(filename)) {
BLI_strncpy(fullname, filename, maxlen);
break;
diff --git a/source/blender/blenlib/intern/storage.c b/source/blender/blenlib/intern/storage.c
index 6b45c6f1cb3..34c6e632131 100644
--- a/source/blender/blenlib/intern/storage.c
+++ b/source/blender/blenlib/intern/storage.c
@@ -44,7 +44,7 @@
#if defined(__sun__) || defined(__sun) || defined(__NetBSD__)
# include <sys/statvfs.h> /* Other modern unix os's should probably use this also */
-#elif !defined(__FreeBSD__) && !defined(linux) && (defined(__sparc) || defined(__sparc__))
+#elif !defined(__FreeBSD__) && !defined(__linux__) && (defined(__sparc) || defined(__sparc__))
# include <sys/statfs.h>
#endif
@@ -53,7 +53,7 @@
# include <sys/mount.h>
#endif
-#if defined(linux) || defined(__CYGWIN32__) || defined(__hpux) || defined(__GNU__) || defined(__GLIBC__)
+#if defined(__linux__) || defined(__CYGWIN32__) || defined(__hpux) || defined(__GNU__) || defined(__GLIBC__)
#include <sys/vfs.h>
#endif
@@ -194,13 +194,13 @@ double BLI_dir_free_space(const char *dir)
strcpy(name, "/");
}
-#if defined(__FreeBSD__) || defined(linux) || defined(__OpenBSD__) || defined(__APPLE__) || defined(__GNU__) || defined(__GLIBC__)
+#if defined(__FreeBSD__) || defined(__linux__) || defined(__OpenBSD__) || defined(__APPLE__) || defined(__GNU__) || defined(__GLIBC__)
if (statfs(name, &disk)) return(-1);
#endif
#if defined(__sun__) || defined(__sun) || defined(__NetBSD__)
if (statvfs(name, &disk)) return(-1);
-#elif !defined(__FreeBSD__) && !defined(linux) && (defined(__sparc) || defined(__sparc__))
+#elif !defined(__FreeBSD__) && !defined(__linux__) && (defined(__sparc) || defined(__sparc__))
/* WARNING - This may not be supported by geeneric unix os's - Campbell */
if (statfs(name, &disk, sizeof(struct statfs), 0)) return(-1);
#endif
@@ -388,17 +388,14 @@ static void bli_adddirstrings(struct BuildDirCtx *dir_ctx)
*/
st_size = file->s.st_size;
- /* FIXME: Either change decimal prefixes to binary ones
- * <http://en.wikipedia.org/wiki/Binary_prefix>, or change
- * divisor factors from 1024 to 1000. */
if (st_size > 1024 * 1024 * 1024) {
- BLI_snprintf(file->size, sizeof(file->size), "%.2f GB", ((double)st_size) / (1024 * 1024 * 1024));
+ BLI_snprintf(file->size, sizeof(file->size), "%.2f GiB", ((double)st_size) / (1024 * 1024 * 1024));
}
else if (st_size > 1024 * 1024) {
- BLI_snprintf(file->size, sizeof(file->size), "%.1f MB", ((double)st_size) / (1024 * 1024));
+ BLI_snprintf(file->size, sizeof(file->size), "%.1f MiB", ((double)st_size) / (1024 * 1024));
}
else if (st_size > 1024) {
- BLI_snprintf(file->size, sizeof(file->size), "%d KB", (int)(st_size / 1024));
+ BLI_snprintf(file->size, sizeof(file->size), "%d KiB", (int)(st_size / 1024));
}
else {
BLI_snprintf(file->size, sizeof(file->size), "%d B", (int)st_size);
diff --git a/source/blender/blenlib/intern/string.c b/source/blender/blenlib/intern/string.c
index 03bed428c07..572b142d044 100644
--- a/source/blender/blenlib/intern/string.c
+++ b/source/blender/blenlib/intern/string.c
@@ -47,6 +47,8 @@
# pragma GCC diagnostic error "-Wsign-conversion"
#endif
+// #define DEBUG_STRSIZE
+
/**
* Duplicates the first \a len bytes of cstring \a str
* into a newly mallocN'd string and returns it. \a str
@@ -85,15 +87,18 @@ char *BLI_strdup(const char *str)
*/
char *BLI_strdupcat(const char *__restrict str1, const char *__restrict str2)
{
- size_t len;
- char *n;
+ /* include the NULL terminator of str2 only */
+ const size_t str1_len = strlen(str1);
+ const size_t str2_len = strlen(str2) + 1;
+ char *str, *s;
- len = strlen(str1) + strlen(str2);
- n = MEM_mallocN(len + 1, "strdupcat");
- strcpy(n, str1);
- strcat(n, str2);
-
- return n;
+ str = MEM_mallocN(str1_len + str2_len, "strdupcat");
+ s = str;
+
+ memcpy(s, str1, str1_len); s += str1_len;
+ memcpy(s, str2, str2_len);
+
+ return str;
}
/**
@@ -111,6 +116,10 @@ char *BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t
size_t srclen = BLI_strnlen(src, maxncpy - 1);
BLI_assert(maxncpy != 0);
+#ifdef DEBUG_STRSIZE
+ memset(dst, 0xff, sizeof(*dst) * maxncpy);
+#endif
+
memcpy(dst, src, srclen);
dst[srclen] = '\0';
return dst;
@@ -134,6 +143,10 @@ size_t BLI_strncpy_rlen(char *__restrict dst, const char *__restrict src, const
size_t srclen = BLI_strnlen(src, maxncpy - 1);
BLI_assert(maxncpy != 0);
+#ifdef DEBUG_STRSIZE
+ memset(dst, 0xff, sizeof(*dst) * maxncpy);
+#endif
+
memcpy(dst, src, srclen);
dst[srclen] = '\0';
return srclen;
@@ -149,21 +162,21 @@ size_t BLI_strcpy_rlen(char *__restrict dst, const char *__restrict src)
/**
* Portable replacement for #vsnprintf
*/
-size_t BLI_vsnprintf(char *__restrict buffer, size_t count, const char *__restrict format, va_list arg)
+size_t BLI_vsnprintf(char *__restrict buffer, size_t maxncpy, const char *__restrict format, va_list arg)
{
size_t n;
BLI_assert(buffer != NULL);
- BLI_assert(count > 0);
+ BLI_assert(maxncpy > 0);
BLI_assert(format != NULL);
- n = (size_t)vsnprintf(buffer, count, format, arg);
+ n = (size_t)vsnprintf(buffer, maxncpy, format, arg);
- if (n != -1 && n < count) {
+ if (n != -1 && n < maxncpy) {
buffer[n] = '\0';
}
else {
- buffer[count - 1] = '\0';
+ buffer[maxncpy - 1] = '\0';
}
return n;
@@ -172,13 +185,17 @@ size_t BLI_vsnprintf(char *__restrict buffer, size_t count, const char *__restri
/**
* Portable replacement for #snprintf
*/
-size_t BLI_snprintf(char *__restrict buffer, size_t count, const char *__restrict format, ...)
+size_t BLI_snprintf(char *__restrict dst, size_t maxncpy, const char *__restrict format, ...)
{
size_t n;
va_list arg;
+#ifdef DEBUG_STRSIZE
+ memset(dst, 0xff, sizeof(*dst) * maxncpy);
+#endif
+
va_start(arg, format);
- n = BLI_vsnprintf(buffer, count, format, arg);
+ n = BLI_vsnprintf(dst, maxncpy, format, arg);
va_end(arg);
return n;
@@ -226,6 +243,7 @@ size_t BLI_strescape(char *__restrict dst, const char *__restrict src, const siz
goto escape_finish;
case '\\':
case '"':
+ /* fall-through */
/* less common but should also be support */
case '\t':
@@ -239,9 +257,10 @@ size_t BLI_strescape(char *__restrict dst, const char *__restrict src, const siz
/* not enough space to escape */
break;
}
- /* intentionally pass through */
+ /* fall-through */
default:
*dst = *src;
+ break;
}
dst++;
src++;
@@ -286,34 +305,30 @@ char *BLI_str_quoted_substrN(const char *__restrict str, const char *__restrict
}
/**
+ * string with all instances of substr_old replaced with substr_new,
* Returns a copy of the cstring \a str into a newly mallocN'd
- * string with all instances of oldText replaced with newText,
* and returns it.
*
* \note A rather wasteful string-replacement utility, though this shall do for now...
* Feel free to replace this with an even safe + nicer alternative
*
- * \param str The string to replace occurrences of oldText in
- * \param oldText The text in the string to find and replace
- * \param newText The text in the string to find and replace
+ * \param str The string to replace occurrences of substr_old in
+ * \param substr_old The text in the string to find and replace
+ * \param substr_new The text in the string to find and replace
* \retval Returns the duplicated string
*/
-char *BLI_replacestr(char *__restrict str, const char *__restrict oldText, const char *__restrict newText)
+char *BLI_replacestrN(const char *__restrict str, const char *__restrict substr_old, const char *__restrict substr_new)
{
DynStr *ds = NULL;
- size_t lenOld = strlen(oldText);
- char *match;
-
- /* sanity checks */
- if ((str == NULL) || (str[0] == 0))
- return NULL;
- else if ((oldText == NULL) || (newText == NULL) || (oldText[0] == 0))
- return BLI_strdup(str);
-
+ size_t len_old = strlen(substr_old);
+ const char *match;
+
+ BLI_assert(substr_old[0] != '\0');
+
/* while we can still find a match for the old substring that we're searching for,
* keep dicing and replacing
*/
- while ( (match = strstr(str, oldText)) ) {
+ while ((match = strstr(str, substr_old))) {
/* the assembly buffer only gets created when we actually need to rebuild the string */
if (ds == NULL)
ds = BLI_dynstr_new();
@@ -322,39 +337,35 @@ char *BLI_replacestr(char *__restrict str, const char *__restrict oldText, const
* copy the text up to this position and advance the current position in the string
*/
if (str != match) {
- /* replace the token at the 'match' position with \0 so that the copied string will be ok,
- * add the segment of the string from str to match to the buffer, then restore the value at match
+ /* add the segment of the string from str to match to the buffer, then restore the value at match
*/
- match[0] = 0;
- BLI_dynstr_append(ds, str);
- match[0] = oldText[0];
+ BLI_dynstr_nappend(ds, str, (match - str));
/* now our current position should be set on the start of the match */
str = match;
}
/* add the replacement text to the accumulation buffer */
- BLI_dynstr_append(ds, newText);
+ BLI_dynstr_append(ds, substr_new);
/* advance the current position of the string up to the end of the replaced segment */
- str += lenOld;
+ str += len_old;
}
/* finish off and return a new string that has had all occurrences of */
if (ds) {
- char *newStr;
+ char *str_new;
/* add what's left of the string to the assembly buffer
- * - we've been adjusting str to point at the end of the replaced segments
+ * - we've been adjusting str to point at the end of the replaced segments
*/
- if (str != NULL)
- BLI_dynstr_append(ds, str);
+ BLI_dynstr_append(ds, str);
/* convert to new c-string (MEM_malloc'd), and free the buffer */
- newStr = BLI_dynstr_get_cstring(ds);
+ str_new = BLI_dynstr_get_cstring(ds);
BLI_dynstr_free(ds);
- return newStr;
+ return str_new;
}
else {
/* just create a new copy of the entire string - we avoid going through the assembly buffer
diff --git a/source/blender/blenlib/intern/string_utf8.c b/source/blender/blenlib/intern/string_utf8.c
index b8dca95ae33..225b3c5538f 100644
--- a/source/blender/blenlib/intern/string_utf8.c
+++ b/source/blender/blenlib/intern/string_utf8.c
@@ -45,6 +45,8 @@
# pragma GCC diagnostic error "-Wsign-conversion"
#endif
+// #define DEBUG_STRSIZE
+
/* from libswish3, originally called u8_isvalid(),
* modified to return the index of the bad character (byte index not utf).
* http://svn.swish-e.org/libswish3/trunk/src/libswish3/utf8.c r3044 - campbell */
@@ -195,6 +197,10 @@ char *BLI_strncpy_utf8(char *__restrict dst, const char *__restrict src, size_t
BLI_assert(maxncpy != 0);
+#ifdef DEBUG_STRSIZE
+ memset(dst, 0xff, sizeof(*dst) * maxncpy);
+#endif
+
/* note: currently we don't attempt to deal with invalid utf8 chars */
BLI_STR_UTF8_CPY(dst, src, maxncpy);
@@ -208,6 +214,10 @@ char *BLI_strncat_utf8(char *__restrict dst, const char *__restrict src, size_t
maxncpy--;
}
+#ifdef DEBUG_STRSIZE
+ memset(dst, 0xff, sizeof(*dst) * maxncpy);
+#endif
+
BLI_STR_UTF8_CPY(dst, src, maxncpy);
return dst;
@@ -220,11 +230,16 @@ char *BLI_strncat_utf8(char *__restrict dst, const char *__restrict src, size_t
size_t BLI_strncpy_wchar_as_utf8(char *__restrict dst, const wchar_t *__restrict src, const size_t maxncpy)
{
+ const size_t maxlen = maxncpy - 1;
size_t len = 0;
BLI_assert(maxncpy != 0);
- while (*src && len < maxncpy) { /* XXX can still run over the buffer because utf8 size isn't known :| */
+#ifdef DEBUG_STRSIZE
+ memset(dst, 0xff, sizeof(*dst) * maxncpy);
+#endif
+
+ while (*src && len < maxlen) { /* XXX can still run over the buffer because utf8 size isn't known :| */
len += BLI_str_utf8_from_unicode((unsigned int)*src++, dst + len);
}
@@ -245,24 +260,16 @@ size_t BLI_wstrlen_utf8(const wchar_t *src)
return len;
}
-/* this is very close to 'BLI_str_utf8_size' functionality, perhaps we should de-duplicate */
-/* size of UTF-8 character in bytes */
-static size_t strlen_utf8_char(const char *strc)
+size_t BLI_strlen_utf8_ex(const char *strc, size_t *r_len_bytes)
{
- if ((*strc & 0xe0) == 0xc0) {
- if ((strc[1] & 0x80) && (strc[1] & 0x40) == 0x00)
- return 2;
- }
- else if ((*strc & 0xf0) == 0xe0) {
- if ((strc[1] & strc[2] & 0x80) && ((strc[1] | strc[2]) & 0x40) == 0x00)
- return 3;
- }
- else if ((*strc & 0xf8) == 0xf0) {
- if ((strc[1] & strc[2] & strc[3] & 0x80) && ((strc[1] | strc[2] | strc[3]) & 0x40) == 0x00)
- return 4;
- }
+ size_t len;
+ const char *strc_orig = strc;
- return 1;
+ for (len = 0; *strc; len++)
+ strc += BLI_str_utf8_size_safe(strc);
+
+ *r_len_bytes = (size_t)(strc - strc_orig);
+ return len;
}
size_t BLI_strlen_utf8(const char *strc)
@@ -270,8 +277,22 @@ size_t BLI_strlen_utf8(const char *strc)
size_t len;
for (len = 0; *strc; len++)
- strc += strlen_utf8_char(strc);
+ strc += BLI_str_utf8_size_safe(strc);
+
+ return len;
+}
+
+size_t BLI_strnlen_utf8_ex(const char *strc, const size_t maxlen, size_t *r_len_bytes)
+{
+ size_t len;
+ const char *strc_orig = strc;
+ const char *strc_end = strc + maxlen;
+
+ for (len = 0; *strc && strc < strc_end; len++) {
+ strc += BLI_str_utf8_size_safe(strc);
+ }
+ *r_len_bytes = (size_t)(strc - strc_orig);
return len;
}
@@ -280,15 +301,13 @@ size_t BLI_strlen_utf8(const char *strc)
* \param maxlen the string length (in bytes)
* \return the unicode length (not in bytes!)
*/
-size_t BLI_strnlen_utf8(const char *start, const size_t maxlen)
+size_t BLI_strnlen_utf8(const char *strc, const size_t maxlen)
{
- const char *strc = start;
- const char *strc_end = start + maxlen;
-
size_t len;
+ const char *strc_end = strc + maxlen;
for (len = 0; *strc && strc < strc_end; len++) {
- strc += strlen_utf8_char(strc);
+ strc += BLI_str_utf8_size_safe(strc);
}
return len;
@@ -296,13 +315,16 @@ size_t BLI_strnlen_utf8(const char *start, const size_t maxlen)
size_t BLI_strncpy_wchar_from_utf8(wchar_t *__restrict dst_w, const char *__restrict src_c, const size_t maxncpy)
{
+ const size_t maxlen = maxncpy - 1;
size_t len = 0;
- if (dst_w == NULL || src_c == NULL) {
- return 0;
- }
+ BLI_assert(maxncpy != 0);
- while (*src_c && len < maxncpy) {
+#ifdef DEBUG_STRSIZE
+ memset(dst_w, 0xff, sizeof(*dst_w) * maxncpy);
+#endif
+
+ while (*src_c && len != maxlen) {
size_t step = 0;
unsigned int unicode = BLI_str_utf8_as_unicode_and_size(src_c, &step);
if (unicode != BLI_UTF8_ERR) {
@@ -316,6 +338,9 @@ size_t BLI_strncpy_wchar_from_utf8(wchar_t *__restrict dst_w, const char *__rest
dst_w++;
len++;
}
+
+ *dst_w = 0;
+
return len;
}
diff --git a/source/blender/blenlib/intern/threads.c b/source/blender/blenlib/intern/threads.c
index e0ea3bbf685..2b6fb52c49c 100644
--- a/source/blender/blenlib/intern/threads.c
+++ b/source/blender/blenlib/intern/threads.c
@@ -508,6 +508,52 @@ void BLI_rw_mutex_free(ThreadRWMutex *mutex)
MEM_freeN(mutex);
}
+/* Ticket Mutex Lock */
+
+struct TicketMutex {
+ pthread_cond_t cond;
+ pthread_mutex_t mutex;
+ unsigned int queue_head, queue_tail;
+};
+
+TicketMutex *BLI_ticket_mutex_alloc(void)
+{
+ TicketMutex *ticket = MEM_callocN(sizeof(TicketMutex), "TicketMutex");
+
+ pthread_cond_init(&ticket->cond, NULL);
+ pthread_mutex_init(&ticket->mutex, NULL);
+
+ return ticket;
+}
+
+void BLI_ticket_mutex_free(TicketMutex *ticket)
+{
+ pthread_mutex_destroy(&ticket->mutex);
+ pthread_cond_destroy(&ticket->cond);
+ MEM_freeN(ticket);
+}
+
+void BLI_ticket_mutex_lock(TicketMutex *ticket)
+{
+ unsigned int queue_me;
+
+ pthread_mutex_lock(&ticket->mutex);
+ queue_me = ticket->queue_tail++;
+
+ while (queue_me != ticket->queue_head)
+ pthread_cond_wait(&ticket->cond, &ticket->mutex);
+
+ pthread_mutex_unlock(&ticket->mutex);
+}
+
+void BLI_ticket_mutex_unlock(TicketMutex *ticket)
+{
+ pthread_mutex_lock(&ticket->mutex);
+ ticket->queue_head++;
+ pthread_cond_broadcast(&ticket->cond);
+ pthread_mutex_unlock(&ticket->mutex);
+}
+
/* ************************************************ */
typedef struct ThreadedWorker {