[vlc-commits] [Git][videolan/vlc][master] 12 commits: mux/ts: fix buggy iso639 handling

Jean-Baptiste Kempf gitlab at videolan.org
Sat Jun 12 13:23:55 UTC 2021



Jean-Baptiste Kempf pushed to branch master at VideoLAN / VLC


Commits:
740d1347 by Lyndon Brown at 2021-06-12T13:09:35+00:00
mux/ts: fix buggy iso639 handling

a handful of small mistakes were made in "simplifying" the iso-639
handling back in b8774b3c1a183e41dc8b9e7be55e48cc10ddac91. this
corrects those mistakes, and in doing so brings this back into line
with all other use of the iso-639 lookup functions.

the mistakes:

 1. the english/native comments were added the wrong way around.

 2. the 2T fallback lookup was made unreachable.

    after searching with the 2B code, we either have a match, or the
    'unknown' record (which uses '?' characters). since every single entry
    in the table has a non-empty 2T code (ignoring the irrelevant end
    marker), and since the 'unknown' item also has a non-empty 2T code
    ("???"), the fallback path to search with 2T would never be triggered.

 3. the avoidance of storing language code on failed lookup was broken.

    the `*code` condition would always be true, since matching records
    always have a 2T code, and for no match "???" is always returned from
    the 'unknown' record. this means that for failed matches, "???" would
    be unintentionally written into the entry.

 4. the len==3 condition on iso-639-2 lookup was lost.

    the previous code conditionally only performed an iso-639-2 lookup if
    the string length is 3, just like all other cases of such lookups
    throughout the codebase. there was no specific reason for this to have
    been removed here. (this is going to get restored anyway momentarily
    when the code gets de-duplicated by a new function).

 5. an incorrect comment was given to the newly introduced function.

    the new `GetIso639_2LangCode()` helper function it introduced always
    returns len==3 strings, never len==0.

- - - - -
570a218d by Lyndon Brown at 2021-06-12T13:09:35+00:00
mux/ts: ditch unnecessary helper function

this was introduced in b8774b3c1a183e41dc8b9e7be55e48cc10ddac91 as part of
de-duplicating code, however the two blocks that used the relevant code
were also merged in the same commit, making the function unnecessary.

this is being done partly as cleanup before the next commit, which would
remove it anyway, but doing it separately first makes the diffs more
clear.

this brings the use of the lookup functions back into line with use
everywhere else in the codebase.

- - - - -
61bdcc3f by Lyndon Brown at 2021-06-12T13:09:35+00:00
iso639: de-duplicate code lookup handling

...with a new function, which also replaces direct use of the three
code-specific functions.

all users of these three functions had a common pattern of using the
iso-639-1 lookup for len==2 codes, and for len==3 doing a 2B lookup,
falling back to a 2T lookup if that failed.

this pattern is now implemented in the new `vlc_find_iso639()` function.

the three individual functions are now made private, not being needed
publicly anymore. they also now just do a straight `strcmp()` rather than
`strncmp()` because they are only called for the right length of strings.

the implementation will be tweaked slightly in the next commit.

- - - - -
1ea38705 by Lyndon Brown at 2021-06-12T13:09:35+00:00
iso639: ditch use of the 'unknown' record

just return NULL instead - much more simple and efficient.

- - - - -
3ffbe14c by Lyndon Brown at 2021-06-12T13:09:35+00:00
iso639: add capability for 'any-field' alternate searches

esout, dvdnav and bluray are currently using a very old hack of searching
all fields of the raw language table for searches where they want to allow
matches against the names, not just codes. this is a step towards getting
rid of that ugly old hack by offering proper functionality for doing such
a search.

the implementation currently duplicates that used by the three previously
mentioned use cases. i intend to rework the implementation in a subsequent
commit; first though we need to just set things up for simply removing the
hack. that new implementation will better justify this being done with a
flag rather than a separate function.

- - - - -
8c726220 by Lyndon Brown at 2021-06-12T13:09:35+00:00
esout,dvdnav,bluray: fix ugly language search hack

using the new functionality of the new  `vlc_find_iso639()` function.

