changeset 2332:29c53b9ebe92

locale-independent ASCII character case handling Basically, I and i are different letters in Turkic languages, and this causes problems for str(n)casecmp and toupper/tolower in these locales when dillo is dealing with ASCII.
author corvid <corvid@lavabit.com>
date Fri, 11 Nov 2011 04:26:41 +0000
parents 32af8c55f1bc
children 3788d44f371b
files dlib/dlib.c dlib/dlib.h dpi/bookmarks.c dpi/cookies.c dpi/datauri.c dpi/downloads.cc dpi/dpiutil.c dpi/file.c dpi/ftp.c dpi/https.c dpid/dpid.c dw/fltkplatform.cc dw/style.cc lout/misc.hh src/IO/http.c src/IO/mime.c src/auth.c src/cache.c src/capi.c src/colors.c src/cookies.c src/css.cc src/cssparser.cc src/decode.c src/form.cc src/html.cc src/keys.cc src/misc.c src/prefsparser.cc src/table.cc src/uicmd.cc src/url.c src/web.cc test/dw_anchors_test.cc
diffstat 34 files changed, 309 insertions(+), 250 deletions(-) [+]
line wrap: on
line diff
--- a/dlib/dlib.c	Fri Nov 11 03:48:55 2011 +0000
+++ b/dlib/dlib.c	Fri Nov 11 04:26:41 2011 +0000
@@ -173,16 +173,21 @@
 }
 
 /*
+ * ASCII functions to avoid the case difficulties introduced by I/i in
+ * Turkic locales.
+ */
+
+/*
  * Case insensitive strstr
  */
