Subject: Use c_strcasecmp for portable ASCII case-insensitive comparison

From: Paul Eggert <[email-masked]>
Date: Mon, 25 Jun 2012 18:42:08 -0700

Tags: patch

Emacs currently use 'strcasecmp' and 'strncasecmp' for
case-insensitive comparison but these have problems in multibyte
locales.  In practice Emacs code really just wants a C-locale
version of these functions so I'm planning on installing the
following patch after some more testing.  I'm giving some
heads-up as this affects the Microsoft ports.

=== modified file 'ChangeLog'
--- ChangeLog	2012-06-26 01:05:39 +0000
+++ ChangeLog	2012-06-26 01:35:27 +0000
@@ -1,5 +1,14 @@
 2012-06-26  Paul Eggert  <[email-masked]>
 
+	Use c_strcasecmp for portable ASCII case-insensitive comparison.
+	This is safer than strcasecmp, which has unspecified behavior
+	outside the POSIX locale and in practice sometimes does not work
+	in multibyte locales.  Similarly for c_strncasecmp and strncasecmp.
+	* configure.in (strcasecmp, strncasecmp): Remove checks.
+	* lib/c-ctype.c, lib/c-ctype.h, lib/c-strcase.h, lib/c-strcasecmp.c:
+	* lib/c-strncasecmp.c: New files, taken from gnulib.
+	* lib/gnulib.mk, m4/gnulib-comp.m4: Regenerate.
+
 	Clean out last vestiges of the old HAVE_CONFIG_H stuff.
 	* lib/makefile.w32-in (LOCAL_FLAGS): Remove -DHAVE_CONFIG_H.

=== modified file 'admin/ChangeLog'
--- admin/ChangeLog	2012-06-24 16:18:41 +0000
+++ admin/ChangeLog	2012-06-26 01:35:27 +0000
@@ -1,3 +1,8 @@
+2012-06-26  Paul Eggert  <[email-masked]>
+
+	Use c_strcasecmp for portable ASCII case-insensitive comparison.
+	* merge-gnulib (GNULIB_MODULES): Add c-strcase.
+
 2012-06-24  Dmitry Antipov  <[email-masked]>
 
 	First Coccinelle semantic patch.

=== modified file 'admin/merge-gnulib'
--- admin/merge-gnulib	2012-06-22 21:17:42 +0000
+++ admin/merge-gnulib	2012-06-26 01:35:27 +0000
@@ -26,7 +26,7 @@
 GNULIB_URL=git://git.savannah.gnu.org/gnulib.git
 
 GNULIB_MODULES='
-  alloca-opt
+  alloca-opt c-strcase
   careadlinkat crypto/md5 crypto/sha1 crypto/sha256 crypto/sha512
   dtoastr dtotimespec dup2
   filemode getloadavg getopt-gnu gettime gettimeofday

=== modified file 'configure.in'
--- configure.in	2012-06-25 14:07:04 +0000
+++ configure.in	2012-06-26 01:35:27 +0000
@@ -2671,7 +2671,6 @@
 difftime posix_memalign \
 getpwent endpwent getgrent endgrent \
 touchlock \
-strcasecmp strncasecmp \
 cfmakeraw cfsetspeed copysign __executable_start)
 
 dnl Cannot use AC_CHECK_FUNCS

=== modified file 'lib-src/ChangeLog'
--- lib-src/ChangeLog	2012-06-26 01:05:39 +0000
+++ lib-src/ChangeLog	2012-06-26 01:35:27 +0000
@@ -1,5 +1,10 @@
 2012-06-26  Paul Eggert  <[email-masked]>
 
+	Use c_strcasecmp for portable ASCII case-insensitive comparison.
+	* etags.c: Include c-strcase.h.
+	(etags_strcasecmp, etags_strncasecmp): Remove.
+	All uses replaced with c_strcasecmp and c_strncasecmp.
+
 	Clean out last vestiges of the old HAVE_CONFIG_H stuff.
 	* Makefile.in (BASE_CFLAGS):
 	* makefile.w32-in (LOCAL_FLAGS): Remove -DHAVE_CONFIG_H.

=== modified file 'lib-src/etags.c'
--- lib-src/etags.c	2012-06-26 01:05:39 +0000
+++ lib-src/etags.c	2012-06-26 01:35:27 +0000
@@ -144,6 +144,7 @@
 #include <errno.h>
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <c-strcase.h>
 
 #include <assert.h>
 #ifdef NDEBUG
@@ -174,9 +175,9 @@
 #endif
 
 #define streq(s,t)	(assert ((s)!=NULL || (t)!=NULL), !strcmp (s, t))
-#define strcaseeq(s,t)	(assert ((s)!=NULL && (t)!=NULL), !etags_strcasecmp (s, t))
+#define strcaseeq(s,t)	(assert ((s)!=NULL && (t)!=NULL), !c_strcasecmp (s, t))
 #define strneq(s,t,n)	(assert ((s)!=NULL || (t)!=NULL), !strncmp (s, t, n))
-#define strncaseeq(s,t,n) (assert ((s)!=NULL && (t)!=NULL), !etags_strncasecmp (s, t, n))
+#define strncaseeq(s,t,n) (assert ((s)!=NULL && (t)!=NULL), !c_strncasecmp (s, t, n))
 
 #define CHARS 256		/* 2^sizeof(char) */
 #define CHAR(x)		((unsigned int)(x) & (CHARS - 1))
@@ -375,16 +376,6 @@
 static char *savestr (const char *);
 static char *etags_strchr (const char *, int);
 static char *etags_strrchr (const char *, int);
-#ifdef HAVE_STRCASECMP
-#define etags_strcasecmp(x,y) strcasecmp ((x), (y))
-#else
-static int etags_strcasecmp (const char *, const char *);
-#endif
-#ifdef HAVE_STRNCASECMP
-#define etags_strncasecmp(x,y,z) strncasecmp ((x), (y), (z))
-#else
-static int etags_strncasecmp (const char *, const char *, int);
-#endif
 static char *etags_getcwd (void);
 static char *relative_filename (char *, char *);
 static char *absolute_filename (char *, char *);
@@ -6314,52 +6305,6 @@
   return NULL;
 }
 
-#ifndef HAVE_STRCASECMP
-/*
- * Compare two strings, ignoring case for alphabetic characters.
- *
- * Same as BSD's strcasecmp, included for portability.
- */
-static int
-etags_strcasecmp (register const char *s1, register const char *s2)
-{
-  while (*s1 != '\0'
-	 && (ISALPHA (*s1) && ISALPHA (*s2)
-	     ? lowcase (*s1) == lowcase (*s2)
-	     : *s1 == *s2))
-    s1++, s2++;
-
-  return (ISALPHA (*s1) && ISALPHA (*s2)
-	  ? lowcase (*s1) - lowcase (*s2)
-	  : *s1 - *s2);
-}
-#endif /* HAVE_STRCASECMP */
-
-#ifndef HAVE_STRNCASECMP
-/*
- * Compare two strings, ignoring case for alphabetic characters.
- * Stop after a given number of characters
- *
- * Same as BSD's strncasecmp, included for portability.
- */
-static int
-etags_strncasecmp (register const char *s1, register const char *s2, register int n)
-{
-  while (*s1 != '\0' && n-- > 0
-	 && (ISALPHA (*s1) && ISALPHA (*s2)
-	     ? lowcase (*s1) == lowcase (*s2)
-	     : *s1 == *s2))
-    s1++, s2++;
-
-  if (n < 0)
-    return 0;
-  else
-    return (ISALPHA (*s1) && ISALPHA (*s2)
-	    ? lowcase (*s1) - lowcase (*s2)
-	    : *s1 - *s2);
-}
-#endif /* HAVE_STRCASECMP */
-
 /* Skip spaces (end of string is not space), return new pointer. */
 static char *
 skip_spaces (char *cp)

