2
* ***** BEGIN GPL LICENSE BLOCK *****
4
* This program is free software; you can redistribute it and/or
5
* modify it under the terms of the GNU General Public License
6
* as published by the Free Software Foundation; either version 2
7
* of the License, or (at your option) any later version.
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
14
* You should have received a copy of the GNU General Public License
15
* along with this program; if not, write to the Free Software Foundation,
16
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18
* The Original Code is Copyright (C) 2011 Blender Foundation.
19
* All rights reserved.
21
* Contributor(s): Campbell Barton.
23
* ***** END GPL LICENSE BLOCK *****
27
/** \file blender/blenlib/intern/string_cursor_utf8.c
34
#include "BLI_utildefines.h"
35
#include "BLI_string_utf8.h"
37
#include "BLI_string_cursor_utf8.h" /* own include */
39
typedef enum strCursorDelimType {
44
STRCUR_DELIM_OPERATOR,
46
STRCUR_DELIM_WHITESPACE,
50
/* return 1 if char ch is special character, otherwise return 0 */
51
static strCursorDelimType test_special_char(const char *ch_utf8)
53
/* for full unicode support we really need to have large lookup tables to figure
54
* out whats what in every possible char set - and python, glib both have these. */
55
unsigned int uch = BLI_str_utf8_as_unicode(ch_utf8);
57
if ((uch >= 'a' && uch <= 'z') ||
58
(uch >= 'A' && uch <= 'Z') ||
59
(uch == '_') /* not quite correct but allow for python, could become configurable */
62
return STRCUR_DELIM_ALPHA;
68
return STRCUR_DELIM_PUNCT;
76
return STRCUR_DELIM_BRACE;
89
return STRCUR_DELIM_OPERATOR;
92
case '\"': // " - an extra closing one for Aligorith's text editor
93
return STRCUR_DELIM_QUOTE;
96
return STRCUR_DELIM_WHITESPACE;
106
/* case '_': *//* special case, for python */
107
return STRCUR_DELIM_OTHER;
112
return STRCUR_DELIM_NONE;
115
int BLI_str_cursor_step_next_utf8(const char *str, size_t maxlen, int *pos)
117
const char *str_end = str + (maxlen + 1);
118
const char *str_pos = str + (*pos);
119
const char *str_next = BLI_str_find_next_char_utf8(str_pos, str_end);
121
(*pos) += (str_next - str_pos);
122
if ((*pos) > maxlen) {
131
int BLI_str_cursor_step_prev_utf8(const char *str, size_t UNUSED(maxlen), int *pos)
134
const char *str_pos = str + (*pos);
135
const char *str_prev = BLI_str_find_prev_char_utf8(str, str_pos);
137
(*pos) -= (str_pos - str_prev);
145
void BLI_str_cursor_step_utf8(const char *str, size_t maxlen,
146
int *pos, strCursorJumpDirection direction,
147
strCursorJumpType jump)
149
const short pos_prev = *pos;
151
if (direction == STRCUR_DIR_NEXT) {
152
BLI_str_cursor_step_next_utf8(str, maxlen, pos);
154
if (jump != STRCUR_JUMP_NONE) {
155
const strCursorDelimType is_special = (*pos) < maxlen ? test_special_char(&str[*pos]) : STRCUR_DELIM_NONE;
156
/* jump between special characters (/,\,_,-, etc.),
157
* look at function test_special_char() for complete
158
* list of special character, ctr -> */
159
while ((*pos) < maxlen) {
160
if (BLI_str_cursor_step_next_utf8(str, maxlen, pos)) {
161
if ((jump != STRCUR_JUMP_ALL) && (is_special != test_special_char(&str[*pos])))
165
break; /* unlikely but just in case */
170
else if (direction == STRCUR_DIR_PREV) {
171
BLI_str_cursor_step_prev_utf8(str, maxlen, pos);
173
if (jump != STRCUR_JUMP_NONE) {
174
const strCursorDelimType is_special = (*pos) > 1 ? test_special_char(&str[(*pos) - 1]) : STRCUR_DELIM_NONE;
175
/* jump between special characters (/,\,_,-, etc.),
176
* look at function test_special_char() for complete
177
* list of special character, ctr -> */
179
if (BLI_str_cursor_step_prev_utf8(str, maxlen, pos)) {
180
if ((jump != STRCUR_JUMP_ALL) && (is_special != test_special_char(&str[*pos])))
188
/* left only: compensate for index/change in direction */
189
if (((*pos) != 0) && ABS(pos_prev - (*pos)) >= 1) {
190
BLI_str_cursor_step_next_utf8(str, maxlen, pos);