Version 21.60.1: Nov 24, 2021 Code optimization in insertion of links in a string.

This commit is contained in:
acanas 2021-11-24 12:45:32 +01:00
parent 14f64fd450
commit 431fd3dfd7
2 changed files with 79 additions and 58 deletions

View File

@ -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. 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 CSS_FILE "swad21.59.css"
#define JS_FILE "swad21.59.js" #define JS_FILE "swad21.59.js"
/* /*
TODO: Rename CENTRE to CENTER in help wiki. TODO: Rename CENTRE to CENTER in help wiki.
TODO: Rename ASSESSMENT.Announcements to ASSESSMENT.Calls_for_exams 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.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.59: Nov 22, 2021 Code refactoring in timeline. (319149 lines)
Version 21.58.2: Nov 21, 2021 Code refactoring in timeline. (319135 lines) Version 21.58.2: Nov 21, 2021 Code refactoring in timeline. (319135 lines)

View File

@ -34,6 +34,7 @@
#include <stdlib.h> // For malloc and free #include <stdlib.h> // For malloc and free
#include <string.h> // For string functions #include <string.h> // For string functions
#include "swad_database.h" // TODO: Remove
#include "swad_error.h" #include "swad_error.h"
#include "swad_form.h" #include "swad_form.h"
#include "swad_global.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, static void Str_CreateNextLink (struct Str_Link **Link,
struct Str_Link **LastLink); struct Str_Link **LastLink);
static void Str_FreeLinks (struct Str_Link *LastLink); static void Str_FreeLinks (struct Str_Link *LastLink);
static bool Str_CheckURL (char **PtrSrc, static Str_LinkType_t Str_CheckURL (char **PtrSrc,
struct Str_Link **Link, struct Str_Link **Link,
struct Str_Link **LastLink, struct Str_Link **LastLink,
size_t MaxCharsURLOnScreen); size_t MaxCharsURLOnScreen);
static bool Str_CheckNickname (char **PtrSrc, static Str_LinkType_t Str_CheckNickname (char **PtrSrc,
struct Str_Link **Link, struct Str_Link **Link,
struct Str_Link **LastLink); struct Str_Link **LastLink);
static void Str_InsertSubstring (const struct Str_Substring *PtrSrc,char **PtrDst); static void Str_CopySubstring (const struct Str_Substring *PtrSrc,char **PtrDst);
static unsigned Str_GetNextASCIICharFromStr (const char *Ptr,unsigned char *Ch); 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; for (PtrSrc = Txt;
*PtrSrc;) *PtrSrc;)
{
Link->Type = Str_LINK_UNKNOWN;
/* Check if the next char is the start of a URL */ /* 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 */ /* 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 */ /* The next char is not the start of a URL or a nickname */
PtrSrc++; PtrSrc++;
}
/**********************************************************************/ /**********************************************************************/
/***** If there are one or more links (URLs or nicknames) in text *****/ /***** 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, /***** Insert links from end to start of text,
only if there is enough space available in text *****/ only if there is enough space available in text *****/
TxtLength = strlen (Txt); TxtLength = strlen (Txt);
if (TxtLength + LastLink->AddedLengthUntilHere <= MaxLength) if (TxtLength + LastLink->AddedLengthUntilHere <= MaxLength)
for (Link = LastLink; for (Link = LastLink;
Link; Link;
Link = Link->Prev) Link = Link->Prev)
@ -250,8 +250,8 @@ void Str_InsertLinks (char *Txt,unsigned long MaxLength,size_t MaxCharsURLOnScre
i++) i++)
*PtrDst-- = *PtrSrc--; *PtrDst-- = *PtrSrc--;
/***** Step 2: Insert thirs part of anchor *****/ /***** Step 2: Copy third part of anchor *****/
Str_InsertSubstring (Anchor3,&PtrDst); Str_CopySubstring (Anchor3,&PtrDst);
/***** Step 3: Move forward the link (URL or nickname) /***** Step 3: Move forward the link (URL or nickname)
to be shown on screen *****/ to be shown on screen *****/
@ -259,7 +259,7 @@ void Str_InsertLinks (char *Txt,unsigned long MaxLength,size_t MaxCharsURLOnScre
{ {
case Str_LINK_URL: case Str_LINK_URL:
if (Link->URLorNick.Len <= MaxCharsURLOnScreen) if (Link->URLorNick.Len <= MaxCharsURLOnScreen)
Str_InsertSubstring (&Link->URLorNick,&PtrDst); Str_CopySubstring (&Link->URLorNick,&PtrDst);
else else
{ {
/* Limit the length of URL */ /* 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); strncpy (Limited.Str,Link->URLorNick.Str,Link->URLorNick.Len);
Limited.Str[Link->URLorNick.Len] = '\0'; Limited.Str[Link->URLorNick.Len] = '\0';
Limited.Len = Str_LimitLengthHTMLStr (Limited.Str,MaxCharsURLOnScreen); Limited.Len = Str_LimitLengthHTMLStr (Limited.Str,MaxCharsURLOnScreen);
Str_InsertSubstring (&Limited,&PtrDst); Str_CopySubstring (&Limited,&PtrDst);
free (Limited.Str); free (Limited.Str);
} }
break; break;
case Str_LINK_NICK: case Str_LINK_NICK:
Str_InsertSubstring (&Link->URLorNick,&PtrDst); Str_CopySubstring (&Link->URLorNick,&PtrDst);
break; break;
default: default:
break; break;
} }
/***** Step 4: Insert second part of anchor *****/ /***** Step 4: Copy second part of anchor *****/
Str_InsertSubstring (Anchor2,&PtrDst); 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 (it's mandatory to do the copy in reverse order
to avoid overwriting source URL or nickname) *****/ to avoid overwriting source URL or nickname) *****/
Str_InsertSubstring (&Link->URLorNick,&PtrDst); Str_CopySubstring (&Link->URLorNick,&PtrDst);
/***** Step 6: Insert first part of anchor *****/ /***** Step 6: Copy first part of anchor *****/
Str_InsertSubstring (Anchor1,&PtrDst); Str_CopySubstring (Anchor1,&PtrDst);
} }
} }
@ -354,16 +354,17 @@ static void Str_FreeLinks (struct Str_Link *LastLink)
/**************************** Check if a URL found ***************************/ /**************************** Check if a URL found ***************************/
static bool Str_CheckURL (char **PtrSrc, static Str_LinkType_t Str_CheckURL (char **PtrSrc,
struct Str_Link **Link, struct Str_Link **Link,
struct Str_Link **LastLink, struct Str_Link **LastLink,
size_t MaxCharsURLOnScreen) size_t MaxCharsURLOnScreen)
{ {
unsigned char Ch; unsigned char Ch;
size_t NumChars1; size_t NumChars1;
size_t NumChars2; size_t NumChars2;
char *PtrEnd; // Pointer to the last char of URL/nickname in original text 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) 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 *****/ /***** Check if the next char is the start of a URL *****/
if (tolower ((int) *(*PtrSrc)) == (int) 'h') if (tolower ((int) *(*PtrSrc)) == (int) 'h')
@ -380,7 +381,7 @@ static bool Str_CheckURL (char **PtrSrc,
{ {
if (*++(*PtrSrc) == '/') // http:/... if (*++(*PtrSrc) == '/') // http:/...
if (*++(*PtrSrc) == '/') // http://... if (*++(*PtrSrc) == '/') // http://...
(*Link)->Type = Str_LINK_URL; Type = Str_LINK_URL;
} }
else if (tolower ((int) *(*PtrSrc)) == (int) 's') // https... else if (tolower ((int) *(*PtrSrc)) == (int) 's') // https...
{ {
@ -388,13 +389,13 @@ static bool Str_CheckURL (char **PtrSrc,
{ {
if (*++(*PtrSrc) == '/') // https:/... if (*++(*PtrSrc) == '/') // https:/...
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 *****/ /***** Find URL end *****/
(*PtrSrc)++; // Points to first character after http:// or https:// (*PtrSrc)++; // Points to first character after http:// or https://
@ -441,22 +442,21 @@ static bool Str_CheckURL (char **PtrSrc,
/***** Create next link *****/ /***** Create next link *****/
Str_CreateNextLink (Link,LastLink); Str_CreateNextLink (Link,LastLink);
} }
return true;
} }
return false; return Type;
} }
/************************* Check if a nickname found *************************/ /************************* Check if a nickname found *************************/
static bool Str_CheckNickname (char **PtrSrc, static Str_LinkType_t Str_CheckNickname (char **PtrSrc,
struct Str_Link **Link, struct Str_Link **Link,
struct Str_Link **LastLink) struct Str_Link **LastLink)
{ {
extern const char *Lan_STR_LANG_ID[1 + Lan_NUM_LANGUAGES]; extern const char *Lan_STR_LANG_ID[1 + Lan_NUM_LANGUAGES];
size_t Length; size_t Length;
char ParamsStr[Frm_MAX_BYTES_PARAMS_STR]; 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 *****/ /***** Check if the next char is the start of a nickname *****/
if ((int) *(*PtrSrc) == (int) '@') if ((int) *(*PtrSrc) == (int) '@')
@ -484,9 +484,9 @@ static bool Str_CheckNickname (char **PtrSrc,
Length = (*Link)->URLorNick.Len - 1; // Do not count the initial @ Length = (*Link)->URLorNick.Len - 1; // Do not count the initial @
if (Length >= Nck_MIN_CHARS_NICK_WITHOUT_ARROBA && if (Length >= Nck_MIN_CHARS_NICK_WITHOUT_ARROBA &&
Length <= Nck_MAX_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 *****/ /***** Create id for this form *****/
Gbl.Form.Num++; Gbl.Form.Num++;
@ -530,29 +530,49 @@ static bool Str_CheckNickname (char **PtrSrc,
/***** Create next link *****/ /***** Create next link *****/
Str_CreateNextLink (Link,LastLink); Str_CreateNextLink (Link,LastLink);
} }
return true;
} }
return false; return Type;
} }
/************** Copy source substring to destination, backwards **************/ /************** 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 *PtrSrc; // Local pointer optimizes access to memory
char *PtrSrcStart; char *PtrDst; // Local pointer optimizes access to memory
char *PtrDstStart; size_t Len = Src->Len;
size_t Len = PtrSrc->Len; /*
Example: Src->Str = "<a href=\""
*PtrDst -= Len; // Update destination pointer Src->Len = 9
PtrSrcStart = PtrSrc->Str; Src->Str
PtrDstStart = *PtrDst + 1; |
for (i = 0; _v_________________
i < Len; |<|a|_|h|r|e|f|=|"|
i++) | | | | | | | | |
*PtrDstStart++ = *PtrSrcStart++; \ \ \ \ \ \ \ \ \
\ \ \ \ \ \ \ \ \
\ \ \ \ \ \ \ \ \
\ \ \ \ \ \ \ \ \
\ \ \ \ \ \ \ \ \
| | | | | | | | |
_______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
}
} }
/*****************************************************************************/ /*****************************************************************************/