mirror of
https://git.do.srb2.org/KartKrew/Kart-Public.git
synced 2024-12-28 13:21:10 +00:00
Use a superior strcasestr
This commit is contained in:
parent
51cb3c9008
commit
b4e900be1f
3 changed files with 113 additions and 67 deletions
67
src/m_misc.c
67
src/m_misc.c
|
@ -1607,73 +1607,6 @@ void strcatbf(char *s1, const char *s2, const char *s3)
|
||||||
strcat(s1, tmp);
|
strcat(s1, tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Locate a substring, case-insensitively.
|
|
||||||
* Know that I hate this style. -James
|
|
||||||
*
|
|
||||||
* \param s The string to search within.
|
|
||||||
* \param q The substring to find.
|
|
||||||
* \return a pointer to the located substring, or NULL if it could be found.
|
|
||||||
*/
|
|
||||||
char *strcasestr(const char *s, const char *q)
|
|
||||||
{
|
|
||||||
void **vpp;/* a hack! */
|
|
||||||
|
|
||||||
size_t qz;
|
|
||||||
|
|
||||||
const char *up;
|
|
||||||
const char *lp;
|
|
||||||
|
|
||||||
int uc;
|
|
||||||
int lc;
|
|
||||||
|
|
||||||
qz = strlen(q);
|
|
||||||
|
|
||||||
uc = toupper(*q);
|
|
||||||
lc = tolower(*q);
|
|
||||||
|
|
||||||
up = s;
|
|
||||||
lp = s;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
if (uc > 0)
|
|
||||||
{
|
|
||||||
up = strchr(up, uc);
|
|
||||||
if (!up || ( lc == 0 && lp < up ))
|
|
||||||
uc = -1;
|
|
||||||
else
|
|
||||||
if (strnicmp(q, up, qz) == 0)
|
|
||||||
uc = 0;
|
|
||||||
else
|
|
||||||
up++;
|
|
||||||
}
|
|
||||||
if (lc > 0)
|
|
||||||
{
|
|
||||||
lp = strchr(lp, lc);
|
|
||||||
if (!lp || ( uc == 0 && up < lp ))
|
|
||||||
lc = -1;
|
|
||||||
else
|
|
||||||
if (strnicmp(q, lp, qz) == 0)
|
|
||||||
lc = 0;
|
|
||||||
else
|
|
||||||
lp++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while (( uc > 0 ) || ( lc > 0 )) ;
|
|
||||||
|
|
||||||
if (uc == 0)
|
|
||||||
vpp = (void **)&up;
|
|
||||||
else
|
|
||||||
vpp = (void **)&lp;
|
|
||||||
|
|
||||||
/*
|
|
||||||
We can dereference a double void pointer and cast it to remove const.
|
|
||||||
This works because the original variable (the pointer) is writeable,
|
|
||||||
but its value is not.
|
|
||||||
*/
|
|
||||||
return (char *)*vpp;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Converts an ASCII Hex string into an integer. Thanks, Borland!
|
/** Converts an ASCII Hex string into an integer. Thanks, Borland!
|
||||||
* <Inuyasha> I don't know if this belongs here specifically, but it sure
|
* <Inuyasha> I don't know if this belongs here specifically, but it sure
|
||||||
* doesn't belong in p_spec.c, that's for sure
|
* doesn't belong in p_spec.c, that's for sure
|
||||||
|
|
110
src/strcasestr.c
Normal file
110
src/strcasestr.c
Normal file
|
@ -0,0 +1,110 @@
|
||||||
|
/*
|
||||||
|
strcasestr -- case insensitive substring searching function.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
Copyright 2019 James R.
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source forms, with or without modification, is
|
||||||
|
permitted provided that the following condition is met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
condition and the following disclaimer.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define SWAP( a, b ) \
|
||||||
|
(\
|
||||||
|
(a) ^= (b),\
|
||||||
|
(b) ^= (a),\
|
||||||
|
(a) ^= (b)\
|
||||||
|
)
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
trycmp (char **pp, char *cp,
|
||||||
|
const char *q, size_t qn)
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
p = (*pp);
|
||||||
|
if (strncasecmp(p, q, qn) == 0)
|
||||||
|
return 0;
|
||||||
|
(*pp) = strchr(&p[1], (*cp));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
swapp (char ***ppap, char ***ppbp, char **cpap, char **cpbp)
|
||||||
|
{
|
||||||
|
SWAP(*(intptr_t *)ppap, *(intptr_t *)ppbp);
|
||||||
|
SWAP(*(intptr_t *)cpap, *(intptr_t *)cpbp);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
strcasestr (const char *s, const char *q)
|
||||||
|
{
|
||||||
|
size_t qn;
|
||||||
|
|
||||||
|
char uc;
|
||||||
|
char lc;
|
||||||
|
|
||||||
|
char *up;
|
||||||
|
char *lp;
|
||||||
|
|
||||||
|
char **ppa;
|
||||||
|
char **ppb;
|
||||||
|
|
||||||
|
char *cpa;
|
||||||
|
char *cpb;
|
||||||
|
|
||||||
|
uc = toupper(*q);
|
||||||
|
lc = tolower(*q);
|
||||||
|
|
||||||
|
up = strchr(s, uc);
|
||||||
|
lp = strchr(s, lc);
|
||||||
|
|
||||||
|
if (!( (intptr_t)up|(intptr_t)lp ))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!lp || up < lp)
|
||||||
|
{
|
||||||
|
ppa = &up;
|
||||||
|
ppb = &lp;
|
||||||
|
|
||||||
|
cpa = &uc;
|
||||||
|
cpb = &lc;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ppa = &lp;
|
||||||
|
ppb = &up;
|
||||||
|
|
||||||
|
cpa = &lc;
|
||||||
|
cpb = &uc;
|
||||||
|
}
|
||||||
|
|
||||||
|
qn = strlen(q);
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
if (trycmp(ppa, cpa, q, qn) == 0)
|
||||||
|
return (*ppa);
|
||||||
|
|
||||||
|
if (!( (intptr_t)up|(intptr_t)lp ))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (!(*ppa) || ( (*ppb) && (*ppb) < (*ppa) ))
|
||||||
|
swapp(&ppa, &ppb, &cpa, &cpb);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -2,6 +2,7 @@
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Copyright (C) 2006 by Graue.
|
// Copyright (C) 2006 by Graue.
|
||||||
// Copyright (C) 2006-2018 by Sonic Team Junior.
|
// Copyright (C) 2006-2018 by Sonic Team Junior.
|
||||||
|
// Copyright (C) 2019 by James R.
|
||||||
//
|
//
|
||||||
// This program is free software distributed under the
|
// This program is free software distributed under the
|
||||||
// terms of the GNU General Public License, version 2.
|
// terms of the GNU General Public License, version 2.
|
||||||
|
@ -50,3 +51,5 @@ size_t strlcpy(char *dst, const char *src, size_t siz)
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "strcasestr.c"
|
||||||
|
|
Loading…
Reference in a new issue