=== added file 'lib/c-ctype.c'
--- lib/c-ctype.c	1970-01-01 00:00:00 +0000
+++ lib/c-ctype.c	2012-06-26 01:35:27 +0000
@@ -0,0 +1,395 @@
+/* Character handling in C locale.
+
+   Copyright 2000-2003, 2006, 2009-2012 Free Software Foundation, Inc.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, see <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+
+/* Specification.  */
+#define NO_C_CTYPE_MACROS
+#include "c-ctype.h"
+
+/* The function isascii is not locale dependent. Its use in EBCDIC is
+   questionable. */
+bool
+c_isascii (int c)
+{
+  return (c >= 0x00 && c <= 0x7f);
+}
+
+bool
+c_isalnum (int c)
+{
+#if C_CTYPE_CONSECUTIVE_DIGITS \
+    && C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE
+#if C_CTYPE_ASCII
+  return ((c >= '0' && c <= '9')
+          || ((c & ~0x20) >= 'A' && (c & ~0x20) <= 'Z'));
+#else
+  return ((c >= '0' && c <= '9')
+          || (c >= 'A' && c <= 'Z')
+          || (c >= 'a' && c <= 'z'));
+#endif
+#else
+  switch (c)
+    {
+    case '0': case '1': case '2': case '3': case '4': case '5':
+    case '6': case '7': case '8': case '9':
+    case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
+    case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
+    case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
+    case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
+    case 'Y': case 'Z':
+    case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
+    case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
+    case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
+    case 's': case 't': case 'u': case 'v': case 'w': case 'x':
+    case 'y': case 'z':
+      return 1;
+    default:
+      return 0;
+    }
+#endif
+}
+
+bool
+c_isalpha (int c)
+{
+#if C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE
+#if C_CTYPE_ASCII
+  return ((c & ~0x20) >= 'A' && (c & ~0x20) <= 'Z');
+#else
+  return ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'));
+#endif
+#else
+  switch (c)
+    {
+    case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
+    case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
+    case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
+    case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
+    case 'Y': case 'Z':
+    case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
+    case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
+    case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
+    case 's': case 't': case 'u': case 'v': case 'w': case 'x':
+    case 'y': case 'z':
+      return 1;
+    default:
+      return 0;
+    }
+#endif
+}
+
+bool
+c_isblank (int c)
+{
+  return (c == ' ' || c == '\t');
+}
+
+bool
+c_iscntrl (int c)
+{
+#if C_CTYPE_ASCII
+  return ((c & ~0x1f) == 0 || c == 0x7f);
+#else
+  switch (c)
+    {
+    case ' ': case '!': case '"': case '#': case '$': case '%':
+    case '&': case '\'': case '(': case ')': case '*': case '+':
+    case ',': case '-': case '.': case '/':
+    case '0': case '1': case '2': case '3': case '4': case '5':
+    case '6': case '7': case '8': case '9':
+    case ':': case ';': case '<': case '=': case '>': case '?':
+    case '@':
+    case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
+    case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
+    case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
+    case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
+    case 'Y': case 'Z':
+    case '[': case '\\': case ']': case '^': case '_': case '`':
+    case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
+    case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
+    case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
+    case 's': case 't': case 'u': case 'v': case 'w': case 'x':
+    case 'y': case 'z':
+    case '{': case '|': case '}': case '~':
+      return 0;
+    default:
+      return 1;
+    }
+#endif
+}
+
+bool
+c_isdigit (int c)
+{
+#if C_CTYPE_CONSECUTIVE_DIGITS
+  return (c >= '0' && c <= '9');
+#else
+  switch (c)
+    {
+    case '0': case '1': case '2': case '3': case '4': case '5':
+    case '6': case '7': case '8': case '9':
+      return 1;
+    default:
+      return 0;
+    }
+#endif
+}
+
+bool
+c_islower (int c)
+{
+#if C_CTYPE_CONSECUTIVE_LOWERCASE
+  return (c >= 'a' && c <= 'z');
+#else
+  switch (c)
+    {
+    case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
+    case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
+    case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
+    case 's': case 't': case 'u': case 'v': case 'w': case 'x':
+    case 'y': case 'z':
+      return 1;
+    default:
+      return 0;
+    }
+#endif
+}
+
+bool
+c_isgraph (int c)
+{
+#if C_CTYPE_ASCII
+  return (c >= '!' && c <= '~');
+#else
+  switch (c)
+    {
+    case '!': case '"': case '#': case '$': case '%': case '&':
+    case '\'': case '(': case ')': case '*': case '+': case ',':
+    case '-': case '.': case '/':
+    case '0': case '1': case '2': case '3': case '4': case '5':
+    case '6': case '7': case '8': case '9':
+    case ':': case ';': case '<': case '=': case '>': case '?':
+    case '@':
+    case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
+    case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
+    case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
+    case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
+    case 'Y': case 'Z':
+    case '[': case '\\': case ']': case '^': case '_': case '`':
+    case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
+    case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
+    case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
+    case 's': case 't': case 'u': case 'v': case 'w': case 'x':
+    case 'y': case 'z':
+    case '{': case '|': case '}': case '~':
+      return 1;
+    default:
+      return 0;
+    }
+#endif
+}
+
+bool
+c_isprint (int c)
+{
+#if C_CTYPE_ASCII
+  return (c >= ' ' && c <= '~');
+#else
+  switch (c)
+    {
+    case ' ': case '!': case '"': case '#': case '$': case '%':
+    case '&': case '\'': case '(': case ')': case '*': case '+':
+    case ',': case '-': case '.': case '/':
+    case '0': case '1': case '2': case '3': case '4': case '5':
+    case '6': case '7': case '8': case '9':
+    case ':': case ';': case '<': case '=': case '>': case '?':
+    case '@':
+    case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
+    case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
+    case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
+    case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
+    case 'Y': case 'Z':
+    case '[': case '\\': case ']': case '^': case '_': case '`':
+    case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
+    case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
+    case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
+    case 's': case 't': case 'u': case 'v': case 'w': case 'x':
+    case 'y': case 'z':
+    case '{': case '|': case '}': case '~':
+      return 1;
+    default:
+      return 0;
+    }
+#endif
+}
+
+bool
+c_ispunct (int c)
+{
+#if C_CTYPE_ASCII
+  return ((c >= '!' && c <= '~')
+          && !((c >= '0' && c <= '9')
+               || ((c & ~0x20) >= 'A' && (c & ~0x20) <= 'Z')));
+#else
+  switch (c)
+    {
+    case '!': case '"': case '#': case '$': case '%': case '&':
+    case '\'': case '(': case ')': case '*': case '+': case ',':
+    case '-': case '.': case '/':
+    case ':': case ';': case '<': case '=': case '>': case '?':
+    case '@':
+    case '[': case '\\': case ']': case '^': case '_': case '`':
+    case '{': case '|': case '}': case '~':
+      return 1;
+    default:
+      return 0;
+    }
+#endif
+}
+
+bool
+c_isspace (int c)
+{
+  return (c == ' ' || c == '\t'
+          || c == '\n' || c == '\v' || c == '\f' || c == '\r');
+}
+
+bool
+c_isupper (int c)
+{
+#if C_CTYPE_CONSECUTIVE_UPPERCASE
+  return (c >= 'A' && c <= 'Z');
+#else
+  switch (c)
+    {
+    case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
+    case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
+    case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
+    case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
+    case 'Y': case 'Z':
+      return 1;
+    default:
+      return 0;
+    }
+#endif
+}
+
+bool
+c_isxdigit (int c)
+{
+#if C_CTYPE_CONSECUTIVE_DIGITS \
+    && C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE
+#if C_CTYPE_ASCII
+  return ((c >= '0' && c <= '9')
+          || ((c & ~0x20) >= 'A' && (c & ~0x20) <= 'F'));
+#else
+  return ((c >= '0' && c <= '9')
+          || (c >= 'A' && c <= 'F')
+          || (c >= 'a' && c <= 'f'));
+#endif
+#else
+  switch (c)
+    {
+    case '0': case '1': case '2': case '3': case '4': case '5':
+    case '6': case '7': case '8': case '9':
+    case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
+    case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
+      return 1;
+    default:
+      return 0;
+    }
+#endif
+}
+
+int
+c_tolower (int c)
+{
+#if C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE
+  return (c >= 'A' && c <= 'Z' ? c - 'A' + 'a' : c);
+#else
+  switch (c)
+    {
+    case 'A': return 'a';
+    case 'B': return 'b';
+    case 'C': return 'c';
+    case 'D': return 'd';
+    case 'E': return 'e';
+    case 'F': return 'f';
+    case 'G': return 'g';
+    case 'H': return 'h';
+    case 'I': return 'i';
+    case 'J': return 'j';
+    case 'K': return 'k';
+    case 'L': return 'l';
+    case 'M': return 'm';
+    case 'N': return 'n';
+    case 'O': return 'o';
+    case 'P': return 'p';
+    case 'Q': return 'q';
+    case 'R': return 'r';
+    case 'S': return 's';
+    case 'T': return 't';
+    case 'U': return 'u';
+    case 'V': return 'v';
+    case 'W': return 'w';
+    case 'X': return 'x';
+    case 'Y': return 'y';
+    case 'Z': return 'z';
+    default: return c;
+    }
+#endif
+}
+
+int
+c_toupper (int c)
+{
+#if C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE
+  return (c >= 'a' && c <= 'z' ? c - 'a' + 'A' : c);
+#else
+  switch (c)
+    {
+    case 'a': return 'A';
+    case 'b': return 'B';
+    case 'c': return 'C';
+    case 'd': return 'D';
+    case 'e': return 'E';
+    case 'f': return 'F';
+    case 'g': return 'G';
+    case 'h': return 'H';
+    case 'i': return 'I';
+    case 'j': return 'J';
+    case 'k': return 'K';
+    case 'l': return 'L';
+    case 'm': return 'M';
+    case 'n': return 'N';
+    case 'o': return 'O';
+    case 'p': return 'P';
+    case 'q': return 'Q';
+    case 'r': return 'R';
+    case 's': return 'S';
+    case 't': return 'T';
+    case 'u': return 'U';
+    case 'v': return 'V';
+    case 'w': return 'W';
+    case 'x': return 'X';
+    case 'y': return 'Y';
+    case 'z': return 'Z';
+    default: return c;
+    }
+#endif
+}

