~ubuntu-branches/ubuntu/utopic/blender/utopic-proposed

« back to all changes in this revision

Viewing changes to source/blender/blenlib/intern/string_cursor_utf8.c

  • Committer: Package Import Robot
  • Author(s): Matteo F. Vescovi
  • Date: 2012-04-28 12:11:12 UTC
  • mto: (14.1.6 experimental) (1.5.1)
  • mto: This revision was merged to the branch mainline in revision 34.
  • Revision ID: package-import@ubuntu.com-20120428121112-2zi0vp8b6vejda8i
Tags: upstream-2.63
ImportĀ upstreamĀ versionĀ 2.63

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * ***** BEGIN GPL LICENSE BLOCK *****
 
3
 *
 
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.
 
8
 *
 
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.
 
13
 *
 
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.
 
17
 *
 
18
 * The Original Code is Copyright (C) 2011 Blender Foundation.
 
19
 * All rights reserved.
 
20
 *
 
21
 * Contributor(s): Campbell Barton.
 
22
 *
 
23
 * ***** END GPL LICENSE BLOCK *****
 
24
 *
 
25
 */
 
26
 
 
27
/** \file blender/blenlib/intern/string_cursor_utf8.c
 
28
 *  \ingroup bli
 
29
 */
 
30
 
 
31
#include <stdio.h>
 
32
#include <stdlib.h>
 
33
 
 
34
#include "BLI_utildefines.h"
 
35
#include "BLI_string_utf8.h"
 
36
 
 
37
#include "BLI_string_cursor_utf8.h" /* own include */
 
38
 
 
39
typedef enum strCursorDelimType {
 
40
        STRCUR_DELIM_NONE,
 
41
        STRCUR_DELIM_ALPHA,
 
42
        STRCUR_DELIM_PUNCT,
 
43
        STRCUR_DELIM_BRACE,
 
44
        STRCUR_DELIM_OPERATOR,
 
45
        STRCUR_DELIM_QUOTE,
 
46
        STRCUR_DELIM_WHITESPACE,
 
47
        STRCUR_DELIM_OTHER
 
48
} strCursorDelimType;
 
49
 
 
50
/* return 1 if char ch is special character, otherwise return 0 */
 
51
static strCursorDelimType test_special_char(const char *ch_utf8)
 
52
{
 
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);
 
56
 
 
57
        if ((uch >= 'a' && uch <= 'z') ||
 
58
            (uch >= 'A' && uch <= 'Z') ||
 
59
            (uch == '_') /* not quite correct but allow for python, could become configurable */
 
60
            )
 
61
        {
 
62
                return STRCUR_DELIM_ALPHA;
 
63
        }
 
64
 
 
65
        switch (uch) {
 
66
                case ',':
 
67
                case '.':
 
68
                        return STRCUR_DELIM_PUNCT;
 
69
 
 
70
                case '{':
 
71
                case '}':
 
72
                case '[':
 
73
                case ']':
 
74
                case '(':
 
75
                case ')':
 
76
                        return STRCUR_DELIM_BRACE;
 
77
 
 
78
                case '+':
 
79
                case '-':
 
80
                case '=':
 
81
                case '~':
 
82
                case '%':
 
83
                case '/':
 
84
                case '<':
 
85
                case '>':
 
86
                case '^':
 
87
                case '*':
 
88
                case '&':
 
89
                        return STRCUR_DELIM_OPERATOR;
 
90
 
 
91
                case '\'':
 
92
                case '\"': // " - an extra closing one for Aligorith's text editor
 
93
                        return STRCUR_DELIM_QUOTE;
 
94
 
 
95
                case ' ':
 
96
                        return STRCUR_DELIM_WHITESPACE;
 
97
 
 
98
                case '\\':
 
99
                case '!':
 
100
                case '@':
 
101
                case '#':
 
102
                case '$':
 
103
                case ':':
 
104
                case ';':
 
105
                case '?':
 
106
                        /* case '_': *//* special case, for python */
 
107
                        return STRCUR_DELIM_OTHER;
 
108
 
 
109
                default:
 
110
                        break;
 
111
        }
 
112
        return STRCUR_DELIM_NONE;
 
113
}
 
114
 
 
115
int BLI_str_cursor_step_next_utf8(const char *str, size_t maxlen, int *pos)
 
116
{
 
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);
 
120
        if (str_next) {
 
121
                (*pos) += (str_next - str_pos);
 
122
                if ((*pos) > maxlen) {
 
123
                        (*pos) = maxlen;
 
124
                }
 
125
                return TRUE;
 
126
        }
 
127
 
 
128
        return FALSE;
 
129
}
 
130
 
 
131
int BLI_str_cursor_step_prev_utf8(const char *str, size_t UNUSED(maxlen), int *pos)
 
132
{
 
133
        if ((*pos) > 0) {
 
134
                const char *str_pos = str + (*pos);
 
135
                const char *str_prev = BLI_str_find_prev_char_utf8(str, str_pos);
 
136
                if (str_prev) {
 
137
                        (*pos) -= (str_pos - str_prev);
 
138
                        return TRUE;
 
139
                }
 
140
        }
 
141
 
 
142
        return FALSE;
 
143
}
 
144
 
 
145
void BLI_str_cursor_step_utf8(const char *str, size_t maxlen,
 
146
                              int *pos, strCursorJumpDirection direction,
 
147
                              strCursorJumpType jump)
 
148
{
 
149
        const short pos_prev = *pos;
 
150
 
 
151
        if (direction == STRCUR_DIR_NEXT) {
 
152
                BLI_str_cursor_step_next_utf8(str, maxlen, pos);
 
153
 
 
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])))
 
162
                                                break;
 
163
                                }
 
164
                                else {
 
165
                                        break; /* unlikely but just in case */
 
166
                                }
 
167
                        }
 
168
                }
 
169
        }
 
170
        else if (direction == STRCUR_DIR_PREV) {
 
171
                BLI_str_cursor_step_prev_utf8(str, maxlen, pos);
 
172
 
 
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 -> */
 
178
                        while ((*pos) > 0) {
 
179
                                if (BLI_str_cursor_step_prev_utf8(str, maxlen, pos)) {
 
180
                                        if ((jump != STRCUR_JUMP_ALL) && (is_special != test_special_char(&str[*pos])))
 
181
                                                break;
 
182
                                }
 
183
                                else {
 
184
                                        break;
 
185
                                }
 
186
                        }
 
187
 
 
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);
 
191
                        }
 
192
                }
 
193
        }
 
194
        else {
 
195
                BLI_assert(0);
 
196
        }
 
197
}