From 96ac3c2f7d600a315dd88f3221a902178826567a Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 17 Sep 2014 19:28:46 +1000 Subject: Text Editor: reload missed adding new-line Logic for load/reload was duplicated, Fix T28087 missed reload. De-duplicate, also replace stat -> BLI_stat --- source/blender/blenkernel/intern/text.c | 180 ++++++++++++--------------- source/blender/editors/space_text/text_ops.c | 4 +- 2 files changed, 81 insertions(+), 103 deletions(-) diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c index 4cd85fb342e..86371ba3c80 100644 --- a/source/blender/blenkernel/intern/text.c +++ b/source/blender/blenkernel/intern/text.c @@ -267,14 +267,77 @@ static void cleanup_textline(TextLine *tl) tl->len += txt_extended_ascii_as_utf8(&tl->line); } +/** + * used for load and reload (unlike txt_insert_buf) + * assumes all fields are empty + */ +static void text_from_buf(Text *text, const unsigned char *buffer, const int len) +{ + int i, llen; + + BLI_assert(BLI_listbase_is_empty(&text->lines)); + + text->nlines = 0; + llen = 0; + for (i = 0; i < len; i++) { + if (buffer[i] == '\n') { + TextLine *tmp; + + tmp = (TextLine *) MEM_mallocN(sizeof(TextLine), "textline"); + tmp->line = (char *) MEM_mallocN(llen + 1, "textline_string"); + tmp->format = NULL; + + if (llen) memcpy(tmp->line, &buffer[i - llen], llen); + tmp->line[llen] = 0; + tmp->len = llen; + + cleanup_textline(tmp); + + BLI_addtail(&text->lines, tmp); + text->nlines++; + + llen = 0; + continue; + } + llen++; + } + + /* create new line in cases: + * - rest of line (if last line in file hasn't got \n terminator). + * in this case content of such line would be used to fill text line buffer + * - file is empty. in this case new line is needed to start editing from. + * - last characted in buffer is \n. in this case new line is needed to + * deal with newline at end of file. (see [#28087]) (sergey) */ + if (llen != 0 || text->nlines == 0 || buffer[len - 1] == '\n') { + TextLine *tmp; + + tmp = (TextLine *) MEM_mallocN(sizeof(TextLine), "textline"); + tmp->line = (char *) MEM_mallocN(llen + 1, "textline_string"); + tmp->format = NULL; + + if (llen) memcpy(tmp->line, &buffer[i - llen], llen); + + tmp->line[llen] = 0; + tmp->len = llen; + + cleanup_textline(tmp); + + BLI_addtail(&text->lines, tmp); + text->nlines++; + } + + text->curl = text->sell = text->lines.first; + text->curc = text->selc = 0; +} + int BKE_text_reload(Text *text) { FILE *fp; - int i, llen, len; + int len; unsigned char *buffer; TextLine *tmp; char str[FILE_MAX]; - struct stat st; + BLI_stat_t st; if (!text || !text->name) return 0; @@ -299,13 +362,12 @@ int BKE_text_reload(Text *text) /* clear undo buffer */ MEM_freeN(text->undo_buf); init_undo_text(text); - + fseek(fp, 0L, SEEK_END); len = ftell(fp); fseek(fp, 0L, SEEK_SET); - text->undo_pos = -1; - + buffer = MEM_mallocN(len, "text_buffer"); // under windows fread can return less then len bytes because // of CR stripping @@ -313,51 +375,11 @@ int BKE_text_reload(Text *text) fclose(fp); - stat(str, &st); + BLI_stat(str, &st); text->mtime = st.st_mtime; - - text->nlines = 0; - llen = 0; - for (i = 0; i < len; i++) { - if (buffer[i] == '\n') { - tmp = (TextLine *) MEM_mallocN(sizeof(TextLine), "textline"); - tmp->line = (char *) MEM_mallocN(llen + 1, "textline_string"); - tmp->format = NULL; - if (llen) memcpy(tmp->line, &buffer[i - llen], llen); - tmp->line[llen] = 0; - tmp->len = llen; - - cleanup_textline(tmp); + text_from_buf(text, buffer, len); - BLI_addtail(&text->lines, tmp); - text->nlines++; - - llen = 0; - continue; - } - llen++; - } - - if (llen != 0 || text->nlines == 0) { - tmp = (TextLine *) MEM_mallocN(sizeof(TextLine), "textline"); - tmp->line = (char *) MEM_mallocN(llen + 1, "textline_string"); - tmp->format = NULL; - - if (llen) memcpy(tmp->line, &buffer[i - llen], llen); - - tmp->line[llen] = 0; - tmp->len = llen; - - cleanup_textline(tmp); - - BLI_addtail(&text->lines, tmp); - text->nlines++; - } - - text->curl = text->sell = text->lines.first; - text->curc = text->selc = 0; - MEM_freeN(buffer); return 1; } @@ -365,12 +387,11 @@ int BKE_text_reload(Text *text) Text *BKE_text_load_ex(Main *bmain, const char *file, const char *relpath, const bool is_internal) { FILE *fp; - int i, llen, len; + int len; unsigned char *buffer; - TextLine *tmp; Text *ta; char str[FILE_MAX]; - struct stat st; + BLI_stat_t st; BLI_strncpy(str, file, FILE_MAX); if (relpath) /* can be NULL (bg mode) */ @@ -388,10 +409,6 @@ Text *BKE_text_load_ex(Main *bmain, const char *file, const char *relpath, const if ((U.flag & USER_TXT_TABSTOSPACES_DISABLE) == 0) ta->flags = TXT_TABSTOSPACES; - fseek(fp, 0L, SEEK_END); - len = ftell(fp); - fseek(fp, 0L, SEEK_SET); - if (is_internal == false) { ta->name = MEM_mallocN(strlen(file) + 1, "text_name"); strcpy(ta->name, file); @@ -400,7 +417,12 @@ Text *BKE_text_load_ex(Main *bmain, const char *file, const char *relpath, const ta->flags |= TXT_ISMEM | TXT_ISDIRTY; } + /* clear undo buffer */ init_undo_text(ta); + + fseek(fp, 0L, SEEK_END); + len = ftell(fp); + fseek(fp, 0L, SEEK_SET); buffer = MEM_mallocN(len, "text_buffer"); // under windows fread can return less then len bytes because @@ -409,56 +431,10 @@ Text *BKE_text_load_ex(Main *bmain, const char *file, const char *relpath, const fclose(fp); - stat(str, &st); + BLI_stat(str, &st); ta->mtime = st.st_mtime; - ta->nlines = 0; - llen = 0; - for (i = 0; i < len; i++) { - if (buffer[i] == '\n') { - tmp = (TextLine *) MEM_mallocN(sizeof(TextLine), "textline"); - tmp->line = (char *) MEM_mallocN(llen + 1, "textline_string"); - tmp->format = NULL; - - if (llen) memcpy(tmp->line, &buffer[i - llen], llen); - tmp->line[llen] = 0; - tmp->len = llen; - - cleanup_textline(tmp); - - BLI_addtail(&ta->lines, tmp); - ta->nlines++; - - llen = 0; - continue; - } - llen++; - } - - /* create new line in cases: - * - rest of line (if last line in file hasn't got \n terminator). - * in this case content of such line would be used to fill text line buffer - * - file is empty. in this case new line is needed to start editing from. - * - last characted in buffer is \n. in this case new line is needed to - * deal with newline at end of file. (see [#28087]) (sergey) */ - if (llen != 0 || ta->nlines == 0 || buffer[len - 1] == '\n') { - tmp = (TextLine *) MEM_mallocN(sizeof(TextLine), "textline"); - tmp->line = (char *) MEM_mallocN(llen + 1, "textline_string"); - tmp->format = NULL; - - if (llen) memcpy(tmp->line, &buffer[i - llen], llen); - - tmp->line[llen] = 0; - tmp->len = llen; - - cleanup_textline(tmp); - - BLI_addtail(&ta->lines, tmp); - ta->nlines++; - } - - ta->curl = ta->sell = ta->lines.first; - ta->curc = ta->selc = 0; + text_from_buf(ta, buffer, len); MEM_freeN(buffer); diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c index 2e3d8d056e8..852edaac7dc 100644 --- a/source/blender/editors/space_text/text_ops.c +++ b/source/blender/editors/space_text/text_ops.c @@ -473,7 +473,9 @@ static void txt_write_file(Text *text, ReportList *reports) for (tmp = text->lines.first; tmp; tmp = tmp->next) { fputs(tmp->line, fp); - fputc('\n', fp); + if (tmp->next) { + fputc('\n', fp); + } } fclose(fp); -- cgit v1.2.3