=== added file 'lib/c-ctype.h'
--- lib/c-ctype.h	1970-01-01 00:00:00 +0000
+++ lib/c-ctype.h	2012-06-26 01:35:27 +0000
@@ -0,0 +1,294 @@
+/* Character handling in C locale.
+
+   These functions work like the corresponding functions in <ctype.h>,
+   except that they have the C (POSIX) locale hardwired, whereas the
+   <ctype.h> functions' behaviour depends on the current locale set via
+   setlocale.
+
+   Copyright (C) 2000-2003, 2006, 2008-2012 Free Software Foundation, Inc.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef C_CTYPE_H
+#define C_CTYPE_H
+
+#include <stdbool.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* The functions defined in this file assume the "C" locale and a character
+   set without diacritics (ASCII-US or EBCDIC-US or something like that).
+   Even if the "C" locale on a particular system is an extension of the ASCII
+   character set (like on BeOS, where it is UTF-8, or on AmigaOS, where it
+   is ISO-8859-1), the functions in this file recognize only the ASCII
+   characters.  */
+
+
+/* Check whether the ASCII optimizations apply. */
+
+/* ANSI C89 (and ISO C99 5.2.1.3 too) already guarantees that
+   '0', '1', ..., '9' have consecutive integer values.  */
+#define C_CTYPE_CONSECUTIVE_DIGITS 1
+
+#if ('A' <= 'Z') \
+    && ('A' + 1 == 'B') && ('B' + 1 == 'C') && ('C' + 1 == 'D') \
+    && ('D' + 1 == 'E') && ('E' + 1 == 'F') && ('F' + 1 == 'G') \
+    && ('G' + 1 == 'H') && ('H' + 1 == 'I') && ('I' + 1 == 'J') \
+    && ('J' + 1 == 'K') && ('K' + 1 == 'L') && ('L' + 1 == 'M') \
+    && ('M' + 1 == 'N') && ('N' + 1 == 'O') && ('O' + 1 == 'P') \
+    && ('P' + 1 == 'Q') && ('Q' + 1 == 'R') && ('R' + 1 == 'S') \
+    && ('S' + 1 == 'T') && ('T' + 1 == 'U') && ('U' + 1 == 'V') \
+    && ('V' + 1 == 'W') && ('W' + 1 == 'X') && ('X' + 1 == 'Y') \
+    && ('Y' + 1 == 'Z')
+#define C_CTYPE_CONSECUTIVE_UPPERCASE 1
+#endif
+
+#if ('a' <= 'z') \
+    && ('a' + 1 == 'b') && ('b' + 1 == 'c') && ('c' + 1 == 'd') \
+    && ('d' + 1 == 'e') && ('e' + 1 == 'f') && ('f' + 1 == 'g') \
+    && ('g' + 1 == 'h') && ('h' + 1 == 'i') && ('i' + 1 == 'j') \
+    && ('j' + 1 == 'k') && ('k' + 1 == 'l') && ('l' + 1 == 'm') \
+    && ('m' + 1 == 'n') && ('n' + 1 == 'o') && ('o' + 1 == 'p') \
+    && ('p' + 1 == 'q') && ('q' + 1 == 'r') && ('r' + 1 == 's') \
+    && ('s' + 1 == 't') && ('t' + 1 == 'u') && ('u' + 1 == 'v') \
+    && ('v' + 1 == 'w') && ('w' + 1 == 'x') && ('x' + 1 == 'y') \
+    && ('y' + 1 == 'z')
+#define C_CTYPE_CONSECUTIVE_LOWERCASE 1
+#endif
+
+#if (' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
+    && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
+    && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \
+    && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \
+    && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \
+    && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \
+    && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \
+    && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \
+    && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \
+    && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \
+    && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \
+    && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \
+    && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \
+    && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \
+    && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \
+    && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \
+    && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \
+    && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \
+    && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \
+    && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \
+    && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \
+    && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \
+    && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)
+/* The character set is ASCII or one of its variants or extensions, not EBCDIC.
+   Testing the value of '\n' and '\r' is not relevant.  */
+#define C_CTYPE_ASCII 1
+#endif
+
+
+/* Function declarations. */
+
+/* Unlike the functions in <ctype.h>, which require an argument in the range
+   of the 'unsigned char' type, the functions here operate on values that are
+   in the 'unsigned char' range or in the 'char' range.  In other words,
+   when you have a 'char' value, you need to cast it before using it as
+   argument to a <ctype.h> function:
+
+         const char *s = ...;
+         if (isalpha ((unsigned char) *s)) ...
+
+   but you don't need to cast it for the functions defined in this file:
+
+         const char *s = ...;
+         if (c_isalpha (*s)) ...
+ */
+
+extern bool c_isascii (int c) _GL_ATTRIBUTE_CONST; /* not locale dependent */
+
+extern bool c_isalnum (int c) _GL_ATTRIBUTE_CONST;
+extern bool c_isalpha (int c) _GL_ATTRIBUTE_CONST;
+extern bool c_isblank (int c) _GL_ATTRIBUTE_CONST;
+extern bool c_iscntrl (int c) _GL_ATTRIBUTE_CONST;
+extern bool c_isdigit (int c) _GL_ATTRIBUTE_CONST;
+extern bool c_islower (int c) _GL_ATTRIBUTE_CONST;
+extern bool c_isgraph (int c) _GL_ATTRIBUTE_CONST;
+extern bool c_isprint (int c) _GL_ATTRIBUTE_CONST;
+extern bool c_ispunct (int c) _GL_ATTRIBUTE_CONST;
+extern bool c_isspace (int c) _GL_ATTRIBUTE_CONST;
+extern bool c_isupper (int c) _GL_ATTRIBUTE_CONST;
+extern bool c_isxdigit (int c) _GL_ATTRIBUTE_CONST;
+
+extern int c_tolower (int c) _GL_ATTRIBUTE_CONST;
+extern int c_toupper (int c) _GL_ATTRIBUTE_CONST;
+
+
+#if defined __GNUC__ && defined __OPTIMIZE__ && !defined __OPTIMIZE_SIZE__ && !defined NO_C_CTYPE_MACROS
+
+/* ASCII optimizations. */
+
+#undef c_isascii
+#define c_isascii(c) \
+  ({ int __c = (c); \
+     (__c >= 0x00 && __c <= 0x7f); \
+   })
+
+#if C_CTYPE_CONSECUTIVE_DIGITS \
+    && C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE
+#if C_CTYPE_ASCII
+#undef c_isalnum
+#define c_isalnum(c) \
+  ({ int __c = (c); \
+     ((__c >= '0' && __c <= '9') \
+      || ((__c & ~0x20) >= 'A' && (__c & ~0x20) <= 'Z')); \
+   })
+#else
+#undef c_isalnum
+#define c_isalnum(c) \
+  ({ int __c = (c); \
+     ((__c >= '0' && __c <= '9') \
+      || (__c >= 'A' && __c <= 'Z') \
+      || (__c >= 'a' && __c <= 'z')); \
+   })
+#endif
+#endif
+
+#if C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE
+#if C_CTYPE_ASCII
+#undef c_isalpha
+#define c_isalpha(c) \
+  ({ int __c = (c); \
+     ((__c & ~0x20) >= 'A' && (__c & ~0x20) <= 'Z'); \
+   })
+#else
+#undef c_isalpha
+#define c_isalpha(c) \
+  ({ int __c = (c); \
+     ((__c >= 'A' && __c <= 'Z') || (__c >= 'a' && __c <= 'z')); \
+   })
+#endif
+#endif
+
+#undef c_isblank
+#define c_isblank(c) \
+  ({ int __c = (c); \
+     (__c == ' ' || __c == '\t'); \
+   })
+
+#if C_CTYPE_ASCII
+#undef c_iscntrl
+#define c_iscntrl(c) \
+  ({ int __c = (c); \
+     ((__c & ~0x1f) == 0 || __c == 0x7f); \
+   })
+#endif
+
+#if C_CTYPE_CONSECUTIVE_DIGITS
+#undef c_isdigit
+#define c_isdigit(c) \
+  ({ int __c = (c); \
+     (__c >= '0' && __c <= '9'); \
+   })
+#endif
+
+#if C_CTYPE_CONSECUTIVE_LOWERCASE
+#undef c_islower
+#define c_islower(c) \
+  ({ int __c = (c); \
+     (__c >= 'a' && __c <= 'z'); \
+   })
+#endif
+
+#if C_CTYPE_ASCII
+#undef c_isgraph
+#define c_isgraph(c) \
+  ({ int __c = (c); \
+     (__c >= '!' && __c <= '~'); \
+   })
+#endif
+
+#if C_CTYPE_ASCII
+#undef c_isprint
+#define c_isprint(c) \
+  ({ int __c = (c); \
+     (__c >= ' ' && __c <= '~'); \
+   })
+#endif
+
+#if C_CTYPE_ASCII
+#undef c_ispunct
+#define c_ispunct(c) \
+  ({ int _c = (c); \
+     (c_isgraph (_c) && ! c_isalnum (_c)); \
+   })
+#endif
+
+#undef c_isspace
+#define c_isspace(c) \
+  ({ int __c = (c); \
+     (__c == ' ' || __c == '\t' \
+      || __c == '\n' || __c == '\v' || __c == '\f' || __c == '\r'); \
+   })
+
+#if C_CTYPE_CONSECUTIVE_UPPERCASE
+#undef c_isupper
+#define c_isupper(c) \
+  ({ int __c = (c); \
+     (__c >= 'A' && __c <= 'Z'); \
+   })
+#endif
+
+#if C_CTYPE_CONSECUTIVE_DIGITS \
+    && C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE
+#if C_CTYPE_ASCII
+#undef c_isxdigit
+#define c_isxdigit(c) \
+  ({ int __c = (c); \
+     ((__c >= '0' && __c <= '9') \
+      || ((__c & ~0x20) >= 'A' && (__c & ~0x20) <= 'F')); \
+   })
+#else
+#undef c_isxdigit
+#define c_isxdigit(c) \
+  ({ int __c = (c); \
+     ((__c >= '0' && __c <= '9') \
+      || (__c >= 'A' && __c <= 'F') \
+      || (__c >= 'a' && __c <= 'f')); \
+   })
+#endif
+#endif
+
+#if C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE
+#undef c_tolower
+#define c_tolower(c) \
+  ({ int __c = (c); \
+     (__c >= 'A' && __c <= 'Z' ? __c - 'A' + 'a' : __c); \
+   })
+#undef c_toupper
+#define c_toupper(c) \
+  ({ int __c = (c); \
+     (__c >= 'a' && __c <= 'z' ? __c - 'a' + 'A' : __c); \
+   })
+#endif
+
+#endif /* optimizing for speed */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* C_CTYPE_H */