- - - - -
58ef2327 by Lyndon Brown at 2021-06-12T13:09:35+00:00
esout: language handling simplification

if the code is 2 or 3 chars long it is assumed to be an iso-639 code
and so a direct lookup is performed. otherwise:
 1. a call was made to the `LanguageGetCode()` function, which performs
    a name-inclusive search and then returns the match's ISO-639-1 code,
    or "??" on no match.
 2. a further lookup was then done with that ISO-639-1 code to simply
    get to the record pointer such that it can then get the attribute it
    actually wants here - the language name.

we are in a position now to achieve the goal more efficiently and simply
through `vlc_find_iso639()`.

- - - - -
d9347452 by Lyndon Brown at 2021-06-12T13:09:35+00:00
iso639: replace the name-inclusive search algorithm

...with one that searches the names of all the records, then the codes,
rather than all attributes of one record, then the next.

(it is not necessarily the final form of this new algorithm, with a
further tweak to come in the next commit).

this alternate implementation, is just a simple extension of the "normal"
(code-only) search algorithm, adding an extra conditional table attribute
search, rather than having an entirely different algorithm for
name-inclusive searches (which was copied from the old hack this replaced).

also, under this new algorithm, ISO-639-1 codes are only compared when
len==2, and similarly ISO-639-2 codes are only compared when len==3,
saving wasted comparison effort in exchange for some possible more looping.

note that name-inclusive searches are only performed by dvdnav, bluray, and
esout, and only the first two are relevant with respect to considering any
difference in results, since esout assumes 2/3 char language strings are
iso-639 codes and thus does not perform a name-inclusive search for them (at
the expense of not being able to reach the three letter name records by
name). for dvdnav and bluray, this concerns recognising any user specified
option values indicating "preferred language" per
fc4005c1b9bda46df0fd76c8ebdac770cea5a226.

-- result differences --

the results given happen to be identical to that of the previous algorithm,
both with the current data set, and the updated one in MR 146 ([1]).

noting that the table is updated from the data from glibc, maintaining the
same order, it should be understood that the results would only be
different to the previous algorithm if the table ever had an entry added
with a three/two character name that matches (case insensitively) a code
from an entry earlier in the table, in which case this new entry would be
the match rather than the earlier entry. (name match now always wins
rather than first matching record in the list).

[1]: https://code.videolan.org/videolan/vlc/-/merge_requests/146

- - - - -
58260a7a by Lyndon Brown at 2021-06-12T13:09:35+00:00
iso639: tweak name-inclusive search algorithm to check names last

under this algorithm codes are searched first, names second. (though of
course codes are skipped if length is not 2 or 3).

in short, this is partly because in cases where clashes between short
names and codes occur (which can happen, as discussed shortly), i feel
that it is best to prefer the code match, and partly because of the
disadvantages of using names as identifiers, as discussed in a moment,
that make codes perhaps more likely to be used for most languages.

please note the note in the previous commit about how this is only of
relevance to users specifying language preference for dvdnav and bluray,
with `--sub-language`, `--audio-language` and `--menu-language` options.

-- names as identifiers --

the disadvantages/problems of using names as identifiers:

 1. first, note that since 236ca7aea13a438f92c245565208c9bb6ff9e11c
    introduced the possibility, the help text of the few relevant
    options has never actually informed users that it was possible. (in
    fact they also fail to clarify that the mentioned codes to be used
    are iso-639). so presumably any users of these options are more
    used to using codes already.

 2. only English names are available, since only English names exist in
    the table, and the lookups have never involved translation. this
    makes the feature less useful than originally viewed in the commit
    log of the commit that introduced it. so for instance you can use
    "french" but not in fact "francais".

 3. the names in the iso-639 table are primarily intended for display
    purposes rather than matching purposes. while many of the names are
    simple like "English" and "French", working just fine for the type of
    lookup performed, many are not so ideal like the following examples
    (some of which have been picked from the MR 146 update ([1])):

      - "Greek, Modern" (updated to "Greek, Modern (1453-)")
      - "Chichewa; Nyanja"
      - "Sotho, Southern"
      - "Tonga (Tonga Islands)"
      - "North Azerbaijani"
      - "Limburgan; Limburger; Limburgish"
      - "Gaelic; Scottish Gaelic"
      - "Interlingua (International Auxiliary Language Association)"
      - "Altaic (Other)"
      - "Apache languages"

    there are many such examples (especially after MR 146). (we would
    not want to rename them to be better identifiers, since this would
    make them less ideal for their primary display purpose, and it
    could make future updates from the glibc set much harder).

 5. it is not even possible for users to easily discover the (English)
    language names (or rather labels?) that are available for use
    instead of codes. not all are easily guessable.

 6. as shown by the MR 146 update, the names are far more prone to
    change than codes. this creates a backwards compatibility problem
    both for CLI use and saved settings. (we should not want to avoid
    such updates just for such backwards compatibility).

