Example #1
0
int strnatcmp(const TCHAR *psz1, const TCHAR *psz2)
{
	int ai, bi;
	TCHAR ca, cb;
	int fractional, result;

	__try{
		TCHAR a [MAX_PATH];
		TCHAR b [MAX_PATH];
		memset(a, 0, MAX_PATH);
		memset(b, 0, MAX_PATH);
		_tcscpy_s(a, MAX_PATH, psz1);
		_tcscpy_s(b, MAX_PATH, psz2);
		_tcslwr_s(a, MAX_PATH);
		_tcslwr_s(b, MAX_PATH);
		ai = bi = 0;
		while (1) {
			ca = a[ai];
			cb = b[bi];

			/* skip over leading spaces or zeros */
			while (_is_meaningless_char(ca))
				ca = a[++ai];

			while (_is_meaningless_char(cb))
				cb = b[++bi];

			/* process run of digits */
			if (_istdigit(ca) && _istdigit(cb)) {
				fractional = (ca == '0' || cb == '0');

				if (fractional) {
					if ((result = compare_left(a + ai, b + bi)) != 0)
						return result;
				} else {
					if ((result = compare_right(a + ai, b + bi)) != 0)
						return result;
				}
			}

			if (!ca && !cb) {
				/* The strings compare the same.  Perhaps the caller
				will want to call strcmp to break the tie. */
				return 0;
			}

			if (ca < cb)
				return -1;
			else if (ca > cb)
				return +1;

			++ai;
			++bi;
		}
	}__except(EXCEPTION_EXECUTE_HANDLER){} 

	return 0;
}
Example #2
0
int strnatcmp0(nat_char const *a, nat_char const *b, int fold_case)
{
	int ai, bi;
	nat_char ca, cb;
	int fractional, result;
     
	assert(a && b);
	ai = bi = 0;
	while (1) 
	{
		ca = a[ai]; cb = b[bi];

		/* skip over leading spaces or zeros */
		while (nat_isspace(ca))
			ca = a[++ai];

		while (nat_isspace(cb))
			cb = b[++bi];

		/* process run of digits */
		if (nat_isdigit(ca)  &&  nat_isdigit(cb)) 
		{
			fractional = (ca == '0' || cb == '0');

			if (fractional) 
			{
				if ((result = compare_left(a+ai, b+bi)) != 0)
					return result;
			} 
			else 
			{
				if ((result = compare_right(a+ai, b+bi)) != 0)
					return result;
			}
		}

		if (!ca && !cb) 
		{
			/* The strings compare the same.  Perhaps the caller
                  will want to call strcmp to break the tie. */
			return 0;
		}

		if (fold_case) 
		{
			ca = nat_toupper(ca);
			cb = nat_toupper(cb);
		}
	  
		if (ca < cb)
			return -1;
		else if (ca > cb)
			return +1;

		++ai; ++bi;
	}
}
Example #3
0
static int strnatcmp0(char const *a, char const *b, int fold_case)
{
     int ai, bi;
     int ca, cb;
     int fractional, result;
     
     assert(a && b);
     ai = bi = 0;
     while (1) {
      ca = to_int(a[ai]);
      cb = to_int(b[bi]);

          /* process run of digits */
          if (nat_isdigit(ca)  &&  nat_isdigit(cb)) {
               fractional = (ca == '0' || cb == '0');

               if (fractional) {
                    if ((result = compare_left(a+ai, b+bi)) != 0)
                         return result;
               } else {
                    if ((result = compare_right(a+ai, b+bi)) != 0)
                         return result;
               }
          }

          if (!ca && !cb) {
               /* The strings compare the same.  Call str[case]cmp() to ensure
                  consistent results. */
               if(fold_case)
                   return strcasecmp(a,b);
               else
                   return strcmp(a,b);
          }

          if (fold_case) {
               ca = nat_unify_case(ca);
               cb = nat_unify_case(cb);
          }
          
          if (ca < cb)
               return -1;
          else if (ca > cb)
               return +1;

          ++ai; ++bi;
     }
}
PHPAPI int strnatcmp_ex(char const *a, size_t a_len, char const *b, size_t b_len, int fold_case)
{
	char ca, cb;
	char const *ap, *bp;
	char const *aend = a + a_len,
			   *bend = b + b_len;
	int fractional, result;

	if (a_len == 0 || b_len == 0)
		return a_len - b_len;

	ap = a;
	bp = b;
	while (1) {
		ca = *ap; cb = *bp;

		/* skip over leading spaces or zeros */
		while (isspace((int)ca))
			ca = *++ap;

		while (isspace((int)cb))
			cb = *++bp;

		/* process run of digits */
		if (isdigit((int)ca)  &&  isdigit((int)cb)) {
			fractional = (ca == '0' || cb == '0');

			if (fractional)
				result = compare_left(&ap, aend, &bp, bend);
			else
				result = compare_right(&ap, aend, &bp, bend);

			if (result != 0)
				return result;
			else if (ap == aend && bp == bend)
				/* End of the strings. Let caller sort them out. */
				return 0;
			else {
				/* Keep on comparing from the current point. */
				ca = *ap; cb = *bp;
			}
		}

		if (fold_case) {
			ca = toupper(ca);
			cb = toupper(cb);
		}

		if (ca < cb)
			return -1;
		else if (ca > cb)
			return +1;

		++ap; ++bp;
		if (ap == aend && bp == bend)
			/* The strings compare the same.  Perhaps the caller
			   will want to call strcmp to break the tie. */
			return 0;
		else if (ap == aend)
			return -1;
		else if (bp == bend)
			return 1;
	}
}
Example #5
0
/* {{{ strnatcmp_ex
 */