=== added file 'lib/c-strcase.h'
--- lib/c-strcase.h	1970-01-01 00:00:00 +0000
+++ lib/c-strcase.h	2012-06-26 01:35:27 +0000
@@ -0,0 +1,56 @@
+/* Case-insensitive string comparison functions in C locale.
+   Copyright (C) 1995-1996, 2001, 2003, 2005, 2009-2012 Free Software
+   Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef C_STRCASE_H
+#define C_STRCASE_H
+
+#include <stddef.h>
+
+
+/* The functions defined in this file assume the "C" locale and a character
+   set without diacritics (ASCII-US or EBCDIC-US or something like that).
+   Even if the "C" locale on a particular system is an extension of the ASCII
+   character set (like on BeOS, where it is UTF-8, or on AmigaOS, where it
+   is ISO-8859-1), the functions in this file recognize only the ASCII
+   characters.  More precisely, one of the string arguments must be an ASCII
+   string; the other one can also contain non-ASCII characters (but then
+   the comparison result will be nonzero).  */
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* Compare strings S1 and S2, ignoring case, returning less than, equal to or
+   greater than zero if S1 is lexicographically less than, equal to or greater
+   than S2.  */
+extern int c_strcasecmp (const char *s1, const char *s2) _GL_ATTRIBUTE_PURE;
+
+/* Compare no more than N characters of strings S1 and S2, ignoring case,
+   returning less than, equal to or greater than zero if S1 is
+   lexicographically less than, equal to or greater than S2.  */
+extern int c_strncasecmp (const char *s1, const char *s2, size_t n)
+  _GL_ATTRIBUTE_PURE;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* C_STRCASE_H */

=== added file 'lib/c-strcasecmp.c'
--- lib/c-strcasecmp.c	1970-01-01 00:00:00 +0000
+++ lib/c-strcasecmp.c	2012-06-26 01:35:27 +0000
@@ -0,0 +1,56 @@
+/* c-strcasecmp.c -- case insensitive string comparator in C locale
+   Copyright (C) 1998-1999, 2005-2006, 2009-2012 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, see <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+
+/* Specification.  */
+#include "c-strcase.h"
+
+#include <limits.h>
+
+#include "c-ctype.h"
+
+int
+c_strcasecmp (const char *s1, const char *s2)
+{
+  register const unsigned char *p1 = (const unsigned char *) s1;
+  register const unsigned char *p2 = (const unsigned char *) s2;
+  unsigned char c1, c2;
+
+  if (p1 == p2)
+    return 0;
+
+  do
+    {
+      c1 = c_tolower (*p1);
+      c2 = c_tolower (*p2);
+
+      if (c1 == '\0')
+        break;
+
+      ++p1;
+      ++p2;
+    }
+  while (c1 == c2);
+
+  if (UCHAR_MAX <= INT_MAX)
+    return c1 - c2;
+  else
+    /* On machines where 'char' and 'int' are types of the same size, the
+       difference of two 'unsigned char' values - including the sign bit -
+       doesn't fit in an 'int'.  */
+    return (c1 > c2 ? 1 : c1 < c2 ? -1 : 0);
+}

=== added file 'lib/c-strncasecmp.c'
--- lib/c-strncasecmp.c	1970-01-01 00:00:00 +0000
+++ lib/c-strncasecmp.c	2012-06-26 01:35:27 +0000
@@ -0,0 +1,56 @@
+/* c-strncasecmp.c -- case insensitive string comparator in C locale
+   Copyright (C) 1998-1999, 2005-2006, 2009-2012 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, see <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+
+/* Specification.  */
+#include "c-strcase.h"
+
+#include <limits.h>
+
+#include "c-ctype.h"
+
+int
+c_strncasecmp (const char *s1, const char *s2, size_t n)
+{
+  register const unsigned char *p1 = (const unsigned char *) s1;
+  register const unsigned char *p2 = (const unsigned char *) s2;
+  unsigned char c1, c2;
+
+  if (p1 == p2 || n == 0)
+    return 0;
+
+  do
+    {
+      c1 = c_tolower (*p1);
+      c2 = c_tolower (*p2);
+
+      if (--n == 0 || c1 == '\0')
+        break;
+
+      ++p1;
+      ++p2;
+    }
+  while (c1 == c2);
+
+  if (UCHAR_MAX <= INT_MAX)
+    return c1 - c2;
+  else
+    /* On machines where 'char' and 'int' are types of the same size, the
+       difference of two 'unsigned char' values - including the sign bit -
+       doesn't fit in an 'int'.  */
+    return (c1 > c2 ? 1 : c1 < c2 ? -1 : 0);
+}

=== modified file 'lib/gnulib.mk'
--- lib/gnulib.mk	2012-06-22 21:17:42 +0000
+++ lib/gnulib.mk	2012-06-26 01:35:27 +0000
@@ -21,7 +21,7 @@
 # the same distribution terms as the rest of that program.
 #
 # Generated by gnulib-tool.
-# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --avoid=errno --avoid=fcntl --avoid=fcntl-h --avoid=fstat --avoid=msvc-inval --avoid=msvc-nothrow --avoid=raise --avoid=select --avoid=sigprocmask --avoid=sys_types --avoid=threadlib --makefile-name=gnulib.mk --conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files alloca-opt careadlinkat crypto/md5 crypto/sha1 crypto/sha256 crypto/sha512 dtoastr dtotimespec dup2 filemode getloadavg getopt-gnu gettime gettimeofday ignore-value intprops largefile lstat manywarnings mktime pselect pthread_sigmask readlink socklen stat-time stdarg stdio strftime strtoimax strtoumax symlink sys_stat sys_time time timespec-add timespec-sub utimens warnings
+# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --avoid=errno --avoid=fcntl --avoid=fcntl-h --avoid=fstat --avoid=msvc-inval --avoid=msvc-nothrow --avoid=raise --avoid=select --avoid=sigprocmask --avoid=sys_types --avoid=threadlib --makefile-name=gnulib.mk --conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files alloca-opt c-strcase careadlinkat crypto/md5 crypto/sha1 crypto/sha256 crypto/sha512 dtoastr dtotimespec dup2 filemode getloadavg getopt-gnu gettime gettimeofday ignore-value intprops largefile lstat manywarnings mktime pselect pthread_sigmask readlink socklen stat-time stdarg stdio strftime strtoimax strtoumax symlink sys_stat sys_time time timespec-add timespec-sub utimens warnings

 MOSTLYCLEANFILES += core *.stackdump