so, aside from some cases like "english" and "french", which are ideal
and reliable, for most languages codes are the better choice, putting
more emphasis on codes being checked first. though of course the
name/code clash issue discussed next is more significant.

-- result differences --

the results given are identical with the current data set, since there are
currently no records where the 3-char name of one matches (ignoring case)
the iso-639-2 code of another.

if/when MR 146 is merged, there are some such clashing records added, and
considering the order of the records (preserved from glibc order to make
updates easier if for no other reason), a different match would be returned
by this algorithm than the previous one, preferring now the code-based
match of the later record over the name-based match of the earlier.

the clashing records of interest are:
 - "Kru" and "Kurukh", with the latter having an ISO-639-2 code of "kru".
 - "Mon" and "Mongolian", with the latter having a code of "mon".

with "Kru" coming before "Kurukh" and "Mon" before "Mongolian", use of "kru"
and "mon" with the previous algorithm would have matched "Kru" and "Mon"
named records respectively, while the new algorithm will instead match
"Kurukh" and "Mongolian" respectively, preferring the code-based match.

(MR 146 with the old algorithm actually introduces a regression for
"Mongolian" in that "mon" then matches the "Mon" record, whilst the new
algorithm fixes that, restoring the "Mongolian" match).

thus "Kurukh" and "Mongolian" could with the previous algorithm only be
matched via their full names (or the "mn" iso-639-1 code in the Mongolian
case), whilst with the new algorithm they can be reached via codes also,
whilst "Kru" and "Mon" can only now be reached via codes ("kro" and "mnw"
respectively).

either way there's an unavoidable imperfection in doing a case-insensitive
name-inclusive lookup, but i feel code-based being primary is best; we don't
necessarily want to ditch the name-based lookup considering those languages
that it does work well for, and i don't expect we would want to make the
name search case-sensitive, requiring capitals.

[1]: https://code.videolan.org/videolan/vlc/-/merge_requests/146

- - - - -
35535094 by Lyndon Brown at 2021-06-12T13:09:35+00:00
core: mention "ISO-639" in lang preference option longtext

such that users have a hint of what the different available codes are.

- - - - -
1bd0da3d by Lyndon Brown at 2021-06-12T13:09:35+00:00
esout: switch from using iso-639-1 to iso-639-2B codes

...for es language attributes.

while all iso-639 records in the table (iso-639_def.h) currently have a
two char iso-639-1 code, with the exception of "Original audio", if/when
MR 146 ([1]) is merged, there will be many records with no iso-639-1 code,
which will cause empty strings to be captured in the language properties
for such languages.

all records, now and after MR 146, have an iso-639-2B code so switching to
that will solve the problem. (all but one have iso-639-2T fwiw).

[1]: https://code.videolan.org/videolan/vlc/-/merge_requests/146

- - - - -
145a112e by Lyndon Brown at 2021-06-12T13:09:35+00:00
mux/ps,ts: simplify debug message construction

per suggestion in MR review.

- - - - -


10 changed files:

- include/vlc_iso_lang.h
- modules/access/bluray.c
- modules/access/dvdnav.c
- modules/mux/mp4/libmp4mux.c
- modules/mux/mpeg/ps.c
- modules/mux/mpeg/ts.c
- src/input/es_out.c
- src/libvlc-module.c
- src/libvlccore.sym
- src/text/iso_lang.c


Changes:

