gnu man(1): Recognize locales with Scripts in name
authorJohn Marino <draco@marino.st>
Thu, 13 Aug 2015 12:05:51 +0000 (14:05 +0200)
committerJohn Marino <draco@marino.st>
Thu, 13 Aug 2015 12:09:55 +0000 (14:09 +0200)
Our GNU man considered locales out of the form of xx_YY (where x is
anything except "_" and Y isn't checked) to be invalid.

However, we have valid locales like sr_Cyrl_RS which were being
rejected.  Adjust the validation code to handle these names.

It also appears that man requires a codeset to be specified, e.g.
fr_FR would be ignored but fr_FR.UTF-8 would be accepted.  I didn't
do anything about this.

gnu/usr.bin/man/man/man.c

index ed93b1a..e24e235 100644 (file)
@@ -343,6 +343,7 @@ man_getopt (int argc, char **argv)
      ) {
        char *tmp, *short_locale;
        struct ltable *pltable;
+       size_t locale_len;
 
        *locale_lang = '\0';
        *locale_terr = '\0';
@@ -354,20 +355,25 @@ man_getopt (int argc, char **argv)
        if ((tmp = strchr(short_locale, '.')) != NULL)
                *tmp = '\0';
 
-       if (strlen(short_locale) == 2)
-               strcpy(locale_lang, short_locale);
-       else if ((tmp = strchr(short_locale, '_')) == NULL ||
-                tmp != short_locale + 2 ||
-                strlen(tmp + 1) != 2
-               ) {
-               errno = EINVAL;
-               perror ("ctype locale format");
-               locale = NULL;
-       } else {
+       locale_len = strlen(short_locale);
+       tmp = strchr(short_locale, '_');
+       if (locale_len == 5 && tmp == short_locale + 2) {
+               /* assume position 3 and 4 are not "_"; don't check */
                strncpy(locale_terr, short_locale + 3, 2);
                locale_terr[2] = '\0';
                strncpy(locale_lang, short_locale, 2);
                locale_lang[2] = '\0';
+       } else if (locale_len == 10 && tmp == short_locale + 2 &&
+            short_locale[7] == '_') {
+               /* assume positions 3-6 and 8-9 are not "_" */
+               strncpy(locale_terr, short_locale + 8, 2);
+               locale_terr[2] = '\0';
+               strncpy(locale_lang, short_locale, 2);
+               locale_lang[2] = '\0';
+       } else {
+               errno = EINVAL;
+               perror ("ctype locale format");
+               locale = NULL;
        }
 
        free(short_locale);