@@ -64,6 +64,18 @@
 
 ## end   gnulib module allocator
 
+## begin gnulib module c-ctype
+
+libgnu_a_SOURCES += c-ctype.h c-ctype.c
+
+## end   gnulib module c-ctype
+
+## begin gnulib module c-strcase
+
+libgnu_a_SOURCES += c-strcase.h c-strcasecmp.c c-strncasecmp.c
+
+## end   gnulib module c-strcase
+
 ## begin gnulib module careadlinkat
 
 libgnu_a_SOURCES += careadlinkat.c

=== modified file 'lwlib/ChangeLog'
--- lwlib/ChangeLog	2012-06-26 01:05:39 +0000
+++ lwlib/ChangeLog	2012-06-26 01:35:27 +0000
@@ -1,5 +1,9 @@
 2012-06-26  Paul Eggert  <[email-masked]>
 
+	Use c_strcasecmp for portable ASCII case-insensitive comparison.
+	* lwlib.c: Include c-strcase.h.
+	(lwlib_strcasecmp): Remove.  All uses replaced with c_strcasecmp.
+
 	Clean out last vestiges of the old HAVE_CONFIG_H stuff.
 	* Makefile.in (ALL_CFLAGS): Remove -DHAVE_CONFIG_H.
 	* lwlib-Xaw.c, lwlib-Xlw.c, lwlib-Xm.c, lwlib-utils.c, lwlib.c:

=== modified file 'lwlib/lwlib.c'
--- lwlib/lwlib.c	2012-06-26 01:05:39 +0000
+++ lwlib/lwlib.c	2012-06-26 01:35:27 +0000
@@ -24,6 +24,7 @@
 
 #include <setjmp.h>
 #include <lisp.h>
+#include <c-strcase.h>
 
 #include <sys/types.h>
 #include <stdio.h>
@@ -112,31 +113,6 @@
   return result;
 }
 
-#ifdef HAVE_STRCASECMP
-#define lwlib_strcasecmp(x,y) strcasecmp ((x), (y))
-#else
-
-/* Like strcmp but ignore differences in case.  */
-
-static int
-lwlib_strcasecmp (const char *s1, const char *s2)
-{
-  while (1)
-    {
-      int c1 = *s1++;
-      int c2 = *s2++;
-      if (isupper (c1))
-	c1 = tolower (c1);
-      if (isupper (c2))
-	c2 = tolower (c2);
-      if (c1 != c2)
-	return (c1 > c2 ? 1 : -1);
-      if (c1 == 0)
-	return 0;
-    }
-}
-#endif /* HAVE_STRCASECMP */
-
 static void
 safe_free_str (char *s)
 {
@@ -733,7 +709,7 @@
 {
   const widget_creation_entry* cur;
   for (cur = table; cur->type; cur++)
-    if (!lwlib_strcasecmp (type, cur->type))
+    if (!c_strcasecmp (type, cur->type))
       return cur->function;
   return NULL;
 }

=== modified file 'm4/gnulib-comp.m4'
--- m4/gnulib-comp.m4	2012-06-22 21:17:42 +0000
+++ m4/gnulib-comp.m4	2012-06-26 01:35:27 +0000
@@ -40,6 +40,8 @@
   AC_REQUIRE([gl_PROG_AR_RANLIB])
   # Code from module alloca-opt:
   # Code from module allocator:
+  # Code from module c-ctype:
+  # Code from module c-strcase:
   # Code from module careadlinkat:
   # Code from module clock-time:
   # Code from module crypto/md5:
@@ -518,6 +520,11 @@
   lib/alloca.in.h
   lib/allocator.c
   lib/allocator.h
+  lib/c-ctype.c
+  lib/c-ctype.h
+  lib/c-strcase.h
+  lib/c-strcasecmp.c
+  lib/c-strncasecmp.c
   lib/careadlinkat.c
   lib/careadlinkat.h
   lib/dosname.h

=== modified file 'src/ChangeLog'
--- src/ChangeLog	2012-06-26 01:05:39 +0000
+++ src/ChangeLog	2012-06-26 01:35:27 +0000
@@ -1,5 +1,14 @@
 2012-06-26  Paul Eggert  <[email-masked]>
 
+	Use c_strcasecmp for portable ASCII case-insensitive comparison.
+	* dispextern.h (xstrcasecmp): Remove decl.
+	* dosfns.c, font.c, fontset.c, ftfont.c, image.c, nsfns.m, nsterm.m:
+	* process.c, w32.h, w32font.c, xfaces.c, xfns.c, xfont.c:
+	Include <c-strcase.h>.  Replace all uses of xstrcasecmp with
+	c_strcasecmp.
+	* xfaces.c (xstrcasecmp): Remove.
+	* xfont.c (compare_font_names): Rewrite to avoid casts.
+
 	Clean out last vestiges of the old HAVE_CONFIG_H stuff.
 	* Makefile.in (ALL_CFLAGS):
 	* makefile.w32-in (LOCAL_FLAGS): Remove -DHAVE_CONFIG_H.

=== modified file 'src/dispextern.h'
--- src/dispextern.h	2012-06-25 14:07:04 +0000
+++ src/dispextern.h	2012-06-26 01:35:27 +0000
@@ -3216,11 +3216,6 @@
 char *choose_face_font (struct frame *, Lisp_Object *, Lisp_Object,
                         int *);
 void prepare_face_for_display (struct frame *, struct face *);
-#ifdef HAVE_STRCASECMP
-#define xstrcasecmp(x,y) strcasecmp ((x), (y))
-#else
-int xstrcasecmp (const char *, const char *);
-#endif
 int lookup_named_face (struct frame *, Lisp_Object, int);
 int lookup_basic_face (struct frame *, int);
 int smaller_face (struct frame *, int, int);

=== modified file 'src/dosfns.c'
--- src/dosfns.c	2012-06-19 16:56:28 +0000
+++ src/dosfns.c	2012-06-26 01:35:27 +0000
@@ -25,6 +25,7 @@
 #include <stdio.h>
 #include <dos.h>
 #include <setjmp.h>
+#include <c-strcase.h>
 #include "lisp.h"
 #include "character.h"
 #include "buffer.h"
@@ -396,7 +397,7 @@
   int i;
 
   for (i = 0; i < sizeof (vga_colors) / sizeof (vga_colors[0]); i++)
-    if (xstrcasecmp (name, vga_colors[i]) == 0)
+    if (c_strcasecmp (name, vga_colors[i]) == 0)
       return i;
 
   return
@@ -764,4 +765,3 @@
   dos_decimal_point = 0;
 }
 #endif /* MSDOS */
-

=== modified file 'src/font.c'
--- src/font.c	2012-06-19 16:56:28 +0000
+++ src/font.c	2012-06-26 01:35:27 +0000
@@ -24,6 +24,7 @@
 #include <float.h>
 #include <stdio.h>
 #include <ctype.h>
+#include <c-strcase.h>
 #include <setjmp.h>
 
 #include "lisp.h"
@@ -346,7 +347,7 @@
 	for (j = 1; j < ASIZE (AREF (table, i)); j++)
 	  {
 	    elt = AREF (AREF (table, i), j);
-	    if (xstrcasecmp (s, SSDATA (SYMBOL_NAME (elt))) == 0)
+	    if (c_strcasecmp (s, SSDATA (SYMBOL_NAME (elt))) == 0)
 	      return ((XINT (AREF (AREF (table, i), 0)) << 8)
 		      | (i << 4) | (j - 1));
 	  }

=== modified file 'src/fontset.c'
--- src/fontset.c	2012-06-16 12:24:15 +0000
+++ src/fontset.c	2012-06-26 01:35:27 +0000
@@ -29,6 +29,7 @@
 #include <config.h>
 #include <stdio.h>
 #include <setjmp.h>
+#include <c-strcase.h>
 
 #include "lisp.h"
 #include "blockinput.h"