=====================================
include/vlc_iso_lang.h
=====================================
@@ -37,10 +37,22 @@ struct iso639_lang_t
 #if defined( __cplusplus )
 extern "C" {
 #endif
-VLC_API const iso639_lang_t * GetLang_1( const char * );
-VLC_API const iso639_lang_t * GetLang_2T( const char * );
-VLC_API const iso639_lang_t * GetLang_2B( const char * );
+
+/*
+ * Tries to find the language record for the given ISO-639 language code.
+ *
+ * The provided code should either be a two character ISO-639-1 code, or a three
+ * character ISO-639-2 code. For the latter, a search is done first of the
+ * ISO-639-2B (English) code attributes, falling back to the ISO-639-2T (native)
+ * code attributes if no match. (Case insensitive).
+ *
+ * If `try_name` is set to `true`, then as a last resort, a (case-insensitive)
+ * search of language names will be performed.
+ *
+ * @return A pointer to the matching record, or NULL if no match.
+ */
+VLC_API const iso639_lang_t * vlc_find_iso639( const char *code, bool try_name );
+
 #if defined( __cplusplus )
 }
 #endif
-


=====================================
modules/access/bluray.c
=====================================
@@ -54,10 +54,6 @@
 #include "../demux/mpeg/timestamps.h"
 #include "../demux/timestamps_filter.h"
 
-/* FIXME we should find a better way than including that */
-#include "../../src/text/iso-639_def.h"
-
-
 #include <libbluray/bluray.h>
 #include <libbluray/bluray-version.h>
 #include <libbluray/keys.h>
@@ -498,20 +494,11 @@ static const char *DemuxGetLanguageCode( demux_t *p_demux, const char *psz_var )
     if( ( p = strchr( psz_lang, ',' ) ) )
         *p = '\0';
 
-    for( pl = p_languages; pl->psz_eng_name != NULL; pl++ )
-    {
-        if( *psz_lang == '\0' )
-            continue;
-        if( !strcasecmp( pl->psz_eng_name, psz_lang ) ||
-            !strcasecmp( pl->psz_iso639_1, psz_lang ) ||
-            !strcasecmp( pl->psz_iso639_2T, psz_lang ) ||
-            !strcasecmp( pl->psz_iso639_2B, psz_lang ) )
-            break;
-    }
+    pl = vlc_find_iso639( psz_lang, true );
 
     free( psz_lang );
 
-    if( pl->psz_eng_name != NULL )
+    if( pl != NULL )
         return pl->psz_iso639_2T;
 
     return LANGUAGE_DEFAULT;


=====================================
modules/access/dvdnav.c
=====================================
@@ -53,10 +53,6 @@
 #include <vlc_dialog.h>
 #include <vlc_iso_lang.h>
 
-/* FIXME we should find a better way than including that */
-#include "../../src/text/iso-639_def.h"
-
-
 #include <dvdnav/dvdnav.h>
 /* Expose without patching headers */
 dvdnav_status_t dvdnav_jump_to_sector_by_time(dvdnav_t *, uint64_t, int32_t);
@@ -1248,20 +1244,11 @@ static char *DemuxGetLanguageCode( demux_t *p_demux, const char *psz_var )
     if( ( p = strchr( psz_lang, ',' ) ) )
         *p = '\0';
 
-    for( pl = p_languages; pl->psz_eng_name != NULL; pl++ )
-    {
-        if( *psz_lang == '\0' )
-            continue;
-        if( !strcasecmp( pl->psz_eng_name, psz_lang ) ||
-            !strcasecmp( pl->psz_iso639_1, psz_lang ) ||
-            !strcasecmp( pl->psz_iso639_2T, psz_lang ) ||
-            !strcasecmp( pl->psz_iso639_2B, psz_lang ) )
-            break;
-    }
+    pl = vlc_find_iso639( psz_lang, true );
 
     free( psz_lang );
 
-    if( pl->psz_eng_name != NULL )
+    if( pl != NULL )
         return strdup( pl->psz_iso639_1 );
 
     return strdup(LANGUAGE_DEFAULT);


