]> git.saurik.com Git - apple/libc.git/blobdiff - locale/FreeBSD/collate.c
Libc-1439.100.3.tar.gz
[apple/libc.git] / locale / FreeBSD / collate.c
index d468783ae4c1d7190e004cd5b60f411504cab4e3..e5bc1eb14b76c9bac67c32f4518d71b88a8412dc 100644 (file)
@@ -72,6 +72,7 @@ int __collate_load_error = 1;
 __private_extern__ int
 __collate_load_tables(const char *encoding, locale_t loc)
 {
+       int fd;
        FILE *fp;
        int i, saverr, chains, z;
        char strbuf[STR_LEN], buf[PATH_MAX];
@@ -111,7 +112,12 @@ __collate_load_tables(const char *encoding, locale_t loc)
        /* Range checking not needed, encoding has fixed size */
        (void)strcpy(buf, encoding);
        (void)strcat(buf, "/LC_COLLATE");
-       if ((fp = fdopen(__open_path_locale(buf), "r")) == NULL) {
+       fd = __open_path_locale(buf);
+       if (fd == -1) {
+               return (_LDP_ERROR);
+       }
+       if ((fp = fdopen(fd, "r")) == NULL) {
+               close(fd);
                return (_LDP_ERROR);
        }
 
@@ -387,12 +393,31 @@ largesearch(const wchar_t key, locale_t loc)
        return NULL;
 }
 
-__private_extern__ void
+/*
+* This is provided for programs (like grep) that are calling this
+* private function.  This is also used by wcscoll()
+*/
+void
 __collate_lookup_l(const wchar_t *t, int *len, int *prim, int *sec, locale_t loc)
 {
        struct __collate_st_chain_pri *p2;
        int l;
 
+       if (!*t) {
+               *len = 0;
+               *prim = 0;
+               *sec = 0;
+               return;
+       }
+
+       NORMALIZE_LOCALE(loc);
+       if (loc->__collate_load_error) {
+               *len = 1;
+               *prim = *t;
+               *sec = 0;
+               return;
+       }
+
        *len = 1;
        *prim = *sec = 0;
        p2 = chainsearch(t, &l, loc);
@@ -422,22 +447,41 @@ __collate_lookup_l(const wchar_t *t, int *len, int *prim, int *sec, locale_t loc
 }
 
 /*
- * This is only provided for programs (like grep) that are calling this
- * private function.  This will go away eventually.
+ * This is also provided for programs (like grep) that are calling this
+ * private function - that do not perform their own multi-byte handling.
+ * This will go away eventually.
  */
 void
 __collate_lookup(const unsigned char *t, int *len, int *prim, int *sec)
 {
        locale_t loc = __current_locale();
-       wchar_t *w = __collate_mbstowcs((const char *)t, loc);
+       wchar_t *w = NULL;
        int sverrno;
 
+       if (!*t) {
+               *len = 0;
+               *prim = 0;
+               *sec = 0;
+               return;
+       }
+
+       if (loc->__collate_load_error || (w = __collate_mbstowcs((const char *)t, loc)) == NULL) {
+               *len = 1;
+               *prim = (int)*t;
+               *sec = 0;
+
+               sverrno = errno;
+               free((void*)w);
+               errno = sverrno;
+               return;
+       }
+
        __collate_lookup_l(w, len, prim, sec, loc);
        sverrno = errno;
        free(w);
        errno = sverrno;
 }
+
 __private_extern__ void
 __collate_lookup_which(const wchar_t *t, int *len, int *pri, int which, locale_t loc)
 {