From a3d7cf5d80246d8b833421ba071f9e4a4f8ff4a8 Mon Sep 17 00:00:00 2001 From: Rob Swindell <rob@synchro.net> Date: Mon, 5 Dec 2022 11:01:27 -0800 Subject: [PATCH] Include blank lines in messages edited with internal editor Needed a version of strListSplit() that doesn't treat consecutive delimiters (e.g. "\r\n\r\n") as a single delimiter: so introducing strListDivide(). Like strListSplit(), strListDivide() modifies the input string (replacing first occurrences of delimiter with NUL). Since we don't want "\r\n" to be counted as 2 lines, we need to just split/divide on '\n' and then truncate any line endings (i.e. '\r') chars off the ends of the split strings. Reported by phigan in #synchronet --- src/sbbs3/writemsg.cpp | 3 ++- src/xpdev/str_list.c | 33 +++++++++++++++++++++++++++++++++ src/xpdev/str_list.h | 6 +++++- 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/src/sbbs3/writemsg.cpp b/src/sbbs3/writemsg.cpp index e740547bf9..3013d946a9 100644 --- a/src/sbbs3/writemsg.cpp +++ b/src/sbbs3/writemsg.cpp @@ -931,7 +931,7 @@ ulong sbbs_t::msgeditor(char *buf, const char *top, char *title) maxlines=cfg.level_linespermsg[useron.level]; - if((str = strListSplit(NULL, buf, "\r\n")) == NULL) { + if((str = strListDivide(NULL, buf, "\n")) == NULL) { errormsg(WHERE,ERR_ALLOC,"msgeditor",sizeof(char *)*(maxlines+1)); return(0); } @@ -939,6 +939,7 @@ ulong sbbs_t::msgeditor(char *buf, const char *top, char *title) while(lines > maxlines) free(str[--lines]); str[lines] = NULL; + strListTruncateTrailingLineEndings(str); if(lines) bprintf("\r\nMessage editor: Read in %d lines\r\n",lines); bprintf(text[EnterMsgNow],maxlines); diff --git a/src/xpdev/str_list.c b/src/xpdev/str_list.c index aeace2d05c..f2bd837284 100644 --- a/src/xpdev/str_list.c +++ b/src/xpdev/str_list.c @@ -370,6 +370,7 @@ char* strListInsertFormat(str_list_t* list, size_t index, const char* format, .. } #endif +// Consecutive delimiters are treated as one (empty strings are skipped) str_list_t strListSplit(str_list_t* lp, char* str, const char* delimit) { size_t count; @@ -416,6 +417,38 @@ str_list_t strListSplitCopy(str_list_t* list, const char* str, const char* delim return(new_list); } +// Consecutive delimiters are treated as multiple (empty strings are supported) +str_list_t strListDivide(str_list_t* lp, char* str, const char* delimit) +{ + size_t count; + char* p = str; + char* np; + char* end; + str_list_t list; + + if(str == NULL || delimit == NULL) + return NULL; + + if(lp == NULL) { + if((list = strListInit()) == NULL) + return NULL; + lp = &list; + count = 0; + } else + count = strListCount(*lp); + + end = str + strlen(str); + while(p < end) { + np = p + strcspn(p, delimit); + *np = '\0'; + strListAppend(lp, p, count++); + p = np + 1; + } + + return *lp; +} + + size_t strListMerge(str_list_t* list, str_list_t add_list) { size_t i; diff --git a/src/xpdev/str_list.h b/src/xpdev/str_list.h index a5994b359e..8bc96477af 100644 --- a/src/xpdev/str_list.h +++ b/src/xpdev/str_list.h @@ -100,12 +100,16 @@ DLLEXPORT BOOL strListSwap(const str_list_t, size_t index1, size_t index2); #define strListPop(list) strListRemove(list, STR_LIST_LAST_INDEX) /* Add to an existing or new string list by splitting specified string (str) */ -/* into multiple strings, separated by one of the delimit characters */ +/* into multiple (non-empty) strings, separated by one or more of the delimit characters */ DLLEXPORT str_list_t strListSplit(str_list_t*, char* str, const char* delimit); /* Same as above, but copies str to temporary heap buffer first */ DLLEXPORT str_list_t strListSplitCopy(str_list_t*, const char* str, const char* delimit); +/* Add to an existing or new string list by splitting specified string (str) */ +/* into multiple (possibly empty) strings, separated by one of the delimit characters */ +DLLEXPORT str_list_t strListDivide(str_list_t*, char* str, const char* delimit); + /* Merge 2 string lists (no copying of string data) */ DLLEXPORT size_t strListMerge(str_list_t*, str_list_t append_list); -- GitLab