=====================================
modules/mux/mp4/libmp4mux.c
=====================================
@@ -2050,18 +2050,10 @@ bo_t * mp4mux_GetMoov(mp4mux_handle_t *h, vlc_object_t *p_obj, vlc_tick_t i_dura
 
         if (p_stream->fmt.psz_language) {
             char *psz = p_stream->fmt.psz_language;
-            const iso639_lang_t *pl = NULL;
+            const iso639_lang_t *pl = vlc_find_iso639(psz, false);
             uint16_t lang = 0x0;
 
-            if (strlen(psz) == 2)
-                pl = GetLang_1(psz);
-            else if (strlen(psz) == 3) {
-                pl = GetLang_2B(psz);
-                if (!strcmp(pl->psz_iso639_1, "??"))
-                    pl = GetLang_2T(psz);
-            }
-
-            if (pl && strcmp(pl->psz_iso639_1, "??"))
+            if (pl)
                 lang = ((pl->psz_iso639_2T[0] - 0x60) << 10) |
                        ((pl->psz_iso639_2T[1] - 0x60) <<  5) |
                        ((pl->psz_iso639_2T[2] - 0x60));


=====================================
modules/mux/mpeg/ps.c
=====================================
@@ -352,28 +352,15 @@ static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input )
     if( p_input->p_fmt->psz_language )
     {
         char *psz = p_input->p_fmt->psz_language;
-        const iso639_lang_t *pl = NULL;
+        const iso639_lang_t *pl = vlc_find_iso639( psz, false );
 
-        if( strlen( psz ) == 2 )
-        {
-            pl = GetLang_1( psz );
-        }
-        else if( strlen( psz ) == 3 )
-        {
-            pl = GetLang_2B( psz );
-            if( !strcmp( pl->psz_iso639_1, "??" ) )
-            {
-                pl = GetLang_2T( psz );
-            }
-        }
-        if( pl && strcmp( pl->psz_iso639_1, "??" ) )
+        if( pl )
         {
             p_stream->lang[0] = pl->psz_iso639_2T[0];
             p_stream->lang[1] = pl->psz_iso639_2T[1];
             p_stream->lang[2] = pl->psz_iso639_2T[2];
 
-            msg_Dbg( p_mux, "    - lang=%c%c%c",
-                     p_stream->lang[0], p_stream->lang[1], p_stream->lang[2] );
+            msg_Dbg( p_mux, "    - lang=%3.3s", pl->psz_iso639_2T );
         }
     }
     return VLC_SUCCESS;


=====================================
modules/mux/mpeg/ts.c
=====================================
@@ -836,26 +836,6 @@ static int Control( sout_mux_t *p_mux, int i_query, va_list args )
     }
 }
 
-/* returns a pointer to a valid string, with length 0 or 3 */
-static const char *GetIso639_2LangCode(const char *lang)
-{
-    const iso639_lang_t *pl;
-
-    if (strlen(lang) == 2)
-    {
-        pl = GetLang_1(lang);
-    }
-    else
-    {
-        pl = GetLang_2B(lang);      /* try native code first */
-        if (!*pl->psz_iso639_2T)
-            pl = GetLang_2T(lang);  /* else fallback to english code */
-
-    }
-
-    return pl->psz_iso639_2T;   /* returns the english code */
-}
-
 static void SelectPCRStream( sout_mux_t *p_mux, sout_input_t *p_removed_pcr_input )
 {
     sout_mux_sys_t *p_sys = p_mux->p_sys;
@@ -936,12 +916,12 @@ static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input )
         if (!lang)
             continue;
 
-        const char *code = GetIso639_2LangCode(lang);
-        if (*code)
+        const iso639_lang_t *pl = vlc_find_iso639(lang, false);
+        if (pl)
         {
-            memcpy(&p_stream->pes.lang[i*4], code, 3);
+            memcpy(&p_stream->pes.lang[i*4], pl->psz_iso639_2T, 3);
             p_stream->pes.lang[i*4+3] = 0x00; /* audio type: 0x00 undefined */
-            msg_Dbg( p_mux, "    - lang=%3.3s", &p_stream->pes.lang[i*4] );
+            msg_Dbg( p_mux, "    - lang=%3.3s", pl->psz_iso639_2T );
         }
     }
 


