Author: pfg
Date: Sun Jun  5 19:12:52 2016
New Revision: 301461
URL: https://svnweb.freebsd.org/changeset/base/301461

Log:
  libc/locale: Fix type breakage in __collate_range_cmp().
  
  When collation support was brought in, the second and third
  arguments in __collate_range_cmp() were changed from int to
  wchar_t, breaking the ABI. Change them to a "char" type which
  makes more sense and keeps the ABI compatible.
  
  Also introduce __wcollate_range_cmp() which does work with wide
  characters. This function is used only internally in libc so
  we don't export it. Use the new function in glob(3), fnmatch(3),
  and regexec(3).
  
  PR:           179721
  Suggested by: ache. jilles
  MFC after:    3 weeks (perhaps partial only)

Modified:
  head/lib/libc/gen/fnmatch.c
  head/lib/libc/gen/glob.c
  head/lib/libc/locale/collate.h
  head/lib/libc/locale/collcmp.c
  head/lib/libc/regex/regcomp.c

Modified: head/lib/libc/gen/fnmatch.c
==============================================================================
--- head/lib/libc/gen/fnmatch.c Sun Jun  5 18:16:33 2016        (r301460)
+++ head/lib/libc/gen/fnmatch.c Sun Jun  5 19:12:52 2016        (r301461)
@@ -296,8 +296,8 @@ rangematch(const char *pattern, wchar_t 
 
                        if (table->__collate_load_error ?
                            c <= test && test <= c2 :
-                              __collate_range_cmp(table, c, test) <= 0
-                           && __collate_range_cmp(table, test, c2) <= 0
+                              __wcollate_range_cmp(table, c, test) <= 0
+                           && __wcollate_range_cmp(table, test, c2) <= 0
                           )
                                ok = 1;
                } else if (c == test)

Modified: head/lib/libc/gen/glob.c
==============================================================================
--- head/lib/libc/gen/glob.c    Sun Jun  5 18:16:33 2016        (r301460)
+++ head/lib/libc/gen/glob.c    Sun Jun  5 19:12:52 2016        (r301461)
@@ -832,8 +832,8 @@ match(Char *name, Char *pat, Char *paten
                                if ((*pat & M_MASK) == M_RNG) {
                                        if (table->__collate_load_error ?
                                            CHAR(c) <= CHAR(k) && CHAR(k) <= 
CHAR(pat[1]) :
-                                              __collate_range_cmp(table, 
CHAR(c), CHAR(k)) <= 0
-                                           && __collate_range_cmp(table, 
CHAR(k), CHAR(pat[1])) <= 0
+                                              __wcollate_range_cmp(table, 
CHAR(c), CHAR(k)) <= 0
+                                           && __wcollate_range_cmp(table, 
CHAR(k), CHAR(pat[1])) <= 0
                                           )
                                                ok = 1;
                                        pat += 2;

Modified: head/lib/libc/locale/collate.h
==============================================================================
--- head/lib/libc/locale/collate.h      Sun Jun  5 18:16:33 2016        
(r301460)
+++ head/lib/libc/locale/collate.h      Sun Jun  5 19:12:52 2016        
(r301461)
@@ -128,7 +128,8 @@ int __collate_load_tables(const char *);
 int    __collate_equiv_value(locale_t, const wchar_t *, size_t);
 void   _collate_lookup(struct xlocale_collate *,const wchar_t *, int *, int *,
        int, const int **);
-int    __collate_range_cmp(struct xlocale_collate *, wchar_t, wchar_t);
+int    __collate_range_cmp(struct xlocale_collate *, char, char);
+int    __wcollate_range_cmp(struct xlocale_collate *, wchar_t, wchar_t);
 size_t _collate_wxfrm(struct xlocale_collate *, const wchar_t *, wchar_t *,
        size_t);
 size_t _collate_sxfrm(struct xlocale_collate *, const wchar_t *, char *,

Modified: head/lib/libc/locale/collcmp.c
==============================================================================
--- head/lib/libc/locale/collcmp.c      Sun Jun  5 18:16:33 2016        
(r301460)
+++ head/lib/libc/locale/collcmp.c      Sun Jun  5 19:12:52 2016        
(r301461)
@@ -41,14 +41,27 @@ __FBSDID("$FreeBSD$");
  * Compare two characters using collate
  */
 
-int __collate_range_cmp(struct xlocale_collate *table, wchar_t c1, wchar_t c2)
+int __collate_range_cmp(struct xlocale_collate *table, char c1, char c2)
+{
+       char s1[2], s2[2];
+
+       s1[0] = c1;
+       s1[1] = '\0';
+       s2[0] = c2;
+       s2[1] = '\0';
+       struct _xlocale l = {{0}};
+       l.components[XLC_COLLATE] = (struct xlocale_component *)table;
+       return (strcoll_l(s1, s2, &l));
+}
+
+int __wcollate_range_cmp(struct xlocale_collate *table, wchar_t c1, wchar_t c2)
 {
        wchar_t s1[2], s2[2];
 
        s1[0] = c1;
-       s1[1] = 0;
+       s1[1] = L'\0';
        s2[0] = c2;
-       s2[1] = 0;
+       s2[1] = L'\0';
        struct _xlocale l = {{0}};
        l.components[XLC_COLLATE] = (struct xlocale_component *)table;
        return (wcscoll_l(s1, s2, &l));

Modified: head/lib/libc/regex/regcomp.c
==============================================================================
--- head/lib/libc/regex/regcomp.c       Sun Jun  5 18:16:33 2016        
(r301460)
+++ head/lib/libc/regex/regcomp.c       Sun Jun  5 19:12:52 2016        
(r301461)
@@ -821,10 +821,10 @@ p_b_term(struct parse *p, cset *cs)
                                (void)REQUIRE((uch)start <= (uch)finish, 
REG_ERANGE);
                                CHaddrange(p, cs, start, finish);
                        } else {
-                               (void)REQUIRE(__collate_range_cmp(table, start, 
finish) <= 0, REG_ERANGE);
+                               (void)REQUIRE(__wcollate_range_cmp(table, 
start, finish) <= 0, REG_ERANGE);
                                for (i = 0; i <= UCHAR_MAX; i++) {
-                                       if (   __collate_range_cmp(table, 
start, i) <= 0
-                                           && __collate_range_cmp(table, i, 
finish) <= 0
+                                       if (   __wcollate_range_cmp(table, 
start, i) <= 0
+                                           && __wcollate_range_cmp(table, i, 
finish) <= 0
                                           )
                                                CHadd(p, cs, i);
                                }
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to