Code cleanup: use bool
[blender.git] / source / blender / blenlib / intern / string_cursor_utf8.c
index baf52d922305938cd83a8faa560198ea739ce1e7..57913af370340451b81c585254de65ee8d74ac0e 100644 (file)
 
 #include "BLI_string_cursor_utf8.h" /* own include */
 
 
 #include "BLI_string_cursor_utf8.h" /* own include */
 
+#ifdef __GNUC__
+#  pragma GCC diagnostic error "-Wsign-conversion"
+#endif
+
 typedef enum strCursorDelimType {
        STRCUR_DELIM_NONE,
 typedef enum strCursorDelimType {
        STRCUR_DELIM_NONE,
-       STRCUR_DELIM_ALPHA,
+       STRCUR_DELIM_ALPHANUMERIC,
        STRCUR_DELIM_PUNCT,
        STRCUR_DELIM_BRACE,
        STRCUR_DELIM_OPERATOR,
        STRCUR_DELIM_PUNCT,
        STRCUR_DELIM_BRACE,
        STRCUR_DELIM_OPERATOR,
@@ -47,20 +51,9 @@ typedef enum strCursorDelimType {
        STRCUR_DELIM_OTHER
 } strCursorDelimType;
 
        STRCUR_DELIM_OTHER
 } strCursorDelimType;
 
-/* return 1 if char ch is special character, otherwise return 0 */
-static strCursorDelimType test_special_char(const char ch)
+static strCursorDelimType cursor_delim_type_unicode(const unsigned int uch)
 {
 {
-       /* TODO - use BLI_str_utf8_as_unicode rather then assuming ascii */
-
-       if ((ch >= 'a' && ch <= 'z') ||
-           (ch >= 'A' && ch <= 'Z') ||
-           (ch == '_') /* not quite correct but allow for python, could become configurable */
-           )
-       {
-               return STRCUR_DELIM_ALPHA;
-       }
-
-       switch (ch) {
+       switch (uch) {
                case ',':
                case '.':
                        return STRCUR_DELIM_PUNCT;
                case ',':
                case '.':
                        return STRCUR_DELIM_PUNCT;
@@ -84,41 +77,54 @@ static strCursorDelimType test_special_char(const char ch)
                case '^':
                case '*':
                case '&':
                case '^':
                case '*':
                case '&':
+               case '|':
                        return STRCUR_DELIM_OPERATOR;
 
                case '\'':
                        return STRCUR_DELIM_OPERATOR;
 
                case '\'':
-               case '\"': // " - an extra closing one for Aligorith's text editor
+               case '\"':
                        return STRCUR_DELIM_QUOTE;
 
                case ' ':
                        return STRCUR_DELIM_QUOTE;
 
                case ' ':
+               case '\t':
+               case '\n':
                        return STRCUR_DELIM_WHITESPACE;
 
                case '\\':
                        return STRCUR_DELIM_WHITESPACE;
 
                case '\\':
-               case '!':
                case '@':
                case '#':
                case '$':
                case ':':
                case ';':
                case '?':
                case '@':
                case '#':
                case '$':
                case ':':
                case ';':
                case '?':
+               case '!':
+               case 0xA3:  /* pound */
+               case 0x80:  /* euro */
                        /* case '_': *//* special case, for python */
                        return STRCUR_DELIM_OTHER;
 
                default:
                        break;
        }
                        /* case '_': *//* special case, for python */
                        return STRCUR_DELIM_OTHER;
 
                default:
                        break;
        }
-       return STRCUR_DELIM_NONE;
+       return STRCUR_DELIM_ALPHANUMERIC; /* Not quite true, but ok for now */
+}
+
+static strCursorDelimType cursor_delim_type_utf8(const char *ch_utf8)
+{
+       /* for full unicode support we really need to have large lookup tables to figure
+        * out whats what in every possible char set - and python, glib both have these. */
+       unsigned int uch = BLI_str_utf8_as_unicode(ch_utf8);
+       return cursor_delim_type_unicode(uch);
 }
 
 }
 
-int BLI_str_cursor_step_next_utf8(const char *str, size_t maxlen, int *pos)
+bool BLI_str_cursor_step_next_utf8(const char *str, size_t maxlen, int *pos)
 {
        const char *str_end = str + (maxlen + 1);
        const char *str_pos = str + (*pos);
        const char *str_next = BLI_str_find_next_char_utf8(str_pos, str_end);
        if (str_next) {
                (*pos) += (str_next - str_pos);
 {
        const char *str_end = str + (maxlen + 1);
        const char *str_pos = str + (*pos);
        const char *str_next = BLI_str_find_next_char_utf8(str_pos, str_end);
        if (str_next) {
                (*pos) += (str_next - str_pos);
-               if ((*pos) > maxlen) {
-                       (*pos) = maxlen;
+               if ((*pos) > (int)maxlen) {
+                       (*pos) = (int)maxlen;
                }
                return TRUE;
        }
                }
                return TRUE;
        }
@@ -126,7 +132,7 @@ int BLI_str_cursor_step_next_utf8(const char *str, size_t maxlen, int *pos)
        return FALSE;
 }
 
        return FALSE;
 }
 
-int BLI_str_cursor_step_prev_utf8(const char *str, size_t UNUSED(maxlen), int *pos)
+bool BLI_str_cursor_step_prev_utf8(const char *str, size_t UNUSED(maxlen), int *pos)
 {
        if ((*pos) > 0) {
                const char *str_pos = str + (*pos);
 {
        if ((*pos) > 0) {
                const char *str_pos = str + (*pos);
@@ -142,22 +148,28 @@ int BLI_str_cursor_step_prev_utf8(const char *str, size_t UNUSED(maxlen), int *p
 
 void BLI_str_cursor_step_utf8(const char *str, size_t maxlen,
                               int *pos, strCursorJumpDirection direction,
 
 void BLI_str_cursor_step_utf8(const char *str, size_t maxlen,
                               int *pos, strCursorJumpDirection direction,
-                              strCursorJumpType jump)
+                              strCursorJumpType jump, bool use_init_step)
 {
 {
-       const short pos_prev = *pos;
+       const int pos_orig = *pos;
 
        if (direction == STRCUR_DIR_NEXT) {
 
        if (direction == STRCUR_DIR_NEXT) {
-               BLI_str_cursor_step_next_utf8(str, maxlen, pos);
+               if (use_init_step) {
+                       BLI_str_cursor_step_next_utf8(str, maxlen, pos);
+               }
+               else {
+                       BLI_assert(jump == STRCUR_JUMP_DELIM);
+               }
 
                if (jump != STRCUR_JUMP_NONE) {
 
                if (jump != STRCUR_JUMP_NONE) {
-                       const strCursorDelimType is_special = (*pos) < maxlen ? test_special_char(str[(*pos)]) : STRCUR_DELIM_NONE;
+                       const strCursorDelimType delim_type = (*pos) < maxlen ? cursor_delim_type_utf8(&str[*pos]) : STRCUR_DELIM_NONE;
                        /* jump between special characters (/,\,_,-, etc.),
                        /* jump between special characters (/,\,_,-, etc.),
-                        * look at function test_special_char() for complete
+                        * look at function cursor_delim_type() for complete
                         * list of special character, ctr -> */
                        while ((*pos) < maxlen) {
                                if (BLI_str_cursor_step_next_utf8(str, maxlen, pos)) {
                         * list of special character, ctr -> */
                        while ((*pos) < maxlen) {
                                if (BLI_str_cursor_step_next_utf8(str, maxlen, pos)) {
-                                       if ((jump != STRCUR_JUMP_ALL) && (is_special != test_special_char(str[(*pos)])))
+                                       if ((jump != STRCUR_JUMP_ALL) && (delim_type != cursor_delim_type_utf8(&str[*pos]))) {
                                                break;
                                                break;
+                                       }
                                }
                                else {
                                        break; /* unlikely but just in case */
                                }
                                else {
                                        break; /* unlikely but just in case */
@@ -166,26 +178,121 @@ void BLI_str_cursor_step_utf8(const char *str, size_t maxlen,
                }
        }
        else if (direction == STRCUR_DIR_PREV) {
                }
        }
        else if (direction == STRCUR_DIR_PREV) {
-               BLI_str_cursor_step_prev_utf8(str, maxlen, pos);
+               if (use_init_step) {
+                       BLI_str_cursor_step_prev_utf8(str, maxlen, pos);
+               }
+               else {
+                       BLI_assert(jump == STRCUR_JUMP_DELIM);
+               }
 
                if (jump != STRCUR_JUMP_NONE) {
 
                if (jump != STRCUR_JUMP_NONE) {
-                       const strCursorDelimType is_special = (*pos) > 1 ? test_special_char(str[(*pos) - 1]) : STRCUR_DELIM_NONE;
+                       const strCursorDelimType delim_type = (*pos) > 0 ? cursor_delim_type_utf8(&str[(*pos) - 1]) : STRCUR_DELIM_NONE;
                        /* jump between special characters (/,\,_,-, etc.),
                        /* jump between special characters (/,\,_,-, etc.),
-                        * look at function test_special_char() for complete
+                        * look at function cursor_delim_type() for complete
                         * list of special character, ctr -> */
                        while ((*pos) > 0) {
                         * list of special character, ctr -> */
                        while ((*pos) > 0) {
+                               const int pos_prev = *pos;
                                if (BLI_str_cursor_step_prev_utf8(str, maxlen, pos)) {
                                if (BLI_str_cursor_step_prev_utf8(str, maxlen, pos)) {
-                                       if ((jump != STRCUR_JUMP_ALL) && (is_special != test_special_char(str[(*pos)])))
+                                       if ((jump != STRCUR_JUMP_ALL) && (delim_type != cursor_delim_type_utf8(&str[*pos]))) {
+                                               /* left only: compensate for index/change in direction */
+                                               if ((pos_orig - (*pos)) >= 1) {
+                                                       *pos = pos_prev;
+                                               }
                                                break;
                                                break;
+                                       }
                                }
                                else {
                                        break;
                                }
                        }
                                }
                                else {
                                        break;
                                }
                        }
+               }
+       }
+       else {
+               BLI_assert(0);
+       }
+}
+
+/* wchar_t version of BLI_str_cursor_step_utf8 (keep in sync!)
+ * less complex since it doesn't need to do multi-byte stepping.
+ */
+
+/* helper funcs so we can match BLI_str_cursor_step_utf8 */
+static bool wchar_t_step_next(const wchar_t *UNUSED(str), size_t maxlen, int *pos)
+{
+       if ((*pos) >= (int)maxlen) {
+               return false;
+       }
+       (*pos)++;
+       return true;
+}
+
+static bool wchar_t_step_prev(const wchar_t *UNUSED(str), size_t UNUSED(maxlen), int *pos)
+{
+       if ((*pos) <= 0) {
+               return false;
+       }
+       (*pos)--;
+       return true;
+}
+
+void BLI_str_cursor_step_wchar(const wchar_t *str, size_t maxlen,
+                               int *pos, strCursorJumpDirection direction,
+                               strCursorJumpType jump, bool use_init_step)
+{
+       const int pos_orig = *pos;
+
+       if (direction == STRCUR_DIR_NEXT) {
+               if (use_init_step) {
+                       wchar_t_step_next(str, maxlen, pos);
+               }
+               else {
+                       BLI_assert(jump == STRCUR_JUMP_DELIM);
+               }
+
+               if (jump != STRCUR_JUMP_NONE) {
+                       const strCursorDelimType delim_type = (*pos) < maxlen ? cursor_delim_type_unicode((unsigned int)str[*pos]) : STRCUR_DELIM_NONE;
+                       /* jump between special characters (/,\,_,-, etc.),
+                        * look at function cursor_delim_type_unicode() for complete
+                        * list of special character, ctr -> */
+                       while ((*pos) < maxlen) {
+                               if (wchar_t_step_next(str, maxlen, pos)) {
+                                       if ((jump != STRCUR_JUMP_ALL) && (delim_type != cursor_delim_type_unicode((unsigned int)str[*pos]))) {
+                                               break;
+                                       }
+                               }
+                               else {
+                                       break; /* unlikely but just in case */
+                               }
+                       }
+               }
+       }
+       else if (direction == STRCUR_DIR_PREV) {
+               if (use_init_step) {
+                       wchar_t_step_prev(str, maxlen, pos);
+               }
+               else {
+                       BLI_assert(jump == STRCUR_JUMP_DELIM);
+               }
 
 
-                       /* left only: compensate for index/change in direction */
-                       if (((*pos) != 0) && ABS(pos_prev - (*pos)) >= 1) {
-                               BLI_str_cursor_step_next_utf8(str, maxlen, pos);
+               if (jump != STRCUR_JUMP_NONE) {
+                       const strCursorDelimType delim_type = (*pos) > 0 ? cursor_delim_type_unicode((unsigned int)str[(*pos) - 1]) : STRCUR_DELIM_NONE;
+                       /* jump between special characters (/,\,_,-, etc.),
+                        * look at function cursor_delim_type() for complete
+                        * list of special character, ctr -> */
+                       while ((*pos) > 0) {
+                               const int pos_prev = *pos;
+                               if (wchar_t_step_prev(str, maxlen, pos)) {
+                                       if ((jump != STRCUR_JUMP_ALL) && (delim_type != cursor_delim_type_unicode((unsigned int)str[*pos]))) {
+                                               /* left only: compensate for index/change in direction */
+                                               if ((pos_orig - (*pos)) >= 1) {
+                                                       *pos = pos_prev;
+                                               }
+                                               break;
+                                       }
+                               }
+                               else {
+                                       break;
+                               }
                        }
                }
        }
                        }
                }
        }
@@ -193,3 +300,4 @@ void BLI_str_cursor_step_utf8(const char *str, size_t maxlen,
                BLI_assert(0);
        }
 }
                BLI_assert(0);
        }
 }
+