Exemple #1
0
// Similar to BE_Cross_strcasecmp, but compares up to count chars
int BE_Cross_strncasecmp(const char *s1, const char *s2, size_t count)
{
	unsigned char uc1, uc2;
	for (; count && (*s1) && (BE_Cross_toupper(*s1) == BE_Cross_toupper(*s2)); s1++, s2++, count--);
	// If done, return 0
	if (!count)
		return 0;
	// Otherwise behave as in BE_Cross_strcasecmp
	uc1 = (unsigned char)((char)(BE_Cross_toupper(*s1)));
	uc2 = (unsigned char)((char)(BE_Cross_toupper(*s2)));
	return ((int)uc1 - (int)uc2);
}
Exemple #2
0
int BE_Cross_strcasecmp(const char *s1, const char *s2)
{
	unsigned char uc1, uc2;
	/* This one is easy. We don't care if a value is signed or not. */
	/* All that matters here is consistency (everything is signed). */
	for (; (*s1) && (BE_Cross_toupper(*s1) == BE_Cross_toupper(*s2)); s1++, s2++);
	/* But now, first we cast from int to char, and only *then* to */
	/* unsigned char, so the correct difference can be calculated. */
	uc1 = (unsigned char)((char)(BE_Cross_toupper(*s1)));
	uc2 = (unsigned char)((char)(BE_Cross_toupper(*s2)));
	/* We should still cast back to int, for a signed difference. */
	/* Assumption: An int can store any unsigned char value.      */
	return ((int)uc1 - (int)uc2);
}
Exemple #3
0
int BE_Cross_GetSortedRewritableFilenames_AsUpperCase(char *outFilenames, int maxNum, int strLenBound, const char *suffix)
{
	struct dirent *direntry;
	size_t sufLen = strlen(suffix);
	char *nextFilename = outFilenames, *outFilenamesEnd = outFilenames + maxNum*strLenBound, *outFilenamesLast = outFilenamesEnd - strLenBound;
	char *checkFilename, *checkCh;
	DIR *dir;
	// For the sake of consistency we go over same paths as in file open for reading function
	const char *searchpaths[] = {g_be_selectedGameInstallation->writableVanillaFilesPath, g_be_selectedGameInstallation->path};
	for (int loopvar = 0; loopvar < (int)(sizeof(searchpaths)/sizeof(*searchpaths)); ++loopvar)
	{
		dir = opendir(searchpaths[loopvar]);
		if (!dir)
		{
			continue;
		}
		for (direntry = readdir(dir); direntry; direntry = readdir(dir))
		{
			size_t len = strlen(direntry->d_name);
			if ((len < sufLen) || BE_Cross_strcasecmp(direntry->d_name+len-sufLen, suffix))
			{
				continue;
			}
			len -= sufLen;
			/*** Possibly a HACK - Modify d_name itself ***/
			len = (len >= (size_t)strLenBound) ? (strLenBound-1) : len;
			direntry->d_name[len] = '\0';
			// Convert to upper case
			for (checkCh = direntry->d_name; *checkCh; ++checkCh)
			{
				*checkCh = BE_Cross_toupper(*checkCh);
			}
			// This is basically insertion-sort, but we store
			// the *last* entries if there isn't enough room.
			for (checkFilename = outFilenames; checkFilename < nextFilename; checkFilename += strLenBound)
			{
				if (strcmp(checkFilename, direntry->d_name) > 0)
				{
					break;
				}
			}
			// Gone over all inserted entries
			if (checkFilename == nextFilename)
			{
				if (nextFilename < outFilenamesEnd)
				{
					memcpy(nextFilename, direntry->d_name, 1+len);
					nextFilename += strLenBound;
				}
				else
				{
					memmove(outFilenames, outFilenames+strLenBound, strLenBound*(maxNum-1));
					memcpy(outFilenamesLast, direntry->d_name, 1+len);
				}
			}
			// Shift existing entries and insert new one
			else
			{
				// If there's room for another entry, shift "forward"
				if (nextFilename < outFilenamesEnd)
				{
					memmove(checkFilename + strLenBound, checkFilename, outFilenamesEnd-checkFilename-strLenBound);
					memcpy(checkFilename, direntry->d_name, 1+len);
					nextFilename += strLenBound;
				}
				// Otherwise shift "backwards", but only if there's already an entry "smaller" than current one
				else if (checkFilename != outFilenames)
				{
					memmove(outFilenames, outFilenames+strLenBound, (checkFilename-strLenBound)-outFilenames);
					memcpy(checkFilename-strLenBound, direntry->d_name, 1+len);
				}
			};
		}
		closedir(dir);
	}
	return (nextFilename-outFilenames)/strLenBound;
}