string.c revision 8047c446a7fcabbed23c975bae98e1206ab18591
199767f8919635c4928607450d9e0abb932109ceToomas Soome/* Copyright (c) 2001, Stanford University
199767f8919635c4928607450d9e0abb932109ceToomas Soome * All rights reserved
199767f8919635c4928607450d9e0abb932109ceToomas Soome * See the file LICENSE.txt for information on redistributing this software.
199767f8919635c4928607450d9e0abb932109ceToomas Soome const char *temp;
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (!str) return 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* Allow strdup'ing of NULL strings -- this makes the __fillin functions
199767f8919635c4928607450d9e0abb932109ceToomas Soome * much cleaner. */
199767f8919635c4928607450d9e0abb932109ceToomas Soomechar *crStrndup( const char *str, unsigned int len )
199767f8919635c4928607450d9e0abb932109ceToomas Soomeint crStrcmp( const char *str1, const char *str2 )
199767f8919635c4928607450d9e0abb932109ceToomas Soomeint crStrncmp( const char *str1, const char *str2, int n )
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (i == n) return 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
199767f8919635c4928607450d9e0abb932109ceToomas Soome '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
199767f8919635c4928607450d9e0abb932109ceToomas Soome '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
199767f8919635c4928607450d9e0abb932109ceToomas Soome '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
199767f8919635c4928607450d9e0abb932109ceToomas Soome '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047',
199767f8919635c4928607450d9e0abb932109ceToomas Soome '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057',
199767f8919635c4928607450d9e0abb932109ceToomas Soome '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
199767f8919635c4928607450d9e0abb932109ceToomas Soome '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077',
199767f8919635c4928607450d9e0abb932109ceToomas Soome '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
199767f8919635c4928607450d9e0abb932109ceToomas Soome '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
199767f8919635c4928607450d9e0abb932109ceToomas Soome '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
199767f8919635c4928607450d9e0abb932109ceToomas Soome '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137',
199767f8919635c4928607450d9e0abb932109ceToomas Soome '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
199767f8919635c4928607450d9e0abb932109ceToomas Soome '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
199767f8919635c4928607450d9e0abb932109ceToomas Soome '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
199767f8919635c4928607450d9e0abb932109ceToomas Soome '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177',
199767f8919635c4928607450d9e0abb932109ceToomas Soome '\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207',
199767f8919635c4928607450d9e0abb932109ceToomas Soome '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217',
199767f8919635c4928607450d9e0abb932109ceToomas Soome '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227',
199767f8919635c4928607450d9e0abb932109ceToomas Soome '\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237',
199767f8919635c4928607450d9e0abb932109ceToomas Soome '\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247',
199767f8919635c4928607450d9e0abb932109ceToomas Soome '\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257',
199767f8919635c4928607450d9e0abb932109ceToomas Soome '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267',
199767f8919635c4928607450d9e0abb932109ceToomas Soome '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277',
199767f8919635c4928607450d9e0abb932109ceToomas Soome '\300', '\301', '\302', '\303', '\304', '\305', '\306', '\307',
199767f8919635c4928607450d9e0abb932109ceToomas Soome '\310', '\311', '\312', '\313', '\314', '\315', '\316', '\317',
199767f8919635c4928607450d9e0abb932109ceToomas Soome '\320', '\321', '\322', '\323', '\324', '\325', '\326', '\327',
199767f8919635c4928607450d9e0abb932109ceToomas Soome '\330', '\331', '\332', '\333', '\334', '\335', '\336', '\337',
199767f8919635c4928607450d9e0abb932109ceToomas Soome '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
199767f8919635c4928607450d9e0abb932109ceToomas Soome '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
199767f8919635c4928607450d9e0abb932109ceToomas Soome '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
199767f8919635c4928607450d9e0abb932109ceToomas Soome '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377'
199767f8919635c4928607450d9e0abb932109ceToomas Soomeint crStrcasecmp( const char *str1, const char *str2 )
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (lowercase[(int) *str1] != lowercase[(int) *str2])
199767f8919635c4928607450d9e0abb932109ceToomas Soome return (lowercase[(int) *str1] - lowercase[(int) *str2]);
199767f8919635c4928607450d9e0abb932109ceToomas Soomevoid crStrncpy( char *dest, const char *src, unsigned int len )
199767f8919635c4928607450d9e0abb932109ceToomas Soome crMemcpy( dest, src, len ); /* NOTE: not null-terminated! */
199767f8919635c4928607450d9e0abb932109ceToomas Soome crMemcpy( dest, src, str_len + 1 ); /* includes null terminator */
199767f8919635c4928607450d9e0abb932109ceToomas Soomechar *crStrjoin( const char *str1, const char *str2 )
199767f8919635c4928607450d9e0abb932109ceToomas Soome const int len1 = crStrlen(str1), len2 = crStrlen(str2);
199767f8919635c4928607450d9e0abb932109ceToomas Soomechar *crStrjoin3( const char *str1, const char *str2, const char *str3 )
199767f8919635c4928607450d9e0abb932109ceToomas Soome const int len1 = crStrlen(str1), len2 = crStrlen(str2), len3 = crStrlen(str3);
199767f8919635c4928607450d9e0abb932109ceToomas Soomechar *crStrstr( const char *str, const char *pat )
199767f8919635c4928607450d9e0abb932109ceToomas Soome const char *end = str + crStrlen(str) - pat_len;
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (*str == first_char && !crMemcmp( str, pat, pat_len ))
199767f8919635c4928607450d9e0abb932109ceToomas Soome return (char *) str;
199767f8919635c4928607450d9e0abb932109ceToomas Soome return (char *) str;
199767f8919635c4928607450d9e0abb932109ceToomas Soome return (char *) temp;
199767f8919635c4928607450d9e0abb932109ceToomas Soome/* These functions are from the old wiregl net.c -- hexdumps? Not sure quite yet. */
199767f8919635c4928607450d9e0abb932109ceToomas Soomevoid crBytesToString( char *string, int nstring, void *data, int ndata )
199767f8919635c4928607450d9e0abb932109ceToomas Soome unsigned char *udata;
199767f8919635c4928607450d9e0abb932109ceToomas Soome for ( i = 0; i < ndata && ( offset + 4 <= nstring ); i++ )
199767f8919635c4928607450d9e0abb932109ceToomas Soome offset += sprintf( string + offset, "%02x ", udata[i] );
199767f8919635c4928607450d9e0abb932109ceToomas Soomevoid crWordsToString( char *string, int nstring, void *data, int ndata )
199767f8919635c4928607450d9e0abb932109ceToomas Soome unsigned int *udata;
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* turn byte count into word count */
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* we need an ellipsis if all the words won't fit in the string */
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* if the ellipsis won't fit then print one less word */
199767f8919635c4928607450d9e0abb932109ceToomas Soome for ( i = 0; i < ndata; i++ )
199767f8919635c4928607450d9e0abb932109ceToomas Soome offset += sprintf( string + offset, "%08x ", udata[i] );
199767f8919635c4928607450d9e0abb932109ceToomas Soome else if ( offset > 0 )
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (!str) return 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic int __numOccurrences( const char *str, const char *substr )
199767f8919635c4928607450d9e0abb932109ceToomas Soome while ((temp = crStrstr( temp, substr )) != NULL )
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Split str into a NULL-terminated array of strings, using splitstr as
199767f8919635c4928607450d9e0abb932109ceToomas Soome * the separator.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * It's the same as the Python call string.split(str, splitstr).
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Note: crStrSplit("a b c", " ") returns ["a", "b", "", "c", NULL] though!!!
199767f8919635c4928607450d9e0abb932109ceToomas Soomechar **crStrSplit( const char *str, const char *splitstr )
199767f8919635c4928607450d9e0abb932109ceToomas Soome int num_args = __numOccurrences( str, splitstr ) + 1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome char **faked_argv = (char **) crAlloc( (num_args + 1)*sizeof( *faked_argv ) );
199767f8919635c4928607450d9e0abb932109ceToomas Soome for (i = 0 ; i < num_args ; i++)
199767f8919635c4928607450d9e0abb932109ceToomas Soomechar **crStrSplitn( const char *str, const char *splitstr, int n )
199767f8919635c4928607450d9e0abb932109ceToomas Soome int num_args = __numOccurrences( str, splitstr );
199767f8919635c4928607450d9e0abb932109ceToomas Soome faked_argv = (char **) crAlloc( (num_args + 1) * sizeof( *faked_argv ) );
199767f8919635c4928607450d9e0abb932109ceToomas Soome for (i = 0 ; i < num_args ; i++)
199767f8919635c4928607450d9e0abb932109ceToomas Soome/* Free an array of strings, as returned by crStrSplit() and crStrSplitn(). */
199767f8919635c4928607450d9e0abb932109ceToomas Soome for (i = 0; strings[i]; i++) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome/* Intersect two strings on a word-by-word basis (separated by spaces).
199767f8919635c4928607450d9e0abb932109ceToomas Soome * We typically use this to intersect OpenGL extension strings.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Example: if s1 = "apple banana plum pear"
199767f8919635c4928607450d9e0abb932109ceToomas Soome * and s2 = "plum banana orange"
199767f8919635c4928607450d9e0abb932109ceToomas Soome * then return "banana plum" (or "plum banana").
199767f8919635c4928607450d9e0abb932109ceToomas Soomechar *crStrIntersect( const char *s1, const char *s2 )
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* null strings, no intersection */
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* allocate storage for result (a conservative estimate) */
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* split s1 and s2 at space chars */
199767f8919635c4928607450d9e0abb932109ceToomas Soome for (i = 0; exten1[i]; i++)
199767f8919635c4928607450d9e0abb932109ceToomas Soome for (j = 0; exten2[j]; j++)
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* found an intersection, append to result */
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* free split strings */
199767f8919635c4928607450d9e0abb932109ceToomas Soome /*CRASSERT(crStrlen(result) < resultLen);*/
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* all done! */
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic int crStrParseGlSubver(const char * ver, const char ** pNext, bool bSpacePrefixAllowed)
199767f8919635c4928607450d9e0abb932109ceToomas Soome else if(*ver == ' ' || *ver == '\t' || *ver == 0x0d || *ver == 0x0a)
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* treat this as the end of version string */
199767f8919635c4928607450d9e0abb932109ceToomas Soome crWarning("error parsing version %s", initVer);
199767f8919635c4928607450d9e0abb932109ceToomas Soome int iVer = crStrParseGlSubver(ver, &ver, true);
199767f8919635c4928607450d9e0abb932109ceToomas Soome crWarning("parsing major version returned %d, '%s'", iVer, initVer);
199767f8919635c4928607450d9e0abb932109ceToomas Soome crWarning("major version %d is bigger than the max supported %#x, this is somewhat not expected, failing", iVer, CR_GLVERSION_MAX_MAJOR);
199767f8919635c4928607450d9e0abb932109ceToomas Soome crWarning("parsing minor version failed, '%s'", initVer);
199767f8919635c4928607450d9e0abb932109ceToomas Soome crWarning("minor version %d is bigger than the max supported %#x, this is somewhat not expected, failing", iVer, CR_GLVERSION_MAX_MAJOR);
199767f8919635c4928607450d9e0abb932109ceToomas Soome crWarning("parsing build version failed, '%s', using 0", initVer);
199767f8919635c4928607450d9e0abb932109ceToomas Soome crWarning("build version %d is bigger than the max supported, using max supported val %#x", tmp, CR_GLVERSION_MAX_BUILD);
199767f8919635c4928607450d9e0abb932109ceToomas Soome crDebug("returning version %#x for string '%s'", iVer, initVer);
199767f8919635c4928607450d9e0abb932109ceToomas Soomeint32_t crStrParseI32(const char *pszStr, const int32_t defaultVal)
199767f8919635c4928607450d9e0abb932109ceToomas Soome bool neg = false;
199767f8919635c4928607450d9e0abb932109ceToomas Soome unsigned char iDigit = 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (pszStr[0] == ' ' || pszStr[0] == '\t' || pszStr[0] == '\n')
199767f8919635c4928607450d9e0abb932109ceToomas Soome unsigned char digit;