From 3f8877473fb4c72a6f3edfcfc927b9993a5f3616 Mon Sep 17 00:00:00 2001 From: David Corbett Date: Thu, 19 Jul 2018 13:48:07 -0400 Subject: [PATCH] Switch on the first char of a complex language tag This results in a tenfold speed-up for the common case of tags that are not complex, in the sense of `hb_ot_tags_from_complex_language`. --- src/gen-tag-table.py | 171 ++++-- src/hb-ot-tag-table.hh | 1580 ++++++++++++++++++++++++------------------------ 2 files changed, 922 insertions(+), 829 deletions(-) diff --git a/src/gen-tag-table.py b/src/gen-tag-table.py index dc3511c..3f334e9 100755 --- a/src/gen-tag-table.py +++ b/src/gen-tag-table.py @@ -288,6 +288,37 @@ class LanguageTag (object): except StopIteration: return None + def is_complex (self): + """Return whether this tag is too complex to represent as a + ``LangTag`` in the generated code. + + Complex tags need to be handled in + ``hb_ot_tags_from_complex_language``. + + Returns: + Whether this tag is complex. + """ + return not (len (self.subtags) == 1 + or self.grandfathered + and len (self.subtags[1]) != 3 + and ot.from_bcp_47[self.subtags[0]] == ot.from_bcp_47[self.language]) + + def get_group (self): + """Return the group into which this tag should be categorized in + ``hb_ot_tags_from_complex_language``. + + The group is the first letter of the tag, or ``'und'`` if this tag + should not be matched in a ``switch`` statement in the generated + code. + + Returns: + This tag's group. + """ + return ('und' + if (self.language == 'und' + or self.variant in bcp_47.prefixes and len (bcp_47.prefixes[self.variant]) == 1) + else self.language[0]) + class OpenTypeRegistryParser (HTMLParser): """A parser for the OpenType language system tag registry. @@ -598,16 +629,15 @@ class BCP47Parser (object): for macrolanguage in macrolanguages: self._add_macrolanguage (biggest_macrolanguage, macrolanguage) - def get_name (self, tag): + def get_name (self, lt): """Return the names of the subtags in a language tag. Args: - tag (str): A BCP 47 language tag. + lt (LanguageTag): A BCP 47 language tag. Returns: - The name form of ``tag``. + The name form of ``lt``. """ - lt = LanguageTag (tag) name = self.names[lt.language].split ('\n')[0] if lt.script: name += '; ' + self.names[lt.script.title ()].split ('\n')[0] @@ -909,58 +939,101 @@ print ('\t\t\t\t unsigned int *count /* IN/OUT */,') print ('\t\t\t\t hb_tag_t *tags /* OUT */)') print ('{') -def print_subtag_matches (subtag): +def print_subtag_matches (subtag, new_line): if subtag: - print () - print (' && subtag_matches (lang_str, limit, "-%s")' % subtag, end='') - -for language, tags in sorted (ot.from_bcp_47.items (), key=lambda i: (-len (i[0]), i[0])): - lt = LanguageTag (language) - if len (lt.subtags) == 1 or lt.grandfathered and len (lt.subtags[1]) != 3 and ot.from_bcp_47[lt.subtags[0]] == tags: + if new_line: + print () + print ('\t&& ', end='') + print ('subtag_matches (lang_str, limit, "-%s")' % subtag, end='') + +complex_tags = collections.defaultdict (list) +for initial, group in itertools.groupby ((lt_tags for lt_tags in [ + (LanguageTag (language), tags) + for language, tags in sorted (ot.from_bcp_47.items (), + key=lambda i: (-len (i[0]), i[0])) + ] if lt_tags[0].is_complex ()), + key=lambda lt_tags: lt_tags[0].get_group ()): + complex_tags[initial] += group + +for initial, items in sorted (complex_tags.items ()): + if initial != 'und': continue - print (' if (', end='') - if (lt.language == 'und' or - lt.variant in bcp_47.prefixes and - len (bcp_47.prefixes[lt.variant]) == 1): + for lt, tags in items: if lt.variant in bcp_47.prefixes: expect (next (iter (bcp_47.prefixes[lt.variant])) == lt.language, '%s is not a valid prefix of %s' % (lt.language, lt.variant)) - print ('1', end='') - elif lt.grandfathered: - print ('0 == strcmp (lang_str, "%s")' % lt.language, end='') - else: - print ('lang_matches (lang_str, "%s' % lt.language, end='') - if lt.script: - print ('-%s' % lt.script, end='') - lt.script = None - if lt.region: - print ('-%s' % lt.region, end='') - lt.region = None - print ('")', end='') - print_subtag_matches (lt.script) - print_subtag_matches (lt.region) - print_subtag_matches (lt.variant) - print (')') - print (' {') - write (' /* %s */' % bcp_47.get_name (language)) - print () - if len (tags) == 1: - write (' tags[0] = %s; /* %s */' % (hb_tag (tags[0]), ot.names[tags[0]])) + print (' if (', end='') + print_subtag_matches (lt.script, False) + print_subtag_matches (lt.region, False) + print_subtag_matches (lt.variant, False) + print (')') + print (' {') + write (' /* %s */' % bcp_47.get_name (lt)) + print () + if len (tags) == 1: + write (' tags[0] = %s; /* %s */' % (hb_tag (tags[0]), ot.names[tags[0]])) + print () + print (' *count = 1;') + else: + print (' hb_tag_t possible_tags[] = {') + for tag in tags: + write (' %s, /* %s */' % (hb_tag (tag), ot.names[tag])) + print () + print (' };') + print (' for (i = 0; i < %s && i < *count; i++)' % len (tags)) + print (' tags[i] = possible_tags[i];') + print (' *count = i;') + print (' return true;') + print (' }') + +print (' switch (lang_str[0])') +print (' {') +for initial, items in sorted (complex_tags.items ()): + if initial == 'und': + continue + print (" case '%s':" % initial) + for lt, tags in items: + print (' if (', end='') + if lt.grandfathered: + print ('0 == strcmp (&lang_str[1], "%s")' % lt.language[1:], end='') + else: + string_literal = lt.language[1:] + '-' + if lt.script: + string_literal += lt.script + lt.script = None + if lt.region: + string_literal += '-' + lt.region + lt.region = None + if string_literal[-1] == '-': + print ('0 == strncmp (&lang_str[1], "%s", %i)' % (string_literal, len (string_literal)), end='') + else: + print ('lang_matches (&lang_str[1], "%s")' % string_literal, end='') + print_subtag_matches (lt.script, True) + print_subtag_matches (lt.region, True) + print_subtag_matches (lt.variant, True) + print (')') + print (' {') + write (' /* %s */' % bcp_47.get_name (lt)) print () - print (' *count = 1;') - else: - print (' unsigned int i;') - print (' hb_tag_t possible_tags[] = {') - for tag in tags: - write (' %s, /* %s */' % (hb_tag (tag), ot.names[tag])) + if len (tags) == 1: + write (' tags[0] = %s; /* %s */' % (hb_tag (tags[0]), ot.names[tags[0]])) print () - print (' };') - print (' for (i = 0; i < %s && i < *count; i++)' % len (tags)) - print (' tags[i] = possible_tags[i];') - print (' *count = i;') - print (' return true;') - print (' }') + print (' *count = 1;') + else: + print (' unsigned int i;') + print (' hb_tag_t possible_tags[] = {') + for tag in tags: + write ('\t%s, /* %s */' % (hb_tag (tag), ot.names[tag])) + print () + print (' };') + print (' for (i = 0; i < %s && i < *count; i++)' % len (tags)) + print ('\ttags[i] = possible_tags[i];') + print (' *count = i;') + print (' return true;') + print (' }') + print (' break;') +print (' }') print (' return false;') print ('}') print () @@ -1030,7 +1103,7 @@ verify_disambiguation_dict () for ot_tag, bcp_47_tag in sorted (disambiguation.items ()): write (' case %s: /* %s */' % (hb_tag (ot_tag), ot.names[ot_tag])) print () - write (' return hb_language_from_string (\"%s\", -1); /* %s */' % (bcp_47_tag, bcp_47.get_name (bcp_47_tag))) + write (' return hb_language_from_string (\"%s\", -1); /* %s */' % (bcp_47_tag, bcp_47.get_name (LanguageTag (bcp_47_tag)))) print () print (' default:') diff --git a/src/hb-ot-tag-table.hh b/src/hb-ot-tag-table.hh index 6cc9e06..3722e94 100644 --- a/src/hb-ot-tag-table.hh +++ b/src/hb-ot-tag-table.hh @@ -1066,828 +1066,848 @@ hb_ot_tags_from_complex_language (const char *lang_str, unsigned int *count /* IN/OUT */, hb_tag_t *tags /* OUT */) { - if (lang_matches (lang_str, "cdo-hant-hk")) - { - /* Min Dong Chinese; Han (Traditional variant); Hong Kong */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "cdo-hant-mo")) - { - /* Min Dong Chinese; Han (Traditional variant); Macao */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "cjy-hant-hk")) - { - /* Jinyu Chinese; Han (Traditional variant); Hong Kong */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "cjy-hant-mo")) - { - /* Jinyu Chinese; Han (Traditional variant); Macao */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "cmn-hant-hk")) - { - /* Mandarin Chinese; Han (Traditional variant); Hong Kong */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "cmn-hant-mo")) - { - /* Mandarin Chinese; Han (Traditional variant); Macao */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "cpx-hant-hk")) - { - /* Pu-Xian Chinese; Han (Traditional variant); Hong Kong */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "cpx-hant-mo")) - { - /* Pu-Xian Chinese; Han (Traditional variant); Macao */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "czh-hant-hk")) - { - /* Huizhou Chinese; Han (Traditional variant); Hong Kong */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "czh-hant-mo")) - { - /* Huizhou Chinese; Han (Traditional variant); Macao */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "czo-hant-hk")) - { - /* Min Zhong Chinese; Han (Traditional variant); Hong Kong */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "czo-hant-mo")) - { - /* Min Zhong Chinese; Han (Traditional variant); Macao */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "gan-hant-hk")) - { - /* Gan Chinese; Han (Traditional variant); Hong Kong */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "gan-hant-mo")) - { - /* Gan Chinese; Han (Traditional variant); Macao */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "hak-hant-hk")) - { - /* Hakka Chinese; Han (Traditional variant); Hong Kong */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "hak-hant-mo")) - { - /* Hakka Chinese; Han (Traditional variant); Macao */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "hsn-hant-hk")) - { - /* Xiang Chinese; Han (Traditional variant); Hong Kong */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "hsn-hant-mo")) - { - /* Xiang Chinese; Han (Traditional variant); Macao */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "mnp-hant-hk")) - { - /* Min Bei Chinese; Han (Traditional variant); Hong Kong */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "mnp-hant-mo")) - { - /* Min Bei Chinese; Han (Traditional variant); Macao */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "nan-hant-hk")) - { - /* Min Nan Chinese; Han (Traditional variant); Hong Kong */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "nan-hant-mo")) - { - /* Min Nan Chinese; Han (Traditional variant); Macao */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; - return true; - } - if (1 - && subtag_matches (lang_str, limit, "-fonnapa")) + if (subtag_matches (lang_str, limit, "-fonnapa")) { /* Undetermined; North American Phonetic Alphabet */ tags[0] = HB_TAG('A','P','P','H'); /* Phonetic transcription—Americanist conventions */ *count = 1; return true; } - if (lang_matches (lang_str, "wuu-hant-hk")) - { - /* Wu Chinese; Han (Traditional variant); Hong Kong */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "wuu-hant-mo")) - { - /* Wu Chinese; Han (Traditional variant); Macao */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; - return true; - } - if (0 == strcmp (lang_str, "art-lojban")) - { - /* Lojban */ - tags[0] = HB_TAG('J','B','O',' '); /* Lojban */ - *count = 1; - return true; - } - if (1 - && subtag_matches (lang_str, limit, "-polyton")) + if (subtag_matches (lang_str, limit, "-polyton")) { /* Modern Greek (1453-); Polytonic Greek */ tags[0] = HB_TAG('P','G','R',' '); /* Polytonic Greek */ *count = 1; return true; } - if (1 - && subtag_matches (lang_str, limit, "-fonipa")) + if (subtag_matches (lang_str, limit, "-fonipa")) { /* Undetermined; International Phonetic Alphabet */ tags[0] = HB_TAG('I','P','P','H'); /* Phonetic transcription—IPA conventions */ *count = 1; return true; } - if (lang_matches (lang_str, "zh-hant-hk")) - { - /* Chinese; Han (Traditional variant); Hong Kong */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "zh-hant-mo")) - { - /* Chinese; Han (Traditional variant); Macao */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; - return true; - } - if (0 == strcmp (lang_str, "zh-min-nan")) - { - /* Minnan, Hokkien, Amoy, Taiwanese, Southern Min, Southern Fujian, Hoklo, Southern Fukien, Ho-lo */ - tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "cdo-hans")) - { - /* Min Dong Chinese; Han (Simplified variant) */ - tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "cdo-hant")) - { - /* Min Dong Chinese; Han (Traditional variant) */ - tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "cjy-hans")) - { - /* Jinyu Chinese; Han (Simplified variant) */ - tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "cjy-hant")) - { - /* Jinyu Chinese; Han (Traditional variant) */ - tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "cmn-hans")) - { - /* Mandarin Chinese; Han (Simplified variant) */ - tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "cmn-hant")) - { - /* Mandarin Chinese; Han (Traditional variant) */ - tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "cpx-hans")) - { - /* Pu-Xian Chinese; Han (Simplified variant) */ - tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "cpx-hant")) - { - /* Pu-Xian Chinese; Han (Traditional variant) */ - tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "czh-hans")) - { - /* Huizhou Chinese; Han (Simplified variant) */ - tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "czh-hant")) - { - /* Huizhou Chinese; Han (Traditional variant) */ - tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "czo-hans")) - { - /* Min Zhong Chinese; Han (Simplified variant) */ - tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "czo-hant")) - { - /* Min Zhong Chinese; Han (Traditional variant) */ - tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "gan-hans")) - { - /* Gan Chinese; Han (Simplified variant) */ - tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "gan-hant")) - { - /* Gan Chinese; Han (Traditional variant) */ - tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "hak-hans")) - { - /* Hakka Chinese; Han (Simplified variant) */ - tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "hak-hant")) - { - /* Hakka Chinese; Han (Traditional variant) */ - tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "hsn-hans")) - { - /* Xiang Chinese; Han (Simplified variant) */ - tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "hsn-hant")) - { - /* Xiang Chinese; Han (Traditional variant) */ - tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ - *count = 1; - return true; - } - if (0 == strcmp (lang_str, "i-navajo")) - { - /* Navajo */ - unsigned int i; - hb_tag_t possible_tags[] = { - HB_TAG('N','A','V',' '), /* Navajo */ - HB_TAG('A','T','H',' '), /* Athapaskan */ - }; - for (i = 0; i < 2 && i < *count; i++) - tags[i] = possible_tags[i]; - *count = i; - return true; - } - if (lang_matches (lang_str, "lzh-hans")) - { - /* Literary Chinese; Han (Simplified variant) */ - tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "mnp-hans")) - { - /* Min Bei Chinese; Han (Simplified variant) */ - tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "mnp-hant")) - { - /* Min Bei Chinese; Han (Traditional variant) */ - tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "nan-hans")) - { - /* Min Nan Chinese; Han (Simplified variant) */ - tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "nan-hant")) - { - /* Min Nan Chinese; Han (Traditional variant) */ - tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ - *count = 1; - return true; - } - if (1 - && subtag_matches (lang_str, limit, "-geok")) + if (subtag_matches (lang_str, limit, "-geok")) { /* Undetermined; Khutsuri (Asomtavruli and Nuskhuri) */ tags[0] = HB_TAG('K','G','E',' '); /* Khutsuri Georgian */ *count = 1; return true; } - if (1 - && subtag_matches (lang_str, limit, "-syre")) + if (subtag_matches (lang_str, limit, "-syre")) { /* Undetermined; Syriac (Estrangelo variant) */ tags[0] = HB_TAG('S','Y','R','E'); /* Syriac, Estrangela script-variant (equivalent to ISO 15924 'Syre') */ *count = 1; return true; } - if (1 - && subtag_matches (lang_str, limit, "-syrj")) + if (subtag_matches (lang_str, limit, "-syrj")) { /* Undetermined; Syriac (Western variant) */ tags[0] = HB_TAG('S','Y','R','J'); /* Syriac, Western script-variant (equivalent to ISO 15924 'Syrj') */ *count = 1; return true; } - if (1 - && subtag_matches (lang_str, limit, "-syrn")) + if (subtag_matches (lang_str, limit, "-syrn")) { /* Undetermined; Syriac (Eastern variant) */ tags[0] = HB_TAG('S','Y','R','N'); /* Syriac, Eastern script-variant (equivalent to ISO 15924 'Syrn') */ *count = 1; return true; } - if (lang_matches (lang_str, "wuu-hans")) - { - /* Wu Chinese; Han (Simplified variant) */ - tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "wuu-hant")) - { - /* Wu Chinese; Han (Traditional variant) */ - tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "yue-hans")) - { - /* Yue Chinese; Han (Simplified variant) */ - tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "ga-latg")) - { - /* Irish; Latin (Gaelic variant) */ - tags[0] = HB_TAG('I','R','T',' '); /* Irish Traditional */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "zh-hans")) - { - /* Chinese; Han (Simplified variant) */ - tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "zh-hant")) - { - /* Chinese; Han (Traditional variant) */ - tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "cdo") - && subtag_matches (lang_str, limit, "-hk")) - { - /* Min Dong Chinese; Hong Kong */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "cdo") - && subtag_matches (lang_str, limit, "-mo")) - { - /* Min Dong Chinese; Macao */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "cdo") - && subtag_matches (lang_str, limit, "-tw")) - { - /* Min Dong Chinese; Taiwan, Province of China */ - tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "cjy") - && subtag_matches (lang_str, limit, "-hk")) - { - /* Jinyu Chinese; Hong Kong */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "cjy") - && subtag_matches (lang_str, limit, "-mo")) - { - /* Jinyu Chinese; Macao */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "cjy") - && subtag_matches (lang_str, limit, "-tw")) - { - /* Jinyu Chinese; Taiwan, Province of China */ - tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "cmn") - && subtag_matches (lang_str, limit, "-hk")) - { - /* Mandarin Chinese; Hong Kong */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "cmn") - && subtag_matches (lang_str, limit, "-mo")) - { - /* Mandarin Chinese; Macao */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "cmn") - && subtag_matches (lang_str, limit, "-tw")) - { - /* Mandarin Chinese; Taiwan, Province of China */ - tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "cpx") - && subtag_matches (lang_str, limit, "-hk")) - { - /* Pu-Xian Chinese; Hong Kong */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "cpx") - && subtag_matches (lang_str, limit, "-mo")) - { - /* Pu-Xian Chinese; Macao */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "cpx") - && subtag_matches (lang_str, limit, "-tw")) - { - /* Pu-Xian Chinese; Taiwan, Province of China */ - tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "czh") - && subtag_matches (lang_str, limit, "-hk")) - { - /* Huizhou Chinese; Hong Kong */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "czh") - && subtag_matches (lang_str, limit, "-mo")) - { - /* Huizhou Chinese; Macao */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "czh") - && subtag_matches (lang_str, limit, "-tw")) - { - /* Huizhou Chinese; Taiwan, Province of China */ - tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "czo") - && subtag_matches (lang_str, limit, "-hk")) - { - /* Min Zhong Chinese; Hong Kong */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "czo") - && subtag_matches (lang_str, limit, "-mo")) - { - /* Min Zhong Chinese; Macao */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "czo") - && subtag_matches (lang_str, limit, "-tw")) - { - /* Min Zhong Chinese; Taiwan, Province of China */ - tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "gan") - && subtag_matches (lang_str, limit, "-hk")) - { - /* Gan Chinese; Hong Kong */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "gan") - && subtag_matches (lang_str, limit, "-mo")) - { - /* Gan Chinese; Macao */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "gan") - && subtag_matches (lang_str, limit, "-tw")) - { - /* Gan Chinese; Taiwan, Province of China */ - tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "hak") - && subtag_matches (lang_str, limit, "-hk")) - { - /* Hakka Chinese; Hong Kong */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "hak") - && subtag_matches (lang_str, limit, "-mo")) - { - /* Hakka Chinese; Macao */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "hak") - && subtag_matches (lang_str, limit, "-tw")) - { - /* Hakka Chinese; Taiwan, Province of China */ - tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "hsn") - && subtag_matches (lang_str, limit, "-hk")) - { - /* Xiang Chinese; Hong Kong */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "hsn") - && subtag_matches (lang_str, limit, "-mo")) - { - /* Xiang Chinese; Macao */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "hsn") - && subtag_matches (lang_str, limit, "-tw")) - { - /* Xiang Chinese; Taiwan, Province of China */ - tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "mnp") - && subtag_matches (lang_str, limit, "-hk")) - { - /* Min Bei Chinese; Hong Kong */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "mnp") - && subtag_matches (lang_str, limit, "-mo")) - { - /* Min Bei Chinese; Macao */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "mnp") - && subtag_matches (lang_str, limit, "-tw")) - { - /* Min Bei Chinese; Taiwan, Province of China */ - tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "nan") - && subtag_matches (lang_str, limit, "-hk")) - { - /* Min Nan Chinese; Hong Kong */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "nan") - && subtag_matches (lang_str, limit, "-mo")) - { - /* Min Nan Chinese; Macao */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "nan") - && subtag_matches (lang_str, limit, "-tw")) - { - /* Min Nan Chinese; Taiwan, Province of China */ - tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ - *count = 1; - return true; - } - if (0 == strcmp (lang_str, "no-bok")) - { - /* Norwegian Bokmal */ - tags[0] = HB_TAG('N','O','R',' '); /* Norwegian */ - *count = 1; - return true; - } - if (0 == strcmp (lang_str, "no-nyn")) - { - /* Norwegian Nynorsk */ - tags[0] = HB_TAG('N','Y','N',' '); /* Norwegian Nynorsk (Nynorsk, Norwegian) */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "wuu") - && subtag_matches (lang_str, limit, "-hk")) - { - /* Wu Chinese; Hong Kong */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "wuu") - && subtag_matches (lang_str, limit, "-mo")) - { - /* Wu Chinese; Macao */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "wuu") - && subtag_matches (lang_str, limit, "-tw")) - { - /* Wu Chinese; Taiwan, Province of China */ - tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ - *count = 1; - return true; - } - if (0 == strcmp (lang_str, "zh-min")) - { - /* Min, Fuzhou, Hokkien, Amoy, or Taiwanese */ - tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ - *count = 1; - return true; - } - if (0 == strcmp (lang_str, "i-hak")) - { - /* Hakka */ - tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ - *count = 1; - return true; - } - if (0 == strcmp (lang_str, "i-lux")) - { - /* Luxembourgish */ - tags[0] = HB_TAG('L','T','Z',' '); /* Luxembourgish */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "ro") - && subtag_matches (lang_str, limit, "-md")) - { - /* Romanian; Moldova */ - tags[0] = HB_TAG('M','O','L',' '); /* Moldavian */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "zh") - && subtag_matches (lang_str, limit, "-hk")) - { - /* Chinese; Hong Kong */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "zh") - && subtag_matches (lang_str, limit, "-mo")) - { - /* Chinese; Macao */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; - return true; - } - if (lang_matches (lang_str, "zh") - && subtag_matches (lang_str, limit, "-tw")) - { - /* Chinese; Taiwan, Province of China */ - tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ - *count = 1; - return true; + switch (lang_str[0]) + { + case 'a': + if (0 == strcmp (&lang_str[1], "rt-lojban")) + { + /* Lojban */ + tags[0] = HB_TAG('J','B','O',' '); /* Lojban */ + *count = 1; + return true; + } + break; + case 'c': + if (lang_matches (&lang_str[1], "do-hant-hk")) + { + /* Min Dong Chinese */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "do-hant-mo")) + { + /* Min Dong Chinese */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "jy-hant-hk")) + { + /* Jinyu Chinese */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "jy-hant-mo")) + { + /* Jinyu Chinese */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "mn-hant-hk")) + { + /* Mandarin Chinese */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "mn-hant-mo")) + { + /* Mandarin Chinese */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "px-hant-hk")) + { + /* Pu-Xian Chinese */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "px-hant-mo")) + { + /* Pu-Xian Chinese */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "zh-hant-hk")) + { + /* Huizhou Chinese */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "zh-hant-mo")) + { + /* Huizhou Chinese */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "zo-hant-hk")) + { + /* Min Zhong Chinese */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "zo-hant-mo")) + { + /* Min Zhong Chinese */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "do-hans")) + { + /* Min Dong Chinese */ + tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "do-hant")) + { + /* Min Dong Chinese */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "jy-hans")) + { + /* Jinyu Chinese */ + tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "jy-hant")) + { + /* Jinyu Chinese */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "mn-hans")) + { + /* Mandarin Chinese */ + tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "mn-hant")) + { + /* Mandarin Chinese */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "px-hans")) + { + /* Pu-Xian Chinese */ + tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "px-hant")) + { + /* Pu-Xian Chinese */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "zh-hans")) + { + /* Huizhou Chinese */ + tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "zh-hant")) + { + /* Huizhou Chinese */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "zo-hans")) + { + /* Min Zhong Chinese */ + tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "zo-hant")) + { + /* Min Zhong Chinese */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "do-", 3) + && subtag_matches (lang_str, limit, "-hk")) + { + /* Min Dong Chinese; Hong Kong */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "do-", 3) + && subtag_matches (lang_str, limit, "-mo")) + { + /* Min Dong Chinese; Macao */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "do-", 3) + && subtag_matches (lang_str, limit, "-tw")) + { + /* Min Dong Chinese; Taiwan, Province of China */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "jy-", 3) + && subtag_matches (lang_str, limit, "-hk")) + { + /* Jinyu Chinese; Hong Kong */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "jy-", 3) + && subtag_matches (lang_str, limit, "-mo")) + { + /* Jinyu Chinese; Macao */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "jy-", 3) + && subtag_matches (lang_str, limit, "-tw")) + { + /* Jinyu Chinese; Taiwan, Province of China */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "mn-", 3) + && subtag_matches (lang_str, limit, "-hk")) + { + /* Mandarin Chinese; Hong Kong */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "mn-", 3) + && subtag_matches (lang_str, limit, "-mo")) + { + /* Mandarin Chinese; Macao */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "mn-", 3) + && subtag_matches (lang_str, limit, "-tw")) + { + /* Mandarin Chinese; Taiwan, Province of China */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "px-", 3) + && subtag_matches (lang_str, limit, "-hk")) + { + /* Pu-Xian Chinese; Hong Kong */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "px-", 3) + && subtag_matches (lang_str, limit, "-mo")) + { + /* Pu-Xian Chinese; Macao */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "px-", 3) + && subtag_matches (lang_str, limit, "-tw")) + { + /* Pu-Xian Chinese; Taiwan, Province of China */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "zh-", 3) + && subtag_matches (lang_str, limit, "-hk")) + { + /* Huizhou Chinese; Hong Kong */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "zh-", 3) + && subtag_matches (lang_str, limit, "-mo")) + { + /* Huizhou Chinese; Macao */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "zh-", 3) + && subtag_matches (lang_str, limit, "-tw")) + { + /* Huizhou Chinese; Taiwan, Province of China */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "zo-", 3) + && subtag_matches (lang_str, limit, "-hk")) + { + /* Min Zhong Chinese; Hong Kong */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "zo-", 3) + && subtag_matches (lang_str, limit, "-mo")) + { + /* Min Zhong Chinese; Macao */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "zo-", 3) + && subtag_matches (lang_str, limit, "-tw")) + { + /* Min Zhong Chinese; Taiwan, Province of China */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + *count = 1; + return true; + } + break; + case 'g': + if (lang_matches (&lang_str[1], "an-hant-hk")) + { + /* Gan Chinese */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "an-hant-mo")) + { + /* Gan Chinese */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "an-hans")) + { + /* Gan Chinese */ + tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "an-hant")) + { + /* Gan Chinese */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "a-latg")) + { + /* Irish */ + tags[0] = HB_TAG('I','R','T',' '); /* Irish Traditional */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "an-", 3) + && subtag_matches (lang_str, limit, "-hk")) + { + /* Gan Chinese; Hong Kong */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "an-", 3) + && subtag_matches (lang_str, limit, "-mo")) + { + /* Gan Chinese; Macao */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "an-", 3) + && subtag_matches (lang_str, limit, "-tw")) + { + /* Gan Chinese; Taiwan, Province of China */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + *count = 1; + return true; + } + break; + case 'h': + if (lang_matches (&lang_str[1], "ak-hant-hk")) + { + /* Hakka Chinese */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "ak-hant-mo")) + { + /* Hakka Chinese */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "sn-hant-hk")) + { + /* Xiang Chinese */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "sn-hant-mo")) + { + /* Xiang Chinese */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "ak-hans")) + { + /* Hakka Chinese */ + tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "ak-hant")) + { + /* Hakka Chinese */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "sn-hans")) + { + /* Xiang Chinese */ + tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "sn-hant")) + { + /* Xiang Chinese */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "ak-", 3) + && subtag_matches (lang_str, limit, "-hk")) + { + /* Hakka Chinese; Hong Kong */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "ak-", 3) + && subtag_matches (lang_str, limit, "-mo")) + { + /* Hakka Chinese; Macao */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "ak-", 3) + && subtag_matches (lang_str, limit, "-tw")) + { + /* Hakka Chinese; Taiwan, Province of China */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "sn-", 3) + && subtag_matches (lang_str, limit, "-hk")) + { + /* Xiang Chinese; Hong Kong */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "sn-", 3) + && subtag_matches (lang_str, limit, "-mo")) + { + /* Xiang Chinese; Macao */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "sn-", 3) + && subtag_matches (lang_str, limit, "-tw")) + { + /* Xiang Chinese; Taiwan, Province of China */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + *count = 1; + return true; + } + break; + case 'i': + if (0 == strcmp (&lang_str[1], "-navajo")) + { + /* Navajo */ + unsigned int i; + hb_tag_t possible_tags[] = { + HB_TAG('N','A','V',' '), /* Navajo */ + HB_TAG('A','T','H',' '), /* Athapaskan */ + }; + for (i = 0; i < 2 && i < *count; i++) + tags[i] = possible_tags[i]; + *count = i; + return true; + } + if (0 == strcmp (&lang_str[1], "-hak")) + { + /* Hakka */ + tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ + *count = 1; + return true; + } + if (0 == strcmp (&lang_str[1], "-lux")) + { + /* Luxembourgish */ + tags[0] = HB_TAG('L','T','Z',' '); /* Luxembourgish */ + *count = 1; + return true; + } + break; + case 'l': + if (lang_matches (&lang_str[1], "zh-hans")) + { + /* Literary Chinese */ + tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ + *count = 1; + return true; + } + break; + case 'm': + if (lang_matches (&lang_str[1], "np-hant-hk")) + { + /* Min Bei Chinese */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "np-hant-mo")) + { + /* Min Bei Chinese */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "np-hans")) + { + /* Min Bei Chinese */ + tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "np-hant")) + { + /* Min Bei Chinese */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "np-", 3) + && subtag_matches (lang_str, limit, "-hk")) + { + /* Min Bei Chinese; Hong Kong */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "np-", 3) + && subtag_matches (lang_str, limit, "-mo")) + { + /* Min Bei Chinese; Macao */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "np-", 3) + && subtag_matches (lang_str, limit, "-tw")) + { + /* Min Bei Chinese; Taiwan, Province of China */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + *count = 1; + return true; + } + break; + case 'n': + if (lang_matches (&lang_str[1], "an-hant-hk")) + { + /* Min Nan Chinese */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "an-hant-mo")) + { + /* Min Nan Chinese */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "an-hans")) + { + /* Min Nan Chinese */ + tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "an-hant")) + { + /* Min Nan Chinese */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "an-", 3) + && subtag_matches (lang_str, limit, "-hk")) + { + /* Min Nan Chinese; Hong Kong */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "an-", 3) + && subtag_matches (lang_str, limit, "-mo")) + { + /* Min Nan Chinese; Macao */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "an-", 3) + && subtag_matches (lang_str, limit, "-tw")) + { + /* Min Nan Chinese; Taiwan, Province of China */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + *count = 1; + return true; + } + if (0 == strcmp (&lang_str[1], "o-bok")) + { + /* Norwegian Bokmal */ + tags[0] = HB_TAG('N','O','R',' '); /* Norwegian */ + *count = 1; + return true; + } + if (0 == strcmp (&lang_str[1], "o-nyn")) + { + /* Norwegian Nynorsk */ + tags[0] = HB_TAG('N','Y','N',' '); /* Norwegian Nynorsk (Nynorsk, Norwegian) */ + *count = 1; + return true; + } + break; + case 'r': + if (0 == strncmp (&lang_str[1], "o-", 2) + && subtag_matches (lang_str, limit, "-md")) + { + /* Romanian; Moldova */ + tags[0] = HB_TAG('M','O','L',' '); /* Moldavian */ + *count = 1; + return true; + } + break; + case 'w': + if (lang_matches (&lang_str[1], "uu-hant-hk")) + { + /* Wu Chinese */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "uu-hant-mo")) + { + /* Wu Chinese */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "uu-hans")) + { + /* Wu Chinese */ + tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "uu-hant")) + { + /* Wu Chinese */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "uu-", 3) + && subtag_matches (lang_str, limit, "-hk")) + { + /* Wu Chinese; Hong Kong */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "uu-", 3) + && subtag_matches (lang_str, limit, "-mo")) + { + /* Wu Chinese; Macao */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "uu-", 3) + && subtag_matches (lang_str, limit, "-tw")) + { + /* Wu Chinese; Taiwan, Province of China */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + *count = 1; + return true; + } + break; + case 'y': + if (lang_matches (&lang_str[1], "ue-hans")) + { + /* Yue Chinese */ + tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ + *count = 1; + return true; + } + break; + case 'z': + if (lang_matches (&lang_str[1], "h-hant-hk")) + { + /* Chinese */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "h-hant-mo")) + { + /* Chinese */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (0 == strcmp (&lang_str[1], "h-min-nan")) + { + /* Minnan, Hokkien, Amoy, Taiwanese, Southern Min, Southern Fujian, Hoklo, Southern Fukien, Ho-lo */ + tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "h-hans")) + { + /* Chinese */ + tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "h-hant")) + { + /* Chinese */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + *count = 1; + return true; + } + if (0 == strcmp (&lang_str[1], "h-min")) + { + /* Min, Fuzhou, Hokkien, Amoy, or Taiwanese */ + tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "h-", 2) + && subtag_matches (lang_str, limit, "-hk")) + { + /* Chinese; Hong Kong */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "h-", 2) + && subtag_matches (lang_str, limit, "-mo")) + { + /* Chinese; Macao */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "h-", 2) + && subtag_matches (lang_str, limit, "-tw")) + { + /* Chinese; Taiwan, Province of China */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + *count = 1; + return true; + } + break; } return false; } -- 2.7.4