- size_t I = strlen(A);
- size_t J = strlen(B);
- // If A and B are the same length, compare them ignoring case.
- if (I == J)
- return strcasecmp(A, B);
- // A is shorter than B. In this case A is less than B only when it's
- // lexicographically less than B. strncasecmp() == 0 means A is a prefix of B,
- // which in turn means A should appear *after* B.
- if (I < J)
- return strncasecmp(A, B, I) < 0 ? -1 : 1;
- // Otherwise, vice versa.
- return strncasecmp(A, B, J) <= 0 ? -1 : 1;
+ const char *X = A, *Y = B;
+ char a = tolower(*A), b = tolower(*B);
+ while (a == b) {
+ if (a == '\0')
+ return 0;
+
+ a = tolower(*++X);
+ b = tolower(*++Y);
+ }
+
+ if (a == '\0') // A is a prefix of B.
+ return 1;
+ if (b == '\0') // B is a prefix of A.
+ return -1;
+
+ // Otherwise lexicographic.
+ return (a < b) ? -1 : 1;