@@ -1173,7 +1174,7 @@
       this_name = FONTSET_NAME (fontset);
       if (name_pattern == 1
 	  ? fast_string_match_ignore_case (name, this_name) >= 0
-	  : !xstrcasecmp (SSDATA (name), SSDATA (this_name)))
+	  : !c_strcasecmp (SSDATA (name), SSDATA (this_name)))
 	return i;
     }
   return -1;

=== modified file 'src/ftfont.c'
--- src/ftfont.c	2012-06-13 00:26:40 +0000
+++ src/ftfont.c	2012-06-26 01:35:27 +0000
@@ -26,6 +26,8 @@
 #include <fontconfig/fontconfig.h>
 #include <fontconfig/fcfreetype.h>
 
+#include <c-strcase.h>
+
 #include "lisp.h"
 #include "dispextern.h"
 #include "frame.h"
@@ -166,8 +168,8 @@
 
 #ifdef FC_FONTFORMAT
   if ((FcPatternGetString (p, FC_FONTFORMAT, 0, &fcstr) == FcResultMatch)
-      && xstrcasecmp ((char *) fcstr, "bdf") != 0
-      && xstrcasecmp ((char *) fcstr, "pcf") != 0)
+      && c_strcasecmp ((char *) fcstr, "bdf") != 0
+      && c_strcasecmp ((char *) fcstr, "pcf") != 0)
     /* Not a BDF nor PCF font.  */
     return Qnil;
 #endif
@@ -183,10 +185,10 @@
       end = newstr + (end - str);
       str = newstr;
     }
-  if (xstrcasecmp (str, "Regular") == 0
-      || xstrcasecmp (str, "Bold") == 0
-      || xstrcasecmp (str, "Oblique") == 0
-      || xstrcasecmp (str, "Italic") == 0)
+  if (c_strcasecmp (str, "Regular") == 0
+      || c_strcasecmp (str, "Bold") == 0
+      || c_strcasecmp (str, "Oblique") == 0
+      || c_strcasecmp (str, "Italic") == 0)
     return Qnil;
   adstyle = font_intern_prop (str, end - str, 1);
   if (font_style_to_value (FONT_WIDTH_INDEX, adstyle, 0) >= 0)
@@ -1051,12 +1053,12 @@
 
 	  if (! NILP (adstyle)
 	      && (NILP (this_adstyle)
-		  || xstrcasecmp (SSDATA (SYMBOL_NAME (adstyle)),
-				  SSDATA (SYMBOL_NAME (this_adstyle))) != 0))
+		  || c_strcasecmp (SSDATA (SYMBOL_NAME (adstyle)),
+				   SSDATA (SYMBOL_NAME (this_adstyle))) != 0))
 	    continue;
 	  if (langname
 	      && ! NILP (this_adstyle)
-	      && xstrcasecmp (langname, SSDATA (SYMBOL_NAME (this_adstyle))))
+	      && c_strcasecmp (langname, SSDATA (SYMBOL_NAME (this_adstyle))))
 	    continue;
 	}
       entity = ftfont_pattern_entity (fontset->fonts[i],
@@ -2625,13 +2627,13 @@
       if (len >= 4)
 	{
 	  str = (FcChar8 *) (SDATA (filename) + len - 4);
-	  if (xstrcasecmp ((char *) str, ".ttf") == 0)
+	  if (c_strcasecmp ((char *) str, ".ttf") == 0)
 	    return intern ("truetype");
-	  if (xstrcasecmp ((char *) str, ".pfb") == 0)
+	  if (c_strcasecmp ((char *) str, ".pfb") == 0)
 	    return intern ("type1");
-	  if (xstrcasecmp ((char *) str, ".pcf") == 0)
+	  if (c_strcasecmp ((char *) str, ".pcf") == 0)
 	    return intern ("pcf");
-	  if (xstrcasecmp ((char *) str, ".bdf") == 0)
+	  if (c_strcasecmp ((char *) str, ".bdf") == 0)
 	    return intern ("bdf");
 	}
     }

=== modified file 'src/image.c'
--- src/image.c	2012-06-24 17:39:14 +0000
+++ src/image.c	2012-06-26 01:35:27 +0000
@@ -21,6 +21,7 @@
 #include <stdio.h>
 #include <math.h>
 #include <ctype.h>
+#include <c-strcase.h>
 #include <unistd.h>
 
 #ifdef HAVE_PNG
@@ -3969,7 +3970,7 @@
 
 	  if (CONSP (specified_color) && STRINGP (XCDR (specified_color)))
 	    {
-	      if (xstrcasecmp (SSDATA (XCDR (specified_color)), "None") == 0)
+	      if (c_strcasecmp (SSDATA (XCDR (specified_color)), "None") == 0)
 		color_val = Qt;
 	      else if (x_defined_color (f, SDATA (XCDR (specified_color)),
 					&cdef, 0))
@@ -3978,7 +3979,7 @@
 	}
       if (NILP (color_val) && max_key > 0)
 	{
-	  if (xstrcasecmp (max_color, "None") == 0)
+	  if (c_strcasecmp (max_color, "None") == 0)
 	    color_val = Qt;
 	  else if (x_defined_color (f, max_color, &cdef, 0))
 	    color_val = make_number (cdef.pixel);

=== modified file 'src/nsfns.m'
--- src/nsfns.m	2012-06-16 12:24:15 +0000
+++ src/nsfns.m	2012-06-26 01:35:27 +0000
@@ -33,6 +33,7 @@
 #include <signal.h>
 #include <math.h>
 #include <setjmp.h>
+#include <c-strcase.h>
 
 #include "lisp.h"
 #include "blockinput.h"
@@ -2227,8 +2228,8 @@
 
   res = ns_get_defaults_value (toCheck);
   return !res ? NULL :
-      (!strncasecmp (res, "YES", 3) ? "true" :
-          (!strncasecmp (res, "NO", 2) ? "false" : res));
+      (!c_strncasecmp (res, "YES", 3) ? "true" :
+          (!c_strncasecmp (res, "NO", 2) ? "false" : res));
 }

=== modified file 'src/nsterm.m'
--- src/nsterm.m	2012-06-22 21:17:42 +0000
+++ src/nsterm.m	2012-06-26 01:35:27 +0000
@@ -36,6 +36,7 @@
 #include <signal.h>
 #include <unistd.h>
 #include <setjmp.h>
+#include <c-strcase.h>
 
 #include "lisp.h"
 #include "blockinput.h"
@@ -3855,9 +3856,9 @@
     {
       double f;
       char *pos;
-      if (strcasecmp (value, "YES") == 0)
+      if (c_strcasecmp (value, "YES") == 0)
         *result = yesval;
-      else if (strcasecmp (value, "NO") == 0)
+      else if (c_strcasecmp (value, "NO") == 0)
         *result = noval;
       else if (is_float && (f = strtod (value, &pos), pos != value))
         *result = make_float (f);
@@ -6074,7 +6075,7 @@
 
   if (nr_screens == 1)
     return [super constrainFrameRect:frameRect toScreen:screen];
-  
+
   if (f->output_data.ns->dont_constrain
       || ns_menu_bar_should_be_hidden ())
     return frameRect;

=== modified file 'src/process.c'
--- src/process.c	2012-06-24 20:34:48 +0000
+++ src/process.c	2012-06-26 01:35:27 +0000
@@ -31,6 +31,7 @@
 
 #include <unistd.h>
 #include <fcntl.h>
+#include <c-strcase.h>
 
 #include "lisp.h"
 
@@ -6124,7 +6125,7 @@
     }
 
 #define parse_signal(NAME, VALUE)		\
-  else if (!xstrcasecmp (name, NAME))		\
+  else if (!c_strcasecmp (name, NAME))		\
     XSETINT (sigcode, VALUE)
 
   if (INTEGERP (sigcode))

=== modified file 'src/w32.c'
--- src/w32.c	2012-06-23 16:56:47 +0000
+++ src/w32.c	2012-06-26 01:35:27 +0000
@@ -140,7 +140,7 @@
 #include "ndir.h"
 #include "w32heap.h"
 #include "systime.h"
-#include "dispextern.h"		/* for xstrcasecmp */
+#include "c-strcase.h"
 #include "coding.h"		/* for Vlocale_coding_system */
 
 #include "careadlinkat.h"
@@ -1025,7 +1025,7 @@
   if (!pw)
     return pw;
 
-  if (xstrcasecmp (name, pw->pw_name))
+  if (c_strcasecmp (name, pw->pw_name))
     return NULL;
 
   return pw;