=====================================
src/input/es_out.c
=====================================
@@ -54,8 +54,6 @@
 #include "../stream_output/stream_output.h"
 
 #include <vlc_iso_lang.h>
-/* FIXME we should find a better way than including that */
-#include "../text/iso-639_def.h"
 
 /*****************************************************************************
  * Local prototypes
@@ -3961,7 +3959,7 @@ static const struct es_out_callbacks es_out_cbs =
 };
 
 /****************************************************************************
- * LanguageGetName: try to expend iso639 into plain name
+ * LanguageGetName: try to expand iso639 into plain name
  ****************************************************************************/
 static char *LanguageGetName( const char *psz_code )
 {
@@ -3972,26 +3970,10 @@ static char *LanguageGetName( const char *psz_code )
         return strdup( "" );
     }
 
-    if( strlen( psz_code ) == 2 )
-    {
-        pl = GetLang_1( psz_code );
-    }
-    else if( strlen( psz_code ) == 3 )
-    {
-        pl = GetLang_2B( psz_code );
-        if( !strcmp( pl->psz_iso639_1, "??" ) )
-        {
-            pl = GetLang_2T( psz_code );
-        }
-    }
-    else
-    {
-        char *lang = LanguageGetCode( psz_code );
-        pl = GetLang_1( lang );
-        free( lang );
-    }
+    size_t len = strlen( psz_code );
+    pl = vlc_find_iso639( psz_code, ( len != 2 && len != 3 ) );
 
-    if( !strcmp( pl->psz_iso639_1, "??" ) )
+    if( !pl )
     {
        return strdup( psz_code );
     }
@@ -4001,24 +3983,17 @@ static char *LanguageGetName( const char *psz_code )
     }
 }
 
-/* Get a 2 char code */
+/* Get a 3 char code */
 static char *LanguageGetCode( const char *psz_lang )
 {
     const iso639_lang_t *pl;
-
-    if( psz_lang == NULL || *psz_lang == '\0' )
-        return strdup("??");
-
-    for( pl = p_languages; pl->psz_eng_name != NULL; pl++ )
+    if( psz_lang != NULL )
     {
-        if( !strcasecmp( pl->psz_eng_name, psz_lang ) ||
-            !strcasecmp( pl->psz_iso639_1, psz_lang ) ||
-            !strcasecmp( pl->psz_iso639_2T, psz_lang ) ||
-            !strcasecmp( pl->psz_iso639_2B, psz_lang ) )
-            return strdup( pl->psz_iso639_1 );
+        pl = vlc_find_iso639( psz_lang, true );
+        if( pl != NULL )
+            return strdup( pl->psz_iso639_2B );
     }
-
-    return strdup("??");
+    return strdup("???");
 }
 
 static char **LanguageSplit( const char *psz_langs )
@@ -4051,7 +4026,7 @@ static char **LanguageSplit( const char *psz_langs )
         else
         {
             psz_code = LanguageGetCode( psz_parser );
-            if( strcmp( psz_code, "??" ) )
+            if( strcmp( psz_code, "???" ) )
             {
                 TAB_APPEND( i_psz, ppsz, psz_code );
             }


=====================================
src/libvlc-module.c
=====================================
@@ -621,17 +621,17 @@ static const char *const ppsz_clock_descriptions[] =
 #define INPUT_AUDIOTRACK_LANG_TEXT N_("Audio language")
 #define INPUT_AUDIOTRACK_LANG_LONGTEXT N_( \
     "Language of the audio track you want to use " \
-    "(comma separated, two or three letter country code, you may use 'none' to avoid a fallback to another language).")
+    "(comma separated, two or three letter ISO-639 country code; you may use 'none' to avoid a fallback to another language).")
 
 #define INPUT_SUBTRACK_LANG_TEXT N_("Subtitle language")
 #define INPUT_SUBTRACK_LANG_LONGTEXT N_( \
     "Language of the subtitle track you want to use " \
