diff options
-rw-r--r-- | lib/libsi18n/acclanglist.c | 100 |
1 files changed, 66 insertions, 34 deletions
diff --git a/lib/libsi18n/acclanglist.c b/lib/libsi18n/acclanglist.c index 1fd4f15f..9f910aa6 100644 --- a/lib/libsi18n/acclanglist.c +++ b/lib/libsi18n/acclanglist.c @@ -75,7 +75,7 @@ AcceptLangList(const char* AcceptLanguage, char* cPtr2; int i; int j; - int countLang = 0; + size_t countLang = 0; input = strdup(AcceptLanguage); if (input == (char*)NULL){ @@ -95,8 +95,6 @@ AcceptLangList(const char* AcceptLanguage, } *cPtr2 = '\0'; - countLang = 0; - if (strchr(input,';')) { /* deal with the quality values */ @@ -123,7 +121,7 @@ AcceptLangList(const char* AcceptLanguage, /* sort according to decending qvalue */ /* not a very good algorithm, but count is not likely large */ - for ( i=0 ; i<countLang-1 ; i++ ) { + for ( i=0 ; (countLang>0) && (i<countLang-1) ; i++ ) { for ( j=i+1 ; j<countLang ; j++ ) { if (qvalue[i]<qvalue[j]) { qSwap = qvalue[i]; @@ -158,11 +156,48 @@ AcceptLangList(const char* AcceptLanguage, } /* + See if lang is in the given list. lang should be the two character + lang code. List must contain the exact string, so lang "en" will + match if "en" is in the list, but will not match "en_us" +*/ +static int +langIsInList(const char *lang, size_t listsize, ACCEPT_LANGUAGE_LIST accll) +{ + int retval = 0; + int ii; + + for (ii = 0; !retval && (ii < listsize); ++ii) { + if (!strcmp(lang, accll[ii])) { + retval = 1; + } + } + + return retval; +} + +/* * Get prioritized locale list from NLS_AcceptLangList * * Add additonal language to the list for fallback if locale * name is language_region * + * I think the intention of this code is to take a list sorted + * in q order (by AcceptLangList above) and make sure the list + * has the 2 char lang code if only region codes were given. + * For example, given the list "en_gb, en_us, fr_ca, fr_fr" + * the output list should look like this: + * "en_gb, en_us, fr_ca, fr_fr, en, fr" + * But if the input list is like this: + * "en_gb, en_us, en, fr_ca, fr_fr" - the code should not + * add an "en" since it is already explicitly called out + * in the list + * Also note - the input list may not be well formed - + * It could look like this e.g. + * "en_us, en_gb, fr_ca, en_us, fr_ca, en_gb, fr_fr" + * So we cannot make any assumptions about the list + * having no duplicates or having the languages all + * grouped together. + * */ @@ -170,50 +205,47 @@ int XP_AccLangList(char* AcceptLanguage, ACCEPT_LANGUAGE_LIST AcceptLanguageList) { - int i; - int n; + size_t i; + size_t n; char *defaultLanguage = "en"; ACCEPT_LANGUAGE_LIST curLanguageList; - int index = 0; - char lang[3]; - int k; + size_t maxelems = sizeof(curLanguageList)/sizeof(curLanguageList[0]); + size_t index = 0; + /* parse the given Accept-Language string and sort according + to q values */ n = AcceptLangList(AcceptLanguage, curLanguageList); if (n == 0) return 0; - memset(lang, 0, 3); - for (i = 0; i < n; i++) { - if (*lang && (strncmp(lang, curLanguageList[i], 2) != 0)) { - /* add lang if current language is the last occurence in the list */ - for (k = i+1; (k < n) && strncmp(curLanguageList[k],lang,2); k++); - - if (k == n) { - strcpy(AcceptLanguageList[index++], lang); - *lang = '\0'; - } - } - + /* first, just copy curLanguageList to AcceptLanguageList */ + for (i = 0; (i < n) && (index < maxelems); i++) { strcpy(AcceptLanguageList[index++], curLanguageList[i]); + } - /* Add current language for future appending.,make sure it's not on list */ + /* next, append the lang without the country code in the + order that the country first appears in the list, if + the lang is not already in the list */ + for (i = 0; (i < n) && (index < maxelems); i++) { + /* if current item is a lang + co, grab the lang part */ if ((strlen(curLanguageList[i]) > 2) && (curLanguageList[i][2] == '_')) { - strncpy(lang, curLanguageList[i], 2); - for (k = 0; (k < index) && strcmp(AcceptLanguageList[k], lang); k++); + char lang[3]; + strncpy(lang, curLanguageList[i], 2); + lang[sizeof(lang)-1] = 0; - if (k != index) lang[0] = '\0'; - } + if (!langIsInList(lang, index, AcceptLanguageList)) { + /* lang not already in list - append to list */ + strcpy(AcceptLanguageList[index++], lang); + } + } } - if (lang[0] != '\0') - strcpy(AcceptLanguageList[index++], lang); /* add new lang */ - - /* Append defaultLanguage if it's not in the list */ - for (i = 0; (i < index) && strcmp(AcceptLanguageList[i], defaultLanguage); i++); - - if (i == index) + /* Append defaultLanguage if it's not in the list and we have room */ + if ((index < maxelems) && + !langIsInList(defaultLanguage, index, AcceptLanguageList)) { strcpy(AcceptLanguageList[index++], defaultLanguage); + } - return index; + return (int)index; } |