@@ -1076,7 +1076,7 @@
     {
       strcpy (dflt_passwd.pw_name, uname);
       /* Determine a reasonable uid value.  */
-      if (xstrcasecmp ("administrator", uname) == 0)
+      if (c_strcasecmp ("administrator", uname) == 0)
 	{
 	  dflt_passwd.pw_uid = 500; /* well-known Administrator uid */
 	  dflt_passwd.pw_gid = 513; /* well-known None gid */
@@ -1118,7 +1118,7 @@
   else if (GetUserName (uname, &ulength))
     {
       strcpy (dflt_passwd.pw_name, uname);
-      if (xstrcasecmp ("administrator", uname) == 0)
+      if (c_strcasecmp ("administrator", uname) == 0)
 	dflt_passwd.pw_uid = 0;
       else
 	dflt_passwd.pw_uid = 123;
@@ -1674,7 +1674,7 @@
 	abort ();
       *p = 0;
 
-      if ((p = strrchr (modname, '\\')) && xstrcasecmp (p, "\\bin") == 0)
+      if ((p = strrchr (modname, '\\')) && c_strcasecmp (p, "\\bin") == 0)
 	{
 	  char buf[SET_ENV_BUF_SIZE];
 
@@ -1690,7 +1690,7 @@
       /* FIXME: should use substring of get_emacs_configuration ().
 	 But I don't think the Windows build supports alpha, mips etc
          anymore, so have taken the easy option for now.  */
-      else if (p && xstrcasecmp (p, "\\i386") == 0)
+      else if (p && c_strcasecmp (p, "\\i386") == 0)
 	{
 	  *p = 0;
 	  p = strrchr (modname, '\\');
@@ -1698,7 +1698,7 @@
 	    {
 	      *p = 0;
 	      p = strrchr (modname, '\\');
-	      if (p && xstrcasecmp (p, "\\src") == 0)
+	      if (p && c_strcasecmp (p, "\\src") == 0)
 		{
 		  char buf[SET_ENV_BUF_SIZE];
 
@@ -2101,7 +2101,7 @@
   volume_info_data * info;
 
   for (info = volume_cache; info; info = info->next)
-    if (xstrcasecmp (info->root_dir, root_dir) == 0)
+    if (c_strcasecmp (info->root_dir, root_dir) == 0)
       break;
   return info;
 }
@@ -2379,10 +2379,10 @@
   char * p = strrchr (name, '.');
   return
     (p != NULL
-     && (xstrcasecmp (p, ".exe") == 0 ||
-	 xstrcasecmp (p, ".com") == 0 ||
-	 xstrcasecmp (p, ".bat") == 0 ||
-	 xstrcasecmp (p, ".cmd") == 0));
+     && (c_strcasecmp (p, ".exe") == 0 ||
+	 c_strcasecmp (p, ".com") == 0 ||
+	 c_strcasecmp (p, ".bat") == 0 ||
+	 c_strcasecmp (p, ".cmd") == 0));
 }
 
 /* Emulate the Unix directory procedures opendir, closedir,
@@ -3450,7 +3450,7 @@
       if (dir_find_handle != INVALID_HANDLE_VALUE
 	  && strnicmp (name, dir_pathname, len) == 0
 	  && IS_DIRECTORY_SEP (name[len])
-	  && xstrcasecmp (name + len + 1, dir_static.d_name) == 0)
+	  && c_strcasecmp (name + len + 1, dir_static.d_name) == 0)
 	{
 	  /* This was the last entry returned by readdir.  */
 	  wfd = dir_find_data;
@@ -3673,10 +3673,10 @@
 #if 0 /* no way of knowing the filename */
       char * p = strrchr (name, '.');
       if (p != NULL &&
-	  (xstrcasecmp (p, ".exe") == 0 ||
-	   xstrcasecmp (p, ".com") == 0 ||
-	   xstrcasecmp (p, ".bat") == 0 ||
-	   xstrcasecmp (p, ".cmd") == 0))
+	  (c_strcasecmp (p, ".exe") == 0 ||
+	   c_strcasecmp (p, ".com") == 0 ||
+	   c_strcasecmp (p, ".bat") == 0 ||
+	   c_strcasecmp (p, ".cmd") == 0))
 	permission |= S_IEXEC;
 #endif
     }
@@ -4290,7 +4290,7 @@
       if (result)
 	{
 	  /* Determine a reasonable euid and gid values.  */
-	  if (xstrcasecmp ("administrator", uname) == 0)
+	  if (c_strcasecmp ("administrator", uname) == 0)
 	    {
 	      euid = 500;	/* well-known Administrator uid */
 	      egid = 513;	/* well-known None gid */
@@ -4351,7 +4351,7 @@
 	 user.  */
       else if (GetUserName (uname, &ulength))
 	{
-	  if (xstrcasecmp ("administrator", uname) == 0)
+	  if (c_strcasecmp ("administrator", uname) == 0)
 	    euid = 0;
 	  else
 	    euid = 123;

=== modified file 'src/w32font.c'
--- src/w32font.c	2012-05-02 10:12:13 +0000
+++ src/w32font.c	2012-06-26 01:35:27 +0000
@@ -20,6 +20,7 @@
 #include <windows.h>
 #include <math.h>
 #include <ctype.h>
+#include <c-strcase.h>
 #include <commdlg.h>
 #include <setjmp.h>
 
@@ -1466,7 +1467,7 @@
      to avoid non-truetype fonts, and ends up mixing the Type-1 Helvetica
      with Arial's characteristics, since that attempt to use TrueType works
      some places, but not others.  */
-  if (!xstrcasecmp (font->lfFaceName, "helvetica"))
+  if (!c_strcasecmp (font->lfFaceName, "helvetica"))
     {
       strncpy (full_iname, full_name, LF_FULLFACESIZE);
       full_iname[LF_FULLFACESIZE] = 0;
@@ -1474,7 +1475,7 @@
       return strstr ("helvetica", full_iname) != NULL;
     }
   /* Same for Helv.  */
-  if (!xstrcasecmp (font->lfFaceName, "helv"))
+  if (!c_strcasecmp (font->lfFaceName, "helv"))
     {
       strncpy (full_iname, full_name, LF_FULLFACESIZE);
       full_iname[LF_FULLFACESIZE] = 0;
@@ -1484,8 +1485,8 @@
 
   /* Since Times is mapped to Times New Roman, a substring
      match is not sufficient to filter out the bogus match.  */
-  else if (!xstrcasecmp (font->lfFaceName, "times"))
-    return xstrcasecmp (full_name, "times") == 0;
+  else if (!c_strcasecmp (font->lfFaceName, "times"))
+    return c_strcasecmp (full_name, "times") == 0;
 
   return 1;
 }
@@ -1660,7 +1661,7 @@
   if (NILP (this_entry))
     {
       /* At startup, we want iso8859-1 fonts to come up properly. */
-      if (xstrcasecmp (charset, "iso8859-1") == 0)
+      if (c_strcasecmp (charset, "iso8859-1") == 0)
         return ANSI_CHARSET;
       else
         return DEFAULT_CHARSET;

=== modified file 'src/w32proc.c'
--- src/w32proc.c	2012-06-23 12:44:42 +0000
+++ src/w32proc.c	2012-06-26 01:35:27 +0000
@@ -50,6 +50,8 @@
 #include <langinfo.h>
 #endif
 
+#include <c-strcase.h>
+
 #include "lisp.h"
 #include "w32.h"
 #include "w32heap.h"
@@ -58,7 +60,6 @@
 #include "process.h"
 #include "syssignal.h"
 #include "w32term.h"
-#include "dispextern.h"		/* for xstrcasecmp */
 #include "coding.h"
 
 #define RVA_TO_PTR(var,section,filedata) \
@@ -599,10 +600,10 @@
   p = strrchr (filename, '.');
 
   /* We can only identify DOS .com programs from the extension. */
-  if (p && xstrcasecmp (p, ".com") == 0)
+  if (p && c_strcasecmp (p, ".com") == 0)
     *is_dos_app = TRUE;
-  else if (p && (xstrcasecmp (p, ".bat") == 0
-		 || xstrcasecmp (p, ".cmd") == 0))
+  else if (p && (c_strcasecmp (p, ".bat") == 0
+		 || c_strcasecmp (p, ".cmd") == 0))
     {
       /* A DOS shell script - it appears that CreateProcess is happy to
 	 accept this (somewhat surprisingly); presumably it looks at

=== modified file 'src/xfaces.c'
--- src/xfaces.c	2012-06-25 14:07:04 +0000
+++ src/xfaces.c	2012-06-26 01:35:27 +0000
@@ -205,6 +205,7 @@
 #include <sys/stat.h>
 #include <stdio.h>              /* This needs to be before termchar.h */
 #include <setjmp.h>
+#include <c-strcase.h>
 
 #include "lisp.h"
 #include "character.h"
@@ -716,30 +717,6 @@
 }
 #endif  /* HAVE_NS */
 
-#ifndef HAVE_STRCASECMP
-/* Like strcasecmp/stricmp.  Used to compare parts of font names which
-   are in ISO8859-1.  */
-
-int
-xstrcasecmp (const char *s1, const char *s2)
-{
-  while (*s1 && *s2)
-    {
-      unsigned char b1 = *s1;
-      unsigned char b2 = *s2;
-      unsigned char c1 = tolower (b1);
-      unsigned char c2 = tolower (b2);
-      if (c1 != c2)
-	return c1 < c2 ? -1 : 1;
-      ++s1, ++s2;
-    }
-
-  if (*s1 == 0)
-    return *s2 == 0 ? 0 : -1;
-  return 1;
-}
-#endif /* HAVE_STRCASECMP */
-
 /* If FRAME is nil, return a pointer to the selected frame.
    Otherwise, check that FRAME is a live frame, and return a pointer
    to it.  NPARAM is the parameter number of FRAME, for
@@ -1257,8 +1234,8 @@
 #ifdef HAVE_WINDOW_SYSTEM
     FRAME_WINDOW_P (f)
     ? (!NILP (Fxw_display_color_p (frame))
-       || xstrcasecmp (color_name, "black") == 0
-       || xstrcasecmp (color_name, "white") == 0
+       || c_strcasecmp (color_name, "black") == 0
+       || c_strcasecmp (color_name, "white") == 0
        || (background_p
 	   && face_color_gray_p (f, color_name))
        || (!NILP (Fx_display_grayscale_p (frame))
@@ -2953,7 +2930,7 @@
   else if (EQ (attr, QCunderline))
     {
       int valid_p = 0;
-      
+
       if (UNSPECIFIEDP (value) || IGNORE_DEFFACE_P (value))
 	valid_p = 1;
       else if (NILP (value) || EQ (value, Qt))
@@ -2973,8 +2950,8 @@
               list = CDR_SAFE (list);
               val = CAR_SAFE (list);
               list = CDR_SAFE (list);
-            
-              if(NILP (key) || NILP (val)) 
+
+              if(NILP (key) || NILP (val))
                 {
                   valid_p = 0;
                   break;
@@ -2987,8 +2964,8 @@
                   valid_p = 0;
                   break;
                 }
-              
-              else if (EQ (key, QCstyle) 
+
+              else if (EQ (key, QCstyle)
                        && !(EQ (val, Qline) || EQ (val, Qwave)))
                 {
                   valid_p = 0;
@@ -2996,10 +2973,10 @@
                 }
             }
         }
-      
+
       if (!valid_p)
         signal_error ("Invalid face underline", value);
-      
+
       old_value = LFACE_UNDERLINE (lface);
       LFACE_UNDERLINE (lface) = value;
     }
@@ -3517,13 +3494,13 @@
 
   xassert (STRINGP (value));
 
-  if (xstrcasecmp (SSDATA (value), "on") == 0
-      || xstrcasecmp (SSDATA (value), "true") == 0)
+  if (c_strcasecmp (SSDATA (value), "on") == 0
+      || c_strcasecmp (SSDATA (value), "true") == 0)
     result = Qt;
-  else if (xstrcasecmp (SSDATA (value), "off") == 0
-	   || xstrcasecmp (SSDATA (value), "false") == 0)
+  else if (c_strcasecmp (SSDATA (value), "off") == 0
+	   || c_strcasecmp (SSDATA (value), "false") == 0)
     result = Qnil;
-  else if (xstrcasecmp (SSDATA (value), "unspecified") == 0)
+  else if (c_strcasecmp (SSDATA (value), "unspecified") == 0)
     result = Qunspecified;
   else if (signal_p)
     signal_error ("Invalid face attribute value from X resource", value);
@@ -3542,7 +3519,7 @@
   CHECK_SYMBOL (attr);
   CHECK_STRING (value);
 
-  if (xstrcasecmp (SSDATA (value), "unspecified") == 0)
+  if (c_strcasecmp (SSDATA (value), "unspecified") == 0)
     value = Qunspecified;
   else if (EQ (attr, QCheight))
     {
@@ -4121,10 +4098,10 @@
 {
   xassert (lface_fully_specified_p (lface1)
 	   && lface_fully_specified_p (lface2));
-  return (xstrcasecmp (SSDATA (lface1[LFACE_FAMILY_INDEX]),
-		       SSDATA (lface2[LFACE_FAMILY_INDEX])) == 0
-	  && xstrcasecmp (SSDATA (lface1[LFACE_FOUNDRY_INDEX]),
-			  SSDATA (lface2[LFACE_FOUNDRY_INDEX])) == 0
+  return (c_strcasecmp (SSDATA (lface1[LFACE_FAMILY_INDEX]),
+			SSDATA (lface2[LFACE_FAMILY_INDEX])) == 0
+	  && c_strcasecmp (SSDATA (lface1[LFACE_FOUNDRY_INDEX]),
+			   SSDATA (lface2[LFACE_FOUNDRY_INDEX])) == 0
 	  && EQ (lface1[LFACE_HEIGHT_INDEX], lface2[LFACE_HEIGHT_INDEX])
 	  && EQ (lface1[LFACE_SWIDTH_INDEX], lface2[LFACE_SWIDTH_INDEX])
 	  && EQ (lface1[LFACE_WEIGHT_INDEX], lface2[LFACE_WEIGHT_INDEX])
@@ -4133,8 +4110,8 @@
 	  && (EQ (lface1[LFACE_FONTSET_INDEX], lface2[LFACE_FONTSET_INDEX])
 	      || (STRINGP (lface1[LFACE_FONTSET_INDEX])
 		  && STRINGP (lface2[LFACE_FONTSET_INDEX])
-		  && ! xstrcasecmp (SSDATA (lface1[LFACE_FONTSET_INDEX]),
-				    SSDATA (lface2[LFACE_FONTSET_INDEX]))))
+		  && ! c_strcasecmp (SSDATA (lface1[LFACE_FONTSET_INDEX]),
+				     SSDATA (lface2[LFACE_FONTSET_INDEX]))))
 	  );
 }
 
@@ -5779,7 +5756,7 @@
     }
   else if (CONSP (underline))
     {
-      /* `(:color COLOR :style STYLE)'.  
+      /* `(:color COLOR :style STYLE)'.
          STYLE being one of `line' or `wave'. */
       face->underline_p = 1;
       face->underline_color = 0;
@@ -5821,7 +5798,7 @@
             }
         }
     }
-  
+
   overline = attrs[LFACE_OVERLINE_INDEX];
   if (STRINGP (overline))
     {

=== modified file 'src/xfns.c'
--- src/xfns.c	2012-06-25 10:16:11 +0000
+++ src/xfns.c	2012-06-26 01:35:27 +0000
@@ -21,6 +21,7 @@
 #include <stdio.h>
 #include <math.h>
 #include <setjmp.h>
+#include <c-strcase.h>
 #include <ctype.h>
 #include <unistd.h>
 
@@ -1881,7 +1882,7 @@
 
   /* Make a fontset name from the base font name.  */
   if (xic_default_fontset == base_fontname)
-    { 
+    {
       /* There is no base font name, use the default.  */
       fontsetname = xmalloc (strlen (base_fontname) + 2);
       strcpy (fontsetname, base_fontname);
@@ -3977,7 +3978,7 @@
 
       /* Determine the visual class.  */
       for (i = 0; visual_classes[i].name; ++i)
-	if (xstrcasecmp (s, visual_classes[i].name) == 0)
+	if (c_strcasecmp (s, visual_classes[i].name) == 0)
 	  {
 	    class = visual_classes[i].class;
 	    break;

=== modified file 'src/xfont.c'
--- src/xfont.c	2012-06-13 00:26:40 +0000
+++ src/xfont.c	2012-06-26 01:35:27 +0000
@@ -23,6 +23,7 @@
 #include <stdio.h>
 #include <setjmp.h>
 #include <X11/Xlib.h>
+#include <c-strcase.h>
 
 #include "lisp.h"
 #include "dispextern.h"
@@ -164,8 +165,9 @@
 static int
 compare_font_names (const void *name1, const void *name2)
 {
-  return xstrcasecmp (*(const char **) name1,
-		      *(const char **) name2);
+  char *const *n1 = name1;
+  char *const *n2 = name2;
+  return c_strcasecmp (*n1, *n2);
 }
 
 /* Decode XLFD as iso-8859-1 into OUTPUT, and return the byte length
@@ -398,7 +400,7 @@
 	{
 	  Lisp_Object entity;
 
-	  if (i > 0 && xstrcasecmp (indices[i - 1], indices[i]) == 0)
+	  if (i > 0 && c_strcasecmp (indices[i - 1], indices[i]) == 0)
 	    continue;
 	  entity = font_make_entity ();
 	  xfont_decode_coding_xlfd (indices[i], -1, buf);