mirror of
https://github.com/acanas/swad-core.git
synced 2024-06-01 22:35:28 +02:00
Version 21.60.1: Nov 24, 2021 Code optimization in insertion of links in a string.
This commit is contained in:
parent
14f64fd450
commit
431fd3dfd7
|
@ -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)
|
||||||
|
|
134
swad_string.c
134
swad_string.c
|
@ -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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
Loading…
Reference in New Issue
Block a user