PHPAPI int strnatcmp_ex(char const *a, size_t a_len, char const *b, size_t b_len, int fold_case)
{
	unsigned char ca, cb;
	char const *ap, *bp;
	char const *aend = a + a_len,
			   *bend = b + b_len;
	int fractional, result;
	short leading = 1;

	if (a_len == 0 || b_len == 0) {
		result = 0;

		if (a_len > b_len) {
			if (a_len - b_len <= INT_MAX) {
				result = (int)(a_len - b_len);
			} else {
				result = 1;
			}
		} else {
			if (b_len - a_len <= (size_t)(-INT_MIN)) {
				result = -(int)(b_len - a_len);
			} else {
				result = -1;
			}
		}

		return result;
	}

	ap = a;
	bp = b;
	while (1) {
		ca = *ap; cb = *bp;

		/* skip over leading zeros */
		while (leading && ca == '0' && (ap+1 < aend) && isdigit(*(ap+1))) {
			ca = *++ap;
		}

		while (leading && cb == '0' && (bp+1 < bend) && isdigit(*(bp+1))) {
			cb = *++bp;
		}

		leading = 0;

		/* Skip consecutive whitespace */
		while (isspace((int)(unsigned char)ca)) {
			ca = *++ap;
		}

		while (isspace((int)(unsigned char)cb)) {
			cb = *++bp;
		}

		/* process run of digits */
		if (isdigit((int)(unsigned char)ca)  &&  isdigit((int)(unsigned char)cb)) {
			fractional = (ca == '0' || cb == '0');

			if (fractional)
				result = compare_left(&ap, aend, &bp, bend);
			else
				result = compare_right(&ap, aend, &bp, bend);

			if (result != 0)
				return result;
			else if (ap == aend && bp == bend)
				/* End of the strings. Let caller sort them out. */
				return 0;
			else {
				/* Keep on comparing from the current point. */
				ca = *ap; cb = *bp;
			}
		}

		if (fold_case) {
			ca = toupper((int)(unsigned char)ca);
			cb = toupper((int)(unsigned char)cb);
		}

		if (ca < cb)
			return -1;
		else if (ca > cb)
			return +1;

		++ap; ++bp;
		if (ap >= aend && bp >= bend)
			/* The strings compare the same.  Perhaps the caller
			   will want to call strcmp to break the tie. */
			return 0;
		else if (ap >= aend)
			return -1;
		else if (bp >= bend)
			return 1;
	}
}