PosNextTR)
{
// leave current position unchanged
fseek (FileSrc,CurPos,SEEK_SET);
return Str;
}
Str_FindStrInFile (FileSrc,">",Str_NO_SKIP_HTML_COMMENTS);
for (;;)
{
if ((Ch = Str_ReadCharAndSkipComments (FileSrc,Str_SKIP_HTML_COMMENTS)) == EOF) // Set pointer to '<' if not comment, or to first character after comment if comment
break;
/***** Skip directives except | *****/
if (Ch == (int) '<') // Start of directive, not a comment
{
/* Check if it's */
if (strcasecmp (Str_GetNextStrFromFileConvertingToLower (FileSrc,StrAux,1),"/"))
{ // It's not
Str_FindStrInFileBack (FileSrc,"<",Str_NO_SKIP_HTML_COMMENTS); // Skip directive backward
Str_FindStrInFile (FileSrc,">",Str_NO_SKIP_HTML_COMMENTS);
continue;
}
if (strcasecmp (Str_GetNextStrFromFileConvertingToLower (FileSrc,StrAux,1),"t"))
{ // It's not ",Str_NO_SKIP_HTML_COMMENTS);
continue;
}
if (strcasecmp (Str_GetNextStrFromFileConvertingToLower (FileSrc,StrAux,1),"d"))
{ // It's not ",Str_NO_SKIP_HTML_COMMENTS);
continue;
}
if (strcasecmp (Str_GetNextStrFromFileConvertingToLower (FileSrc,StrAux,1),">"))
{ // It's not
Str_FindStrInFileBack (FileSrc,"<",Str_NO_SKIP_HTML_COMMENTS); // Skip directive backward
Str_FindStrInFile (FileSrc,">",Str_NO_SKIP_HTML_COMMENTS);
continue;
}
break; // If it's
}
SpaceFound = false;
/***** Skip *****/
if (Ch == (int) '&')
{
/* Ver if no it's */
if (strcasecmp (Str_GetNextStrFromFileConvertingToLower (FileSrc,StrAux,1),"n"))
{ // It's not &n
Str_FindStrInFileBack (FileSrc,"&",Str_NO_SKIP_HTML_COMMENTS); // Back until &
Str_FindStrInFile (FileSrc,"&",Str_NO_SKIP_HTML_COMMENTS); // Skip &
}
else if (strcasecmp (Str_GetNextStrFromFileConvertingToLower (FileSrc,StrAux,1),"b"))
{ // It's not &nb
Str_FindStrInFileBack (FileSrc,"&",Str_NO_SKIP_HTML_COMMENTS); // Back until &
Str_FindStrInFile (FileSrc,"&",Str_NO_SKIP_HTML_COMMENTS); // Skip &
}
else if (strcasecmp (Str_GetNextStrFromFileConvertingToLower (FileSrc,StrAux,1),"s"))
{ // It's not &nbs
Str_FindStrInFileBack (FileSrc,"&",Str_NO_SKIP_HTML_COMMENTS); // Back until &
Str_FindStrInFile (FileSrc,"&",Str_NO_SKIP_HTML_COMMENTS); // Skip &
}
else if (strcasecmp (Str_GetNextStrFromFileConvertingToLower (FileSrc,StrAux,1),"p"))
{ // It's not  
Str_FindStrInFileBack (FileSrc,"&",Str_NO_SKIP_HTML_COMMENTS); // Back until &
Str_FindStrInFile (FileSrc,"&",Str_NO_SKIP_HTML_COMMENTS); // Skip &
}
else if (strcasecmp (Str_GetNextStrFromFileConvertingToLower (FileSrc,StrAux,1),";"))
{ // It's not
Str_FindStrInFileBack (FileSrc,"&",Str_NO_SKIP_HTML_COMMENTS); // Back until &
Str_FindStrInFile (FileSrc,"&",Str_NO_SKIP_HTML_COMMENTS); // Skip &
}
else // It's
SpaceFound = true;
}
/***** Skip spaces *****/
if (isspace (Ch) ||
Ch == 0xA0) // Unicode translation for
SpaceFound = true;
if (SpaceFound)
Ch = (int) ' ';
if (i < MaxLength)
Str[i++] = (char) Ch;
}
Str[i] = '\0';
return Str;
}
/*****************************************************************************/
/******************* Read the next N characters in a string ******************/
/*****************************************************************************/
/*
Read from the file FileSrc the next N characters converting them
to lowercase and store them in Str. Return a pointer to the string.
*/
char *Str_GetNextStrFromFileConvertingToLower (FILE *FileSrc,char *Str, int N)
{
int i,Ch;
for (i = 0;
i < N;
i++)
{
if ((Ch = fgetc (FileSrc)) == EOF)
break;
Str[i] = Str_ConvertToLowerLetter ((char) Ch);
}
Str[i] = '\0';
return Str;
}
/*****************************************************************************/
/********** Get from StrSrc into StrDst the next string until space **********/
/*****************************************************************************/
// Modifies *StrSrc
void Str_GetNextStringUntilSpace (const char **StrSrc,char *StrDst,size_t MaxLength)
{
size_t i = 0;
int Ch;
/***** Skip leading spaces *****/
do
{
if ((Ch = (int) **StrSrc) != 0)
(*StrSrc)++;
}
while (isspace (Ch) ||
Ch == 0xA0); // Unicode translation for
/***** Copy string while non-space characters *****/
while (Ch &&
!(isspace (Ch) ||
Ch == 0xA0)) // Unicode translation for
{
if (i < MaxLength)
StrDst[i++] = (char) Ch;
if ((Ch = (int) **StrSrc) != 0)
(*StrSrc)++;
}
StrDst[i] = '\0';
}
/*****************************************************************************/
/******* Get from StrSrc into StrDst the next string until separator *********/
/*****************************************************************************/
// Modifies *StrSrc
void Str_GetNextStringUntilSeparator (const char **StrSrc,char *StrDst,size_t MaxLength)
{
size_t i = 0;
int Ch;
/***** Skip separators *****/
do
{
if ((Ch = (int) **StrSrc) != 0)
(*StrSrc)++;
}
while (isspace (Ch) ||
Ch == 0xA0 || // Unicode translation for
Ch == (int) ',' ||
Ch == (int) ';');
/***** Copy string while no separator found *****/
while (Ch &&
!(isspace (Ch) ||
Ch == 0xA0 || // Unicode translation for
Ch == (int) ',' ||
Ch == (int) ';'))
{
if (i < MaxLength)
StrDst[i++] = (char) Ch;
if ((Ch = (int) **StrSrc) != 0)
(*StrSrc)++;
}
StrDst[i] = '\0';
}
/*****************************************************************************/
/********** Get from file FileSrc the next string until separator ************/
/*****************************************************************************/
void Str_GetNextStringFromFileUntilSeparator (FILE *FileSrc,char *StrDst)
{
int i = 0;
int Ch;
/***** Skip separators *****/
do
Ch = fgetc (FileSrc);
while (Ch != EOF &&
(isspace (Ch) ||
Ch == 0xA0 || // Unicode translation for
Ch == (int) ',' ||
Ch == (int) ';')); // Skip spaces, puntuación, etc.
/***** Copy string while no separator found *****/
while (Ch != EOF &&
!(isspace (Ch) ||
Ch == 0xA0 || // Unicode translation for
Ch == (int) ',' ||
Ch == (int) ';'))
{
if (i < ID_MAX_LENGTH_USR_ID)
StrDst[i++] = (char) Ch;
Ch = fgetc (FileSrc);
}
StrDst[i] = '\0';
}
/*****************************************************************************/
/********** Get from StrSrc into StrDst the next string until comma **********/
/*****************************************************************************/
// Modifies *StrSrc
// Leading spaces are not copied
// Trailing spaces are removed at end
void Str_GetNextStringUntilComma (const char **StrSrc,char *StrDst,size_t MaxLength)
{
int Ch;
char *Ptr;
size_t i = 0;
/***** Skip leading spaces and ',' *****/
Ch = (int) **StrSrc;
while (isspace (Ch) ||
Ch == 0xA0 || // Unicode translation for
Ch == (int) ',')
{
(*StrSrc)++;
Ch = (int) **StrSrc;
}
/***** Copy string until ',' or end *****/
Ptr = StrDst;
while (Ch && Ch != (int) ',')
{
if (i < MaxLength)
{
*Ptr++ = (char) Ch;
i++;
}
(*StrSrc)++;
Ch = (int) **StrSrc;
}
/***** Remove trailing spaces *****/
for (Ptr--;
Ptr >= *StrSrc;
Ptr--)
if (!(isspace ((int) *Ptr) ||
*Ptr == '\xA0')) // Unicode translation for
break;
*(Ptr+1) = '\0';
}
/*****************************************************************************/
/********** Replace special characters in a string for HTML codes ************/
/*****************************************************************************/
void Str_ReplaceSpecialCharByCodes (char *Str,unsigned long MaxLengthStr)
{
char *Ptr, *PtrSrc, *PtrDst, *PtrEndStr;
int LengthSpecStrDst;
unsigned long LengthStrDst = 0;
char StrSpecialChar[256];
/***** Make the conversion *****/
for (Ptr = Str;
*Ptr;)
{
if (*Ptr >= 32 && *Ptr <= 126) // If character is printable in english ==> is OK; else ==> convert to code
{
LengthStrDst++;
Ptr++;
}
else
{
sprintf (StrSpecialChar,"%u;",(unsigned char) *Ptr);
PtrEndStr = Str + strlen (Str);
LengthSpecStrDst = strlen (StrSpecialChar);
LengthStrDst += LengthSpecStrDst;
if (LengthStrDst > MaxLengthStr)
Lay_ShowErrorAndExit ("Not enough memory to convert the format of a string.");
for (PtrSrc = PtrEndStr,
PtrDst = PtrSrc + LengthSpecStrDst - 1;
PtrSrc >= Ptr + 1;
*PtrDst-- = *PtrSrc--); /* Copy backward from '\0' (included) */
/* Copy to appropiate place the special character string */
strncpy (Ptr,StrSpecialChar,LengthSpecStrDst);
/* Increment pointer to character after ';' */
Ptr += LengthSpecStrDst;
}
}
}
/*****************************************************************************/
/***************** Replace several spaces of a string for one ****************/
/*****************************************************************************/
void Str_ReplaceSeveralSpacesForOne (char *Str)
{
char *PtrSrc, *PtrDst;
bool PreviousWasSpace = false;
/***** Do the replacing *****/
for (PtrDst = PtrSrc = Str;
*PtrSrc;)
if (isspace ((int) *PtrSrc) ||
*PtrSrc == '\xA0') // Unicode translation for
{
if (!PreviousWasSpace)
*PtrDst++ = ' ';
PreviousWasSpace = true;
PtrSrc++;
}
else
{
PreviousWasSpace = false;
*PtrDst++ = *PtrSrc++;
}
*PtrDst = '\0';
}
/*****************************************************************************/
/************* Copy a string to another changing ' ' to '%20' ****************/
/*****************************************************************************/
void Str_CopyStrChangingSpaces (const char *StringWithSpaces,char *StringWithoutSpaces,unsigned MaxLength)
{
const char *PtrSrc;
char *PtrDst;
unsigned Length = 0;
for (PtrSrc = StringWithSpaces, PtrDst = StringWithoutSpaces;
*PtrSrc && Length <= MaxLength;
PtrSrc++)
if (*PtrSrc == ' ')
{
Length += 3;
if (Length <= MaxLength)
{
*PtrDst++ = '%';
*PtrDst++ = '2';
*PtrDst++ = '0';
}
}
else
{
Length++;
if (Length <= MaxLength)
*PtrDst++ = *PtrSrc;
}
*PtrDst = '\0';
if (Length > MaxLength)
Lay_ShowErrorAndExit ("Path is too long.");
}
/*****************************************************************************/
/* Convert string with a code (of group type, group, degree, etc.) to long **/
/*****************************************************************************/
// Return -1L if code not found in Str
long Str_ConvertStrCodToLongCod (const char *Str)
{
long Code;
if (Str[0] == '\0')
return -1L;
if (sscanf (Str,"%ld",&Code) != 1)
return -1L;
return Code;
}
/*****************************************************************************/
/**** Compute length of root (all except extension) of the name of a file ****/
/*****************************************************************************/
int Str_GetLengthRootFileName (const char *FileName)
{
return strlen (FileName) - strlen (strrchr (FileName,(int) '.'));
}
/*****************************************************************************/
/************** Get the name of a file from a complete path ******************/
/*****************************************************************************/
// Split a full path in path (without ending '/' ) and a file name
// PathWithoutFileName must have space for at least PATH_MAX+1 bytes
// FileName must have space for at least NAME_MAX+1 bytes
void Str_SplitFullPathIntoPathAndFileName (const char *FullPath,
char *PathWithoutFileName,
char *FileName)
{
const char *PtrFileName;
size_t LengthUntilFileName;
/***** Find the start of filename *****/
if ((PtrFileName = strrchr (FullPath,(int) '/')) != NULL)
PtrFileName++;
else if ((PtrFileName = strrchr (FullPath,(int) '\\')) != NULL)
PtrFileName++;
else
PtrFileName = FullPath;
/***** Get PathWithoutFileName *****/
LengthUntilFileName = (size_t) (PtrFileName - FullPath); // Last slash included
if (LengthUntilFileName > 1)
{
if (LengthUntilFileName > PATH_MAX)
{
strncpy (PathWithoutFileName,FullPath,PATH_MAX);
PathWithoutFileName[PATH_MAX] = '\0';
}
else
{
strncpy (PathWithoutFileName,FullPath,LengthUntilFileName - 1); // Do not copy ending slash
PathWithoutFileName[LengthUntilFileName - 1] = '\0';
}
}
else
PathWithoutFileName[0] = '\0';
/***** Get FileName *****/
strncpy (FileName,PtrFileName,NAME_MAX);
FileName[NAME_MAX] = '\0';
}
/*****************************************************************************/
/************** Check if the extension of a file is .Extension ***************/
/*****************************************************************************/
// Return true if FileName ends by .Extension
// Else return false
bool Str_FileIs (const char *FileName,const char *Extension)
{
int i,j;
/***** Only extensiones of 5 or less characters are valid. For example "zip", "html", "mhtml" *****/
if (strlen (Extension) > 5)
return false;
/***** Check the extension *****/
for (i = strlen (FileName) - 1, j = strlen (Extension) - 1;
i > 0 && j >= 0;
i--, j--)
if (Str_ConvertToLowerLetter (FileName[i]) != Str_ConvertToLowerLetter (Extension[j]))
return false;
if (j >= 0) /* If all the characters of the extension have not been checked
due to the name of the file is too short */
return false;
/***** Check the dot before the extension *****/
return (FileName[i] == '.');
}
/*****************************************************************************/
/**************** Check if the extension of a file is .html ******************/
/*****************************************************************************/
// Return true if FileName ends by .htm or .html
// Else return false
bool Str_FileIsHTML (const char *FileName)
{
if (Str_FileIs (FileName,"htm"))
return true;
return Str_FileIs (FileName,"html");
}
/*****************************************************************************/
/********************* Check if Path1 starts by Path2 ************************/
/*****************************************************************************/
bool Str_Path1BeginsByPath2 (const char *Path1,const char *Path2)
{
/* The string Path1 must start by the complete string Path2 */
while (*Path2)
if (*Path2++ != *Path1++)
return false;
/* The string Path1 starts by the complete string Path2 */
/* Check that the next character of Path1 is '\0' or '/' */
return (bool) (*Path1 == '\0' || *Path1 == '/');
}
/*****************************************************************************/
/** Skip spaces in a file seeking it before of reading the first non-blank ***/
/*****************************************************************************/
void Str_SkipSpacesInFile (FILE *FileSrc)
{
int Ch;
while ((Ch = fgetc (FileSrc)) != EOF)
if (!(isspace (Ch) ||
Ch == 0xA0)) // Unicode translation for
{
fseek (FileSrc,-1L,SEEK_CUR);
break;
}
}
/*****************************************************************************/
/***************** Write a string to a file changing *************************/
/*****************
or
for return *************************/
/***************** and for space *************************/
/*****************************************************************************/
void Str_FilePrintStrChangingBRToRetAndNBSPToSpace (FILE *FileTgt,const char *Str)
{
while (*Str)
{
/* Is ? */
if (*Str == '&')
{
if (*(Str+1) == 'N' || *(Str+1) == 'n')
if (*(Str+2) == 'B' || *(Str+2) == 'b')
if (*(Str+3) == 'S' || *(Str+3) == 's')
if (*(Str+4) == 'P' || *(Str+4) == 'p')
if (*(Str+5) == ';')
{
fputc ((int) ' ',FileTgt);
Str += 6;
continue;
}
}
/* Is
or
? */
else if (*Str == '<')
{
if (*(Str+1) == 'B' || *(Str+1) == 'b')
if (*(Str+2) == 'R' || *(Str+2) == 'r')
{
if (*(Str+3) == '>')
{
fputc ((int) '\n',FileTgt);
Str += 4;
continue;
}
else if (*(Str+3) == ' ')
{
if (*(Str+4) == '/')
if (*(Str+5) == '>')
{
fputc ((int) '\n',FileTgt);
Str += 6;
continue;
}
}
}
}
fputc ((int) *Str,FileTgt);
Str++;
}
}
/*****************************************************************************/
/*************** Search a string in a file and/or in a string ****************/
/*****************************************************************************/
/*
Search in the file FileSrc the string StrDelimit.
Write in the file FileTgt and/or StrDst the characters read from FileSrc, not including StrDelimit!.
FileTgt and StrDst can be NULL if you don't want to use them.
If StrDelimit is found, return 1.
If what is read exceed MaxLength, abort and return 0.
If StrDelimit is not found, return -1.
*/
#define MAX_LENGTH_STR_DELIMIT 100
int Str_ReceiveFileUntilDelimitStr (FILE *FileSrc, FILE *FileTgt, char *StrDst, const char *StrDelimit, unsigned long long MaxLength)
{
int NumBytesIdentical, // Number of characters identical in each iteration of the loop
NumBytesReadButNoWritten = 0, // Number of characters read from the source file
// and not written in the destination file
LengthStrDelimit = strlen (StrDelimit);
int Buffer[MAX_LENGTH_STR_DELIMIT+1];
unsigned long long LengthDst = 0;
int StartIndex = 0, i;
char *Ptr; // Pointer used to go through StrDst writing characters
if (!LengthStrDelimit)
{
if (StrDst != NULL)
*StrDst = '\0';
return 1;
}
if (strlen (StrDelimit) > MAX_LENGTH_STR_DELIMIT)
Lay_ShowErrorAndExit ("Delimiter string too large.");
Ptr = StrDst;
for (;;)
{
if (!NumBytesReadButNoWritten)
{ // Read next character
Buffer[StartIndex] = fgetc (FileSrc);
if (feof (FileSrc))
{
if (StrDst != NULL)
*Ptr = '\0';
return -1;
}
NumBytesReadButNoWritten++;
}
if (Buffer[StartIndex] == (int) StrDelimit[0]) // First character identical
{
for (NumBytesIdentical = 1, i = (StartIndex + 1) % LengthStrDelimit;
NumBytesIdentical < LengthStrDelimit;
NumBytesIdentical++, i = (i + 1) % LengthStrDelimit)
{
if (NumBytesReadButNoWritten == NumBytesIdentical) // Next character identical
{
Buffer[i] = fgetc (FileSrc); // Read next character
if (feof (FileSrc))
{
if (StrDst != NULL)
*Ptr = '\0';
return -1;
}
NumBytesReadButNoWritten++;
}
if (Buffer[i] != (int) StrDelimit[NumBytesIdentical]) // Next different character
break;
}
if (NumBytesIdentical == LengthStrDelimit) // Str found
{
if (StrDst != NULL)
*Ptr = '\0';
return 1;
}
}
if (LengthDst == MaxLength)
{
if (StrDst != NULL)
*Ptr = '\0';
return 0;
}
if (FileTgt != NULL)
fputc (Buffer[StartIndex],FileTgt); // Add the first character to the destination file
if (StrDst != NULL)
*Ptr++ = (char) Buffer[StartIndex];
LengthDst++;
NumBytesReadButNoWritten--;
StartIndex = (StartIndex+1) % LengthStrDelimit;
}
return 0; // Not reached
}
/*****************************************************************************/
/****** Convert invalid characters in a file name to valid characters ********/
/*****************************************************************************/
// Return true if the name of the file o folder is valid
// If the name is not valid, Gbl.Message will contain feedback text
// File names with heading and trailing spaces are allowed
bool Str_ConvertFilFolLnkNameToValid (char *FileName)
{
extern const char *Txt_UPLOAD_FILE_X_invalid_name_NO_HTML;
extern const char *Txt_UPLOAD_FILE_X_invalid_name;
extern const char *Txt_UPLOAD_FILE_Invalid_name_NO_HTML;
extern const char *Txt_UPLOAD_FILE_Invalid_name;
char *Ptr;
unsigned NumAlfanum = 0;
unsigned NumSpaces = 0;
unsigned NumPoints = 0;
bool FileNameIsOK = false;
Ptr = FileName;
if (*Ptr) // FileName is not empty
{
for (;
*Ptr;
Ptr++)
{
if (*Ptr == ' ')
{
NumPoints = 0;
if (++NumSpaces > 1)
{
*Ptr = '_';
NumAlfanum++;
NumSpaces = NumPoints = 0;
}
}
else if (*Ptr == '.')
{
if (++NumPoints > 1) // Don't allow ".."
{
*Ptr = '_';
NumAlfanum++;
NumSpaces = NumPoints = 0;
}
}
else
{
switch (*Ptr)
{
case 'á': *Ptr = 'a'; break;
case 'é': *Ptr = 'e'; break;
case 'í': *Ptr = 'i'; break;
case 'ó': *Ptr = 'o'; break;
case 'ú': *Ptr = 'u'; break;
case 'ñ': *Ptr = 'n'; break;
case 'ä': *Ptr = 'a'; break;
case 'ë': *Ptr = 'e'; break;
case 'ï': *Ptr = 'i'; break;
case 'ö': *Ptr = 'o'; break;
case 'ü': *Ptr = 'u'; break;
case 'ç': *Ptr = 'c'; break;
case 'Á': *Ptr = 'A'; break;
case 'É': *Ptr = 'E'; break;
case 'Í': *Ptr = 'I'; break;
case 'Ó': *Ptr = 'O'; break;
case 'Ú': *Ptr = 'U'; break;
case 'Ñ': *Ptr = 'N'; break;
case 'Ä': *Ptr = 'A'; break;
case 'Ë': *Ptr = 'E'; break;
case 'Ï': *Ptr = 'I'; break;
case 'Ö': *Ptr = 'O'; break;
case 'Ü': *Ptr = 'U'; break;
case 'Ç': *Ptr = 'C'; break;
}
if ((*Ptr >= 'a' && *Ptr <= 'z') ||
(*Ptr >= 'A' && *Ptr <= 'Z') ||
(*Ptr >= '0' && *Ptr <= '9') ||
*Ptr == '_' ||
*Ptr == '-')
{
NumAlfanum++;
NumSpaces = NumPoints = 0;
}
else
{
*Ptr = '_';
NumAlfanum++;
NumSpaces = NumPoints = 0;
}
}
}
if (NumAlfanum)
FileNameIsOK = true;
else
sprintf (Gbl.Message,
Gbl.FileBrowser.UploadingWithDropzone ? Txt_UPLOAD_FILE_X_invalid_name_NO_HTML :
Txt_UPLOAD_FILE_X_invalid_name,
FileName);
}
else // FileName is empty
strcpy (Gbl.Message,
Gbl.FileBrowser.UploadingWithDropzone ? Txt_UPLOAD_FILE_Invalid_name_NO_HTML :
Txt_UPLOAD_FILE_Invalid_name);
return FileNameIsOK;
}
/*****************************************************************************/
/************ Convert a string to a valid name of file or folder *************/
/*****************************************************************************/
void Str_ConvertToValidFileName (char *Str)
{
char *Ptr;
for (Ptr = Str;
*Ptr;
Ptr++)
{
if ((*Ptr >= 'a' && *Ptr <= 'z') ||
(*Ptr >= 'A' && *Ptr <= 'Z') ||
(*Ptr >= '0' && *Ptr <= '9') ||
*Ptr == '_' ||
*Ptr == '-')
continue;
if (isspace ((int) *Ptr) ||
*Ptr == '\xA0')
*Ptr = '_';
else
switch (*Ptr)
{
case 'á': case 'à': case 'ä': case 'â': *Ptr = 'a'; break;
case 'é': case 'è': case 'ë': case 'ê': *Ptr = 'e'; break;
case 'í': case 'ì': case 'ï': case 'î': *Ptr = 'i'; break;
case 'ó': case 'ò': case 'ö': case 'ô': *Ptr = 'o'; break;
case 'ú': case 'ù': case 'ü': case 'û': *Ptr = 'u'; break;
case 'ñ': *Ptr = 'n'; break;
case 'ç': *Ptr = 'c'; break;
case 'Á': case 'À': case 'Ä': case 'Â': *Ptr = 'A'; break;
case 'É': case 'È': case 'Ë': case 'Ê': *Ptr = 'E'; break;
case 'Í': case 'Ì': case 'Ï': case 'Î': *Ptr = 'I'; break;
case 'Ó': case 'Ò': case 'Ö': case 'Ô': *Ptr = 'O'; break;
case 'Ú': case 'Ù': case 'Ü': case 'Û': *Ptr = 'U'; break;
case 'Ñ': *Ptr = 'N'; break;
case 'Ç': *Ptr = 'C'; break;
default: *Ptr = '-'; break;
}
}
}
/*****************************************************************************/
/********** Write a quantity of bytes as bytes, KiB, MiB, GiB or TiB *********/
/*****************************************************************************/
#define Ki 1024.0
#define Mi 1048576.0
#define Gi 1073741824.0
#define Ti 1099511627776.0
void Str_WriteSizeInBytesBrief (double SizeInBytes)
{
if (SizeInBytes < Ki)
fprintf (Gbl.F.Out,"%.0f B",
SizeInBytes);
else if (SizeInBytes < Mi)
fprintf (Gbl.F.Out,"%.0f KiB",
SizeInBytes / Ki);
else if (SizeInBytes < Gi)
fprintf (Gbl.F.Out,"%.0f MiB",
SizeInBytes / Mi);
else if (SizeInBytes < Ti)
fprintf (Gbl.F.Out,"%.0f GiB",
SizeInBytes / Gi);
else
fprintf (Gbl.F.Out,"%.0f TiB",
SizeInBytes / Ti);
}
void Str_WriteSizeInBytesFull (double SizeInBytes)
{
if (SizeInBytes < Ki)
fprintf (Gbl.F.Out,"%.0f B",
SizeInBytes);
else if (SizeInBytes < Mi)
fprintf (Gbl.F.Out,"%.1f KiB",
SizeInBytes / Ki);
else if (SizeInBytes < Gi)
fprintf (Gbl.F.Out,"%.1f MiB",
SizeInBytes / Mi);
else if (SizeInBytes < Ti)
fprintf (Gbl.F.Out,"%.1f GiB",
SizeInBytes / Gi);
else
fprintf (Gbl.F.Out,"%.1f TiB",
SizeInBytes / Ti);
}
/*****************************************************************************/
/******************* Create a random alphanumeric string *********************/
/*****************************************************************************/
#define NUM_ALPHANUM_CHARS (10+26+26)
void Str_CreateRandomAlphanumStr (char *Str,size_t Length)
{
static const char CharTable[NUM_ALPHANUM_CHARS] =
{'0','1','2','3','4','5','6','7','8','9',
'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'
};
size_t i;
/***** Set random chars in string *****/
for (i = 0;
i