-char *dStristr(const char *haystack, const char *needle)
+char *dStriAsciiStr(const char *haystack, const char *needle)
 {
    int i, j;
    char *ret = NULL;
 
    if (haystack && needle) {
       for (i = 0, j = 0; haystack[i] && needle[j]; ++i)
-         if (tolower(haystack[i]) == tolower(needle[j])) {
+         if (D_ASCII_TOLOWER(haystack[i]) == D_ASCII_TOLOWER(needle[j])) {
             ++j;
          } else if (j) {
             i -= j;
@@ -194,6 +199,29 @@
    return ret;
 }
 
+int dStrAsciiCasecmp(const char *s1, const char *s2)
+{
+   int ret = 0;
+
+   while ((*s1 || *s2) &&
+          !(ret = D_ASCII_TOLOWER(*s1) - D_ASCII_TOLOWER(*s2))) {
+      s1++;
+      s2++;
+   }
+   return ret;
+}
+
+int dStrnAsciiCasecmp(const char *s1, const char *s2, size_t n)
+{
+   int ret = 0;
+
+   while (n-- && (*s1 || *s2) &&
+          !(ret = D_ASCII_TOLOWER(*s1) - D_ASCII_TOLOWER(*s2))) {
+      s1++;
+      s2++;
+   }
+   return ret;
+}
 
 /*
  *- dStr ----------------------------------------------------------------------
--- a/dlib/dlib.h	Fri Nov 11 03:48:55 2011 +0000
+++ b/dlib/dlib.h	Fri Nov 11 04:26:41 2011 +0000
@@ -5,7 +5,6 @@
 #include <stddef.h>    /* for size_t */
 #include <stdarg.h>    /* for va_list */
 #include <string.h>    /* for strerror */
-#include <strings.h>   /* for strcasecmp, strncasecmp (POSIX 2001) */
 
 #include "d_size.h"
 
@@ -34,6 +33,8 @@
 #define dIsspace(c) isspace((uchar_t)(c))
 #define dIsalnum(c) isalnum((uchar_t)(c))
 
+#define D_ASCII_TOUPPER(c) (((c) >= 'a' && (c) <= 'z') ? (c) - 0x20 : (c))
+#define D_ASCII_TOLOWER(c) (((c) >= 'A' && (c) <= 'Z') ? (c) + 0x20 : (c))
 /*
  *-- Casts -------------------------------------------------------------------
  */
@@ -86,12 +87,11 @@
 char *dStrstrip(char *s);
 char *dStrnfill(size_t len, char c);
 char *dStrsep(char **orig, const char *delim);
-char *dStristr(const char *haystack, const char *needle);
 void dStrshred(char *s);
+char *dStriAsciiStr(const char *haystack, const char *needle);
+int dStrAsciiCasecmp(const char *s1, const char *s2);
+int dStrnAsciiCasecmp(const char *s1, const char *s2, size_t n);
 
-/* these are in POSIX 2001. Could be implemented if a port requires it */
-#define dStrcasecmp strcasecmp
-#define dStrncasecmp strncasecmp
 #define dStrerror strerror
 
 /*
--- a/dpi/bookmarks.c	Fri Nov 11 03:48:55 2011 +0000
+++ b/dpi/bookmarks.c	Fri Nov 11 04:26:41 2011 +0000
@@ -442,7 +442,7 @@
       if (*e == '+') {
          *p = ' ';
       } else if (*e == '%') {
-         if (dStrncasecmp(e, "%0D%0A", 6) == 0) {
+         if (dStrnAsciiCasecmp(e, "%0D%0A", 6) == 0) {
             *p = '\n';
             e += 5;
          } else {
--- a/dpi/cookies.c	Fri Nov 11 03:48:55 2011 +0000
+++ b/dpi/cookies.c	Fri Nov 11 04:26:41 2011 +0000
@@ -158,7 +158,7 @@
 {
    const DomainNode *n1 = v1, *n2 = v2;
 
-   return dStrcasecmp(n1->domain, n2->domain);
+   return dStrAsciiCasecmp(n1->domain, n2->domain);
 }
 
 /*
@@ -169,7 +169,7 @@
    const DomainNode *node = v1;
    const char *domain = v2;
 
-   return dStrcasecmp(node->domain, domain);
+   return dStrAsciiCasecmp(node->domain, domain);
 }
 
 /*
@@ -468,7 +468,7 @@
    int i;
 
    for (i = 0; i < 12; i++) {
-      if (!dStrncasecmp(months[i], month_name, 3))
+      if (!dStrnAsciiCasecmp(months[i], month_name, 3))
          return i;
    }
    return -1;
@@ -821,15 +821,15 @@
          cookie->expires_at = mktime(tm);
          if (cookie->expires_at == (time_t) -1)
             cookie->expires_at = cookies_future_time;
-      } else if (dStrcasecmp(attr, "Path") == 0) {
+      } else if (dStrAsciiCasecmp(attr, "Path") == 0) {
          value = Cookies_parse_value(&str);
          dFree(cookie->path);
          cookie->path = value;
-      } else if (dStrcasecmp(attr, "Domain") == 0) {
+      } else if (dStrAsciiCasecmp(attr, "Domain") == 0) {
          value = Cookies_parse_value(&str);
          dFree(cookie->domain);
          cookie->domain = value;
-      } else if (dStrcasecmp(attr, "Max-Age") == 0) {
+      } else if (dStrAsciiCasecmp(attr, "Max-Age") == 0) {
          value = Cookies_parse_value(&str);
          if (isdigit(*value) || *value == '-') {
             time_t now = time(NULL);
@@ -845,7 +845,7 @@
             expires = max_age = TRUE;
          }
          dFree(value);
-      } else if (dStrcasecmp(attr, "Expires") == 0) {
+      } else if (dStrAsciiCasecmp(attr, "Expires") == 0) {
          if (!max_age) {
             value = Cookies_parse_value(&str);
             Cookies_unquote_string(value);
@@ -870,10 +870,10 @@
          } else {
             Cookies_eat_value(&str);
          }
-      } else if (dStrcasecmp(attr, "Secure") == 0) {
+      } else if (dStrAsciiCasecmp(attr, "Secure") == 0) {
          cookie->secure = TRUE;
          Cookies_eat_value(&str);
-      } else if (dStrcasecmp(attr, "HttpOnly") == 0) {
+      } else if (dStrAsciiCasecmp(attr, "HttpOnly") == 0) {
          Cookies_eat_value(&str);
       } else {
          MSG("Cookie contains unknown attribute: '%s'\n", attr);
@@ -992,7 +992,7 @@
     * don't, so: No.
     */
 
-   if (!dStrcasecmp(A, B))
+   if (!dStrAsciiCasecmp(A, B))
       return TRUE;
 
    if (Cookies_domain_is_ip(B))
@@ -1002,7 +1002,7 @@
 
    if (diff > 0) {
       /* B is the tail of A, and the match is preceded by a '.' */
-      return (dStrcasecmp(A + diff, B) == 0 && A[diff - 1] == '.');
+      return (dStrAsciiCasecmp(A + diff, B) == 0 && A[diff - 1] == '.');
    } else {
       return FALSE;
    }
@@ -1050,7 +1050,7 @@
 
          for (i = 0; i < tld_num; i++) {
             if (strlen(tlds[i]) == (uint_t) tld_len &&
-                !dStrncasecmp(tlds[i], host + start, tld_len)) {
+                !dStrnAsciiCasecmp(tlds[i], host + start, tld_len)) {
                _MSG("TLD code matched %s\n", tlds[i]);
                ret++;
                break;
@@ -1221,7 +1221,7 @@
    matching_cookies = dList_new(8);
 
    /* Check if the protocol is secure or not */
-   is_ssl = (!dStrcasecmp(url_scheme, "https"));
+   is_ssl = (!dStrAsciiCasecmp(url_scheme, "https"));
 
    is_ip_addr = Cookies_domain_is_ip(url_host);
 
@@ -1350,11 +1350,11 @@
             rule[j++] = line[i++];
          rule[j] = '\0';
 
-         if (dStrcasecmp(rule, "ACCEPT") == 0)
+         if (dStrAsciiCasecmp(rule, "ACCEPT") == 0)
             cc.action = COOKIE_ACCEPT;
-         else if (dStrcasecmp(rule, "ACCEPT_SESSION") == 0)
+         else if (dStrAsciiCasecmp(rule, "ACCEPT_SESSION") == 0)
             cc.action = COOKIE_ACCEPT_SESSION;
-         else if (dStrcasecmp(rule, "DENY") == 0)
+         else if (dStrAsciiCasecmp(rule, "DENY") == 0)
             cc.action = COOKIE_DENY;
          else {
             MSG("Cookies: rule '%s' for domain '%s' is not recognised.\n",
@@ -1363,7 +1363,7 @@
          }
 
          cc.domain = dStrdup(domain);
-         if (dStrcasecmp(cc.domain, "DEFAULT") == 0) {
+         if (dStrAsciiCasecmp(cc.domain, "DEFAULT") == 0) {
             /* Set the default action */
             default_action = cc.action;
             dFree(cc.domain);
@@ -1404,13 +1404,13 @@
       if (ccontrol[i].domain[0] == '.') {
          diff = strlen(domain) - strlen(ccontrol[i].domain);
          if (diff >= 0) {
-            if (dStrcasecmp(domain + diff, ccontrol[i].domain) != 0)
+            if (dStrAsciiCasecmp(domain + diff, ccontrol[i].domain) != 0)
                continue;
          } else {
             continue;
          }
       } else {
-         if (dStrcasecmp(domain, ccontrol[i].domain) != 0)
+         if (dStrAsciiCasecmp(domain, ccontrol[i].domain) != 0)
             continue;
       }
 
--- a/dpi/datauri.c	Fri Nov 11 03:48:55 2011 +0000
+++ b/dpi/datauri.c	Fri Nov 11 04:26:41 2011 +0000
@@ -226,14 +226,14 @@
    char *mime_type = NULL, *p;
    size_t len = 0;
 
-   if (dStrncasecmp(url, "data:", 5) == 0) {
+   if (dStrnAsciiCasecmp(url, "data:", 5) == 0) {
       if ((p = strchr(url, ',')) && p - url < 256) {
          url += 5;
          len = p - url;
          strncpy(buf, url, len);
          buf[len] = 0;
          /* strip ";base64" */
-         if (len >= 7 && dStrcasecmp(buf + len - 7, ";base64") == 0) {
+         if (len >= 7 && dStrAsciiCasecmp(buf + len - 7, ";base64") == 0) {
             len -= 7;
             buf[len] = 0;
          }
@@ -242,7 +242,7 @@
       /* that's it, now handle omitted types */
       if (len == 0) {
          mime_type = dStrdup("text/plain;charset=US-ASCII");
-      } else if (!dStrncasecmp(buf, "charset", 7)) {
+      } else if (!dStrnAsciiCasecmp(buf, "charset", 7)) {
          mime_type = dStrconcat("text/plain", buf, NULL);
       } else {
          mime_type = dStrdup(buf);
@@ -262,7 +262,7 @@
    unsigned char *data = NULL;
 
    if ((p = strchr(url, ',')) && p - url >= 12 &&  /* "data:;base64" */
-       dStrncasecmp(p - 7, ";base64", 7) == 0) {
+       dStrnAsciiCasecmp(p - 7, ";base64", 7) == 0) {
       is_base64 = 1;
    }
 
--- a/dpi/downloads.cc	Fri Nov 11 03:48:55 2011 +0000
+++ b/dpi/downloads.cc	Fri Nov 11 04:26:41 2011 +0000
@@ -327,7 +327,7 @@
    /* escape "'" character for the shell. Is it necessary? */
    esc_url = Escape_uri_str(url, "'");
    /* avoid malicious SMTP relaying with FTP urls */
-   if (dStrncasecmp(esc_url, "ftp:/", 5) == 0)
+   if (dStrnAsciiCasecmp(esc_url, "ftp:/", 5) == 0)
       Filter_smtp_hack(esc_url);
    dl_argv = new char*[8];
    int i = 0;
--- a/dpi/dpiutil.c	Fri Nov 11 03:48:55 2011 +0000
+++ b/dpi/dpiutil.c	Fri Nov 11 04:26:41 2011 +0000
@@ -68,8 +68,10 @@
    if (strchr(s, '%')) {
       for (p = buf; (*p = *s); ++s, ++p) {
          if (*p == '%' && isxdigit(s[1]) && isxdigit(s[2])) {
-            *p = (isdigit(s[1]) ? (s[1] - '0') : toupper(s[1]) - 'A' + 10)*16;
-            *p += isdigit(s[2]) ? (s[2] - '0') : toupper(s[2]) - 'A' + 10;
+            *p = (isdigit(s[1]) ? (s[1] - '0')
+                                : D_ASCII_TOUPPER(s[1]) - 'A' + 10) * 16;
+            *p += isdigit(s[2]) ? (s[2] - '0')
+                                : D_ASCII_TOUPPER(s[2]) - 'A' + 10;
             s += 2;
          }
       }
@@ -121,7 +123,7 @@
    for (i = 0, j = 0; str[i]; ++i) {
       if (str[i] == '&') {
          for (k = 0; k < 5; ++k) {
-            if (!dStrncasecmp(str + i, unsafe_rep[k], unsafe_rep_len[k])) {
+            if (!dStrnAsciiCasecmp(str + i, unsafe_rep[k], unsafe_rep_len[k])) {
                i += unsafe_rep_len[k] - 1;
                break;
             }
@@ -154,7 +156,8 @@
             memmove(url + i, url + i + 1, strlen(url + i));
             --i;
          } else if (c == '%' && url[i+1] == '0' &&
-                    (tolower(url[i+2]) == 'a' || tolower(url[i+2]) == 'd')) {
+                    (D_ASCII_TOLOWER(url[i+2]) == 'a' ||
+                     D_ASCII_TOLOWER(url[i+2]) == 'd')) {
             memmove(url + i, url + i + 3, strlen(url + i + 2));
             --i;
          }
--- a/dpi/file.c	Fri Nov 11 03:48:55 2011 +0000
+++ b/dpi/file.c	Fri Nov 11 04:26:41 2011 +0000
@@ -15,7 +15,7 @@
  * With new HTML layout.
  */
 
-#include <ctype.h>           /* for tolower */
+#include <ctype.h>           /* for isspace */
 #include <errno.h>           /* for errno */
 #include <stdio.h>
 #include <stdlib.h>
@@ -142,12 +142,12 @@
 
    /* HTML try */
    for (i = 0; i < Size && dIsspace(p[i]); ++i);
-   if ((Size - i >= 5  && !dStrncasecmp(p+i, "<html", 5)) ||
-       (Size - i >= 5  && !dStrncasecmp(p+i, "<head", 5)) ||
-       (Size - i >= 6  && !dStrncasecmp(p+i, "<title", 6)) ||
-       (Size - i >= 14 && !dStrncasecmp(p+i, "<!doctype html", 14)) ||
+   if ((Size - i >= 5  && !dStrnAsciiCasecmp(p+i, "<html", 5)) ||
+       (Size - i >= 5  && !dStrnAsciiCasecmp(p+i, "<head", 5)) ||
+       (Size - i >= 6  && !dStrnAsciiCasecmp(p+i, "<title", 6)) ||
+       (Size - i >= 14 && !dStrnAsciiCasecmp(p+i, "<!doctype html", 14)) ||
        /* this line is workaround for FTP through the Squid proxy */
-       (Size - i >= 17 && !dStrncasecmp(p+i, "<!-- HTML listing", 17))) {
+       (Size - i >= 17 && !dStrnAsciiCasecmp(p+i, "<!-- HTML listing", 17))) {
 
       Type = 1;
 
@@ -502,18 +502,18 @@
 
    e++;
 
-   if (!dStrcasecmp(e, "gif")) {
+   if (!dStrAsciiCasecmp(e, "gif")) {
       return "image/gif";
-   } else if (!dStrcasecmp(e, "jpg") ||
-              !dStrcasecmp(e, "jpeg")) {
+   } else if (!dStrAsciiCasecmp(e, "jpg") ||
+              !dStrAsciiCasecmp(e, "jpeg")) {
       return "image/jpeg";
-   } else if (!dStrcasecmp(e, "png")) {
+   } else if (!dStrAsciiCasecmp(e, "png")) {
       return "image/png";
-   } else if (!dStrcasecmp(e, "html") ||
-              !dStrcasecmp(e, "htm") ||
-              !dStrcasecmp(e, "shtml")) {
+   } else if (!dStrAsciiCasecmp(e, "html") ||
+              !dStrAsciiCasecmp(e, "htm") ||
+              !dStrAsciiCasecmp(e, "shtml")) {
       return "text/html";
-   } else if (!dStrcasecmp(e, "txt")) {
+   } else if (!dStrAsciiCasecmp(e, "txt")) {
       return "text/plain";
    } else {
       return NULL;
@@ -712,7 +712,8 @@
 
       /* Check for gzipped file */
       namelen = strlen(client->filename);
-      if (namelen > 3 && !dStrcasecmp(client->filename + namelen - 3, ".gz")) {
+      if (namelen > 3 &&
+          !dStrAsciiCasecmp(client->filename + namelen - 3, ".gz")) {
          gzipped = TRUE;
          namelen -= 3;
       }
@@ -804,7 +805,7 @@
    str += 5;
 
    /* Skip "localhost" */
-   if (dStrncasecmp(str, "//localhost/", 12) == 0)
+   if (dStrnAsciiCasecmp(str, "//localhost/", 12) == 0)
       str += 11;
 
    /* Skip packed slashes, and leave just one */
--- a/dpi/ftp.c	Fri Nov 11 03:48:55 2011 +0000
+++ b/dpi/ftp.c	Fri Nov 11 04:26:41 2011 +0000
@@ -98,12 +98,12 @@
 
    /* HTML try */
    for (i = 0; i < Size && dIsspace(p[i]); ++i);
-   if ((Size - i >= 5  && !dStrncasecmp(p+i, "<html", 5)) ||
-       (Size - i >= 5  && !dStrncasecmp(p+i, "<head", 5)) ||
-       (Size - i >= 6  && !dStrncasecmp(p+i, "<title", 6)) ||
-       (Size - i >= 14 && !dStrncasecmp(p+i, "<!doctype html", 14)) ||
+   if ((Size - i >= 5  && !dStrnAsciiCasecmp(p+i, "<html", 5)) ||
+       (Size - i >= 5  && !dStrnAsciiCasecmp(p+i, "<head", 5)) ||
+       (Size - i >= 6  && !dStrnAsciiCasecmp(p+i, "<title", 6)) ||
+       (Size - i >= 14 && !dStrnAsciiCasecmp(p+i, "<!doctype html", 14)) ||
        /* this line is workaround for FTP through the Squid proxy */
-       (Size - i >= 17 && !dStrncasecmp(p+i, "<!-- HTML listing", 17))) {
+       (Size - i >= 17 && !dStrnAsciiCasecmp(p+i, "<!-- HTML listing", 17))) {
 
       Type = 1;
       st = 0;
--- a/dpi/https.c	Fri Nov 11 03:48:55 2011 +0000
+++ b/dpi/https.c	Fri Nov 11 04:26:41 2011 +0000
@@ -360,9 +360,9 @@
    char * url_look_up = NULL;
 
    /*Determine how much of url we chop off as unneeded*/
-   if (dStrncasecmp(url, "https://", 8) == 0){
+   if (dStrnAsciiCasecmp(url, "https://", 8) == 0){
       url_offset = 8;
-   } else if (dStrncasecmp(url, "http://", 7) == 0) {
+   } else if (dStrnAsciiCasecmp(url, "http://", 7) == 0) {
       url_offset = 7;
       portnum = 80;
    }
--- a/dpid/dpid.c	Fri Nov 11 03:48:55 2011 +0000
+++ b/dpid/dpid.c	Fri Nov 11 04:26:41 2011 +0000
@@ -845,7 +845,7 @@
    if (A->name[A_len - 1] == '*')
       len = A_len - 1;
 
-   return(dStrncasecmp(A->name, B, len));
+   return(dStrnAsciiCasecmp(A->name, B, len));
 }
 
 /*!
--- a/dw/fltkplatform.cc	Fri Nov 11 03:48:55 2011 +0000
+++ b/dw/fltkplatform.cc	Fri Nov 11 04:26:41 2011 +0000
@@ -141,7 +141,7 @@
 static void strstrip(char *big, const char *little)
 {
    if (strlen(big) >= strlen(little) &&
-      strcasecmp(big + strlen(big) - strlen(little), little) == 0)
+      misc::AsciiStrcasecmp(big + strlen(big) - strlen(little), little) == 0)
       *(big + strlen(big) - strlen(little)) = '\0';
 }
 
--- a/dw/style.cc	Fri Nov 11 03:48:55 2011 +0000
+++ b/dw/style.cc	Fri Nov 11 04:26:41 2011 +0000
@@ -889,10 +889,10 @@
    *const roman_I2[] = { "","C","CC","CCC","CD","D","DC","DCC","DCCC","CM" },
    *const roman_I3[] = { "","M","MM","MMM","MMMM" };
 
-static void strtolower (char *s)
+static void strAsciiTolower (char *s)
 {
    for ( ; *s; s++)
-      *s = tolower (*s);
+      *s = misc::AsciiTolower (*s);
 }
 
 /**
@@ -947,7 +947,7 @@
    buf[buflen - 1] = '\0';
 
    if (low)
-      strtolower(buf);
+      strAsciiTolower(buf);
 
 }
 
--- a/lout/misc.hh	Fri Nov 11 03:48:55 2011 +0000
+++ b/lout/misc.hh	Fri Nov 11 04:26:41 2011 +0000
@@ -43,6 +43,27 @@
    return (int) ((d > 0) ? (d + 0.5) : (d - 0.5));
 }
 
+inline int AsciiTolower(char c)
+{
+   return ((c >= 'A' && c <= 'Z') ? c + 0x20 : c);
+}
+
+inline int AsciiToupper(char c)
+{
+   return ((c >= 'a' && c <= 'z') ? c - 0x20 : c);
+}
+
+inline int AsciiStrcasecmp(const char *s1, const char *s2)
+{
+   int ret = 0;
+
+   while ((*s1 || *s2) && !(ret = AsciiTolower(*s1) - AsciiTolower(*s2))) {
+      s1++;
+      s2++;
+   }
+   return ret;
+}
+
 /**
  * \brief Instances of a sub class of this interface may be compared (less,
  *    greater).
--- a/src/IO/http.c	Fri Nov 11 03:48:55 2011 +0000
+++ b/src/IO/http.c	Fri Nov 11 04:26:41 2011 +0000
@@ -480,7 +480,7 @@
          for (p = np; (tok = dStrsep(&p, " "));  ) {
             int start = host_len - strlen(tok);
 
-            if (start >= 0 && dStrcasecmp(host + start, tok) == 0) {
+            if (start >= 0 && dStrAsciiCasecmp(host + start, tok) == 0) {
                /* no_proxy token is suffix of host string */
                ret = 0;
                break;
@@ -719,7 +719,7 @@
    for (i = 0; i < dList_length(host_connections); i++) {
       hc = (HostConnection_t*) dList_nth_data(host_connections, i);
 
-      if (dStrcasecmp(host, hc->host) == 0)
+      if (dStrAsciiCasecmp(host, hc->host) == 0)
          return hc;
    }
 
--- a/src/IO/mime.c	Fri Nov 11 03:48:55 2011 +0000
+++ b/src/IO/mime.c	Fri Nov 11 04:26:41 2011 +0000
@@ -67,7 +67,7 @@
 
    if (Size) {
       for ( i = 0; i < MimeMinItemsSize; ++i )
-         if (dStrncasecmp(Key, MimeMinItems[i].Name, Size) == 0)
+         if (dStrnAsciiCasecmp(Key, MimeMinItems[i].Name, Size) == 0)
             return MimeMinItems[i].Data;
    }
    return NULL;
@@ -83,7 +83,7 @@
 
    if (Size) {
       for ( i = 0; i < MimeMajItemsSize; ++i )
-         if (dStrncasecmp(Key, MimeMajItems[i].Name, Size) == 0)
+         if (dStrnAsciiCasecmp(Key, MimeMajItems[i].Name, Size) == 0)
             return MimeMajItems[i].Data;
    }
    return NULL;
--- a/src/auth.c	Fri Nov 11 03:48:55 2011 +0000
+++ b/src/auth.c	Fri Nov 11 04:26:41 2011 +0000
@@ -228,7 +228,7 @@
 static int Auth_parse_basic_challenge_cb(AuthParse_t *auth_parse, char *token,
                                          const char *value)
 {
-   if (dStrcasecmp("realm", token) == 0) {
+   if (dStrAsciiCasecmp("realm", token) == 0) {
       if (!auth_parse->realm)
          auth_parse->realm = strdup(value);
       return 0; /* end parsing */
@@ -243,7 +243,7 @@
 {
    const char *const fn = "Auth_parse_digest_challenge_cb";
 
-   if (!dStrcasecmp("realm", token) && !auth_parse->realm)
+   if (!dStrAsciiCasecmp("realm", token) && !auth_parse->realm)
       auth_parse->realm = strdup(value);
    else if (!strcmp("domain", token) && !auth_parse->domain)
       auth_parse->domain = strdup(value);
@@ -252,9 +252,9 @@
    else if (!strcmp("opaque", token) && !auth_parse->opaque)
       auth_parse->opaque = strdup(value);
    else if (strcmp("stale", token) == 0) {
-      if (dStrcasecmp("true", value) == 0)
+      if (dStrAsciiCasecmp("true", value) == 0)
          auth_parse->stale = 1;
-      else if (dStrcasecmp("false", value) == 0)
+      else if (dStrAsciiCasecmp("false", value) == 0)
          auth_parse->stale = 0;
       else {
          MSG("%s: Invalid stale value: %s\n", fn, value);
@@ -359,8 +359,8 @@
    int i;
 
    for (i = 0; (host = dList_nth_data(auth_hosts, i)); i++)
-      if (((dStrcasecmp(URL_SCHEME(url), host->scheme) == 0) &&
-           (dStrcasecmp(URL_AUTHORITY(url), host->authority) == 0)))
+      if (((dStrAsciiCasecmp(URL_SCHEME(url), host->scheme) == 0) &&
+           (dStrAsciiCasecmp(URL_AUTHORITY(url), host->authority) == 0)))
          return host;
 
    return NULL;
@@ -672,11 +672,11 @@
    char *chal;
 
    for (i = 0; (chal = dList_nth_data(challenges, i)); ++i)
-      if (!dStrncasecmp(chal, "Digest ", 7))
+      if (!dStrnAsciiCasecmp(chal, "Digest ", 7))
          if (Auth_do_auth(chal, DIGEST, url))
             return 1;
    for (i = 0; (chal = dList_nth_data(challenges, i)); ++i)
-      if (!dStrncasecmp(chal, "Basic ", 6))
+      if (!dStrnAsciiCasecmp(chal, "Basic ", 6))
          if (Auth_do_auth(chal, BASIC, url))
             return 1;
 
--- a/src/cache.c	Fri Nov 11 03:48:55 2011 +0000
+++ b/src/cache.c	Fri Nov 11 04:26:41 2011 +0000
@@ -13,7 +13,6 @@
  * Dillo's cache module
  */
 
-#include <ctype.h>              /* for tolower */
 #include <sys/types.h>
 
 #include <stdlib.h>
@@ -521,7 +520,7 @@
             /* META only gives charset; use detected MIME type too */
             entry->TypeNorm = dStrconcat(entry->TypeDet, ctype, NULL);
          } else if (*from == 'm' &&
-                    !dStrncasecmp(ctype, "text/xhtml", 10)) {
+                    !dStrnAsciiCasecmp(ctype, "text/xhtml", 10)) {
             /* WORKAROUND: doxygen uses "text/xhtml" in META */
             entry->TypeNorm = dStrdup(entry->TypeDet);
          }
@@ -584,7 +583,7 @@
    for (i = 0; header[i]; i++) {
       /* Search fieldname */
       for (j = 0; fieldname[j]; j++)
-        if (tolower(fieldname[j]) != tolower(header[i + j]))
+        if (D_ASCII_TOLOWER(fieldname[j]) != D_ASCII_TOLOWER(header[i + j]))
            break;
       if (fieldname[j]) {
          /* skip to next line */
@@ -620,7 +619,7 @@
    for (i = 0; header[i]; i++) {
       /* Search fieldname */
       for (j = 0; fieldname[j]; j++)
-         if (tolower(fieldname[j]) != tolower(header[i + j]))
+         if (D_ASCII_TOLOWER(fieldname[j]) != D_ASCII_TOLOWER(header[i + j]))
             break;
       if (fieldname[j]) {
          /* skip to next line */
@@ -694,8 +693,8 @@
                entry->Flags |= CA_TempRedirect;   /* 302 Temporary Redirect */
 
             if (URL_FLAGS(location_url) & (URL_Post + URL_Get) &&
-                dStrcasecmp(URL_SCHEME(location_url), "dpi") == 0 &&
-                dStrcasecmp(URL_SCHEME(entry->Url), "dpi") != 0) {
+                dStrAsciiCasecmp(URL_SCHEME(location_url), "dpi") == 0 &&
+                dStrAsciiCasecmp(URL_SCHEME(entry->Url), "dpi") != 0) {
                /* Forbid dpi GET and POST from non dpi-generated urls */
                MSG("Redirection Denied! '%s' -> '%s'\n",
                    URL_STR(entry->Url), URL_STR(location_url));
@@ -734,7 +733,7 @@
           * If Transfer-Encoding is present, Content-Length must be ignored.
           * If the Transfer-Encoding is non-identity, it is an error.
           */
-         if (dStrcasecmp(encoding, "identity"))
+         if (dStrAsciiCasecmp(encoding, "identity"))
             MSG_HTTP("Content-Length and non-identity Transfer-Encoding "
                      "headers both present.\n");
       } else {
@@ -1045,9 +1044,9 @@
  */
 int a_Cache_download_enabled(const DilloUrl *url)
 {
-   if (!dStrcasecmp(URL_SCHEME(url), "http") ||
-       !dStrcasecmp(URL_SCHEME(url), "https") ||
-       !dStrcasecmp(URL_SCHEME(url), "ftp"))
+   if (!dStrAsciiCasecmp(URL_SCHEME(url), "http") ||
+       !dStrAsciiCasecmp(URL_SCHEME(url), "https") ||
+       !dStrAsciiCasecmp(URL_SCHEME(url), "ftp"))
       return 1;
    return 0;
 }
--- a/src/capi.c	Fri Nov 11 03:48:55 2011 +0000
+++ b/src/capi.c	Fri Nov 11 04:26:41 2011 +0000
@@ -229,7 +229,7 @@
    const DilloUrl *referer;
    int allow = FALSE;
 
-   if (dStrcasecmp(URL_SCHEME(url), "dpi") == 0) {
+   if (dStrAsciiCasecmp(URL_SCHEME(url), "dpi") == 0) {
       if (!(URL_FLAGS(url) & (URL_Post + URL_Get))) {
          allow = TRUE;
       } else if (!(URL_FLAGS(url) & URL_Post) &&
@@ -239,7 +239,7 @@
          /* only allow GET&POST dpi-requests from dpi-generated urls */
          if (a_Nav_stack_size(bw)) {
             referer = a_History_get_url(NAV_TOP_UIDX(bw));
-            if (dStrcasecmp(URL_SCHEME(referer), "dpi") == 0) {
+            if (dStrAsciiCasecmp(URL_SCHEME(referer), "dpi") == 0) {
                allow = TRUE;
             }
          }
@@ -266,10 +266,10 @@
    char *p, *server = NULL, *url_str = URL_STR(url);
    Dstr *tmp;
 
-   if ((dStrncasecmp(url_str, "http:", 5) == 0) ||
-       (dStrncasecmp(url_str, "about:", 6) == 0)) {
+   if ((dStrnAsciiCasecmp(url_str, "http:", 5) == 0) ||
+       (dStrnAsciiCasecmp(url_str, "about:", 6) == 0)) {
       /* URL doesn't use dpi (server = NULL) */
-   } else if (dStrncasecmp(url_str, "dpi:/", 5) == 0) {
+   } else if (dStrnAsciiCasecmp(url_str, "dpi:/", 5) == 0) {
       /* dpi prefix, get this server's name */
       if ((p = strchr(url_str + 5, '/')) != NULL) {
          server = dStrndup(url_str + 5, (uint_t)(p - url_str - 5));
@@ -388,7 +388,8 @@
                        *want_host = URL_HOST(wanted);
             if (want_host[0] == '\0') {
                ret = (req_host[0] == '\0' ||
-                      !dStrcasecmp(URL_SCHEME(wanted), "data")) ? TRUE : FALSE;
+                      !dStrAsciiCasecmp(URL_SCHEME(wanted), "data"))
+                     ? TRUE : FALSE;
             } else {
                /* This will regard "www.dillo.org" and "www.dillo.org." as
                 * different, but it doesn't seem worth caring about.
@@ -454,7 +455,7 @@
    } else if (Capi_url_uses_dpi(web->url, &server)) {
       /* dpi request */
       if ((safe = a_Capi_dpi_verify_request(web->bw, web->url))) {
-         if (dStrcasecmp(scheme, "dpi") == 0) {
+         if (dStrAsciiCasecmp(scheme, "dpi") == 0) {
             if (strcmp(server, "vsource") == 0) {
                /* allow "view source" reload upon user request */
             } else {
@@ -478,7 +479,7 @@
       }
       dFree(server);
 
-   } else if (!dStrcasecmp(scheme, "http")) {
+   } else if (!dStrAsciiCasecmp(scheme, "http")) {
       /* http request */
       if (reload) {
          a_Capi_conn_abort_by_url(web->url);
@@ -491,7 +492,7 @@
       }
       use_cache = 1;
 
-   } else if (!dStrcasecmp(scheme, "about")) {
+   } else if (!dStrAsciiCasecmp(scheme, "about")) {
       /* internal request */
       use_cache = 1;
    }
--- a/src/colors.c	Fri Nov 11 03:48:55 2011 +0000
+++ b/src/colors.c	Fri Nov 11 04:26:41 2011 +0000
@@ -262,7 +262,7 @@
       high = NCOLORS - 1;
       while (low <= high) {
          mid = (low + high) / 2;
-         if ((ret = dStrcasecmp(cp, color_keyword[mid].key)) < 0)
+         if ((ret = dStrAsciiCasecmp(cp, color_keyword[mid].key)) < 0)
             high = mid - 1;
          else if (ret > 0)
             low = mid + 1;
--- a/src/cookies.c	Fri Nov 11 03:48:55 2011 +0000
+++ b/src/cookies.c	Fri Nov 11 04:26:41 2011 +0000
@@ -284,11 +284,11 @@
             rule[j++] = line[i++];
          rule[j] = '\0';
 
-         if (dStrcasecmp(rule, "ACCEPT") == 0)
+         if (dStrAsciiCasecmp(rule, "ACCEPT") == 0)
             cc.action = COOKIE_ACCEPT;
-         else if (dStrcasecmp(rule, "ACCEPT_SESSION") == 0)
+         else if (dStrAsciiCasecmp(rule, "ACCEPT_SESSION") == 0)
             cc.action = COOKIE_ACCEPT_SESSION;
-         else if (dStrcasecmp(rule, "DENY") == 0)
+         else if (dStrAsciiCasecmp(rule, "DENY") == 0)
             cc.action = COOKIE_DENY;
          else {
             MSG("Cookies: rule '%s' for domain '%s' is not recognised.\n",
@@ -297,7 +297,7 @@
          }
 
          cc.domain = dStrdup(domain);
-         if (dStrcasecmp(cc.domain, "DEFAULT") == 0) {
+         if (dStrAsciiCasecmp(cc.domain, "DEFAULT") == 0) {
             /* Set the default action */
             default_action = cc.action;
             dFree(cc.domain);
@@ -338,13 +338,13 @@
       if (ccontrol[i].domain[0] == '.') {
          diff = strlen(domain) - strlen(ccontrol[i].domain);
          if (diff >= 0) {
-            if (dStrcasecmp(domain + diff, ccontrol[i].domain) != 0)
+            if (dStrAsciiCasecmp(domain + diff, ccontrol[i].domain) != 0)
                continue;
          } else {
             continue;
          }
       } else {
-         if (dStrcasecmp(domain, ccontrol[i].domain) != 0)
+         if (dStrAsciiCasecmp(domain, ccontrol[i].domain) != 0)
             continue;
       }
 
--- a/src/css.cc	Fri Nov 11 03:48:55 2011 +0000
+++ b/src/css.cc	Fri Nov 11 04:26:41 2011 +0000
@@ -265,16 +265,16 @@
    if (element != ELEMENT_ANY && element != n->element)
       return false;
    if (pseudo != NULL &&
-      (n->pseudo == NULL || dStrcasecmp (pseudo, n->pseudo) != 0))
+      (n->pseudo == NULL || dStrAsciiCasecmp (pseudo, n->pseudo) != 0))
       return false;
-   if (id != NULL && (n->id == NULL || dStrcasecmp (id, n->id) != 0))
+   if (id != NULL && (n->id == NULL || dStrAsciiCasecmp (id, n->id) != 0))
       return false;
    if (klass != NULL) {
       for (int i = 0; i < klass->size (); i++) {
          bool found = false;
          if (n->klass != NULL) {
             for (int j = 0; j < n->klass->size (); j++) {
-               if (dStrcasecmp (klass->get(i), n->klass->get(j)) == 0) {
+               if (dStrAsciiCasecmp (klass->get(i), n->klass->get(j)) == 0) {
                   found = true;
                   break;
                }
--- a/src/cssparser.cc	Fri Nov 11 03:48:55 2011 +0000
+++ b/src/cssparser.cc	Fri Nov 11 04:26:41 2011 +0000
@@ -674,7 +674,7 @@
       case CSS_TYPE_ENUM:
          if (ttype == CSS_TK_SYMBOL) {
             for (i = 0; Css_property_info[prop].enum_symbols[i]; i++)
-               if (dStrcasecmp(tval,
+               if (dStrAsciiCasecmp(tval,
                      Css_property_info[prop].enum_symbols[i]) == 0)
                   return true;
          }
@@ -682,11 +682,11 @@
 
       case CSS_TYPE_MULTI_ENUM:
          if (ttype == CSS_TK_SYMBOL) {
-            if (dStrcasecmp(tval, "none") == 0) {
+            if (dStrAsciiCasecmp(tval, "none") == 0) {
                return true;
             } else {
                for (i = 0; Css_property_info[prop].enum_symbols[i]; i++) {
-                  if (dStrcasecmp(tval,
+                  if (dStrAsciiCasecmp(tval,
                         Css_property_info[prop].enum_symbols[i]) == 0)
                      return true;
                }
@@ -703,14 +703,14 @@
       case CSS_TYPE_SIGNED_LENGTH:
          if (ttype == CSS_TK_DECINT ||
              ttype == CSS_TK_FLOAT ||
-             (ttype == CSS_TK_SYMBOL && dStrcasecmp(tval, "auto") == 0))
+             (ttype == CSS_TK_SYMBOL && dStrAsciiCasecmp(tval, "auto") == 0))
             return true;
          break;
 
       case CSS_TYPE_COLOR:
          if ((ttype == CSS_TK_COLOR ||
               ttype == CSS_TK_SYMBOL) &&
-            (dStrcasecmp(tval, "rgb") == 0 ||
+            (dStrAsciiCasecmp(tval, "rgb") == 0 ||
              a_Color_parse(tval, -1, &err) != -1))
             return true;
          break;
@@ -838,7 +838,7 @@
    case CSS_TYPE_ENUM:
       if (ttype == CSS_TK_SYMBOL) {
          for (i = 0; Css_property_info[prop].enum_symbols[i]; i++)
-            if (dStrcasecmp(tval,
+            if (dStrAsciiCasecmp(tval,
                             Css_property_info[prop].enum_symbols[i]) == 0) {
                val->intVal = i;
                ret = true;
@@ -853,10 +853,10 @@
       ret = true;
 
       while (ttype == CSS_TK_SYMBOL) {
-         if (dStrcasecmp(tval, "none") != 0) {
+         if (dStrAsciiCasecmp(tval, "none") != 0) {
             for (i = 0, found = false;
                  !found && Css_property_info[prop].enum_symbols[i]; i++) {
-               if (dStrcasecmp(tval,
+               if (dStrAsciiCasecmp(tval,
                                Css_property_info[prop].enum_symbols[i]) == 0)
                   val->intVal |= (1 << i);
             }
@@ -877,32 +877,32 @@
          if (!spaceSeparated && ttype == CSS_TK_SYMBOL) {
             ret = true;
 
-            if (dStrcasecmp(tval, "px") == 0) {
+            if (dStrAsciiCasecmp(tval, "px") == 0) {
                lentype = CSS_LENGTH_TYPE_PX;
                nextToken();
-            } else if (dStrcasecmp(tval, "mm") == 0) {
+            } else if (dStrAsciiCasecmp(tval, "mm") == 0) {
                lentype = CSS_LENGTH_TYPE_MM;
                nextToken();
-            } else if (dStrcasecmp(tval, "cm") == 0) {
+            } else if (dStrAsciiCasecmp(tval, "cm") == 0) {
                lentype = CSS_LENGTH_TYPE_MM;
                fval *= 10;
                nextToken();
-            } else if (dStrcasecmp(tval, "in") == 0) {
+            } else if (dStrAsciiCasecmp(tval, "in") == 0) {
                lentype = CSS_LENGTH_TYPE_MM;
                fval *= 25.4;
                nextToken();
-            } else if (dStrcasecmp(tval, "pt") == 0) {
+            } else if (dStrAsciiCasecmp(tval, "pt") == 0) {
                lentype = CSS_LENGTH_TYPE_MM;
                fval *= (25.4 / 72);
                nextToken();
-            } else if (dStrcasecmp(tval, "pc") == 0) {
+            } else if (dStrAsciiCasecmp(tval, "pc") == 0) {
                lentype = CSS_LENGTH_TYPE_MM;
                fval *= (25.4 / 6);
                nextToken();
-            } else if (dStrcasecmp(tval, "em") == 0) {
+            } else if (dStrAsciiCasecmp(tval, "em") == 0) {
                lentype = CSS_LENGTH_TYPE_EM;
                nextToken();
-            } else if (dStrcasecmp(tval, "ex") == 0) {
+            } else if (dStrAsciiCasecmp(tval, "ex") == 0) {
                lentype = CSS_LENGTH_TYPE_EX;
                nextToken();
             } else {
@@ -927,7 +927,7 @@
             ret = true;
 
          val->intVal = CSS_CREATE_LENGTH(fval, lentype);
-      } else if (ttype == CSS_TK_SYMBOL && dStrcasecmp(tval, "auto") == 0) {
+      } else if (ttype == CSS_TK_SYMBOL && !dStrAsciiCasecmp(tval, "auto")) {
          ret = true;
          val->intVal = CSS_LENGTH_TYPE_AUTO;
          nextToken();
@@ -943,7 +943,7 @@
             ret = true;
          nextToken();
       } else if (ttype == CSS_TK_SYMBOL) {
-         if (dStrcasecmp(tval, "rgb") == 0) {
+         if (dStrAsciiCasecmp(tval, "rgb") == 0) {
             nextToken();
             if (parseRgbColor(&val->intVal))
                ret = true;
@@ -1022,7 +1022,7 @@
    if (ttype == CSS_TK_CHAR && tval[0] == '!') {
       nextToken();
       if (ttype == CSS_TK_SYMBOL &&
-          dStrcasecmp(tval, "important") == 0) {
+          dStrAsciiCasecmp(tval, "important") == 0) {
          nextToken();
          return true;
       }
@@ -1036,7 +1036,7 @@
  */
 static int Css_property_info_cmp(const void *a, const void *b)
 {
-   return dStrcasecmp(((CssPropertyInfo *) a)->symbol,
+   return dStrAsciiCasecmp(((CssPropertyInfo *) a)->symbol,
                       ((CssPropertyInfo *) b)->symbol);
 }
 
@@ -1046,7 +1046,7 @@
  */
 static int Css_shorthand_info_cmp(const void *a, const void *b)
 {
-   return dStrcasecmp(((CssShorthandInfo *) a)->symbol,
+   return dStrAsciiCasecmp(((CssShorthandInfo *) a)->symbol,
                       ((CssShorthandInfo *) b)->symbol);
 }
 
@@ -1391,7 +1391,7 @@
    Dstr *urlStr = NULL;
 
    if (ttype != CSS_TK_SYMBOL ||
-      dStrcasecmp(tval, "url") != 0)
+      dStrAsciiCasecmp(tval, "url") != 0)
       return NULL;
 
    nextToken();
@@ -1437,7 +1437,7 @@
    nextToken();
 
    if (ttype == CSS_TK_SYMBOL &&
-       dStrcasecmp(tval, "url") == 0)
+       dStrAsciiCasecmp(tval, "url") == 0)
       urlStr = parseUrl();
    else if (ttype == CSS_TK_STRING)
       urlStr = dStrdup (tval);
@@ -1449,8 +1449,8 @@
       mediaSyntaxIsOK = false;
       mediaIsSelected = false;
       while (ttype == CSS_TK_SYMBOL) {
-         if (dStrcasecmp(tval, "all") == 0 ||
-             dStrcasecmp(tval, "screen") == 0)
+         if (dStrAsciiCasecmp(tval, "all") == 0 ||
+             dStrAsciiCasecmp(tval, "screen") == 0)
             mediaIsSelected = true;
          nextToken();
          if (ttype == CSS_TK_CHAR && tval[0] == ',') {
@@ -1491,8 +1491,8 @@
 
    /* parse a comma-separated list of media */
    while (ttype == CSS_TK_SYMBOL) {
-      if (dStrcasecmp(tval, "all") == 0 ||
-          dStrcasecmp(tval, "screen") == 0)
+      if (dStrAsciiCasecmp(tval, "all") == 0 ||
+          dStrAsciiCasecmp(tval, "screen") == 0)
          mediaIsSelected = true;
       nextToken();
       if (ttype == CSS_TK_CHAR && tval[0] == ',') {
@@ -1578,11 +1578,11 @@
           parser.tval[0] == '@') {
          parser.nextToken();
          if (parser.ttype == CSS_TK_SYMBOL) {
-            if (dStrcasecmp(parser.tval, "import") == 0 &&
+            if (dStrAsciiCasecmp(parser.tval, "import") == 0 &&
                 html != NULL &&
                 importsAreAllowed) {
                parser.parseImport(html, url);
-            } else if (dStrcasecmp(parser.tval, "media") == 0) {
+            } else if (dStrAsciiCasecmp(parser.tval, "media") == 0) {
                parser.parseMedia();
             } else {
                parser.ignoreStatement();
--- a/src/decode.c	Fri Nov 11 03:48:55 2011 +0000
+++ b/src/decode.c	Fri Nov 11 04:26:41 2011 +0000
@@ -190,7 +190,7 @@
 {
    Decode *dc = NULL;
 
-   if (format && !dStrcasecmp(format, "chunked")) {
+   if (format && !dStrAsciiCasecmp(format, "chunked")) {
       int *chunk_remaining = dNew(int, 1);
       *chunk_remaining = 0;
       dc = dNew(Decode, 1);
@@ -215,7 +215,8 @@
    Decode *dc = NULL;
 
    if (format && *format) {
-      if (!dStrcasecmp(format, "gzip") || !dStrcasecmp(format, "x-gzip")) {
+      if (!dStrAsciiCasecmp(format, "gzip") ||
+          !dStrAsciiCasecmp(format, "x-gzip")) {
          z_stream *zs;
          _MSG("gzipped data!\n");
 
@@ -245,17 +246,17 @@
  */
 static int Decode_is_ascii(const char *str)
 {
-   return (!(dStrcasecmp(str, "ASCII") &&
-             dStrcasecmp(str, "US-ASCII") &&
-             dStrcasecmp(str, "us") &&
-             dStrcasecmp(str, "IBM367") &&
-             dStrcasecmp(str, "cp367") &&
-             dStrcasecmp(str, "csASCII") &&
-             dStrcasecmp(str, "ANSI_X3.4-1968") &&
-             dStrcasecmp(str, "iso-ir-6") &&
-             dStrcasecmp(str, "ANSI_X3.4-1986") &&
-             dStrcasecmp(str, "ISO_646.irv:1991") &&
-             dStrcasecmp(str, "ISO646-US")));
+   return (!(dStrAsciiCasecmp(str, "ASCII") &&
+             dStrAsciiCasecmp(str, "US-ASCII") &&
+             dStrAsciiCasecmp(str, "us") &&
+             dStrAsciiCasecmp(str, "IBM367") &&
+             dStrAsciiCasecmp(str, "cp367") &&
+             dStrAsciiCasecmp(str, "csASCII") &&
+             dStrAsciiCasecmp(str, "ANSI_X3.4-1968") &&
+             dStrAsciiCasecmp(str, "iso-ir-6") &&
+             dStrAsciiCasecmp(str, "ANSI_X3.4-1986") &&
+             dStrAsciiCasecmp(str, "ISO_646.irv:1991") &&
+             dStrAsciiCasecmp(str, "ISO646-US")));
 }
 
 /*
@@ -271,7 +272,7 @@
 
    if (format &&
        strlen(format) &&
-       dStrcasecmp(format,"UTF-8") &&
+       dStrAsciiCasecmp(format,"UTF-8") &&
        !Decode_is_ascii(format)) {
 
       iconv_t ic = iconv_open("UTF-8", format);
--- a/src/form.cc	Fri Nov 11 03:48:55 2011 +0000
+++ b/src/form.cc	Fri Nov 11 04:26:41 2011 +0000
@@ -271,7 +271,7 @@
       for (int idx = 0; idx < inputs->size(); idx++) {
          DilloHtmlInput *input = inputs->get(idx);
          if (input->type == DILLO_HTML_INPUT_RADIO &&
-             input->name && !dStrcasecmp(input->name, name))
+             input->name && !dStrAsciiCasecmp(input->name, name))
             return input;
       }
    }
@@ -318,9 +318,9 @@
 
    method = DILLO_HTML_METHOD_GET;
    if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "method"))) {
-      if (!dStrcasecmp(attrbuf, "post")) {
+      if (!dStrAsciiCasecmp(attrbuf, "post")) {
          method = DILLO_HTML_METHOD_POST;
-      } else if (dStrcasecmp(attrbuf, "get")) {
+      } else if (dStrAsciiCasecmp(attrbuf, "get")) {
          BUG_MSG("Unknown form submission method \"%s\"\n", attrbuf);
       }
    }
@@ -333,7 +333,7 @@
    content_type = DILLO_HTML_ENC_URLENCODED;
    if ((method == DILLO_HTML_METHOD_POST) &&
        ((attrbuf = a_Html_get_attr(html, tag, tagsize, "enctype")))) {
-      if (!dStrcasecmp(attrbuf, "multipart/form-data"))
+      if (!dStrAsciiCasecmp(attrbuf, "multipart/form-data"))
          content_type = DILLO_HTML_ENC_MULTIPART;
    }
    charset = NULL;
@@ -343,9 +343,9 @@
       char *ptr = first = dStrdup(attrbuf);
       while (ptr && !charset) {
          char *curr = dStrsep(&ptr, " ,");
-         if (!dStrcasecmp(curr, "utf-8")) {
+         if (!dStrAsciiCasecmp(curr, "utf-8")) {
             charset = curr;
-         } else if (!dStrcasecmp(curr, "UNKNOWN")) {
+         } else if (!dStrAsciiCasecmp(curr, "UNKNOWN")) {
             /* defined to be whatever encoding the document is in */
             charset = html->charset;
          }
@@ -441,18 +441,18 @@
 
    init_str = NULL;
    inp_type = DILLO_HTML_INPUT_UNKNOWN;
-   if (!dStrcasecmp(type, "password")) {
+   if (!dStrAsciiCasecmp(type, "password")) {
       inp_type = DILLO_HTML_INPUT_PASSWORD;
       attrbuf = a_Html_get_attr(html, tag, tagsize, "size");
       int size = Html_input_get_size(html, attrbuf);
       resource = factory->createEntryResource (size, true, NULL);
       init_str = value;
-   } else if (!dStrcasecmp(type, "checkbox")) {
+   } else if (!dStrAsciiCasecmp(type, "checkbox")) {
       inp_type = DILLO_HTML_INPUT_CHECKBOX;
       resource = factory->createCheckButtonResource(false);
       init_val = (a_Html_get_attr(html, tag, tagsize, "checked") != NULL);
       init_str = (value) ? value : dStrdup("on");
-   } else if (!dStrcasecmp(type, "radio")) {
+   } else if (!dStrAsciiCasecmp(type, "radio")) {
       inp_type = DILLO_HTML_INPUT_RADIO;
       RadioButtonResource *rb_r = NULL;
       DilloHtmlInput *input = Html_get_radio_input(html, name);
@@ -461,22 +461,22 @@
       resource = factory->createRadioButtonResource(rb_r, false);
       init_val = (a_Html_get_attr(html, tag, tagsize, "checked") != NULL);
       init_str = value;
-   } else if (!dStrcasecmp(type, "hidden")) {
+   } else if (!dStrAsciiCasecmp(type, "hidden")) {
       inp_type = DILLO_HTML_INPUT_HIDDEN;
       init_str = value;
       int size = Html_input_get_size(html, NULL);
       resource = factory->createEntryResource(size, false, name);
-   } else if (!dStrcasecmp(type, "submit")) {
+   } else if (!dStrAsciiCasecmp(type, "submit")) {
       inp_type = DILLO_HTML_INPUT_SUBMIT;
       init_str = (value) ? value : dStrdup("submit");
       resource = factory->createLabelButtonResource(init_str);
 //    gtk_widget_set_sensitive(widget, FALSE); /* Until end of FORM! */
-   } else if (!dStrcasecmp(type, "reset")) {
+   } else if (!dStrAsciiCasecmp(type, "reset")) {
       inp_type = DILLO_HTML_INPUT_RESET;
       init_str = (value) ? value : dStrdup("Reset");
       resource = factory->createLabelButtonResource(init_str);
 //    gtk_widget_set_sensitive(widget, FALSE); /* Until end of FORM! */
-   } else if (!dStrcasecmp(type, "image")) {
+   } else if (!dStrAsciiCasecmp(type, "image")) {
       if (URL_FLAGS(html->base_url) & URL_SpamSafe) {
          /* Don't request the image; make a text submit button instead */
          inp_type = DILLO_HTML_INPUT_SUBMIT;
@@ -491,7 +491,7 @@
          embed = Html_input_image(html, tag, tagsize);
          init_str = value;
       }
-   } else if (!dStrcasecmp(type, "file")) {
+   } else if (!dStrAsciiCasecmp(type, "file")) {
       bool valid = true;
       if (html->InFlags & IN_FORM) {
          DilloHtmlForm *form = html->getCurrentForm();
@@ -512,7 +512,7 @@
          init_str = dStrdup("File selector");
          resource = factory->createLabelButtonResource(init_str);
       }
-   } else if (!dStrcasecmp(type, "button")) {
+   } else if (!dStrAsciiCasecmp(type, "button")) {
       inp_type = DILLO_HTML_INPUT_BUTTON;
       if (value) {
          init_str = value;
@@ -521,7 +521,7 @@
    } else {
       /* Text input, which also is the default */
       inp_type = DILLO_HTML_INPUT_TEXT;
-      if (*type && dStrcasecmp(type, "text"))
+      if (*type && dStrAsciiCasecmp(type, "text"))
          BUG_MSG("Unknown input type: \"%s\"\n", type);
       attrbuf = a_Html_get_attr(html, tag, tagsize, "size");
       int size = Html_input_get_size(html, attrbuf);
@@ -831,11 +831,11 @@
 
    type = a_Html_get_attr_wdef(html, tag, tagsize, "type", "");
 
-   if (!dStrcasecmp(type, "button")) {
+   if (!dStrAsciiCasecmp(type, "button")) {
       inp_type = DILLO_HTML_INPUT_BUTTON;
-   } else if (!dStrcasecmp(type, "reset")) {
+   } else if (!dStrAsciiCasecmp(type, "reset")) {
       inp_type = DILLO_HTML_INPUT_BUTTON_RESET;
-   } else if (!dStrcasecmp(type, "submit") || !*type) {
+   } else if (!dStrAsciiCasecmp(type, "submit") || !*type) {
       /* submit button is the default */
       inp_type = DILLO_HTML_INPUT_BUTTON_SUBMIT;
    } else {
@@ -1034,7 +1034,7 @@
    char *boundary = NULL;
    iconv_t char_encoder = (iconv_t) -1;
 
-   if (submit_charset && dStrcasecmp(submit_charset, "UTF-8")) {
+   if (submit_charset && dStrAsciiCasecmp(submit_charset, "UTF-8")) {
       char_encoder = iconv_open(submit_charset, "UTF-8");
       if (char_encoder == (iconv_t) -1) {
          MSG_WARN("Cannot convert to character encoding '%s'\n",
@@ -1308,8 +1308,8 @@
       (void)a_Misc_get_content_type_from_data(file->str, file->len, &ctype);
       /* Heuristic: text/plain with ".htm[l]" extension -> text/html */
       if ((ext = strrchr(filename, '.')) &&
-          !dStrcasecmp(ctype, "text/plain") &&
-          (!dStrcasecmp(ext, ".html") || !dStrcasecmp(ext, ".htm"))) {
+          !dStrAsciiCasecmp(ctype, "text/plain") &&
+          (!dStrAsciiCasecmp(ext, ".html") || !dStrAsciiCasecmp(ext, ".htm"))){
          ctype = "text/html";
       }
 
@@ -1474,7 +1474,7 @@
    for (int idx = 0; idx < inputs->size(); idx++) {
       DilloHtmlInput *input = inputs->get(idx);
       if (input->type == DILLO_HTML_INPUT_RADIO &&
-          input->name && !dStrcasecmp(input->name, name))
+          input->name && !dStrAsciiCasecmp(input->name, name))
          return input;
    }
    return NULL;
--- a/src/html.cc	Fri Nov 11 03:48:55 2011 +0000
+++ b/src/html.cc	Fri Nov 11 04:26:41 2011 +0000
@@ -16,7 +16,7 @@
 /*-----------------------------------------------------------------------------
  * Includes
  *---------------------------------------------------------------------------*/
-#include <ctype.h>      /* for isspace and tolower */
+#include <ctype.h>      /* for isspace */
 #include <string.h>     /* for memcpy and memmove */
 #include <stdlib.h>
 #include <stdio.h>      /* for sprintf */
@@ -311,16 +311,16 @@
    if ((align = a_Html_get_attr(html, tag, tagsize, "align"))) {
       TextAlignType textAlignType = TEXT_ALIGN_LEFT;
 
-      if (dStrcasecmp (align, "left") == 0)
+      if (dStrAsciiCasecmp (align, "left") == 0)
          textAlignType = TEXT_ALIGN_LEFT;
-      else if (dStrcasecmp (align, "right") == 0)
+      else if (dStrAsciiCasecmp (align, "right") == 0)
          textAlignType = TEXT_ALIGN_RIGHT;
-      else if (dStrcasecmp (align, "center") == 0)
+      else if (dStrAsciiCasecmp (align, "center") == 0)
          textAlignType = TEXT_ALIGN_CENTER;
-      else if (dStrcasecmp (align, "justify") == 0)
+      else if (dStrAsciiCasecmp (align, "justify") == 0)
          textAlignType = TEXT_ALIGN_JUSTIFY;
 #if 0
-      else if (dStrcasecmp (align, "char") == 0) {
+      else if (dStrAsciiCasecmp (align, "char") == 0) {
          /* TODO: Actually not supported for <p> etc. */
          v.textAlign = TEXT_ALIGN_STRING;
          if ((charattr = a_Html_get_attr(html, tag, tagsize, "char"))) {
@@ -352,11 +352,11 @@
    VAlignType valign;
 
    if ((attr = a_Html_get_attr(html, tag, tagsize, "valign"))) {
-      if (dStrcasecmp (attr, "top") == 0)
+      if (dStrAsciiCasecmp (attr, "top") == 0)
          valign = VALIGN_TOP;
-      else if (dStrcasecmp (attr, "bottom") == 0)
+      else if (dStrAsciiCasecmp (attr, "bottom") == 0)
          valign = VALIGN_BOTTOM;
-      else if (dStrcasecmp (attr, "baseline") == 0)
+      else if (dStrAsciiCasecmp (attr, "baseline") == 0)
          valign = VALIGN_BASELINE;
       else
          valign = VALIGN_MIDDLE;
@@ -1240,7 +1240,7 @@
    int i;
 
    for (i = 0; i < tagsize && tagstr[i] != '\0'; i++) {
-      if (tolower(tagstr[i]) != tolower(tag[i]))
+      if (D_ASCII_TOLOWER(tagstr[i]) != D_ASCII_TOLOWER(tag[i]))
          return false;
    }
    /* The test for '/' is for xml compatibility: "empty/>" will be matched. */
@@ -1530,18 +1530,18 @@
    _MSG("New: {%s}\n", ntag);
 
    /* The default DT_NONE type is TagSoup */
-   if (!dStrncasecmp(ntag, HTML_SGML_sig, strlen(HTML_SGML_sig))) {
+   if (!dStrnAsciiCasecmp(ntag, HTML_SGML_sig, strlen(HTML_SGML_sig))) {
       p = ntag + strlen(HTML_SGML_sig) + 1;
       if (!strncmp(p, HTML401, strlen(HTML401)) &&
-          dStristr(p + strlen(HTML401), HTML401_url)) {
+          dStriAsciiStr(p + strlen(HTML401), HTML401_url)) {
          html->DocType = DT_HTML;
          html->DocTypeVersion = 4.01f;
       } else if (!strncmp(p, XHTML1, strlen(XHTML1)) &&
-                 dStristr(p + strlen(XHTML1), XHTML1_url)) {
+                 dStriAsciiStr(p + strlen(XHTML1), XHTML1_url)) {
          html->DocType = DT_XHTML;
          html->DocTypeVersion = 1.0f;
       } else if (!strncmp(p, XHTML11, strlen(XHTML11)) &&
-                 dStristr(p + strlen(XHTML11), XHTML11_url)) {
+                 dStriAsciiStr(p + strlen(XHTML11), XHTML11_url)) {
          html->DocType = DT_XHTML;
          html->DocTypeVersion = 1.1f;
       } else if (!strncmp(p, HTML40, strlen(HTML40))) {
@@ -1554,7 +1554,7 @@
          html->DocType = DT_HTML;
          html->DocTypeVersion = 2.0f;
       }
-   } else if (!dStrcasecmp(ntag, HTML5_sig)) {
+   } else if (!dStrAsciiCasecmp(ntag, HTML5_sig)) {
       BUG_MSG("Document follows HTML5 working draft; treating as HTML4.\n");
       html->DocType = DT_HTML;
       html->DocTypeVersion = 5.0f;
@@ -1687,11 +1687,11 @@
 
    if (!(attrbuf = a_Html_get_attr(html, tag, tagsize, "type"))) {
       BUG_MSG("type attribute is required for <style>\n");
-   } else if (dStrcasecmp(attrbuf, "text/css")) {
+   } else if (dStrAsciiCasecmp(attrbuf, "text/css")) {
       html->loadCssFromStash = false;
    }
    if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "media")) &&
-       dStrcasecmp(attrbuf, "all") && !dStristr(attrbuf, "screen")) {
+       dStrAsciiCasecmp(attrbuf, "all") && !dStriAsciiStr(attrbuf, "screen")) {
       /* HTML 4.01 sec. 6.13 says that media descriptors are case-sensitive,
        * but sec. 14.2.3 says that the attribute is case-insensitive.
        * TODO can be a comma-separated list.
@@ -1860,7 +1860,7 @@
    textblock->addWidget(bullet, html->styleEngine->wordStyle ());
    textblock->addSpace(html->styleEngine->wordStyle ());
 
-   if (tolower(tag[1]) == 'i') {
+   if (D_ASCII_TOLOWER(tag[1]) == 'i') {
       /* IFRAME usually comes with very long advertising/spying URLS,
        * to not break rendering we will force name="IFRAME" */
       textblock->addText ("IFRAME", html->styleEngine->wordStyle ());
@@ -2120,7 +2120,7 @@
       Image->bg_color = HT2TB(html)->getBgColor()->getColor();
 
    load_now = prefs.load_images ||
-              !dStrcasecmp(URL_SCHEME(url), "data") ||
+              !dStrAsciiCasecmp(URL_SCHEME(url), "data") ||
               (a_Capi_get_flags_with_redirection(url) & CAPI_IsCached);
    bool loading = false;
    if (load_now)
@@ -2292,15 +2292,15 @@
    }
    attrbuf = a_Html_get_attr(html, tag, tagsize, "shape");
 
-   if (!attrbuf || !*attrbuf || !dStrcasecmp(attrbuf, "rect")) {
+   if (!attrbuf || !*attrbuf || !dStrAsciiCasecmp(attrbuf, "rect")) {
       /* the default shape is a rectangle */
       type = RECTANGLE;
-   } else if (dStrcasecmp(attrbuf, "default") == 0) {
+   } else if (dStrAsciiCasecmp(attrbuf, "default") == 0) {
       /* "default" is the background */
       type = BACKGROUND;
-   } else if (dStrcasecmp(attrbuf, "circle") == 0) {
+   } else if (dStrAsciiCasecmp(attrbuf, "circle") == 0) {
       type = CIRCLE;
-   } else if (dStrncasecmp(attrbuf, "poly", 4) == 0) {
+   } else if (dStrnAsciiCasecmp(attrbuf, "poly", 4) == 0) {
       type = POLYGON;
    } else {
       BUG_MSG("<area> unknown shape: \"%s\"\n", attrbuf);
@@ -2394,7 +2394,7 @@
    char ch, *p1, *p2;
    Dstr *Buf = html->attr_data;
 
-   if (dStrncasecmp("javascript", Buf->str, 10) == 0) {
+   if (dStrnAsciiCasecmp("javascript", Buf->str, 10) == 0) {
       i = strcspn(Buf->str, "'\"");
       ch = Buf->str[i];
       if ((ch == '"' || ch == '\'') &&
@@ -2440,7 +2440,7 @@
 
    if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "href"))) {
       /* if it's a javascript link, extract the reference. */
-      if (tolower(attrbuf[0]) == 'j')
+      if (D_ASCII_TOLOWER(attrbuf[0]) == 'j')
          attrbuf = Html_get_javascript_link(html);
 
       url = a_Html_url_new(html, attrbuf, NULL, 0);
@@ -2548,11 +2548,11 @@
    if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "type"))) {
 
       /* list_style_type explicitly defined */
-      if (dStrcasecmp(attrbuf, "disc") == 0)
+      if (dStrAsciiCasecmp(attrbuf, "disc") == 0)
          list_style_type = LIST_STYLE_TYPE_DISC;
-      else if (dStrcasecmp(attrbuf, "circle") == 0)
+      else if (dStrAsciiCasecmp(attrbuf, "circle") == 0)
          list_style_type = LIST_STYLE_TYPE_CIRCLE;
-      else if (dStrcasecmp(attrbuf, "square") == 0)
+      else if (dStrAsciiCasecmp(attrbuf, "square") == 0)
          list_style_type = LIST_STYLE_TYPE_SQUARE;
       else
          /* invalid value */
@@ -2853,7 +2853,7 @@
    }
 
    if ((equiv = a_Html_get_attr(html, tag, tagsize, "http-equiv"))) {
-      if (!dStrcasecmp(equiv, "refresh") &&
+      if (!dStrAsciiCasecmp(equiv, "refresh") &&
           (content = a_Html_get_attr(html, tag, tagsize, "content"))) {
 
          /* Get delay, if present, and make a message with it */
@@ -2905,7 +2905,7 @@
          a_Url_free(new_url);
          dFree(mr_url);
 
-      } else if (!dStrcasecmp(equiv, "content-type") &&
+      } else if (!dStrAsciiCasecmp(equiv, "content-type") &&
                  (content = a_Html_get_attr(html, tag, tagsize, "content"))) {
          _MSG("Html_tag_open_meta: content={%s}\n", content);
          /* Cannot ask cache whether the content type was changed, as
@@ -3010,14 +3010,14 @@
    dReturn_if_fail (prefs.load_stylesheets);
    /* CSS stylesheet link */
    if (!(attrbuf = a_Html_get_attr(html, tag, tagsize, "rel")) ||
-       dStrcasecmp(attrbuf, "stylesheet"))
+       dStrAsciiCasecmp(attrbuf, "stylesheet"))
       return;
 
    /* IMPLIED attributes? */
    if (((attrbuf = a_Html_get_attr(html, tag, tagsize, "type")) &&
-        dStrcasecmp(attrbuf, "text/css")) ||
+        dStrAsciiCasecmp(attrbuf, "text/css")) ||
        ((attrbuf = a_Html_get_attr(html, tag, tagsize, "media")) &&
-        !dStristr(attrbuf, "screen") && dStrcasecmp(attrbuf, "all")))
+        !dStriAsciiStr(attrbuf, "screen") && dStrAsciiCasecmp(attrbuf, "all")))
       return;
 
    if (!(attrbuf = a_Html_get_attr(html, tag, tagsize, "href")) ||
@@ -3231,8 +3231,8 @@
 static int Html_tag_compare(const char *p1, const char *p2)
 {
    while ( *p2 ) {
-      if (tolower(*p1) != *p2)
-         return(tolower(*p1) - *p2);
+      if (D_ASCII_TOLOWER(*p1) != *p2)
+         return(D_ASCII_TOLOWER(*p1) - *p2);
       ++p1;
       ++p2;
    }
@@ -3474,7 +3474,7 @@
    if (ni == -1) {
       /* TODO: doctype parsing is a bit fuzzy, but enough for the time being */
       if (!(html->InFlags & IN_HTML)) {
-         if (tagsize > 9 && !dStrncasecmp(tag, "<!doctype", 9))
+         if (tagsize > 9 && !dStrnAsciiCasecmp(tag, "<!doctype", 9))
             Html_parse_doctype(html, tag, tagsize);
       }
       /* Ignore unknown tags */
@@ -3591,8 +3591,11 @@
                        (tag[i] == '=' || isspace(tag[i]) || tag[i] == '>')))) {
             state = SEEK_TOKEN_START;
             --i;
-         } else if (tolower(tag[i]) != tolower(attrname[attr_pos++]))
-            state = SEEK_ATTR_START;
+         } else {
+            if (D_ASCII_TOLOWER(tag[i]) != D_ASCII_TOLOWER(attrname[attr_pos]))
+               state = SEEK_ATTR_START;
+            attr_pos++;
+         }
          break;
 
       case SEEK_TOKEN_START:
--- a/src/keys.cc	Fri Nov 11 03:48:55 2011 +0000
+++ b/src/keys.cc	Fri Nov 11 04:26:41 2011 +0000
@@ -245,7 +245,7 @@
 {
    uint_t i;
    for (i = 0; i < sizeof(keyNames) / sizeof(Mapping_t); i++) {
-      if (!dStrcasecmp(keyNames[i].name, keyName)) {
+      if (!dStrAsciiCasecmp(keyNames[i].name, keyName)) {
          return keyNames[i].value;
       }
    }
@@ -262,7 +262,7 @@
    uint_t i;
 
    for (i = 0; i < sizeof(default_keys) / sizeof(KeyBinding_t); i++) {
-      if (!dStrcasecmp(default_keys[i].name, commandName))
+      if (!dStrAsciiCasecmp(default_keys[i].name, commandName))
          return default_keys[i].cmd;
    }
    return KEYS_INVALID;
@@ -276,7 +276,7 @@
 {
    uint_t i;
    for (i = 0; i < sizeof(modifierNames) / sizeof(Mapping_t); i++) {
-      if (!dStrcasecmp(modifierNames[i].name, modifierName)) {
+      if (!dStrAsciiCasecmp(modifierNames[i].name, modifierName)) {
          return modifierNames[i].value;
       }
    }
--- a/src/misc.c	Fri Nov 11 03:48:55 2011 +0000
+++ b/src/misc.c	Fri Nov 11 04:26:41 2011 +0000
@@ -141,12 +141,12 @@
 
    /* HTML try */
    for (i = 0; i < Size && dIsspace(p[i]); ++i);
-   if ((Size - i >= 5  && !dStrncasecmp(p+i, "<html", 5)) ||
-       (Size - i >= 5  && !dStrncasecmp(p+i, "<head", 5)) ||
-       (Size - i >= 6  && !dStrncasecmp(p+i, "<title", 6)) ||
-       (Size - i >= 14 && !dStrncasecmp(p+i, "<!doctype html", 14)) ||
+   if ((Size - i >= 5  && !dStrnAsciiCasecmp(p+i, "<html", 5)) ||
+       (Size - i >= 5  && !dStrnAsciiCasecmp(p+i, "<head", 5)) ||
+       (Size - i >= 6  && !dStrnAsciiCasecmp(p+i, "<title", 6)) ||
+       (Size - i >= 14 && !dStrnAsciiCasecmp(p+i, "<!doctype html", 14)) ||
        /* this line is workaround for FTP through the Squid proxy */
-       (Size - i >= 17 && !dStrncasecmp(p+i, "<!-- HTML listing", 17))) {
+       (Size - i >= 17 && !dStrnAsciiCasecmp(p+i, "<!-- HTML listing", 17))) {
 
       Type = DT_TEXT_HTML;
       st = 0;
@@ -233,8 +233,8 @@
          *minor = dStrndup(str, s - str);
    }
    if (charset && *s &&
-       (dStrncasecmp(type, "text/", 5) == 0 ||
-        dStrncasecmp(type, "application/xhtml+xml", 21) == 0)) {
+       (dStrnAsciiCasecmp(type, "text/", 5) == 0 ||
+        dStrnAsciiCasecmp(type, "application/xhtml+xml", 21) == 0)) {
       /* "charset" parameter defined for text media type in RFC 2046,
        * application/xhtml+xml in RFC 3236.
        *
@@ -246,7 +246,7 @@
       const char terminators[] = " ;\t";
       const char key[] = "charset";
 
-      if ((s = dStristr(str, key)) &&
+      if ((s = dStriAsciiStr(str, key)) &&
           (s == str || strchr(terminators, s[-1]))) {
          s += sizeof(key) - 1;
          for ( ; *s == ' ' || *s == '\t'; ++s);
@@ -283,12 +283,12 @@
    a_Misc_parse_content_type(ct1, &major1, &minor1, &charset1);
    a_Misc_parse_content_type(ct2, &major2, &minor2, &charset2);
 
-   if (major1 && major2 && !dStrcasecmp(major1, major2) &&
-       minor1 && minor2 && !dStrcasecmp(minor1, minor2) &&
+   if (major1 && major2 && !dStrAsciiCasecmp(major1, major2) &&
+       minor1 && minor2 && !dStrAsciiCasecmp(minor1, minor2) &&
        ((!charset1 && !charset2) ||
-        (charset1 && charset2 && !dStrcasecmp(charset1, charset2)) ||
-        (!charset1 && charset2 && !dStrcasecmp(charset2, "UTF-8")) ||
-        (charset1 && !charset2 && !dStrcasecmp(charset1, "UTF-8")))) {
+        (charset1 && charset2 && !dStrAsciiCasecmp(charset1, charset2)) ||
+        (!charset1 && charset2 && !dStrAsciiCasecmp(charset2, "UTF-8")) ||
+        (charset1 && !charset2 && !dStrAsciiCasecmp(charset1, "UTF-8")))) {
       ret = 0;
    } else {
       ret = 1;
@@ -328,22 +328,23 @@
       return 0; /* there's no mismatch without server type */
 
    for (i = 1; MimeTypes[i].str; ++i)
-      if (dStrncasecmp(EntryType, MimeTypes[i].str, MimeTypes[i].len) == 0)
+      if (dStrnAsciiCasecmp(EntryType, MimeTypes[i].str, MimeTypes[i].len) ==0)
          break;
 
    if (!MimeTypes[i].str) {
       /* type not found, no mismatch */
       st = 0;
-   } else if (dStrncasecmp(EntryType, "image/", 6) == 0 &&
-             !dStrncasecmp(DetectedType,MimeTypes[i].str,MimeTypes[i].len)){
+   } else if (dStrnAsciiCasecmp(EntryType, "image/", 6) == 0 &&
+             !dStrnAsciiCasecmp(DetectedType, MimeTypes[i].str,
+                                MimeTypes[i].len)){
       /* An image, and there's an exact match */
       st = 0;
-   } else if (dStrncasecmp(EntryType, "text/", 5) ||
-              dStrncasecmp(DetectedType, "application/", 12)) {
+   } else if (dStrnAsciiCasecmp(EntryType, "text/", 5) ||
+              dStrnAsciiCasecmp(DetectedType, "application/", 12)) {
       /* Not an application sent as text */
       st = 0;
-   } else if (dStrncasecmp(EntryType, "application/xhtml+xml", 21) &&
-              dStrncasecmp(DetectedType, "text/html", 9)) {
+   } else if (dStrnAsciiCasecmp(EntryType, "application/xhtml+xml", 21) &&
+              dStrnAsciiCasecmp(DetectedType, "text/html", 9)) {
       /* XML version of HTML */
       st = 0;
    }
--- a/src/prefsparser.cc	Fri Nov 11 03:48:55 2011 +0000
+++ b/src/prefsparser.cc	Fri Nov 11 04:26:41 2011 +0000
@@ -127,8 +127,8 @@
 
    switch (node->type) {
    case PREFS_BOOL:
-      *(bool_t *)node->pref = (!dStrcasecmp(value, "yes") ||
-                               !dStrcasecmp(value, "true"));
+      *(bool_t *)node->pref = (!dStrAsciiCasecmp(value, "yes") ||
+                               !dStrAsciiCasecmp(value, "true"));
       break;
    case PREFS_COLOR:
       *(int32_t *)node->pref = a_Color_parse(value, *(int32_t*)node->pref,&st);
@@ -167,18 +167,18 @@
                             &prefs.width, &prefs.height);
       break;
    case PREFS_FILTER:
-      if (!dStrcasecmp(value, "same_domain"))
+      if (!dStrAsciiCasecmp(value, "same_domain"))
          prefs.filter_auto_requests = PREFS_FILTER_SAME_DOMAIN;
       else {
-         if (dStrcasecmp(value, "allow_all"))
+         if (dStrAsciiCasecmp(value, "allow_all"))
             MSG_WARN("prefs: unrecognized value for filter_auto_requests\n");
          prefs.filter_auto_requests = PREFS_FILTER_ALLOW_ALL;
       }
       break;
    case PREFS_PANEL_SIZE:
-      if (!dStrcasecmp(value, "tiny"))
+      if (!dStrAsciiCasecmp(value, "tiny"))
          prefs.panel_size = P_tiny;
-      else if (!dStrcasecmp(value, "small"))
+      else if (!dStrAsciiCasecmp(value, "small"))
          prefs.panel_size = P_small;
       else /* default to "medium" */
          prefs.panel_size = P_medium;
--- a/src/table.cc	Fri Nov 11 03:48:55 2011 +0000
+++ b/src/table.cc	Fri Nov 11 04:26:41 2011 +0000
@@ -81,13 +81,13 @@
                                         a_Html_parse_length (html, attrbuf));
 
    if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "align"))) {
-      if (dStrcasecmp (attrbuf, "left") == 0)
+      if (dStrAsciiCasecmp (attrbuf, "left") == 0)
          html->styleEngine->setNonCssHint (CSS_PROPERTY_TEXT_ALIGN,
                                            CSS_TYPE_ENUM, TEXT_ALIGN_LEFT);
-      else if (dStrcasecmp (attrbuf, "right") == 0)
+      else if (dStrAsciiCasecmp (attrbuf, "right") == 0)
          html->styleEngine->setNonCssHint (CSS_PROPERTY_TEXT_ALIGN,
                                            CSS_TYPE_ENUM, TEXT_ALIGN_RIGHT);
-      else if (dStrcasecmp (attrbuf, "center") == 0)
+      else if (dStrAsciiCasecmp (attrbuf, "center") == 0)
          html->styleEngine->setNonCssHint (CSS_PROPERTY_TEXT_ALIGN,
                                            CSS_TYPE_ENUM, TEXT_ALIGN_CENTER);
    }
--- a/src/uicmd.cc	Fri Nov 11 03:48:55 2011 +0000
+++ b/src/uicmd.cc	Fri Nov 11 04:26:41 2011 +0000
@@ -597,7 +597,7 @@
       /* Filter URL string */
       new_urlstr = a_Url_string_strip_delimiters(urlstr);
 
-      if (!dStrncasecmp(new_urlstr, "file:", 5)) {
+      if (!dStrnAsciiCasecmp(new_urlstr, "file:", 5)) {
          /* file URI */
          ch = new_urlstr[5];
          if (!ch || ch == '.') {
--- a/src/url.c	Fri Nov 11 03:48:55 2011 +0000
+++ b/src/url.c	Fri Nov 11 04:26:41 2011 +0000
@@ -54,7 +54,7 @@
 #define URL_STR_FIELD_CMP(s1,s2) \
    (s1) && (s2) ? strcmp(s1,s2) : !(s1) && !(s2) ? 0 : (s1) ? 1 : -1
 #define URL_STR_FIELD_I_CMP(s1,s2) \
-   (s1) && (s2) ? dStrcasecmp(s1,s2) : !(s1) && !(s2) ? 0 : (s1) ? 1 : -1
+   (s1) && (s2) ? dStrAsciiCasecmp(s1,s2) : !(s1) && !(s2) ? 0 : (s1) ? 1 : -1
 
 /*
  * Return the url as a string.
@@ -702,7 +702,7 @@
 
          for (i = 0; i < tld_num; i++) {
             if (strlen(tlds[i]) == (uint_t) tld_len &&
-                !dStrncasecmp(tlds[i], host + start, tld_len)) {
+                !dStrnAsciiCasecmp(tlds[i], host + start, tld_len)) {
                _MSG("TLD code matched %s\n", tlds[i]);
                ret++;
                break;
@@ -759,6 +759,7 @@
    if (!u1 || !u2)
       return FALSE;
 
-   return dStrcasecmp(Url_host_find_public_suffix(URL_HOST(u1)),
-                      Url_host_find_public_suffix(URL_HOST(u2))) ? FALSE :TRUE;
+   return dStrAsciiCasecmp(Url_host_find_public_suffix(URL_HOST(u1)),
+                           Url_host_find_public_suffix(URL_HOST(u2)))
+          ? FALSE : TRUE;
 }
--- a/src/web.cc	Fri Nov 11 03:48:55 2011 +0000
+++ b/src/web.cc	Fri Nov 11 04:26:41 2011 +0000
@@ -95,7 +95,7 @@
 
    } else {
       /* A non-RootUrl. At this moment we only handle image-children */
-      if (!dStrncasecmp(Type, "image/", 6)) {
+      if (!dStrnAsciiCasecmp(Type, "image/", 6)) {
          dw = (Widget*) a_Mime_set_viewer(Type, Web, Call, Data);
       } else {
          MSG_HTTP("'%s' cannot be displayed as image; has media type '%s'\n",
--- a/test/dw_anchors_test.cc	Fri Nov 11 03:48:55 2011 +0000
+++ b/test/dw_anchors_test.cc	Fri Nov 11 04:26:41 2011 +0000
@@ -69,14 +69,14 @@
 
    char buf[16];
    strcpy (buf, numbers[textblockNo]);
-   buf[0] = toupper (buf[0]);
+   buf[0] = lout::misc::AsciiToupper (buf[0]);
    topTextblock->addText (buf, headingStyle);
    topTextblock->addParbreak (5, headingStyle);
 
    for (int i = 0; i < 30; i++) {
       strcpy (buf, numbers[textblockNo]);
       if (i == 0)
-         buf[0] = toupper (buf[0]);
+         buf[0] = lout::misc::AsciiToupper (buf[0]);
       strcat (buf, i == 29 ? "." : ",");
 
       topTextblock->addText (buf, wordStyle);
@@ -109,7 +109,7 @@
    for (int i = 0; i < 10; i++) {
       char buf[16];
       strcpy (buf, numbers[i]);
-      buf[0] = toupper (buf[0]);
+      buf[0] = lout::misc::AsciiToupper (buf[0]);
       buttonLabel[i] = strdup(buf);
       Fl_Button *button = new Fl_Button(0, 20 * i, 50, 20, buttonLabel[i]);
       button->callback (anchorCallback, (void*)(long)i);