Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBastien Montagne <montagne29@wanadoo.fr>2015-09-28 11:04:37 +0300
committerBastien Montagne <montagne29@wanadoo.fr>2015-09-28 11:04:37 +0300
commitfc97204742d348797c7f16a44978bb7e756af473 (patch)
treef7dc5320d915e4257cd92fa717af7940121e891a /source/blender/editors/space_text/text_ops.c
parent1a6d45527fe873d48139aa403f13bb3d828cd841 (diff)
Fix T46293: Text Editor: Convert to spaces/to tabs was totally broken with non-ASCII strings.
Code was totally unaware of UTF8, also it was needlessly complicated...
Diffstat (limited to 'source/blender/editors/space_text/text_ops.c')
-rw-r--r--source/blender/editors/space_text/text_ops.c146
1 files changed, 69 insertions, 77 deletions
diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c
index a2fae2d5667..543fa0a0f72 100644
--- a/source/blender/editors/space_text/text_ops.c
+++ b/source/blender/editors/space_text/text_ops.c
@@ -1054,108 +1054,100 @@ static int text_convert_whitespace_exec(bContext *C, wmOperator *op)
Text *text = CTX_data_edit_text(C);
TextLine *tmp;
FlattenString fs;
- size_t a, j;
- char *new_line;
- int extra, number; //unknown for now
+ size_t a, j, max_len = 0;
int type = RNA_enum_get(op->ptr, "type");
/* first convert to all space, this make it a lot easier to convert to tabs
* because there is no mixtures of ' ' && '\t' */
for (tmp = text->lines.first; tmp; tmp = tmp->next) {
- const char *text_check_line = tmp->line;
- const int text_check_line_len = tmp->len;
- number = flatten_string(st, &fs, text_check_line) + 1;
+ char *new_line;
+
+ flatten_string(st, &fs, tmp->line);
+ new_line = BLI_strdup(fs.buf);
flatten_string_free(&fs);
- new_line = MEM_callocN(number, "Converted_Line");
- j = 0;
- for (a = 0; a < text_check_line_len; a++) { //foreach char in line
- if (text_check_line[a] == '\t') { //checking for tabs
- //get the number of spaces this tabs is showing
- //i don't like doing it this way but will look into it later
- new_line[j] = '\0';
- number = flatten_string(st, &fs, new_line);
- flatten_string_free(&fs);
- new_line[j] = '\t';
- new_line[j + 1] = '\0';
- number = flatten_string(st, &fs, new_line) - number;
- flatten_string_free(&fs);
- for (extra = 0; extra < number; extra++) {
- new_line[j] = ' ';
- j++;
- }
- }
- else {
- new_line[j] = text_check_line[a];
- j++;
- }
- }
- new_line[j] = '\0';
- // put new_line in the tmp->line spot still need to try and set the curc correctly
- if (tmp->line) MEM_freeN(tmp->line);
- if (tmp->format) MEM_freeN(tmp->format);
+ /* Put new_line in the tmp->line spot still need to try and set the curc correctly. */
+ if (tmp->line)
+ MEM_freeN(tmp->line);
+ if (tmp->format)
+ MEM_freeN(tmp->format);
tmp->line = new_line;
tmp->len = strlen(new_line);
tmp->format = NULL;
+ if (tmp->len > max_len) {
+ max_len = tmp->len;
+ }
}
- if (type == TO_TABS) { // Converting to tabs
- //start over from the beginning
-
+ if (type == TO_TABS) {
+ char *tmp_line = MEM_mallocN(sizeof(*tmp_line) * (max_len + 1), __func__);
+
for (tmp = text->lines.first; tmp; tmp = tmp->next) {
const char *text_check_line = tmp->line;
const int text_check_line_len = tmp->len;
- extra = 0;
- for (a = 0; a < text_check_line_len; a++) {
- number = 0;
- for (j = 0; j < (size_t)st->tabnumber; j++) {
- if ((a + j) <= text_check_line_len) { //check to make sure we are not pass the end of the line
- if (text_check_line[a + j] != ' ') {
- number = 1;
+ char *tmp_line_cur = tmp_line;
+ const size_t tab_len = st->tabnumber;
+
+ for (a = 0; a < text_check_line_len;) {
+ /* A tab can only start at a position multiple of tab_len... */
+ if (!(a % tab_len) && (text_check_line[a] == ' ')) {
+ /* a + 0 we already know to be ' ' char... */
+ for (j = 1; (j < tab_len) && (a + j < text_check_line_len) && (text_check_line[a + j] == ' '); j++);
+
+ if (j == tab_len) {
+ /* We found a set of spaces that can be replaced by a tab... */
+ if ((tmp_line_cur == tmp_line) && a != 0) {
+ /* Copy all 'valid' string already 'parsed'... */
+ memcpy(tmp_line_cur, text_check_line, a);
+ tmp_line_cur += a;
}
+ *tmp_line_cur = '\t';
+ tmp_line_cur++;
+ a += j;
}
- }
- if (!number) { //found all number of space to equal a tab
- a = a + (st->tabnumber - 1);
- extra = extra + 1;
- }
- }
-
- if (extra > 0) { //got tabs make malloc and do what you have to do
- new_line = MEM_callocN(text_check_line_len - (((st->tabnumber * extra) - extra) - 1), "Converted_Line");
- extra = 0; //reuse vars
- for (a = 0; a < text_check_line_len; a++) {
- number = 0;
- for (j = 0; j < (size_t)st->tabnumber; j++) {
- if ((a + j) <= text_check_line_len) { //check to make sure we are not pass the end of the line
- if (text_check_line[a + j] != ' ') {
- number = 1;
- }
+ else {
+ if (tmp_line_cur != tmp_line) {
+ memcpy(tmp_line_cur, &text_check_line[a], j);
+ tmp_line_cur += j;
}
+ a += j;
}
-
- if (!number) { //found all number of space to equal a tab
- new_line[extra] = '\t';
- a = a + (st->tabnumber - 1);
- extra++;
-
- }
- else { //not adding a tab
- new_line[extra] = text_check_line[a];
- extra++;
+ }
+ else {
+ size_t len = BLI_str_utf8_size_safe(&text_check_line[a]);
+ if (tmp_line_cur != tmp_line) {
+ memcpy(tmp_line_cur, &text_check_line[a], len);
+ tmp_line_cur += len;
}
+ a += len;
}
- new_line[extra] = '\0';
- // put new_line in the tmp->line spot still need to try and set the curc correctly
- if (tmp->line) MEM_freeN(tmp->line);
- if (tmp->format) MEM_freeN(tmp->format);
-
- tmp->line = new_line;
- tmp->len = strlen(new_line);
+ }
+
+ if (tmp_line_cur != tmp_line) {
+ *tmp_line_cur = '\0';
+
+#ifndef NDEBUG
+ BLI_assert(tmp_line_cur - tmp_line <= max_len);
+
+ flatten_string(st, &fs, tmp_line);
+ BLI_assert(STREQ(fs.buf, tmp->line));
+ flatten_string_free(&fs);
+#endif
+
+ /* Put new_line in the tmp->line spot still need to try and set the curc correctly. */
+ if (tmp->line)
+ MEM_freeN(tmp->line);
+ if (tmp->format)
+ MEM_freeN(tmp->format);
+
+ tmp->line = BLI_strdup(tmp_line);
+ tmp->len = strlen(tmp_line);
tmp->format = NULL;
}
}
+
+ MEM_freeN(tmp_line);
}
text_update_edited(text);