Blender V4.3
text_format.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#include <cstring>
10
11#include "MEM_guardedalloc.h"
12
13#include "BLI_blenlib.h"
14#include "BLI_string_utils.hh"
15
16#include "DNA_space_types.h"
17#include "DNA_text_types.h"
18
19#include "ED_text.hh"
20
21#include "text_format.hh"
22
23/****************** flatten string **********************/
24
25static void flatten_string_append(FlattenString *fs, const char *c, int accum, int len)
26{
27 int i;
28
29 if (fs->pos + len > fs->len) {
30 char *nbuf;
31 int *naccum;
32 fs->len *= 2;
33
34 nbuf = static_cast<char *>(MEM_callocN(sizeof(*fs->buf) * fs->len, "fs->buf"));
35 memcpy(nbuf, fs->buf, sizeof(*fs->buf) * fs->pos);
36
37 naccum = static_cast<int *>(MEM_callocN(sizeof(*fs->accum) * fs->len, "fs->accum"));
38 memcpy(naccum, fs->accum, sizeof(*fs->accum) * fs->pos);
39
40 if (fs->buf != fs->fixedbuf) {
41 MEM_freeN(fs->buf);
42 MEM_freeN(fs->accum);
43 }
44
45 fs->buf = nbuf;
46 fs->accum = naccum;
47 }
48
49 for (i = 0; i < len; i++) {
50 fs->buf[fs->pos + i] = c[i];
51 fs->accum[fs->pos + i] = accum;
52 }
53
54 fs->pos += len;
55}
56
57int flatten_string(const SpaceText *st, FlattenString *fs, const char *in)
58{
59 int r, i, total = 0;
60
61 memset(fs, 0, sizeof(FlattenString));
62 fs->buf = fs->fixedbuf;
63 fs->accum = fs->fixedaccum;
64 fs->len = sizeof(fs->fixedbuf);
65
66 for (r = 0, i = 0; *in; r++) {
67 if (*in == '\t') {
68 i = st->tabnumber - (total % st->tabnumber);
69 total += i;
70
71 while (i--) {
72 flatten_string_append(fs, " ", r, 1);
73 }
74
75 in++;
76 }
77 else {
78 size_t len = BLI_str_utf8_size_safe(in);
79 flatten_string_append(fs, in, r, len);
80 in += len;
81 total++;
82 }
83 }
84
85 flatten_string_append(fs, "\0", r, 1);
86
87 return total;
88}
89
91{
92 if (fs->buf != fs->fixedbuf) {
93 MEM_freeN(fs->buf);
94 }
95 if (fs->accum != fs->fixedaccum) {
96 MEM_freeN(fs->accum);
97 }
98}
99
101{
102 const int len = (fs->pos - int(str - fs->buf)) - 1;
103 BLI_assert(strlen(str) == len);
104 return len;
105}
106
108{
109 if (line->format) {
110 if (strlen(line->format) < len) {
111 MEM_freeN(line->format);
112 line->format = static_cast<char *>(MEM_mallocN(len + 2, "SyntaxFormat"));
113 if (!line->format) {
114 return 0;
115 }
116 }
117 }
118 else {
119 line->format = static_cast<char *>(MEM_mallocN(len + 2, "SyntaxFormat"));
120 if (!line->format) {
121 return 0;
122 }
123 }
124
125 return 1;
126}
127
128void text_format_fill(const char **str_p, char **fmt_p, const char type, const int len)
129{
130 const char *str = *str_p;
131 char *fmt = *fmt_p;
132 int i = 0;
133
134 while (i < len) {
135 const int size = BLI_str_utf8_size_safe(str);
136 *fmt++ = type;
137
138 str += size;
139 i += 1;
140 }
141
142 str--;
143 fmt--;
144
145 BLI_assert(*str != '\0');
146
147 *str_p = str;
148 *fmt_p = fmt;
149}
150void text_format_fill_ascii(const char **str_p, char **fmt_p, const char type, const int len)
151{
152 const char *str = *str_p;
153 char *fmt = *fmt_p;
154
155 memset(fmt, type, len);
156
157 str += len - 1;
158 fmt += len - 1;
159
160 BLI_assert(*str != '\0');
161
162 *str_p = str;
163 *fmt_p = fmt;
164}
165
166/* *** Registration *** */
167static ListBase tft_lb = {nullptr, nullptr};
172
174{
175 if (text) {
176 const char *text_ext = strchr(text->id.name + 2, '.');
177 if (text_ext) {
178 text_ext++; /* skip the '.' */
179 /* Check all text formats in the static list */
181 /* All formats should have an ext, but just in case */
182 const char **ext;
183 for (ext = tft->ext; *ext; ext++) {
184 /* If extension matches text name, return the matching tft */
185 if (BLI_strcasecmp(text_ext, *ext) == 0) {
186 return tft;
187 }
188 }
189 }
190 }
191
192 /* If we make it here we never found an extension that worked - return
193 * the "default" text format */
194 return static_cast<TextFormatType *>(tft_lb.first);
195 }
196
197 /* Return the "default" text format */
198 return static_cast<TextFormatType *>(tft_lb.first);
199}
200
202{
204 return format->comment_line;
205}
206
208{
209 if (text == nullptr) {
210 return false;
211 }
212
213 const char *text_ext = BLI_path_extension(text->id.name + 2);
214 if (text_ext == nullptr) {
215 /* Extensionless data-blocks are considered highlightable as Python. */
216 return true;
217 }
218 text_ext++; /* skip the '.' */
219 if (BLI_string_is_decimal(text_ext)) {
220 /* "Text.001" is treated as extensionless, and thus highlightable. */
221 return true;
222 }
223
224 /* Check all text formats in the static list */
226 /* All formats should have an ext, but just in case */
227 const char **ext;
228 for (ext = tft->ext; *ext; ext++) {
229 /* If extension matches text name, return the matching tft */
230 if (BLI_strcasecmp(text_ext, *ext) == 0) {
231 return true;
232 }
233 }
234 }
235
236 /* The filename has a non-numerical extension that we could not highlight. */
237 return false;
238}
239
240int text_format_string_literal_find(const Span<const char *> string_literals, const char *text)
241{
242 auto cmp_fn = [](const char *text, const char *string_literal) {
243 return strcmp(text, string_literal) < 0;
244 };
245 const char *const *string_literal_p = std::upper_bound(
246 std::begin(string_literals), std::end(string_literals), text, cmp_fn);
247
248 if (string_literal_p != std::begin(string_literals)) {
249 const char *string = *(string_literal_p - 1);
250 const size_t string_len = strlen(string);
251 if (strncmp(string, text, string_len) == 0) {
252 return string_len;
253 }
254 }
255
256 return 0;
257}
258
259#ifndef NDEBUG
261{
262 return std::is_sorted(string_literals.begin(),
263 string_literals.end(),
264 [](const char *a, const char *b) { return strcmp(a, b) < 0; });
265}
266#endif
#define BLI_assert(a)
Definition BLI_assert.h:50
#define LISTBASE_FOREACH(type, var, list)
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:110
const char * BLI_path_extension(const char *filepath) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT
int char char int BLI_strcasecmp(const char *s1, const char *s2) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1
int BLI_str_utf8_size_safe(const char *p) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
size_t bool BLI_string_is_decimal(const char *string) ATTR_NONNULL(1)
unsigned int uint
Read Guarded memory(de)allocation.
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
constexpr const T * end() const
Definition BLI_span.hh:225
constexpr const T * begin() const
Definition BLI_span.hh:221
local_group_size(16, 16) .push_constant(Type b
int len
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
#define str(s)
format
void *(* MEM_mallocN)(size_t len, const char *str)
Definition mallocn.cc:44
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
void *(* MEM_callocN)(size_t len, const char *str)
Definition mallocn.cc:42
int fixedaccum[256]
char fixedbuf[256]
void * first
int flatten_string_strlen(FlattenString *fs, const char *str)
static void flatten_string_append(FlattenString *fs, const char *c, int accum, int len)
int flatten_string(const SpaceText *st, FlattenString *fs, const char *in)
void text_format_fill(const char **str_p, char **fmt_p, const char type, const int len)
void flatten_string_free(FlattenString *fs)
const bool text_format_string_literals_check_sorted_array(const Span< const char * > string_literals)
const char * ED_text_format_comment_line_prefix(Text *text)
int text_format_string_literal_find(const Span< const char * > string_literals, const char *text)
static ListBase tft_lb
TextFormatType * ED_text_format_get(Text *text)
void text_format_fill_ascii(const char **str_p, char **fmt_p, const char type, const int len)
bool ED_text_is_syntax_highlight_supported(Text *text)
void ED_text_format_register(TextFormatType *tft)
int text_check_format_len(TextLine *line, uint len)
static int cmp_fn(const void *a, const void *b)