/* lang.c
Copyright (c) 2003-2021 HandBrake Team
This file is part of the HandBrake source code
Homepage: .
It may be used under the terms of the GNU General Public License v2.
For full terms see the file COPYING file or visit http://www.gnu.org/licenses/gpl-2.0.html
*/
#include "handbrake/lang.h"
#include
#include
// Fake iso639 entry to deal with selection of "any" language
static iso639_lang_t lang_any =
{ "Any", "", "yy", "any" };
static const iso639_lang_t languages[] =
{ { "Unknown", "", "", "und" },
{ "Afar", "Qafar", "aa", "aar" },
{ "Abkhaz", "Аԥсуа бызшәа", "ab", "abk" },
{ "Afrikaans", "Afrikaans", "af", "afr" },
{ "Akan", "Akan", "ak", "aka" },
{ "Albanian", "shqip", "sq", "sqi", "alb" },
{ "Amharic", "አማርኛ", "am", "amh" },
{ "Arabic", "العربية", "ar", "ara" },
{ "Aragonese", "aragonés", "an", "arg" },
{ "Armenian", "Հայերեն", "hy", "hye", "arm" },
{ "Assamese", "অসমীয়া", "as", "asm" },
{ "Avar", "магӏарул мацӏ", "av", "ava" },
{ "Avestan", "", "ae", "ave" },
{ "Aymara", "Aymar aru", "ay", "aym" },
{ "Azerbaijani", "Azərbaycanılı", "az", "aze" },
{ "Bashkir", "Башҡорт", "ba", "bak" },
{ "Bambara", "Bamana", "bm", "bam" },
{ "Basque", "euskara", "eu", "eus", "baq" },
{ "Belarusian", "Беларуская", "be", "bel" },
{ "Bengali", "Bangla", "bn", "ben" },
{ "Bihari", "", "bh", "bih" },
{ "Bislama", "Bislama", "bi", "bis" },
{ "Bosnian", "bosanski", "bs", "bos" },
{ "Breton", "brezhoneg", "br", "bre" },
{ "Bulgarian", "български", "bg", "bul" },
{ "Burmese", "ဗမာ", "my", "mya", "bur" },
{ "Catalan", "català", "ca", "cat" },
{ "Chamorro", "Finu' Chamorro", "ch", "cha" },
{ "Chechen", "Нохчийн Мотт", "ce", "che" },
{ "Chinese", "中文", "zh", "zho", "chi" },
{ "Church Slavonic", "", "cu", "chu" },
{ "Chuvash", "Чӑвашла", "cv", "chv" },
{ "Cornish", "kernewek", "kw", "cor" },
{ "Corsican", "Corsu", "co", "cos" },
{ "Cree", "", "cr", "cre" },
{ "Croatian", "hrvatski", "hr", "hrv", "scr" },
{ "Czech", "čeština", "cs", "ces", "cze" },
{ "Danish", "dansk", "da", "dan" },
{ "Divehi", "ދިވެހިބަސް", "dv", "div" },
{ "Dutch", "Nederlands", "nl", "nld", "dut" },
{ "Dzongkha", "རྫོང་ཁ", "dz", "dzo" },
{ "English", "English", "en", "eng" },
{ "Esperanto", "esperanto", "eo", "epo" },
{ "Estonian", "eesti", "et", "est" },
{ "Ewe", "eʋegbe", "ee", "ewe" },
{ "Faroese", "føroyskt", "fo", "fao" },
{ "Fijian", "Na Vosa Vakaviti", "fj", "fij" },
{ "Finnish", "suomi", "fi", "fin" },
{ "French", "Francais", "fr", "fra", "fre" },
{ "Western Frisian", "Frysk", "fy", "fry" },
{ "Fulah", "Fulah", "ff", "ful" },
{ "Georgian", "ქართული", "ka", "kat", "geo" },
{ "German", "Deutsch", "de", "deu", "ger" },
{ "Gaelic (Scots)", "Gàidhlig", "gd", "gla" },
{ "Galician", "galego", "gl", "glg" },
{ "Manx", "Gaelg", "gv", "glv" },
{ "Greek, Modern", "Ελληνικά", "el", "ell", "gre" },
{ "Greenlandic", "Kalaallisut", "kl", "kal" },
{ "Guarani", "Avañe’ẽ", "gn", "grn" },
{ "Gujarati", "ગુજરાતી", "gu", "guj" },
{ "Haitian", "", "ht", "hat" },
{ "Hausa", "Hausa", "ha", "hau" },
{ "Hebrew", "עברית", "he", "heb", "", "iw" },
{ "Herero", "Otjiherero", "hz", "her" },
{ "Hindi", "हिंदी", "hi", "hin" },
{ "Hiri Motu", "", "ho", "hmo" },
{ "Hungarian", "magyar", "hu", "hun" },
{ "Igbo", "Igbo", "ig", "ibo" },
{ "Icelandic", "íslenska", "is", "isl", "ice" },
{ "Ido", "", "io", "ido" },
{ "Inuktitut", "Inuktitut", "iu", "iku" },
{ "Interlingue", "", "ie", "ile" },
{ "Interlingua", "", "ia", "ina" },
{ "Indonesian", "Bahasa Indonesia", "id", "ind", "", "in" },
{ "Inupiaq", "", "ik", "ipk" },
{ "Irish", "Gaeilge", "ga", "gle" },
{ "Italian", "italiano", "it", "ita" },
{ "Javanese", "Basa Jawa", "jv", "jav", "", "jw" },
{ "Japanese", "日本語", "ja", "jpn" },
{ "Kannada", "", "kn", "kan" },
{ "Kashmiri", "کٲشُر", "ks", "kas" },
{ "Kanuri", "Kanuri", "kr", "kau" },
{ "Kazakh", "қазақ тілі", "kk", "kaz" },
{ "Central Khmer", "ភាសាខ្មែរ", "km", "khm" },
{ "Kikuyu", "Gikuyu", "ki", "kik" },
{ "Kinyarwanda", "Kinyarwanda", "rw", "kin" },
{ "Kirghiz", "قىرعىزچا", "ky", "kir" },
{ "Komi", "Коми кыв", "kv", "kom" },
{ "Kongo", "Kikongo", "kg", "kon" },
{ "Korean", "한국어", "ko", "kor" },
{ "Kuanyama", "Oshikwanyama", "kj", "kua" },
{ "Kurdish", "کوردی", "ku", "kur" },
{ "Lao", "ລາວ", "lo", "lao" },
{ "Latin", "lingua latīna", "la", "lat" },
{ "Latvian", "latviešu", "lv", "lav" },
{ "Limburgish", "Limburgs", "li", "lim" },
{ "Lingala", "lingála", "ln", "lin" },
{ "Lithuanian", "lietuvių", "lt", "lit" },
{ "Luxembourgish", "Lëtzebuergesch", "lb", "ltz" },
{ "Luba-Katanga", "Tshiluba", "lu", "lub" },
{ "Ganda", "Luganda", "lg", "lug" },
{ "Macedonian", "македонски", "mk", "mkd", "mac" },
{ "Marshallese", "Kajin M̧ajeļ", "mh", "mah" },
{ "Malayalam", "മലയാളം", "ml", "mal" },
{ "Maori", "Reo Māori", "mi", "mri", "mao" },
{ "Marathi", "मराठी", "mr", "mar" },
{ "Malay", "Bahasa Melayu", "ms", "msa", "msa" },
{ "Malagasy", "Malagasy", "mg", "mlg" },
{ "Maltese", "Malti", "mt", "mlt" },
{ "Moldavian", "limba moldovenească", "mo", "mol" },
{ "Mongolian", "Монгол хэл", "mn", "mon" },
{ "Nauruan", "dorerin Naoero", "na", "nau" },
{ "Navajo", "Diné bizaad", "nv", "nav" },
{ "Ndebele, South", "Nrebele", "nr", "nbl" },
{ "Ndebele, North", "isiNdebele", "nd", "nde" },
{ "Ndonga", "Oshindonga", "ng", "ndo" },
{ "Nepali", "नेपाली", "ne", "nep" },
{ "Norwegian Nynorsk", "nynorsk", "nn", "nno" },
{ "Norwegian Bokmål", "norsk bokmål", "nb", "nob" },
{ "Norwegian", "norsk", "no", "nor" },
{ "Nuosu", "ꆈꌠ꒿", "ii", "iii" },
{ "Chewa", "Nyanja", "ny", "nya" },
{ "Occitan (post 1500); Provençal", "Occitan", "oc", "oci" },
{ "Ojibwe", "ᐊᓂᔑᓈᐯᒧᐎᓐ", "oj", "oji" },
{ "Oriya", "ଓଡ଼ିଆ", "or", "ori" },
{ "Oromo", "Oromoo", "om", "orm" },
{ "Ossetian; Ossetic", "Ирон æвзаг", "os", "oss" },
{ "Persian", "فارسی", "fa", "fas", "per" },
{ "Pali", "Pāli", "pi", "pli" },
{ "Polish", "polski", "pl", "pol" },
{ "Portuguese", "Portugues", "pt", "por" },
{ "Punjabi", "ਪੰਜਾਬੀ", "pa", "pan" },
{ "Pashto", "پښتو", "ps", "pus" },
{ "Quechua", "runasimi", "qu", "que" },
{ "Romanian", "română", "ro", "ron", "rum" },
{ "Romansh", "rumantsch", "rm", "roh" },
{ "Rundi", "Ikirundi", "rn", "run" },
{ "Russian", "русский", "ru", "rus" },
{ "Samoan", "Gagana fa'a Sāmoa", "sm", "smo" },
{ "Sango", "Sängö", "sg", "sag" },
{ "Sanskrit", "संस्कृत", "sa", "san" },
{ "Sardinian", "sardu", "sc", "srd" },
{ "Serbian", "srpski", "sr", "srp", "scc" },
{ "Sinhala", "සිංහල", "si", "sin" },
{ "Slovak", "slovenčina", "sk", "slk", "slo" },
{ "Slovenian", "slovenščina", "sl", "slv" },
{ "Northern Sami", "davvisámegiella", "se", "sme" },
{ "Shona", "chiShona", "sn", "sna" },
{ "Sindhi", "سنڌي", "sd", "snd" },
{ "Somali", "Soomaali", "so", "som" },
{ "Sotho, Southern", "Sesotho", "st", "sot" },
{ "Spanish", "español", "es", "spa" },
{ "Swati", "Siswati", "ss", "ssw" },
{ "Sundanese", "Basa Sunda", "su", "sun" },
{ "Swahili", "Kiswahili", "sw", "swa" },
{ "Swedish", "svenska", "sv", "swe" },
{ "Tahitian", "Reo Tahiti", "ty", "tah" },
{ "Tajik", "Тоҷикӣ", "tg", "tgk" },
{ "Tamil", "தமிழ்", "ta", "tam" },
{ "Tatar", "Татар", "tt", "tat" },
{ "Telugu", "తెలుగు", "te", "tel" },
{ "Tagalog", "Katagalugan", "tl", "tgl" },
{ "Thai", "ไทย", "th", "tha" },
{ "Tibetan", "བོད་ཡིག", "bo", "bod", "tib" },
{ "Tigrinya", "ትግርኛ", "ti", "tir" },
{ "Tonga (Tonga Islands)", "lea fakatonga", "to", "ton" },
{ "Tswana", "Setswana", "tn", "tsn" },
{ "Tsonga", "Xitsonga", "ts", "tso" },
{ "Turkmen", "Türkmen dili", "tk", "tuk" },
{ "Turkish", "Türkçe", "tr", "tur" },
{ "Twi", "", "tw", "twi" },
{ "Ukrainian", "українська", "uk", "ukr" },
{ "Urdu", "اُردو", "ur", "urd" },
{ "Uyghur", "ئۇيغۇرچە", "ug", "uig" },
{ "Uzbek", "O'zbekcha", "uz", "uzb" },
{ "Venda", "Tshivenḓa", "ve", "ven" },
{ "Vietnamese", "Tiếng Việt", "vi", "vie" },
{ "Volapük", "Volapük", "vo", "vol" },
{ "Welsh", "Cymraeg", "cy", "cym", "wel" },
{ "Walloon", "Walon", "wa", "wln" },
{ "Wolof", "Wolof", "wo", "wol" },
{ "Xhosa", "isiXhosa", "xh", "xho" },
{ "Yiddish", "ייִדיש", "yi", "yid", "", "ji" },
{ "Yoruba", "Èdè Yorùbá", "yo", "yor" },
{ "Zhuang", "Vahcuengh", "za", "zha" },
{ "Zulu", "isiZulu", "zu", "zul" },
{ NULL, NULL, NULL } };
static const int lang_count = sizeof(languages) / sizeof(languages[0]);
const int lang_lookup_index( const char * str )
{
int ii = 0;
const iso639_lang_t * lang;
// We use fake lang_any iso639 to designate a match for "Any" language
if ((lang_any.iso639_1 && !strcasecmp(lang_any.iso639_1, str)) ||
(lang_any.iso639 && !strcasecmp(lang_any.iso639, str)) ||
(lang_any.iso639_2 && !strcasecmp(lang_any.iso639_2, str)) ||
(lang_any.iso639_2b && !strcasecmp(lang_any.iso639_2b, str)) ||
(lang_any.eng_name && !strcasecmp(lang_any.eng_name, str)) ||
(lang_any.native_name && !strcasecmp(lang_any.native_name, str)))
{
return -1;
}
for (ii = 0; languages[ii].eng_name; ii++)
{
lang = &languages[ii];
if ((lang->iso639_1 && !strcasecmp(lang->iso639_1, str)) ||
(lang->iso639 && !strcasecmp(lang->iso639, str)) ||
(lang->iso639_2 && !strcasecmp(lang->iso639_2, str)) ||
(lang->iso639_2b && !strcasecmp(lang->iso639_2b, str)) ||
(lang->eng_name && !strcasecmp(lang->eng_name, str)) ||
(lang->native_name && !strcasecmp(lang->native_name, str)))
{
return ii;
}
}
return -1;
}
const iso639_lang_t * lang_lookup( const char * str )
{
return lang_for_index(lang_lookup_index(str));
}
const iso639_lang_t * lang_for_index( int index )
{
if (index == -1)
return &lang_any;
if (index < 0 || index >= lang_count)
return NULL;
return &languages[index];
}
iso639_lang_t * lang_for_code( int code )
{
char code_string[2];
iso639_lang_t * lang;
code_string[0] = tolower( ( code >> 8 ) & 0xFF );
code_string[1] = tolower( code & 0xFF );
if ((lang_any.iso639_1 && !strncmp(lang_any.iso639_1, code_string, 2)) ||
(lang_any.iso639 && !strncmp(lang_any.iso639, code_string, 2)))
{
return &lang_any;
}
for (lang = (iso639_lang_t*) languages; lang->eng_name; lang++)
{
if ((lang->iso639_1 && !strncmp( lang->iso639_1, code_string, 2)) ||
(lang->iso639 && !strncmp(lang->iso639, code_string, 2)))
{
return lang;
}
}
// Not found, return "Unknown"
return (iso639_lang_t*) languages;
}
iso639_lang_t * lang_for_code2( const char *code )
{
char code_string[4];
iso639_lang_t * lang;
code_string[0] = tolower( code[0] );
code_string[1] = tolower( code[1] );
code_string[2] = tolower( code[2] );
code_string[3] = 0;
if ((lang_any.iso639_2 && !strcmp(lang_any.iso639_2, code_string)) ||
(lang_any.iso639_2b && !strcmp(lang_any.iso639_2b, code_string)))
{
return &lang_any;
}
for( lang = (iso639_lang_t*) languages; lang->eng_name; lang++ )
{
if ((lang->iso639_2 && !strcmp(lang->iso639_2, code_string)) ||
(lang->iso639_2b && !strcmp(lang->iso639_2b, code_string)))
{
return lang;
}
}
// Not found, return "Unknown"
return (iso639_lang_t*) languages;
}
int lang_to_code(const iso639_lang_t *lang)
{
int code = 0;
if (lang)
code = (lang->iso639_1[0] << 8) | lang->iso639_1[1];
return code;
}
iso639_lang_t * lang_for_english( const char * english )
{
iso639_lang_t * lang;
if (!strcmp(lang_any.eng_name, english))
{
return &lang_any;
}
for (lang = (iso639_lang_t*) languages; lang->eng_name; lang++)
{
if (!strcmp(lang->eng_name, english))
{
return lang;
}
}
// Not found, return "Unknown"
return (iso639_lang_t*) languages;
}
const iso639_lang_t* lang_get_any(void)
{
return &lang_any;
}
const iso639_lang_t* lang_get_next(const iso639_lang_t *last)
{
if (last == NULL || last == &lang_any)
{
return (const iso639_lang_t*)languages;
}
if (last < languages || // out of bounds
last >= languages + lang_count - 2) // last valid language
{
return NULL;
}
return ++last;
}