diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2011-09-15 17:02:37 +0400 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2011-09-15 17:02:37 +0400 |
commit | 30293dc2ca8052ad0c7113c77365feca590f4d05 (patch) | |
tree | c5f4a092be7204ef2107792c0a16c0d9f331dbba /source/blender/blenlib | |
parent | e715a7185ca176c8a73cd638d4acaa40f75a7d77 (diff) | |
parent | 9648c6016b35a72aa23395f5d200e342df16490b (diff) |
svn merge -r39834:40222 https://svn.blender.org/svnroot/bf-blender/trunk/blender
Diffstat (limited to 'source/blender/blenlib')
-rw-r--r-- | source/blender/blenlib/BLI_math_inline.h | 5 | ||||
-rw-r--r-- | source/blender/blenlib/BLI_math_matrix.h | 5 | ||||
-rw-r--r-- | source/blender/blenlib/BLI_math_vector.h | 7 | ||||
-rw-r--r-- | source/blender/blenlib/BLI_string.h | 9 | ||||
-rw-r--r-- | source/blender/blenlib/BLI_utildefines.h | 6 | ||||
-rw-r--r-- | source/blender/blenlib/CMakeLists.txt | 1 | ||||
-rw-r--r-- | source/blender/blenlib/intern/BLI_kdopbvh.c | 21 | ||||
-rw-r--r-- | source/blender/blenlib/intern/graph.c | 4 | ||||
-rw-r--r-- | source/blender/blenlib/intern/math_matrix.c | 32 | ||||
-rw-r--r-- | source/blender/blenlib/intern/math_vector.c | 8 | ||||
-rw-r--r-- | source/blender/blenlib/intern/math_vector_inline.c | 22 | ||||
-rw-r--r-- | source/blender/blenlib/intern/noise.c | 16 | ||||
-rw-r--r-- | source/blender/blenlib/intern/string.c | 120 | ||||
-rw-r--r-- | source/blender/blenlib/intern/string_utf8.c | 183 |
14 files changed, 290 insertions, 149 deletions
diff --git a/source/blender/blenlib/BLI_math_inline.h b/source/blender/blenlib/BLI_math_inline.h index 0f8493e25a6..4309e6122df 100644 --- a/source/blender/blenlib/BLI_math_inline.h +++ b/source/blender/blenlib/BLI_math_inline.h @@ -45,7 +45,12 @@ extern "C" { #define MALWAYS_INLINE MINLINE #else #define MINLINE static inline +#if (defined(__APPLE__) && defined(__ppc__)) +/* static inline __attribute__ here breaks osx ppc gcc42 build */ #define MALWAYS_INLINE static __attribute__((always_inline)) +#else +#define MALWAYS_INLINE static inline __attribute__((always_inline)) +#endif #endif #else #define MINLINE diff --git a/source/blender/blenlib/BLI_math_matrix.h b/source/blender/blenlib/BLI_math_matrix.h index d8719f399ae..d6a8f0fb925 100644 --- a/source/blender/blenlib/BLI_math_matrix.h +++ b/source/blender/blenlib/BLI_math_matrix.h @@ -66,6 +66,9 @@ void swap_m4m4(float A[4][4], float B[4][4]); void add_m3_m3m3(float R[3][3], float A[3][3], float B[3][3]); void add_m4_m4m4(float R[4][4], float A[4][4], float B[4][4]); +void sub_m3_m3m3(float R[3][3], float A[3][3], float B[3][3]); +void sub_m4_m4m4(float R[4][4], float A[4][4], float B[4][4]); + void mul_m3_m3m3(float R[3][3], float A[3][3], float B[3][3]); void mul_m4_m4m4(float R[4][4], float A[4][4], float B[4][4]); void mul_m4_m3m4(float R[4][4], float A[3][3], float B[4][4]); @@ -80,7 +83,7 @@ void mul_serie_m4(float R[4][4], float M5[4][4], float M6[4][4], float M7[4][4], float M8[4][4]); void mul_m4_v3(float M[4][4], float r[3]); -void mul_v3_m4v3(float r[3], float M[4][4], float v[3]); +void mul_v3_m4v3(float r[3], float M[4][4], const float v[3]); void mul_mat3_m4_v3(float M[4][4], float r[3]); void mul_m4_v4(float M[4][4], float r[4]); void mul_v4_m4v4(float r[4], float M[4][4], float v[4]); diff --git a/source/blender/blenlib/BLI_math_vector.h b/source/blender/blenlib/BLI_math_vector.h index c8b598a1e85..a807a395b78 100644 --- a/source/blender/blenlib/BLI_math_vector.h +++ b/source/blender/blenlib/BLI_math_vector.h @@ -56,6 +56,12 @@ MINLINE void swap_v2_v2(float a[2], float b[2]); MINLINE void swap_v3_v3(float a[3], float b[3]); MINLINE void swap_v4_v4(float a[4], float b[4]); +/* short */ +MINLINE void copy_v2_v2_short(short r[2], const short a[2]); +MINLINE void copy_v3_v3_short(short r[3], const short a[3]); +MINLINE void copy_v4_v4_short(short r[4], const short a[4]); + + /********************************* Arithmetic ********************************/ MINLINE void add_v3_fl(float r[3], float f); @@ -124,6 +130,7 @@ void interp_v3_v3v3v3(float p[3], const float v1[3], const float v2[3], const fl void interp_v3_v3v3v3v3(float p[3], const float v1[3], const float v2[3], const float v3[3], const float v4[3], const float w[4]); void interp_v4_v4v4(float r[4], const float a[4], const float b[4], const float t); void interp_v4_v4v4v4(float p[4], const float v1[4], const float v2[4], const float v3[4], const float w[3]); +void interp_v4_v4v4v4v4(float p[4], const float v1[4], const float v2[4], const float v3[4], const float v4[4], const float w[4]); void mid_v3_v3v3(float r[3], const float a[3], const float b[3]); diff --git a/source/blender/blenlib/BLI_string.h b/source/blender/blenlib/BLI_string.h index 4a0c2ab9482..c53ce9dced5 100644 --- a/source/blender/blenlib/BLI_string.h +++ b/source/blender/blenlib/BLI_string.h @@ -139,12 +139,15 @@ size_t BLI_strnlen(const char *str, size_t maxlen); void BLI_timestr(double _time, char *str); /* time var is global */ -int BLI_utf8_invalid_byte(const char *str, int length); -int BLI_utf8_invalid_strip(char *str, int length); - void BLI_ascii_strtolower(char *str, int len); void BLI_ascii_strtoupper(char *str, int len); + +/* string_utf8.c - may move these into their own header some day - campbell */ +char *BLI_strncpy_utf8(char *dst, const char *src, size_t maxncpy); +int BLI_utf8_invalid_byte(const char *str, int length); +int BLI_utf8_invalid_strip(char *str, int length); + #ifdef __cplusplus } #endif diff --git a/source/blender/blenlib/BLI_utildefines.h b/source/blender/blenlib/BLI_utildefines.h index 1a1f7be2471..9a3b81e5776 100644 --- a/source/blender/blenlib/BLI_utildefines.h +++ b/source/blender/blenlib/BLI_utildefines.h @@ -176,6 +176,12 @@ /* useful for debugging */ #define AT __FILE__ ":" STRINGIFY(__LINE__) +/* so we can use __func__ everywhere */ +#if defined(_MSC_VER) +# define __func__ __FUNCTION__ +#endif + + /* UNUSED macro, for function argument */ #ifdef __GNUC__ # define UNUSED(x) UNUSED_ ## x __attribute__((__unused__)) diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt index b4fc983008c..aa822731474 100644 --- a/source/blender/blenlib/CMakeLists.txt +++ b/source/blender/blenlib/CMakeLists.txt @@ -80,6 +80,7 @@ set(SRC intern/scanfill.c intern/storage.c intern/string.c + intern/string_utf8.c intern/threads.c intern/time.c intern/uvproject.c diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c index dcbe043f0d0..eae4f918a67 100644 --- a/source/blender/blenlib/intern/BLI_kdopbvh.c +++ b/source/blender/blenlib/intern/BLI_kdopbvh.c @@ -408,7 +408,7 @@ static void create_kdop_hull(BVHTree *tree, BVHNode *node, float *co, int numpoi // for all Axes. for (i = tree->start_axis; i < tree->stop_axis; i++) { - newminmax = INPR(&co[k * 3], KDOP_AXES[i]); + newminmax = dot_v3v3(&co[k * 3], KDOP_AXES[i]); if (newminmax < bv[2 * i]) bv[2 * i] = newminmax; if (newminmax > bv[(2 * i) + 1]) @@ -1193,17 +1193,6 @@ BVHTreeOverlap *BLI_bvhtree_overlap(BVHTree *tree1, BVHTree *tree2, unsigned int return overlap; } - -/* - * Nearest neighbour - BLI_bvhtree_find_nearest - */ -static float squared_dist(const float *a, const float *b) -{ - float tmp[3]; - VECSUB(tmp, a, b); - return INPR(tmp, tmp); -} - //Determines the nearest point of the given node BV. Returns the squared distance to that point. static float calc_nearest_point(const float *proj, BVHNode *node, float *nearest) { @@ -1226,7 +1215,7 @@ static float calc_nearest_point(const float *proj, BVHNode *node, float *nearest VECCOPY(nearest, data->co); for(i = data->tree->start_axis; i != data->tree->stop_axis; i++, bv+=2) { - float proj = INPR( nearest, KDOP_AXES[i]); + float proj = dot_v3v3( nearest, KDOP_AXES[i]); float dl = bv[0] - proj; float du = bv[1] - proj; @@ -1240,7 +1229,7 @@ static float calc_nearest_point(const float *proj, BVHNode *node, float *nearest } } */ - return squared_dist(proj, nearest); + return len_squared_v3v3(proj, nearest); } @@ -1404,7 +1393,7 @@ int BLI_bvhtree_find_nearest(BVHTree *tree, const float *co, BVHTreeNearest *nea for(i = data.tree->start_axis; i != data.tree->stop_axis; i++) { - data.proj[i] = INPR(data.co, KDOP_AXES[i]); + data.proj[i] = dot_v3v3(data.co, KDOP_AXES[i]); } if(nearest) @@ -1596,7 +1585,7 @@ int BLI_bvhtree_ray_cast(BVHTree *tree, const float *co, const float *dir, float for(i=0; i<3; i++) { - data.ray_dot_axis[i] = INPR( data.ray.direction, KDOP_AXES[i]); + data.ray_dot_axis[i] = dot_v3v3(data.ray.direction, KDOP_AXES[i]); data.idot_axis[i] = 1.0f / data.ray_dot_axis[i]; if(fabsf(data.ray_dot_axis[i]) < FLT_EPSILON) diff --git a/source/blender/blenlib/intern/graph.c b/source/blender/blenlib/intern/graph.c index 2e26f4bd9c9..8b9cddcc1d1 100644 --- a/source/blender/blenlib/intern/graph.c +++ b/source/blender/blenlib/intern/graph.c @@ -591,7 +591,7 @@ static void testRadialSymmetry(BGraph *graph, BNode* root_node, RadialArc* ring, node1 = BLI_otherNode(ring[i].arc, root_node); node2 = BLI_otherNode(ring[j].arc, root_node); - VECCOPY(p, node2->p); + copy_v3_v3(p, node2->p); BLI_mirrorAlongAxis(p, root_node->p, normal); /* check if it's within limit before continuing */ @@ -605,7 +605,7 @@ static void testRadialSymmetry(BGraph *graph, BNode* root_node, RadialArc* ring, if (symmetric) { /* mark node as symmetric physically */ - VECCOPY(root_node->symmetry_axis, axis); + copy_v3_v3(root_node->symmetry_axis, axis); root_node->symmetry_flag |= SYM_PHYSICAL; root_node->symmetry_flag |= SYM_RADIAL; diff --git a/source/blender/blenlib/intern/math_matrix.c b/source/blender/blenlib/intern/math_matrix.c index 3c79a77707a..20c503de2c3 100644 --- a/source/blender/blenlib/intern/math_matrix.c +++ b/source/blender/blenlib/intern/math_matrix.c @@ -306,7 +306,7 @@ void mul_serie_m4(float answ[][4], float m1[][4], } } -void mul_m4_v3(float mat[][4], float *vec) +void mul_m4_v3(float mat[][4], float vec[3]) { float x,y; @@ -317,7 +317,7 @@ void mul_m4_v3(float mat[][4], float *vec) vec[2]=x*mat[0][2] + y*mat[1][2] + mat[2][2]*vec[2] + mat[3][2]; } -void mul_v3_m4v3(float *in, float mat[][4], float *vec) +void mul_v3_m4v3(float in[3], float mat[][4], const float vec[3]) { float x,y; @@ -329,7 +329,7 @@ void mul_v3_m4v3(float *in, float mat[][4], float *vec) } /* same as mul_m4_v3() but doesnt apply translation component */ -void mul_mat3_m4_v3(float mat[][4], float *vec) +void mul_mat3_m4_v3(float mat[][4], float vec[3]) { float x,y; @@ -384,7 +384,7 @@ void mul_m3_v3(float M[3][3], float r[3]) copy_v3_v3(r, tmp); } -void mul_transposed_m3_v3(float mat[][3], float *vec) +void mul_transposed_m3_v3(float mat[][3], float vec[3]) { float x,y; @@ -422,7 +422,7 @@ void mul_mat3_m4_fl(float m[4][4], float f) m[i][j] *= f; } -void mul_m3_v3_double(float mat[][3], double *vec) +void mul_m3_v3_double(float mat[][3], double vec[3]) { double x,y; @@ -451,6 +451,24 @@ void add_m4_m4m4(float m1[][4], float m2[][4], float m3[][4]) m1[i][j]= m2[i][j] + m3[i][j]; } +void sub_m3_m3m3(float m1[][3], float m2[][3], float m3[][3]) +{ + int i, j; + + for(i=0;i<3;i++) + for(j=0;j<3;j++) + m1[i][j]= m2[i][j] - m3[i][j]; +} + +void sub_m4_m4m4(float m1[][4], float m2[][4], float m3[][4]) +{ + int i, j; + + for(i=0;i<4;i++) + for(j=0;j<4;j++) + m1[i][j]= m2[i][j] - m3[i][j]; +} + int invert_m3(float m[3][3]) { float tmp[3][3]; @@ -961,14 +979,14 @@ void size_to_mat4(float mat[][4], const float size[3]) copy_m4_m3(mat, tmat); } -void mat3_to_size(float *size, float mat[][3]) +void mat3_to_size(float size[3], float mat[][3]) { size[0]= len_v3(mat[0]); size[1]= len_v3(mat[1]); size[2]= len_v3(mat[2]); } -void mat4_to_size(float *size, float mat[][4]) +void mat4_to_size(float size[3], float mat[][4]) { size[0]= len_v3(mat[0]); size[1]= len_v3(mat[1]); diff --git a/source/blender/blenlib/intern/math_vector.c b/source/blender/blenlib/intern/math_vector.c index 15d671e38d7..7dbceff46e4 100644 --- a/source/blender/blenlib/intern/math_vector.c +++ b/source/blender/blenlib/intern/math_vector.c @@ -96,6 +96,14 @@ void interp_v4_v4v4v4(float p[4], const float v1[4], const float v2[4], const fl p[3] = v1[3]*w[0] + v2[3]*w[1] + v3[3]*w[2]; } +void interp_v4_v4v4v4v4(float p[4], const float v1[4], const float v2[4], const float v3[4], const float v4[4], const float w[4]) +{ + p[0] = v1[0]*w[0] + v2[0]*w[1] + v3[0]*w[2] + v4[0]*w[3]; + p[1] = v1[1]*w[0] + v2[1]*w[1] + v3[1]*w[2] + v4[1]*w[3]; + p[2] = v1[2]*w[0] + v2[2]*w[1] + v3[2]*w[2] + v4[2]*w[3]; + p[3] = v1[3]*w[0] + v2[3]*w[1] + v3[3]*w[2] + v4[3]*w[3]; +} + void mid_v3_v3v3(float v[3], const float v1[3], const float v2[3]) { v[0]= 0.5f*(v1[0] + v2[0]); diff --git a/source/blender/blenlib/intern/math_vector_inline.c b/source/blender/blenlib/intern/math_vector_inline.c index 28708af7486..13623d9a93a 100644 --- a/source/blender/blenlib/intern/math_vector_inline.c +++ b/source/blender/blenlib/intern/math_vector_inline.c @@ -79,6 +79,28 @@ MINLINE void copy_v4_v4(float r[4], const float a[4]) r[3]= a[3]; } +/* short */ +MINLINE void copy_v2_v2_short(short r[2], const short a[2]) +{ + r[0]= a[0]; + r[1]= a[1]; +} + +MINLINE void copy_v3_v3_short(short r[3], const short a[3]) +{ + r[0]= a[0]; + r[1]= a[1]; + r[2]= a[2]; +} + +MINLINE void copy_v4_v4_short(short r[4], const short a[4]) +{ + r[0]= a[0]; + r[1]= a[1]; + r[2]= a[2]; + r[3]= a[3]; +} + MINLINE void swap_v2_v2(float a[2], float b[2]) { SWAP(float, a[0], b[0]); diff --git a/source/blender/blenlib/intern/noise.c b/source/blender/blenlib/intern/noise.c index 9bc666dc971..9efe8dc9739 100644 --- a/source/blender/blenlib/intern/noise.c +++ b/source/blender/blenlib/intern/noise.c @@ -263,13 +263,21 @@ static float newPerlinU(float x, float y, float z) static float orgBlenderNoise(float x, float y, float z) { register float cn1, cn2, cn3, cn4, cn5, cn6, i, *h; - float ox, oy, oz, jx, jy, jz; + float fx, fy, fz, ox, oy, oz, jx, jy, jz; float n= 0.5; int ix, iy, iz, b00, b01, b10, b11, b20, b21; - ox= (x- (ix= (int)floor(x)) ); - oy= (y- (iy= (int)floor(y)) ); - oz= (z- (iz= (int)floor(z)) ); + fx= floor(x); + fy= floor(y); + fz= floor(z); + + ox= x- fx; + oy= y- fy; + oz= z- fz; + + ix= (int)fx; + iy= (int)fy; + iz= (int)fz; jx= ox-1; jy= oy-1; diff --git a/source/blender/blenlib/intern/string.c b/source/blender/blenlib/intern/string.c index c4ed44f0cdb..8315161aeda 100644 --- a/source/blender/blenlib/intern/string.c +++ b/source/blender/blenlib/intern/string.c @@ -1,8 +1,4 @@ -/* util.c - * - * various string, file, list operations. - * - * +/* * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** @@ -129,7 +125,7 @@ size_t BLI_strescape(char *dst, const char *src, const size_t maxlen) while(len < maxlen) { switch(*src) { case '\0': - break; + goto escape_finish; case '\\': case '"': @@ -154,6 +150,8 @@ size_t BLI_strescape(char *dst, const char *src, const size_t maxlen) len++; } +escape_finish: + *dst= '\0'; return len; @@ -397,116 +395,6 @@ size_t BLI_strnlen(const char *str, size_t maxlen) return end ? (size_t) (end - str) : maxlen; } -/* 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 */ - -/* based on the valid_utf8 routine from the PCRE library by Philip Hazel - - length is in bytes, since without knowing whether the string is valid - it's hard to know how many characters there are! */ - -static const char trailingBytesForUTF8[256] = { - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 -}; - -int BLI_utf8_invalid_byte(const char *str, int length) -{ - const unsigned char *p, *pend = (unsigned char*)str + length; - unsigned char c; - int ab; - - for (p = (unsigned char*)str; p < pend; p++) { - c = *p; - if (c < 128) - continue; - if ((c & 0xc0) != 0xc0) - goto utf8_error; - ab = trailingBytesForUTF8[c]; - if (length < ab) - goto utf8_error; - length -= ab; - - p++; - /* Check top bits in the second byte */ - if ((*p & 0xc0) != 0x80) - goto utf8_error; - - /* Check for overlong sequences for each different length */ - switch (ab) { - /* Check for xx00 000x */ - case 1: - if ((c & 0x3e) == 0) goto utf8_error; - continue; /* We know there aren't any more bytes to check */ - - /* Check for 1110 0000, xx0x xxxx */ - case 2: - if (c == 0xe0 && (*p & 0x20) == 0) goto utf8_error; - break; - - /* Check for 1111 0000, xx00 xxxx */ - case 3: - if (c == 0xf0 && (*p & 0x30) == 0) goto utf8_error; - break; - - /* Check for 1111 1000, xx00 0xxx */ - case 4: - if (c == 0xf8 && (*p & 0x38) == 0) goto utf8_error; - break; - - /* Check for leading 0xfe or 0xff, - and then for 1111 1100, xx00 00xx */ - case 5: - if (c == 0xfe || c == 0xff || - (c == 0xfc && (*p & 0x3c) == 0)) goto utf8_error; - break; - } - - /* Check for valid bytes after the 2nd, if any; all must start 10 */ - while (--ab > 0) { - if ((*(p+1) & 0xc0) != 0x80) goto utf8_error; - p++; /* do this after so we get usable offset - campbell */ - } - } - - return -1; - -utf8_error: - - return (int)((char *)p - (char *)str) - 1; -} - -int BLI_utf8_invalid_strip(char *str, int length) -{ - int bad_char, tot= 0; - - while((bad_char= BLI_utf8_invalid_byte(str, length)) != -1) { - str += bad_char; - length -= bad_char; - - if(length == 0) { - /* last character bad, strip it */ - *str= '\0'; - tot++; - break; - } - else { - /* strip, keep looking */ - memmove(str, str + 1, length); - tot++; - } - } - - return tot; -} - void BLI_ascii_strtolower(char *str, int len) { int i; diff --git a/source/blender/blenlib/intern/string_utf8.c b/source/blender/blenlib/intern/string_utf8.c new file mode 100644 index 00000000000..5c37d3003e4 --- /dev/null +++ b/source/blender/blenlib/intern/string_utf8.c @@ -0,0 +1,183 @@ +/* + * $Id: + * + * ***** 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. + * + * The Original Code is Copyright (C) 2011 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Campbell Barton. + * + * ***** END GPL LICENSE BLOCK ***** + * + */ + + /** \file blender/blenlib/intern/string_utf8.c + * \ingroup bli + */ + +#include <string.h> + +/* 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 */ + +/* based on the valid_utf8 routine from the PCRE library by Philip Hazel + + length is in bytes, since without knowing whether the string is valid + it's hard to know how many characters there are! */ + +static const char trailingBytesForUTF8[256] = { + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 +}; + +int BLI_utf8_invalid_byte(const char *str, int length) +{ + const unsigned char *p, *pend = (unsigned char*)str + length; + unsigned char c; + int ab; + + for (p = (unsigned char*)str; p < pend; p++) { + c = *p; + if (c < 128) + continue; + if ((c & 0xc0) != 0xc0) + goto utf8_error; + ab = trailingBytesForUTF8[c]; + if (length < ab) + goto utf8_error; + length -= ab; + + p++; + /* Check top bits in the second byte */ + if ((*p & 0xc0) != 0x80) + goto utf8_error; + + /* Check for overlong sequences for each different length */ + switch (ab) { + /* Check for xx00 000x */ + case 1: + if ((c & 0x3e) == 0) goto utf8_error; + continue; /* We know there aren't any more bytes to check */ + + /* Check for 1110 0000, xx0x xxxx */ + case 2: + if (c == 0xe0 && (*p & 0x20) == 0) goto utf8_error; + break; + + /* Check for 1111 0000, xx00 xxxx */ + case 3: + if (c == 0xf0 && (*p & 0x30) == 0) goto utf8_error; + break; + + /* Check for 1111 1000, xx00 0xxx */ + case 4: + if (c == 0xf8 && (*p & 0x38) == 0) goto utf8_error; + break; + + /* Check for leading 0xfe or 0xff, + and then for 1111 1100, xx00 00xx */ + case 5: + if (c == 0xfe || c == 0xff || + (c == 0xfc && (*p & 0x3c) == 0)) goto utf8_error; + break; + } + + /* Check for valid bytes after the 2nd, if any; all must start 10 */ + while (--ab > 0) { + if ((*(p+1) & 0xc0) != 0x80) goto utf8_error; + p++; /* do this after so we get usable offset - campbell */ + } + } + + return -1; + +utf8_error: + + return (int)((char *)p - (char *)str) - 1; +} + +int BLI_utf8_invalid_strip(char *str, int length) +{ + int bad_char, tot= 0; + + while((bad_char= BLI_utf8_invalid_byte(str, length)) != -1) { + str += bad_char; + length -= bad_char; + + if(length == 0) { + /* last character bad, strip it */ + *str= '\0'; + tot++; + break; + } + else { + /* strip, keep looking */ + memmove(str, str + 1, length); + tot++; + } + } + + return tot; +} + + +/* compatible with BLI_strncpy, but esnure no partial utf8 chars */ + +/* array copied from glib's glib's gutf8.c, + * note: this looks to be at odd's with 'trailingBytesForUTF8', + * need to find out what gives here! - campbell */ +static const size_t utf8_skip_data[256] = { + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, + 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,6,6,1,1 +}; + +char *BLI_strncpy_utf8(char *dst, const char *src, size_t maxncpy) +{ + char *dst_r= dst; + size_t utf8_size; + + /* note: currently we dont attempt to deal with invalid utf8 chars */ + + while(*src != '\0' && (utf8_size= utf8_skip_data[*src]) < maxncpy) { + maxncpy -= utf8_size; + switch(utf8_size) { + case 6: *dst ++ = *src ++; + case 5: *dst ++ = *src ++; + case 4: *dst ++ = *src ++; + case 3: *dst ++ = *src ++; + case 2: *dst ++ = *src ++; + case 1: *dst ++ = *src ++; + } + } + *dst= '\0'; + return dst_r; +} + |