public: crtlib: refactoring with new macros, use system strlcpy/strlcat if possible
This commit is contained in:
parent
a9e83fb9cf
commit
af23b0c67b
2 changed files with 102 additions and 76 deletions
|
@ -60,37 +60,6 @@ size_t Q_colorstr( const char *string )
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t Q_strncat( char *dst, const char *src, size_t size )
|
|
||||||
{
|
|
||||||
register char *d = dst;
|
|
||||||
register const char *s = src;
|
|
||||||
register size_t n = size;
|
|
||||||
size_t dlen;
|
|
||||||
|
|
||||||
if( !dst || !src || !size )
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
// find the end of dst and adjust bytes left but don't go past end
|
|
||||||
while( n-- != 0 && *d != '\0' ) d++;
|
|
||||||
dlen = d - dst;
|
|
||||||
n = size - dlen;
|
|
||||||
|
|
||||||
if( n == 0 ) return( dlen + Q_strlen( s ));
|
|
||||||
|
|
||||||
while( *s != '\0' )
|
|
||||||
{
|
|
||||||
if( n != 1 )
|
|
||||||
{
|
|
||||||
*d++ = *s;
|
|
||||||
n--;
|
|
||||||
}
|
|
||||||
s++;
|
|
||||||
}
|
|
||||||
|
|
||||||
*d = '\0';
|
|
||||||
return( dlen + ( s - src )); // count does not include NULL
|
|
||||||
}
|
|
||||||
|
|
||||||
int Q_atoi( const char *str )
|
int Q_atoi( const char *str )
|
||||||
{
|
{
|
||||||
int val = 0;
|
int val = 0;
|
||||||
|
@ -349,7 +318,7 @@ const char* Q_timestamp( int format )
|
||||||
return timestamp;
|
return timestamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined( HAVE_STRCASESTR )
|
#if !HAVE_STRCASESTR && !HAVE_STRISTR
|
||||||
char *Q_stristr( const char *string, const char *string2 )
|
char *Q_stristr( const char *string, const char *string2 )
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
|
|
145
public/crtlib.h
145
public/crtlib.h
|
@ -64,7 +64,6 @@ const char *Q_buildbranch( void );
|
||||||
void Q_strnlwr( const char *in, char *out, size_t size_out );
|
void Q_strnlwr( const char *in, char *out, size_t size_out );
|
||||||
#define Q_strlen( str ) (( str ) ? strlen(( str )) : 0 )
|
#define Q_strlen( str ) (( str ) ? strlen(( str )) : 0 )
|
||||||
size_t Q_colorstr( const char *string );
|
size_t Q_colorstr( const char *string );
|
||||||
size_t Q_strncat( char *dst, const char *src, size_t siz );
|
|
||||||
int Q_atoi( const char *str );
|
int Q_atoi( const char *str );
|
||||||
float Q_atof( const char *str );
|
float Q_atof( const char *str );
|
||||||
void Q_atov( float *vec, const char *str, size_t siz );
|
void Q_atov( float *vec, const char *str, size_t siz );
|
||||||
|
@ -142,91 +141,149 @@ static inline qboolean Q_isspace( const char *str )
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// libc implementations
|
|
||||||
static inline int Q_strcmp( const char *s1, const char *s2 )
|
static inline int Q_strcmp( const char *s1, const char *s2 )
|
||||||
{
|
{
|
||||||
return unlikely(!s1) ?
|
if( likely( s1 && s2 ))
|
||||||
( !s2 ? 0 : -1 ) :
|
return strcmp( s1, s2 );
|
||||||
( unlikely(!s2) ? 1 : strcmp( s1, s2 ));
|
return ( s1 ? 1 : 0 ) - ( s2 ? 1 : 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int Q_strncmp( const char *s1, const char *s2, size_t n )
|
static inline int Q_strncmp( const char *s1, const char *s2, size_t n )
|
||||||
{
|
{
|
||||||
return unlikely(!s1) ?
|
if( likely( s1 && s2 ))
|
||||||
( !s2 ? 0 : -1 ) :
|
return strncmp( s1, s2, n );
|
||||||
( unlikely(!s2) ? 1 : strncmp( s1, s2, n ));
|
return ( s1 ? 1 : 0 ) - ( s2 ? 1 : 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline char *Q_strstr( const char *s1, const char *s2 )
|
static inline char *Q_strstr( const char *s1, const char *s2 )
|
||||||
{
|
{
|
||||||
return unlikely( !s1 || !s2 ) ? NULL : (char*)strstr( s1, s2 );
|
if( likely( s1 && s2 ))
|
||||||
|
return (char *)strstr( s1, s2 );
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Q_strncpy is the same as strlcpy
|
// libc extensions, be careful what to enable or what not
|
||||||
static inline size_t Q_strncpy( char *dst, const char *src, size_t siz )
|
static inline size_t Q_strncpy( char *dst, const char *src, size_t size )
|
||||||
{
|
{
|
||||||
|
#if HAVE_STRLCPY
|
||||||
|
if( unlikely( !dst || !src || !size ))
|
||||||
|
return 0;
|
||||||
|
return strlcpy( dst, src, size );
|
||||||
|
#else
|
||||||
size_t len;
|
size_t len;
|
||||||
|
if( unlikely( !dst || !src || !size ))
|
||||||
if( unlikely( !dst || !src || !siz ))
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
len = strlen( src );
|
len = strlen( src );
|
||||||
if( len + 1 > siz ) // check if truncate
|
if( len + 1 > size ) // check if truncate
|
||||||
{
|
{
|
||||||
memcpy( dst, src, siz - 1 );
|
memcpy( dst, src, size - 1 );
|
||||||
dst[siz - 1] = 0;
|
dst[size - 1] = 0;
|
||||||
}
|
}
|
||||||
else memcpy( dst, src, len + 1 );
|
else memcpy( dst, src, len + 1 );
|
||||||
|
|
||||||
return len; // count does not include NULL
|
return len; // count does not include NULL
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// libc extensions, be careful
|
static inline size_t Q_strncat( char *dst, const char *src, size_t size )
|
||||||
|
{
|
||||||
|
#if HAVE_STRLCAT
|
||||||
|
if( unlikely( !dst || !src || !size ))
|
||||||
|
return 0;
|
||||||
|
return strlcat( dst, src, size );
|
||||||
|
#else
|
||||||
|
char *d = dst;
|
||||||
|
const char *s = src;
|
||||||
|
size_t n = size;
|
||||||
|
size_t dlen;
|
||||||
|
|
||||||
#if XASH_WIN32
|
if( unlikely( !dst || !src || !size ))
|
||||||
#define strcasecmp stricmp
|
return 0;
|
||||||
#define strncasecmp strnicmp
|
|
||||||
#endif // XASH_WIN32
|
|
||||||
|
|
||||||
|
// find the end of dst and adjust bytes left but don't go past end
|
||||||
|
while( n-- != 0 && *d != '\0' ) d++;
|
||||||
|
dlen = d - dst;
|
||||||
|
n = size - dlen;
|
||||||
|
|
||||||
|
if( n == 0 ) return( dlen + Q_strlen( s ));
|
||||||
|
|
||||||
|
while( *s != '\0' )
|
||||||
|
{
|
||||||
|
if( n != 1 )
|
||||||
|
{
|
||||||
|
*d++ = *s;
|
||||||
|
n--;
|
||||||
|
}
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
|
||||||
|
*d = '\0';
|
||||||
|
return( dlen + ( s - src )); // count does not include NULL
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if HAVE_STRICMP || HAVE_STRCASECMP
|
||||||
static inline int Q_stricmp( const char *s1, const char *s2 )
|
static inline int Q_stricmp( const char *s1, const char *s2 )
|
||||||
{
|
{
|
||||||
return unlikely(!s1) ?
|
if( likely( s1 && s2 ))
|
||||||
( !s2 ? 0 : -1 ) :
|
{
|
||||||
( unlikely(!s2) ? 1 : strcasecmp( s1, s2 ));
|
#if HAVE_STRICMP
|
||||||
|
return stricmp( s1, s2 );
|
||||||
|
#elif HAVE_STRCASECMP
|
||||||
|
return strcasecmp( s1, s2 );
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
return ( s1 ? 1 : 0 ) - ( s2 ? 1 : 0 );
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
int Q_stricmp( const char *s1, const char *s2 );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_STRICMP || HAVE_STRCASECMP
|
||||||
static inline int Q_strnicmp( const char *s1, const char *s2, size_t n )
|
static inline int Q_strnicmp( const char *s1, const char *s2, size_t n )
|
||||||
{
|
{
|
||||||
return unlikely(!s1) ?
|
if( likely( s1 && s2 ))
|
||||||
( !s2 ? 0 : -1 ) :
|
{
|
||||||
( unlikely(!s2) ? 1 : strncasecmp( s1, s2, n ));
|
#if HAVE_STRICMP
|
||||||
}
|
return strnicmp( s1, s2, n );
|
||||||
|
#elif HAVE_STRCASECMP
|
||||||
#if defined( HAVE_STRCASESTR )
|
return strncasecmp( s1, s2, n );
|
||||||
#if XASH_WIN32
|
|
||||||
#define strcasestr stristr
|
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
return ( s1 ? 1 : 0 ) - ( s2 ? 1 : 0 );
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
int Q_strnicmp( const char *s1, const char *s2, size_t n );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if HAVE_STRISTR || HAVE_STRCASESTR
|
||||||
static inline char *Q_stristr( const char *s1, const char *s2 )
|
static inline char *Q_stristr( const char *s1, const char *s2 )
|
||||||
{
|
{
|
||||||
return unlikely( !s1 || !s2 ) ? NULL : (char *)strcasestr( s1, s2 );
|
if( likely( s1 && s2 ))
|
||||||
}
|
#if HAVE_STRISTR
|
||||||
#else // defined( HAVE_STRCASESTR )
|
return (char *)stristr( s1, s2 );
|
||||||
char *Q_stristr( const char *s1, const char *s2 );
|
#elif HAVE_STRCASESTR
|
||||||
#endif // defined( HAVE_STRCASESTR )
|
return (char *)strcasestr( s1, s2 );
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined( HAVE_STRCHRNUL )
|
return NULL;
|
||||||
|
}
|
||||||
|
#else // !HAVE_STRISTR && !HAVE_STRCASESTR
|
||||||
|
char *Q_stristr( const char *s1, const char *s2 );
|
||||||
|
#endif // !HAVE_STRISTR && !HAVE_STRCASESTR
|
||||||
|
|
||||||
|
#if HAVE_STRCHRNUL
|
||||||
#define Q_strchrnul strchrnul
|
#define Q_strchrnul strchrnul
|
||||||
#else
|
#else // !HAVE_STRCHRNUL
|
||||||
static inline const char *Q_strchrnul( const char *s, int c )
|
static inline const char *Q_strchrnul( const char *s, int c )
|
||||||
{
|
{
|
||||||
const char *p = Q_strchr( s, c );
|
const char *p = Q_strchr( s, c );
|
||||||
|
if( p ) return p;
|
||||||
if( p )
|
|
||||||
return p;
|
|
||||||
|
|
||||||
return s + Q_strlen( s );
|
return s + Q_strlen( s );
|
||||||
}
|
}
|
||||||
#endif
|
#endif // !HAVE_STRCHRNUL
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue