usr/src/lib/liborchestrator/locale.c
branchoi_151a
changeset 1416 2c9d399a58c0
parent 1414 5cff819a623b
child 1431 be5c727ec6be
--- a/usr/src/lib/liborchestrator/locale.c	Tue Aug 16 20:54:08 2011 +0000
+++ b/usr/src/lib/liborchestrator/locale.c	Tue Aug 16 20:54:08 2011 +0000
@@ -22,6 +22,9 @@
  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
+/*
+ * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
+ */
 
 #include <fcntl.h>
 #include <stdio.h>
@@ -80,17 +83,12 @@
 	char	*lang_code;
 } chinese_values[] = {
 	{"zh", SIMPLIFIED_CHINESE, "sc"},
-	{"zh.GBK", SIMPLIFIED_CHINESE, "sc"},
-	{"zh.UTF-8", SIMPLIFIED_CHINESE, "sc"},
 	{"zh_CN", SIMPLIFIED_CHINESE, "sc"},
-	{"zh_CN.GB18030", SIMPLIFIED_CHINESE, "sc"},
-	{"zh_CN.UTF-8", SIMPLIFIED_CHINESE, "sc"},
 	{"zh_HK", TRADITIONAL_CHINESE, "tc"},
-	{"zh_HK.BIG5HK", TRADITIONAL_CHINESE, "tc"},
-	{"zh_HK.UTF-8", TRADITIONAL_CHINESE, "tc"},
+	{"zh_MO", TRADITIONAL_CHINESE, "tc"},
+	{"zh_SG", TRADITIONAL_CHINESE, "tc"},
 	{"zh_TW", TRADITIONAL_CHINESE, "tc"},
-	{"zh_TW.BIG5", TRADITIONAL_CHINESE, "tc"},
-	{"zh_TW.UTF-8", TRADITIONAL_CHINESE, "tc"}
+	{ NULL }
 };
 
 
@@ -124,6 +122,7 @@
 static void 	sort_lang_list(char **unsorted_list, int total);
 static char 	*substitute_chinese_language(char *locale, char **code);
 static char 	*substitute_C_POSIX_language(char **code);
+static char 	*substitute_language(char *locale, char **code);
 static void 	update_init(FILE *fp, char *locale);
 static void 	update_env(char *locale);
 
@@ -642,8 +641,8 @@
 	lang_info_t	*tmp, *last, *new;
 	locale_info_t	*lp = NULL;
 	char		**trans_lang = NULL;
+	char		*sub = NULL;
 	char		*tmp_lang = NULL;
-	char		*tmp_locale = NULL;
 	char		*code = NULL;
 	char		*desc = NULL;
 	int		total;
@@ -653,18 +652,16 @@
 	 * For Chinese we have to handle it specially. There is Traditional
 	 * Chinese or Simplified Chinese. Everything else is a locale.
 	 */
