From 431fd3dfd7559967104f7dd4bbc101e7c0c74761 Mon Sep 17 00:00:00 2001 From: acanas Date: Wed, 24 Nov 2021 12:45:32 +0100 Subject: [PATCH] Version 21.60.1: Nov 24, 2021 Code optimization in insertion of links in a string. --- swad_changelog.h | 3 +- swad_string.c | 134 +++++++++++++++++++++++++++-------------------- 2 files changed, 79 insertions(+), 58 deletions(-) diff --git a/swad_changelog.h b/swad_changelog.h index 2a9ee3a68..7d5a21084 100644 --- a/swad_changelog.h +++ b/swad_changelog.h @@ -602,13 +602,14 @@ TODO: FIX BUG, URGENT! En las fechas como par TODO: En las encuestas, que los estudiantes no puedan ver los resultados hasta que no finalice el plazo. */ -#define Log_PLATFORM_VERSION "SWAD 21.60 (2021-11-24)" +#define Log_PLATFORM_VERSION "SWAD 21.60.1 (2021-11-24)" #define CSS_FILE "swad21.59.css" #define JS_FILE "swad21.59.js" /* TODO: Rename CENTRE to CENTER in help wiki. TODO: Rename ASSESSMENT.Announcements to ASSESSMENT.Calls_for_exams + Version 21.60.1: Nov 24, 2021 Code optimization in insertion of links in a string. (319233 lines) Version 21.60: Nov 24, 2021 Code refactoring inserting links in a string. (319208 lines) Version 21.59: Nov 22, 2021 Code refactoring in timeline. (319149 lines) Version 21.58.2: Nov 21, 2021 Code refactoring in timeline. (319135 lines) diff --git a/swad_string.c b/swad_string.c index d291d2d75..c0f4e9077 100644 --- a/swad_string.c +++ b/swad_string.c @@ -34,6 +34,7 @@ #include // For malloc and free #include // For string functions +#include "swad_database.h" // TODO: Remove #include "swad_error.h" #include "swad_form.h" #include "swad_global.h" @@ -85,14 +86,14 @@ static void Str_CreateFirstLink (struct Str_Link **Link, static void Str_CreateNextLink (struct Str_Link **Link, struct Str_Link **LastLink); static void Str_FreeLinks (struct Str_Link *LastLink); -static bool Str_CheckURL (char **PtrSrc, - struct Str_Link **Link, - struct Str_Link **LastLink, - size_t MaxCharsURLOnScreen); -static bool Str_CheckNickname (char **PtrSrc, - struct Str_Link **Link, - struct Str_Link **LastLink); -static void Str_InsertSubstring (const struct Str_Substring *PtrSrc,char **PtrDst); +static Str_LinkType_t Str_CheckURL (char **PtrSrc, + struct Str_Link **Link, + struct Str_Link **LastLink, + size_t MaxCharsURLOnScreen); +static Str_LinkType_t Str_CheckNickname (char **PtrSrc, + struct Str_Link **Link, + struct Str_Link **LastLink); +static void Str_CopySubstring (const struct Str_Substring *PtrSrc,char **PtrDst); static unsigned Str_GetNextASCIICharFromStr (const char *Ptr,unsigned char *Ch); @@ -197,16 +198,15 @@ void Str_InsertLinks (char *Txt,unsigned long MaxLength,size_t MaxCharsURLOnScre for (PtrSrc = Txt; *PtrSrc;) - { - Link->Type = Str_LINK_UNKNOWN; - /* Check if the next char is the start of a URL */ - if (!Str_CheckURL (&PtrSrc,&Link,&LastLink,MaxCharsURLOnScreen)) + if ((Link->Type = Str_CheckURL (&PtrSrc, + &Link,&LastLink, + MaxCharsURLOnScreen)) == Str_LINK_UNKNOWN) /* Check if the next char is the start of a nickname */ - if (!Str_CheckNickname (&PtrSrc,&Link,&LastLink)) + if ((Link->Type = Str_CheckNickname (&PtrSrc, + &Link,&LastLink)) == Str_LINK_UNKNOWN) /* The next char is not the start of a URL or a nickname */ PtrSrc++; - } /**********************************************************************/ /***** If there are one or more links (URLs or nicknames) in text *****/ @@ -216,7 +216,7 @@ void Str_InsertLinks (char *Txt,unsigned long MaxLength,size_t MaxCharsURLOnScre /***** Insert links from end to start of text, only if there is enough space available in text *****/ TxtLength = strlen (Txt); - if (TxtLength + LastLink->AddedLengthUntilHere <= MaxLength) + if (TxtLength + LastLink->AddedLengthUntilHere <= MaxLength) for (Link = LastLink; Link; Link = Link->Prev) @@ -250,8 +250,8 @@ void Str_InsertLinks (char *Txt,unsigned long MaxLength,size_t MaxCharsURLOnScre i++) *PtrDst-- = *PtrSrc--; - /***** Step 2: Insert thirs part of anchor *****/ - Str_InsertSubstring (Anchor3,&PtrDst); + /***** Step 2: Copy third part of anchor *****/ + Str_CopySubstring (Anchor3,&PtrDst); /***** Step 3: Move forward the link (URL or nickname) to be shown on screen *****/ @@ -259,7 +259,7 @@ void Str_InsertLinks (char *Txt,unsigned long MaxLength,size_t MaxCharsURLOnScre { case Str_LINK_URL: if (Link->URLorNick.Len <= MaxCharsURLOnScreen) - Str_InsertSubstring (&Link->URLorNick,&PtrDst); + Str_CopySubstring (&Link->URLorNick,&PtrDst); else { /* Limit the length of URL */ @@ -268,27 +268,27 @@ void Str_InsertLinks (char *Txt,unsigned long MaxLength,size_t MaxCharsURLOnScre strncpy (Limited.Str,Link->URLorNick.Str,Link->URLorNick.Len); Limited.Str[Link->URLorNick.Len] = '\0'; Limited.Len = Str_LimitLengthHTMLStr (Limited.Str,MaxCharsURLOnScreen); - Str_InsertSubstring (&Limited,&PtrDst); + Str_CopySubstring (&Limited,&PtrDst); free (Limited.Str); } break; case Str_LINK_NICK: - Str_InsertSubstring (&Link->URLorNick,&PtrDst); + Str_CopySubstring (&Link->URLorNick,&PtrDst); break; default: break; } - /***** Step 4: Insert second part of anchor *****/ - Str_InsertSubstring (Anchor2,&PtrDst); + /***** Step 4: Copy second part of anchor *****/ + Str_CopySubstring (Anchor2,&PtrDst); - /***** Step 5: Insert link into directive A + /***** Step 5: Copy link into directive A (it's mandatory to do the copy in reverse order to avoid overwriting source URL or nickname) *****/ - Str_InsertSubstring (&Link->URLorNick,&PtrDst); + Str_CopySubstring (&Link->URLorNick,&PtrDst); - /***** Step 6: Insert first part of anchor *****/ - Str_InsertSubstring (Anchor1,&PtrDst); + /***** Step 6: Copy first part of anchor *****/ + Str_CopySubstring (Anchor1,&PtrDst); } } @@ -354,16 +354,17 @@ static void Str_FreeLinks (struct Str_Link *LastLink) /**************************** Check if a URL found ***************************/ -static bool Str_CheckURL (char **PtrSrc, - struct Str_Link **Link, - struct Str_Link **LastLink, - size_t MaxCharsURLOnScreen) +static Str_LinkType_t Str_CheckURL (char **PtrSrc, + struct Str_Link **Link, + struct Str_Link **LastLink, + size_t MaxCharsURLOnScreen) { unsigned char Ch; size_t NumChars1; size_t NumChars2; char *PtrEnd; // Pointer to the last char of URL/nickname in original text char *Limited; // URL displayed on screen (may be shorter than actual length) + Str_LinkType_t Type = Str_LINK_UNKNOWN; /***** Check if the next char is the start of a URL *****/ if (tolower ((int) *(*PtrSrc)) == (int) 'h') @@ -380,7 +381,7 @@ static bool Str_CheckURL (char **PtrSrc, { if (*++(*PtrSrc) == '/') // http:/... if (*++(*PtrSrc) == '/') // http://... - (*Link)->Type = Str_LINK_URL; + Type = Str_LINK_URL; } else if (tolower ((int) *(*PtrSrc)) == (int) 's') // https... { @@ -388,13 +389,13 @@ static bool Str_CheckURL (char **PtrSrc, { if (*++(*PtrSrc) == '/') // https:/... if (*++(*PtrSrc) == '/') // https://... - (*Link)->Type = Str_LINK_URL; + Type = Str_LINK_URL; } } } } } - if ((*Link)->Type == Str_LINK_URL) + if (Type == Str_LINK_URL) { /***** Find URL end *****/ (*PtrSrc)++; // Points to first character after http:// or https:// @@ -441,22 +442,21 @@ static bool Str_CheckURL (char **PtrSrc, /***** Create next link *****/ Str_CreateNextLink (Link,LastLink); } - - return true; } - return false; + return Type; } /************************* Check if a nickname found *************************/ -static bool Str_CheckNickname (char **PtrSrc, - struct Str_Link **Link, - struct Str_Link **LastLink) +static Str_LinkType_t Str_CheckNickname (char **PtrSrc, + struct Str_Link **Link, + struct Str_Link **LastLink) { extern const char *Lan_STR_LANG_ID[1 + Lan_NUM_LANGUAGES]; size_t Length; char ParamsStr[Frm_MAX_BYTES_PARAMS_STR]; + Str_LinkType_t Type = Str_LINK_UNKNOWN; /***** Check if the next char is the start of a nickname *****/ if ((int) *(*PtrSrc) == (int) '@') @@ -484,9 +484,9 @@ static bool Str_CheckNickname (char **PtrSrc, Length = (*Link)->URLorNick.Len - 1; // Do not count the initial @ if (Length >= Nck_MIN_CHARS_NICK_WITHOUT_ARROBA && Length <= Nck_MAX_CHARS_NICK_WITHOUT_ARROBA) - (*Link)->Type = Str_LINK_NICK; + Type = Str_LINK_NICK; - if ((*Link)->Type == Str_LINK_NICK) + if (Type == Str_LINK_NICK) { /***** Create id for this form *****/ Gbl.Form.Num++; @@ -530,29 +530,49 @@ static bool Str_CheckNickname (char **PtrSrc, /***** Create next link *****/ Str_CreateNextLink (Link,LastLink); } - - return true; } - return false; + return Type; } /************** Copy source substring to destination, backwards **************/ -static void Str_InsertSubstring (const struct Str_Substring *PtrSrc,char **PtrDst) +static void Str_CopySubstring (const struct Str_Substring *Src,char **Dst) { - size_t i; - char *PtrSrcStart; - char *PtrDstStart; - size_t Len = PtrSrc->Len; - - *PtrDst -= Len; // Update destination pointer - PtrSrcStart = PtrSrc->Str; - PtrDstStart = *PtrDst + 1; - for (i = 0; - i < Len; - i++) - *PtrDstStart++ = *PtrSrcStart++; + char *PtrSrc; // Local pointer optimizes access to memory + char *PtrDst; // Local pointer optimizes access to memory + size_t Len = Src->Len; + /* + Example: Src->Str = "Len = 9 + Src->Str + | + _v_________________ + |<|a|_|h|r|e|f|=|"| + | | | | | | | | | + \ \ \ \ \ \ \ \ \ + \ \ \ \ \ \ \ \ \ + \ \ \ \ \ \ \ \ \ + \ \ \ \ \ \ \ \ \ + \ \ \ \ \ \ \ \ \ + | | | | | | | | | + _______v_v_v_v_v_v_v_v_v_____________ + |_|_|_|<|a|_|h|r|e|f|=|"|_|_|_|_|_|_| + ^ ^ + | | + PtrDst (*Dst) + The copy has to be done backwards to avoid overwriting the original string + */ + if (Len) + { + PtrSrc = Src->Str + Len - 1; + PtrDst = *Dst; // Make a local copy of destination pointer + for (; + Len; + Len--) + *PtrDst-- = *PtrSrc--; + *Dst = PtrDst; // Update destination pointer + } } /*****************************************************************************/