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);
|
||||
}
|
||||
|
||||
/** 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!
|
||||
* <Inuyasha> I don't know if this belongs here specifically, but it 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-2018 by Sonic Team Junior.
|
||||
// Copyright (C) 2019 by James R.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// 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
|
||||
|
||||
#include "strcasestr.c"
|
||||
|
|
Loading…
Reference in a new issue