~ubuntu-branches/ubuntu/trusty/blender/trusty

« back to all changes in this revision

Viewing changes to source/blender/editors/space_text/text_format_lua.c

  • Committer: Package Import Robot
  • Author(s): Jeremy Bicha
  • Date: 2013-03-06 12:08:47 UTC
  • mfrom: (1.5.1) (14.1.8 experimental)
  • Revision ID: package-import@ubuntu.com-20130306120847-frjfaryb2zrotwcg
Tags: 2.66a-1ubuntu1
* Resynchronize with Debian (LP: #1076930, #1089256, #1052743, #999024,
  #1122888, #1147084)
* debian/control:
  - Lower build-depends on libavcodec-dev since we're not
    doing the libav9 transition in Ubuntu yet

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
 * GNU General Public License for more details.
 
12
 *
 
13
 * You should have received a copy of the GNU General Public License
 
14
 * along with this program; if not, write to the Free Software Foundation,
 
15
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 
16
 *
 
17
 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
 
18
 * All rights reserved.
 
19
 *
 
20
 * The Original Code is: all of this file.
 
21
 *
 
22
 * Contributor(s): none yet.
 
23
 *
 
24
 * ***** END GPL LICENSE BLOCK *****
 
25
 */
 
26
 
 
27
/** \file blender/editors/space_text/text_format_lua.c
 
28
 *  \ingroup sptext
 
29
 */
 
30
 
 
31
#include <string.h>
 
32
 
 
33
#include "BLI_blenlib.h"
 
34
 
 
35
#include "DNA_text_types.h"
 
36
#include "DNA_space_types.h"
 
37
 
 
38
#include "BKE_text.h"
 
39
 
 
40
#include "text_format.h"
 
41
 
 
42
/* *** Lua Keywords (for format_line) *** */
 
43
 
 
44
/* Checks the specified source string for a Lua keyword (minus boolean & 'nil'). 
 
45
 * This name must start at the beginning of the source string and must be 
 
46
 * followed by a non-identifier (see text_check_identifier(char)) or null char.
 
47
 *
 
48
 * If a keyword is found, the length of the matching word is returned.
 
49
 * Otherwise, -1 is returned.
 
50
 *
 
51
 * See:
 
52
 * http://www.lua.org/manual/5.1/manual.html#2.1
 
53
 */
 
54
 
 
55
static int txtfmt_lua_find_keyword(const char *string)
 
56
{
 
57
        int i, len;
 
58
 
 
59
        if      (STR_LITERAL_STARTSWITH(string, "and",      len)) i = len;
 
60
        else if (STR_LITERAL_STARTSWITH(string, "break",    len)) i = len;
 
61
        else if (STR_LITERAL_STARTSWITH(string, "do",       len)) i = len;
 
62
        else if (STR_LITERAL_STARTSWITH(string, "else",     len)) i = len;
 
63
        else if (STR_LITERAL_STARTSWITH(string, "elseif",   len)) i = len;
 
64
        else if (STR_LITERAL_STARTSWITH(string, "end",      len)) i = len;
 
65
        else if (STR_LITERAL_STARTSWITH(string, "for",      len)) i = len;
 
66
        else if (STR_LITERAL_STARTSWITH(string, "function", len)) i = len;
 
67
        else if (STR_LITERAL_STARTSWITH(string, "if",       len)) i = len;
 
68
        else if (STR_LITERAL_STARTSWITH(string, "in",       len)) i = len;
 
69
        else if (STR_LITERAL_STARTSWITH(string, "local",    len)) i = len;
 
70
        else if (STR_LITERAL_STARTSWITH(string, "not",      len)) i = len;
 
71
        else if (STR_LITERAL_STARTSWITH(string, "or",       len)) i = len;
 
72
        else if (STR_LITERAL_STARTSWITH(string, "repeat",   len)) i = len;
 
73
        else if (STR_LITERAL_STARTSWITH(string, "return",   len)) i = len;
 
74
        else if (STR_LITERAL_STARTSWITH(string, "then",     len)) i = len;
 
75
        else if (STR_LITERAL_STARTSWITH(string, "until",    len)) i = len;
 
76
        else if (STR_LITERAL_STARTSWITH(string, "while",    len)) i = len;
 
77
        else                                                      i = 0;
 
78
 
 
79
        /* If next source char is an identifier (eg. 'i' in "definate") no match */
 
80
        if (i == 0 || text_check_identifier(string[i]))
 
81
                return -1;
 
82
        return i;
 
83
}
 
84
 
 
85
/* Checks the specified source string for a Lua special name/function. This 
 
86
 * name must start at the beginning of the source string and must be followed 
 
87
 * by a non-identifier (see text_check_identifier(char)) or null character.
 
88
 *
 
89
 * If a special name is found, the length of the matching name is returned.
 
90
 * Otherwise, -1 is returned. 
 
91
 * 
 
92
 * See:
 
93
 * http://www.lua.org/manual/5.1/manual.html#5.1
 
94
 */
 
95
 
 
96
static int txtfmt_lua_find_specialvar(const char *string)
 
97
{
 
98
        int i, len;
 
99
 
 
100
        if      (STR_LITERAL_STARTSWITH(string, "assert",           len))   i = len;
 
101
        else if (STR_LITERAL_STARTSWITH(string, "collectgarbage",   len))   i = len;
 
102
        else if (STR_LITERAL_STARTSWITH(string, "dofile",           len))   i = len;
 
103
        else if (STR_LITERAL_STARTSWITH(string, "error",            len))   i = len;
 
104
        else if (STR_LITERAL_STARTSWITH(string, "_G",               len))   i = len;
 
105
        else if (STR_LITERAL_STARTSWITH(string, "getfenv",          len))   i = len;
 
106
        else if (STR_LITERAL_STARTSWITH(string, "getmetatable",     len))   i = len;
 
107
        else if (STR_LITERAL_STARTSWITH(string, "__index",          len))   i = len;
 
108
        else if (STR_LITERAL_STARTSWITH(string, "ipairs",           len))   i = len;
 
109
        else if (STR_LITERAL_STARTSWITH(string, "load",             len))   i = len;
 
110
        else if (STR_LITERAL_STARTSWITH(string, "loadfile",         len))   i = len;
 
111
        else if (STR_LITERAL_STARTSWITH(string, "loadstring",       len))   i = len;
 
112
        else if (STR_LITERAL_STARTSWITH(string, "next",             len))   i = len;
 
113
        else if (STR_LITERAL_STARTSWITH(string, "pairs",            len))   i = len;
 
114
        else if (STR_LITERAL_STARTSWITH(string, "pcall",            len))   i = len;
 
115
        else if (STR_LITERAL_STARTSWITH(string, "print",            len))   i = len;
 
116
        else if (STR_LITERAL_STARTSWITH(string, "rawequal",         len))   i = len;
 
117
        else if (STR_LITERAL_STARTSWITH(string, "rawget",           len))   i = len;
 
118
        else if (STR_LITERAL_STARTSWITH(string, "rawset",           len))   i = len;
 
119
        else if (STR_LITERAL_STARTSWITH(string, "select",           len))   i = len;
 
120
        else if (STR_LITERAL_STARTSWITH(string, "setfenv",          len))   i = len;
 
121
        else if (STR_LITERAL_STARTSWITH(string, "setmetatable",     len))   i = len;
 
122
        else if (STR_LITERAL_STARTSWITH(string, "tonumber",         len))   i = len;
 
123
        else if (STR_LITERAL_STARTSWITH(string, "tostring",         len))   i = len;
 
124
        else if (STR_LITERAL_STARTSWITH(string, "type",             len))   i = len;
 
125
        else if (STR_LITERAL_STARTSWITH(string, "unpack",           len))   i = len;
 
126
        else if (STR_LITERAL_STARTSWITH(string, "_VERSION",         len))   i = len;
 
127
        else if (STR_LITERAL_STARTSWITH(string, "xpcall",           len))   i = len;
 
128
        else                                                i = 0;
 
129
 
 
130
        /* If next source char is an identifier (eg. 'i' in "definate") no match */
 
131
        if (i == 0 || text_check_identifier(string[i]))
 
132
                return -1;
 
133
        return i;
 
134
}
 
135
 
 
136
static int txtfmt_lua_find_bool(const char *string)
 
137
{
 
138
        int i, len;
 
139
 
 
140
        if      (STR_LITERAL_STARTSWITH(string, "nil",   len))  i = len;
 
141
        else if (STR_LITERAL_STARTSWITH(string, "true",  len))  i = len;
 
142
        else if (STR_LITERAL_STARTSWITH(string, "false", len))  i = len;
 
143
        else                                                    i = 0;
 
144
 
 
145
        /* If next source char is an identifier (eg. 'i' in "Nonetheless") no match */
 
146
        if (i == 0 || text_check_identifier(string[i]))
 
147
                return -1;
 
148
        return i;
 
149
}
 
150
 
 
151
static char txtfmt_lua_format_identifier(const char *str)
 
152
{
 
153
        char fmt;
 
154
        if      ((txtfmt_lua_find_specialvar(str))  != -1) fmt = FMT_TYPE_SPECIAL;
 
155
        else if ((txtfmt_lua_find_keyword(str))     != -1) fmt = FMT_TYPE_KEYWORD;
 
156
        else                                               fmt = FMT_TYPE_DEFAULT;
 
157
        return fmt;
 
158
}
 
159
 
 
160
static void txtfmt_lua_format_line(SpaceText *st, TextLine *line, const int do_next)
 
161
{
 
162
        FlattenString fs;
 
163
        const char *str;
 
164
        char *fmt;
 
165
        char cont_orig, cont, find, prev = ' ';
 
166
        int len, i;
 
167
 
 
168
        /* Get continuation from previous line */
 
169
        if (line->prev && line->prev->format != NULL) {
 
170
                fmt = line->prev->format;
 
171
                cont = fmt[strlen(fmt) + 1]; /* Just after the null-terminator */
 
172
                BLI_assert((FMT_CONT_ALL & cont) == cont);
 
173
        }
 
174
        else {
 
175
                cont = FMT_CONT_NOP;
 
176
        }
 
177
 
 
178
        /* Get original continuation from this line */
 
179
        if (line->format != NULL) {
 
180
                fmt = line->format;
 
181
                cont_orig = fmt[strlen(fmt) + 1]; /* Just after the null-terminator */
 
182
                BLI_assert((FMT_CONT_ALL & cont_orig) == cont_orig);
 
183
        }
 
184
        else {
 
185
                cont_orig = 0xFF;
 
186
        }
 
187
 
 
188
        len = flatten_string(st, &fs, line->line);
 
189
        str = fs.buf;
 
190
        if (!text_check_format_len(line, len)) {
 
191
                flatten_string_free(&fs);
 
192
                return;
 
193
        }
 
194
        fmt = line->format;
 
195
 
 
196
        while (*str) {
 
197
                /* Handle escape sequences by skipping both \ and next char */
 
198
                if (*str == '\\') {
 
199
                        *fmt = prev; fmt++; str++;
 
200
                        if (*str == '\0') break;
 
201
                        *fmt = prev; fmt++; str += BLI_str_utf8_size_safe(str);
 
202
                        continue;
 
203
                }
 
204
                /* Handle continuations */
 
205
                else if (cont) {
 
206
                        /* Multi-line comments */
 
207
                        if (cont & FMT_CONT_COMMENT_C) {
 
208
                                if (*str == ']' && *(str + 1) == ']') {
 
209
                                        *fmt = FMT_TYPE_COMMENT; fmt++; str++;
 
210
                                        *fmt = FMT_TYPE_COMMENT;
 
211
                                        cont = FMT_CONT_NOP;
 
212
                                }
 
213
                                else {
 
214
                                        *fmt = FMT_TYPE_COMMENT;
 
215
                                }
 
216
                                /* Handle other comments */
 
217
                        }
 
218
                        else {
 
219
                                find = (cont & FMT_CONT_QUOTEDOUBLE) ? '"' : '\'';
 
220
                                if (*str == find) cont = 0;
 
221
                                *fmt = FMT_TYPE_STRING;
 
222
                        }
 
223
 
 
224
                        str += BLI_str_utf8_size_safe(str) - 1;
 
225
                }
 
226
                /* Not in a string... */
 
227
                else {
 
228
                        /* Multi-line comments */
 
229
                        if (*str == '-'       && *(str + 1) == '-' &&
 
230
                            *(str + 2) == '[' && *(str + 3) == '[')
 
231
                        {
 
232
                                cont = FMT_CONT_COMMENT_C;
 
233
                                *fmt = FMT_TYPE_COMMENT; fmt++; str++;
 
234
                                *fmt = FMT_TYPE_COMMENT; fmt++; str++;
 
235
                                *fmt = FMT_TYPE_COMMENT; fmt++; str++;
 
236
                                *fmt = FMT_TYPE_COMMENT;
 
237
                        }
 
238
                        /* Single line comment */
 
239
                        else if (*str == '-' && *(str + 1) == '-') {
 
240
                                text_format_fill(&str, &fmt, FMT_TYPE_COMMENT, len - (int)(str - fs.buf));
 
241
                        }
 
242
                        else if (*str == '"' || *str == '\'') {
 
243
                                /* Strings */
 
244
                                find = *str;
 
245
                                cont = (*str == '"') ? FMT_CONT_QUOTEDOUBLE : FMT_CONT_QUOTESINGLE;
 
246
                                *fmt = FMT_TYPE_STRING;
 
247
                        }
 
248
                        /* Whitespace (all ws. has been converted to spaces) */
 
249
                        else if (*str == ' ') {
 
250
                                *fmt = FMT_TYPE_WHITESPACE;
 
251
                        }
 
252
                        /* Numbers (digits not part of an identifier and periods followed by digits) */
 
253
                        else if ((prev != FMT_TYPE_DEFAULT && text_check_digit(*str)) ||
 
254
                                 (*str == '.' && text_check_digit(*(str + 1))))
 
255
                        {
 
256
                                *fmt = FMT_TYPE_NUMERAL;
 
257
                        }
 
258
                        /* Booleans */
 
259
                        else if (prev != FMT_TYPE_DEFAULT && (i = txtfmt_lua_find_bool(str)) != -1) {
 
260
                                if (i > 0) {
 
261
                                        text_format_fill_ascii(&str, &fmt, FMT_TYPE_NUMERAL, i);
 
262
                                }
 
263
                                else {
 
264
                                        str += BLI_str_utf8_size_safe(str) - 1;
 
265
                                        *fmt = FMT_TYPE_DEFAULT;
 
266
                                }
 
267
                        }
 
268
                        /* Punctuation */
 
269
                        else if ((*str != '#') && text_check_delim(*str)) {
 
270
                                *fmt = FMT_TYPE_SYMBOL;
 
271
                        }
 
272
                        /* Identifiers and other text (no previous ws. or delims. so text continues) */
 
273
                        else if (prev == FMT_TYPE_DEFAULT) {
 
274
                                str += BLI_str_utf8_size_safe(str) - 1;
 
275
                                *fmt = FMT_TYPE_DEFAULT;
 
276
                        }
 
277
                        /* Not ws, a digit, punct, or continuing text. Must be new, check for special words */
 
278
                        else {
 
279
                                /* Special vars(v) or built-in keywords(b) */
 
280
                                /* keep in sync with 'txtfmt_osl_format_identifier()' */
 
281
                                if      ((i = txtfmt_lua_find_specialvar(str))   != -1) prev = FMT_TYPE_SPECIAL;
 
282
                                else if ((i = txtfmt_lua_find_keyword(str))      != -1) prev = FMT_TYPE_KEYWORD;
 
283
 
 
284
                                if (i > 0) {
 
285
                                        text_format_fill_ascii(&str, &fmt, prev, i);
 
286
                                }
 
287
                                else {
 
288
                                        str += BLI_str_utf8_size_safe(str) - 1;
 
289
                                        *fmt = FMT_TYPE_DEFAULT;
 
290
                                }
 
291
                        }
 
292
                }
 
293
                prev = *fmt; fmt++; str++;
 
294
        }
 
295
 
 
296
        /* Terminate and add continuation char */
 
297
        *fmt = '\0'; fmt++;
 
298
        *fmt = cont;
 
299
 
 
300
        /* If continuation has changed and we're allowed, process the next line */
 
301
        if (cont != cont_orig && do_next && line->next) {
 
302
                txtfmt_lua_format_line(st, line->next, do_next);
 
303
        }
 
304
 
 
305
        flatten_string_free(&fs);
 
306
}
 
307
 
 
308
void ED_text_format_register_lua(void)
 
309
{
 
310
        static TextFormatType tft = {0};
 
311
        static const char *ext[] = {"lua", NULL};
 
312
 
 
313
        tft.format_identifier = txtfmt_lua_format_identifier;
 
314
        tft.format_line       = txtfmt_lua_format_line;
 
315
        tft.ext = ext;
 
316
 
 
317
        ED_text_format_register(&tft);
 
318
}