-    "(comma separated, two or three letters country code, you may use 'any' as a fallback).")
+    "(comma separated, two or three letter ISO-639 country code; you may use 'any' as a fallback).")
 
 #define INPUT_MENUTRACK_LANG_TEXT N_("Menu language")
 #define INPUT_MENUTRACK_LANG_LONGTEXT N_( \
     "Language of the menus you want to use with DVD/BluRay " \
-    "(comma separated, two or three letters country code, you may use 'any' as a fallback).")
+    "(comma separated, two or three letter ISO-639 country code; you may use 'any' as a fallback).")
 
 #define INPUT_VIDEOTRACK_ID_TEXT N_("Video track ID")
 #define INPUT_VIDEOTRACK_ID_LONGTEXT N_( \


=====================================
src/libvlccore.sym
=====================================
@@ -127,9 +127,7 @@ filter_ConfigureBlend
 filter_DeleteBlend
 filter_NewBlend
 FromCharset
-GetLang_1
-GetLang_2B
-GetLang_2T
+vlc_find_iso639
 vlc_http_auth_Init
 vlc_http_auth_Deinit
 vlc_http_auth_ParseWwwAuthenticateHeader


=====================================
src/text/iso_lang.c
=====================================
@@ -40,39 +40,66 @@
  *****************************************************************************/
 #include "iso-639_def.h"
 
-static const iso639_lang_t unknown_language =
-    { "Unknown", "??", "???", "???" };
+static const iso639_lang_t * GetLang_1( const char * psz_code )
+{
+    const iso639_lang_t *p_lang;
+
+    for( p_lang = p_languages; p_lang->psz_eng_name; p_lang++ )
+        if( !strcasecmp( p_lang->psz_iso639_1, psz_code ) )
+            return p_lang;
 
-const iso639_lang_t * GetLang_1( const char * psz_code )
+    return NULL;
+}
+
+static const iso639_lang_t * GetLang_2T( const char * psz_code )
 {
     const iso639_lang_t *p_lang;
 
     for( p_lang = p_languages; p_lang->psz_eng_name; p_lang++ )
-        if( !strncasecmp( p_lang->psz_iso639_1, psz_code, 2 ) )
+        if( !strcasecmp( p_lang->psz_iso639_2T, psz_code ) )
             return p_lang;
 
-    return &unknown_language;
+    return NULL;
 }
 
-const iso639_lang_t * GetLang_2T( const char * psz_code )
+static const iso639_lang_t * GetLang_2B( const char * psz_code )
 {
     const iso639_lang_t *p_lang;
 
     for( p_lang = p_languages; p_lang->psz_eng_name; p_lang++ )
-        if( !strncasecmp( p_lang->psz_iso639_2T, psz_code, 3 ) )
+        if( !strcasecmp( p_lang->psz_iso639_2B, psz_code ) )
             return p_lang;
 
-    return &unknown_language;
+    return NULL;
 }
 
-const iso639_lang_t * GetLang_2B( const char * psz_code )
+static const iso639_lang_t * GetLang_name( const char * psz_lang )
 {
     const iso639_lang_t *p_lang;
 
     for( p_lang = p_languages; p_lang->psz_eng_name; p_lang++ )
-        if( !strncasecmp( p_lang->psz_iso639_2B, psz_code, 3 ) )
+        if( !strcasecmp( p_lang->psz_eng_name, psz_lang ) )
             return p_lang;
 
-    return &unknown_language;
+    return NULL;
 }
 
+const iso639_lang_t * vlc_find_iso639( const char *code, bool try_name )
+{
+    const iso639_lang_t *result = NULL;
+    size_t len = strlen(code);
+
+    if (len == 2)
+        result = GetLang_1(code);
+    else if (len == 3)
+    {
+        result = GetLang_2B(code);
+        if (result == NULL)
+            result = GetLang_2T(code);
+    }
+
+    if (try_name && !result && len != 0)
+        result = GetLang_name(code);
+
+    return result;
+}



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/73cfe7b94577c5958bcad17011dcc706592dad38...145a112e7f5def891f54dd4c0ed1fb6bd052116c

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/73cfe7b94577c5958bcad17011dcc706592dad38...145a112e7f5def891f54dd4c0ed1fb6bd052116c
You're receiving this email because of your account on code.videolan.org.




More information about the vlc-commits mailing list