make setlocale return a single name for LC_ALL if all categories match
authorRich Felker <dalias@aerifal.cx>
Tue, 21 Mar 2017 12:54:19 +0000 (08:54 -0400)
committerRich Felker <dalias@aerifal.cx>
Tue, 21 Mar 2017 12:54:19 +0000 (08:54 -0400)
when called for LC_ALL, setlocale has to return a string representing
the state of all locale categories. the simplest way to do this was to
always return a delimited list of values for each category, but that's
not friendly in the fairly common case where all categories have the
same setting. He X proposed a patch to check for this case and return
a single name; this patch is a simplified approach to do the same.

src/locale/setlocale.c

index 8dae5a4..623660c 100644 (file)
@@ -48,10 +48,13 @@ char *setlocale(int cat, const char *name)
                        }
                }
                char *s = buf;
+               const char *part;
+               int same = 0;
                for (i=0; i<LC_ALL; i++) {
                        const struct __locale_map *lm =
                                libc.global_locale.cat[i];
-                       const char *part = lm ? lm->name : "C";
+                       if (lm == libc.global_locale.cat[0]) same++;
+                       part = lm ? lm->name : "C";
                        size_t l = strlen(part);
                        memcpy(s, part, l);
                        s[l] = ';';
@@ -59,7 +62,7 @@ char *setlocale(int cat, const char *name)
                }
                *--s = 0;
                UNLOCK(lock);
-               return buf;
+               return same==LC_ALL ? (char *)part : buf;
        }
 
        char *ret = setlocale_one_unlocked(cat, name);