-	if (strncmp(lang, "zh", 2) == 0) {
-		tmp_lang = strdup(dgettext(TEXT_DOMAIN,
-		    substitute_chinese_language(lang, &code)));
-		if (locale == NULL)
-			tmp_locale = strdup(dgettext(TEXT_DOMAIN, lang));
+	sub = substitute_language(lang, &code);
+
+	if (sub != NULL) {
+		tmp_lang = strdup(sub);
+		if (tmp_lang == NULL)
+			goto error;
 	}
-	if (strncmp(lang, "C", 1) == 0) {
-		tmp_lang = strdup(dgettext(TEXT_DOMAIN,
-		    substitute_C_POSIX_language(&code)));
-		if (locale == NULL)
-			tmp_locale = strdup(dgettext(TEXT_DOMAIN, lang));
-	}
+
+	if (locale == NULL)
+		locale = dgettext(TEXT_DOMAIN, lang);
 
 	new = (lang_info_t *)malloc(sizeof (lang_info_t));
 	if (new == NULL)
@@ -696,7 +693,7 @@
 
 	new->def_lang = is_default;
 
-	if (locale != NULL || tmp_locale != NULL) {
+	if (locale != NULL) {
 		lp = (locale_info_t *)malloc(sizeof (locale_info_t));
 		if (lp == NULL) {
 			om_set_error(OM_NO_SPACE);
@@ -704,11 +701,7 @@
 		}
 		(void) memset(lp, 0, sizeof (locale_info_t));
 
-		if (tmp_locale) {
-			lp->locale_name = tmp_locale;
-		} else {
-			lp->locale_name = strdup(locale);
-		}
+		lp->locale_name = strdup(locale);
 		if (lp->locale_name == NULL) {
 			om_set_error(OM_NO_SPACE);
 			goto error;
@@ -743,12 +736,10 @@
 		list = new;
 	}
 
-	free(code);
 	*(return_list) = list;
 	return (OM_SUCCESS);
 
 error:
-	free(code);
 	om_free_lang_info(new);
 	om_free_locale_info(lp);
 	return (OM_FAILURE);
@@ -776,7 +767,7 @@
 get_lang_entry(char *lang_name, lang_info_t *search_list)
 {
 	lang_info_t 	*list = NULL;
-	char		*tmp_lang = NULL;
+	char		*sub = NULL;
 	char		*code = NULL;
 	boolean_t	found = B_FALSE;
 
@@ -786,10 +777,7 @@
 	 * Chinese language names are stored differently.
 	 */
 
-	if (strncmp(lang_name, "zh", 2) == 0)  {
-		tmp_lang = strdup(dgettext(TEXT_DOMAIN,
-		    substitute_chinese_language(lang_name, &code)));
-	}
+	sub = substitute_language(lang_name, &code);
 
 	for (list = search_list; list != NULL; list = list->next) {
 		if (code) {
@@ -805,9 +793,6 @@
 		}
 	}
 
-	free(tmp_lang);
-	free(code);
-
 	if (!found)
 		return (NULL);
 	return (list);
@@ -939,7 +924,8 @@
 				}
 			}
 		} else if (strcmp(lang, "C") == 0 ||
-		    strcmp(lang, "POSIX") == 0) {
+		    strcmp(lang, "POSIX") == 0 ||
+		    strcmp(lang, "C/POSIX") == 0) {
 			free(lang);
 			lang = strdup("en");
 			is_default = B_TRUE;
@@ -1146,7 +1132,8 @@
 				}
 			}
 		} else if (strcmp(lang, "C") == 0 ||
-		    strcmp(lang, "POSIX") == 0) {
+		    strcmp(lang, "POSIX") == 0 ||
+		    strcmp(lang, "C/POSIX") == 0) {
 			free(lang);
 			lang = strdup("en");
 			if (lang == NULL) {
@@ -1577,16 +1564,15 @@
 	char	**lpp = *list;
 	char	**tmp_list;
 	char	*tmp = NULL;
+	char	*sub = NULL;
 	char	*code;
 
 	tmp_list = *list;
 
-	if (strncmp(locale, "zh", 2) == 0) {
-		tmp = strdup(dgettext(TEXT_DOMAIN,
-		    substitute_chinese_language(locale, &code)));
-	} else if (strcmp(locale, "C") == 0 || strcmp(locale, "POSIX") == 0 ||
-	    strcmp(locale, "C/POSIX") == 0) {
-		tmp = strdup(dgettext(TEXT_DOMAIN, "English"));
+	sub = substitute_language(locale, &code);
+
+	if (sub != NULL) {
+		tmp = strdup(sub);
 	} else {
 		tmp = strdup(dgettext(TEXT_DOMAIN,
 		    orchestrator_lang_list[j].lang_name));
@@ -1642,6 +1628,7 @@
 	}
 	return (B_FALSE);
 }
+
 static char *
 substitute_C_POSIX_language(char **code)
 {
@@ -1651,18 +1638,8 @@
 	 * locale is C and or POSIX. Set to English, set code
 	 * to 'en'.
 	 */
-	lang = strdup(dgettext(TEXT_DOMAIN, "English"));
-	if (lang == NULL) {
-		om_set_error(OM_NO_SPACE);
-		*code = NULL;
-		return (lang);
-	}
-	*code = strdup("en");
-	if (*code == NULL) {
-		free(lang);
-		lang = NULL;
-		om_set_error(OM_NO_SPACE);
-	}
+	lang = dgettext(TEXT_DOMAIN, "English");
+	*code = "en";
 	return (lang);
 }
 
@@ -1670,26 +1647,41 @@
 substitute_chinese_language(char *locale, char **code)
 {
 	int 		i;
+	int		len;
 	char		*sub = NULL;
 
-	*code = NULL;
-
-	for (i = 0; chinese_values[i].lang; i++) {
-		if (strcmp(locale, chinese_values[i].lang) == 0) {
-			sub = strdup(chinese_values[i].lang_name);
-			*code = strdup(chinese_values[i].lang_code);
-			if (sub == NULL || *code == NULL) {
-				free(sub);
-				om_set_error(OM_NO_SPACE);
-				return (NULL);
-			} else {
-				return (sub);
-			}
+	for (i = 0; chinese_values[i].lang != NULL; i++) {
+		len = strlen(chinese_values[i].lang);
+		if ((strncmp(locale,  chinese_values[i].lang, len) == 0) &&
+		    (locale[len] == '\0' || locale[len] == '.')) {
+			sub =
+			    dgettext(TEXT_DOMAIN, chinese_values[i].lang_name);
+			*code = chinese_values[i].lang_code;
+			return (sub);
 		}
 	}
+
+	om_set_error(OM_INVALID_LOCALE);
 	return (sub);
 }
 
+static char *
+substitute_language(char *locale, char **code)
+{
+	char *lang = NULL;
+
+	if (strncmp(locale, "zh", 2) == 0) {
+		lang = substitute_chinese_language(locale, code);
+		if (lang == NULL)
+			goto error;
+	} else if (strcmp(locale, "C") == 0 || strcmp(locale, "POSIX") == 0) {
+		lang = substitute_C_POSIX_language(code);
+	}
+
+error:
+	return (lang);
+}
+
 static void
 sort_lang_list(char **unsorted_list, int total)
 {