Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
videolan
vlc
Commits
cf98594d
Commit
cf98594d
authored
Oct 12, 2012
by
Rémi Denis-Courmont
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
module_need(): rewrite using module_list_cap()
parent
a57b503d
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
108 additions
and
166 deletions
+108
-166
src/modules/modules.c
src/modules/modules.c
+108
-166
No files found.
src/modules/modules.c
View file @
cf98594d
...
...
@@ -157,19 +157,35 @@ void module_stop (vlc_object_t *obj, const module_t *m)
deactivate
(
obj
);
}
typedef
struct
module_list_t
static
bool
module_match_name
(
const
module_t
*
m
,
const
char
*
name
)
{
module_t
*
p_module
;
int16_t
i_score
;
bool
b_force
;
}
module_list_t
;
/* Plugins with zero score must be matched explicitly. */
if
(
!
strcasecmp
(
"any"
,
name
))
return
m
->
i_score
>
0
;
for
(
unsigned
i
=
0
;
i
<
m
->
i_shortcuts
;
i
++
)
if
(
!
strcasecmp
(
m
->
pp_shortcuts
[
i
],
name
))
return
true
;
return
false
;
}
static
int
modulecmp
(
const
void
*
a
,
const
void
*
b
)
static
int
module_load
(
vlc_object_t
*
obj
,
module_t
*
m
,
vlc_activate_t
init
,
va_list
args
)
{
const
module_list_t
*
la
=
a
,
*
lb
=
b
;
/* Note that qsort() uses _ascending_ order,
* so the smallest module is the one with the biggest score. */
return
lb
->
i_score
-
la
->
i_score
;
int
ret
=
VLC_SUCCESS
;
if
(
module_Map
(
obj
,
m
))
return
VLC_EGENERIC
;
if
(
m
->
pf_activate
!=
NULL
)
{
va_list
ap
;
va_copy
(
ap
,
args
);
ret
=
init
(
m
->
pf_activate
,
ap
);
va_end
(
ap
);
}
return
ret
;
}
#undef vlc_module_load
...
...
@@ -185,198 +201,124 @@ static int modulecmp (const void *a, const void *b)
* variable arguments passed to this function. This scheme is meant to
* support arbitrary prototypes for the module entry point.
*
* \param
p_this
VLC object
* \param
psz_
capability capability, i.e. class of module
* \param
psz_
name name name of the module asked, if any
* \param
b_
strict if true, do not fallback to plugin with a different name
* \param
obj
VLC object
* \param capability capability, i.e. class of module
* \param name name name of the module asked, if any
* \param strict if true, do not fallback to plugin with a different name
* but the same capability
* \param probe module probe callback
* \return the module or NULL in case of a failure
*/
module_t
*
vlc_module_load
(
vlc_object_t
*
p_this
,
const
char
*
psz_
capability
,
const
char
*
psz_name
,
bool
b_
strict
,
module_t
*
vlc_module_load
(
vlc_object_t
*
obj
,
const
char
*
capability
,
const
char
*
name
,
bool
strict
,
vlc_activate_t
probe
,
...)
{
int
i_shortcuts
=
0
;
char
*
psz_shortcuts
=
NULL
,
*
psz_var
=
NULL
;
bool
b_force_backup
=
p_this
->
b_force
;
/* Deal with variables */
if
(
psz_name
&&
psz_name
[
0
]
==
'$'
)
{
psz_name
=
psz_var
=
var_CreateGetString
(
p_this
,
psz_name
+
1
);
}
/* Count how many different shortcuts were asked for */
if
(
psz_name
&&
*
psz_name
)
{
char
*
psz_parser
,
*
psz_last_shortcut
;
/* If the user wants none, give him none. */
if
(
!
strcmp
(
psz_name
,
"none"
)
)
{
free
(
psz_var
);
return
NULL
;
}
i_shortcuts
++
;
psz_parser
=
psz_shortcuts
=
psz_last_shortcut
=
strdup
(
psz_name
);
char
*
var
=
NULL
;
while
(
(
psz_parser
=
strchr
(
psz_parser
,
','
)
)
)
{
*
psz_parser
=
'\0'
;
i_shortcuts
++
;
psz_last_shortcut
=
++
psz_parser
;
}
if
(
name
==
NULL
||
name
[
0
]
==
'\0'
)
name
=
"any"
;
/* Check if the user wants to override the "strict" mode */
if
(
psz_last_shortcut
)
{
if
(
!
strcmp
(
psz_last_shortcut
,
"none"
)
)
{
b_strict
=
true
;
i_shortcuts
--
;
}
else
if
(
!
strcmp
(
psz_last_shortcut
,
"any"
)
)
{
b_strict
=
false
;
i_shortcuts
--
;
}
}
}
/* Sort the modules and test them */
size_t
total
,
match
=
0
;
module_t
**
p_all
=
module_list_get
(
&
total
);
module_list_t
*
p_list
=
xmalloc
(
total
*
sizeof
(
module_list_t
)
);
/* Parse the module list for capabilities and probe each of them */
for
(
size_t
i
=
0
;
i
<
total
;
i
++
)
/* Deal with variables */
if
(
name
[
0
]
==
'$'
)
{
module_t
*
p_module
=
p_all
[
i
];
int
i_shortcut_bonus
=
0
;
/* Test that this module can do what we need */
if
(
!
module_provides
(
p_module
,
psz_capability
)
)
continue
;
/* If we required a shortcut, check this plugin provides it. */
if
(
i_shortcuts
>
0
)
{
const
char
*
name
=
psz_shortcuts
;
for
(
unsigned
i_short
=
i_shortcuts
;
i_short
>
0
;
i_short
--
)
{
for
(
unsigned
i
=
0
;
i
<
p_module
->
i_shortcuts
;
i
++
)
{
if
(
!
strcasecmp
(
name
,
p_module
->
pp_shortcuts
[
i
]
)
)
{
/* Found it */
i_shortcut_bonus
=
i_short
*
10000
;
goto
found_shortcut
;
}
}
/* Go to the next shortcut... This is so lame! */
name
+=
strlen
(
name
)
+
1
;
}
/* If we are in "strict" mode and we couldn't
* find the module in the list of provided shortcuts,
* then kick the bastard out of here!!! */
if
(
b_strict
)
continue
;
}
/* Trash <= 0 scored plugins (they can only be selected by shortcut) */
if
(
p_module
->
i_score
<=
0
)
continue
;
found_shortcut:
/* Store this new module */
p_list
[
match
].
p_module
=
p_module
;
p_list
[
match
].
i_score
=
p_module
->
i_score
+
i_shortcut_bonus
;
p_list
[
match
].
b_force
=
i_shortcut_bonus
&&
b_strict
;
match
++
;
var
=
var_InheritString
(
obj
,
name
+
1
);
name
=
(
var
!=
NULL
)
?
var
:
"any"
;
}
/* We can release the list, interesting modules are held */
module_list_free
(
p_all
);
/* Find matching modules */
module_t
**
mods
;
ssize_t
total
=
module_list_cap
(
&
mods
,
capability
);
if
(
match
==
0
)
msg_Dbg
(
obj
,
"looking for %s module matching
\"
%s
\"
: %zd candidates"
,
capability
,
name
,
total
);
if
(
total
<=
0
)
{
m
sg_Dbg
(
p_this
,
"no %s module matched
\"
%s
\"
"
,
psz_capability
,
(
psz_name
&&
*
psz_name
)
?
psz_name
:
"any"
);
return
NULL
;
// shortcut
m
odule_list_free
(
mods
);
msg_Dbg
(
obj
,
"no %s modules"
,
capability
);
return
NULL
;
}
/* Sort candidates by descending score */
qsort
(
p_list
,
match
,
sizeof
(
p_list
[
0
]),
modulecmp
);
msg_Dbg
(
p_this
,
"looking for %s module: %zu candidate%s"
,
psz_capability
,
match
,
match
==
1
?
""
:
"s"
);
/* Parse the linked list and use the first successful module */
module_t
*
p_module
=
NULL
;
module_t
*
module
=
NULL
;
const
bool
b_force_backup
=
obj
->
b_force
;
/* FIXME: remove this */
va_list
args
;
va_start
(
args
,
probe
);
for
(
size_t
i
=
0
;
(
i
<
match
)
&&
(
p_module
==
NULL
);
i
++
)
while
(
*
name
)
{
module_t
*
p_cand
=
p_list
[
i
].
p_module
;
char
buf
[
32
];
size_t
slen
=
strcspn
(
name
,
","
);
if
(
module_Map
(
p_this
,
p_cand
))
if
(
likely
(
slen
<
sizeof
(
buf
)))
{
memcpy
(
buf
,
name
,
slen
);
buf
[
slen
]
=
'\0'
;
}
name
+=
slen
;
name
+=
strspn
(
name
,
","
);
if
(
unlikely
(
slen
>=
sizeof
(
buf
)))
continue
;
p_this
->
b_force
=
p_list
[
i
].
b_force
;
int
ret
;
const
char
*
shortcut
=
buf
;
assert
(
shortcut
!=
NULL
);
if
(
likely
(
p_cand
->
pf_activate
!=
NULL
))
obj
->
b_force
=
strict
&&
strcasecmp
(
"any"
,
shortcut
);
for
(
ssize_t
i
=
0
;
i
<
total
;
i
++
)
{
va_list
ap
;
module_t
*
cand
=
mods
[
i
];
if
(
cand
==
NULL
)
continue
;
// module failed in previous iteration
if
(
!
module_match_name
(
cand
,
shortcut
))
continue
;
mods
[
i
]
=
NULL
;
// only try each module once at most...
va_copy
(
ap
,
args
);
ret
=
probe
(
p_cand
->
pf_activate
,
ap
);
va_end
(
ap
);
int
ret
=
module_load
(
obj
,
cand
,
probe
,
args
);
switch
(
ret
)
{
case
VLC_SUCCESS
:
module
=
cand
;
/* fall through */
case
VLC_ETIMEOUT
:
goto
done
;
}
}
else
ret
=
VLC_SUCCESS
;
}
switch
(
ret
)
/* None of the shortcuts matched, fall back to any module */
if
(
!
strict
)
{
obj
->
b_force
=
false
;
for
(
ssize_t
i
=
0
;
i
<
total
;
i
++
)
{
case
VLC_SUCCESS
:
/* good module! */
p_module
=
p_cand
;
break
;
case
VLC_ETIMEOUT
:
/* good module, but aborted */
break
;
module_t
*
cand
=
mods
[
i
];
if
(
cand
==
NULL
)
continue
;
default:
/* bad module */
continue
;
int
ret
=
module_load
(
obj
,
cand
,
probe
,
args
);
switch
(
ret
)
{
case
VLC_SUCCESS
:
module
=
cand
;
/* fall through */
case
VLC_ETIMEOUT
:
goto
done
;
}
}
}
done:
va_end
(
args
);
free
(
p_list
);
p_this
->
b_force
=
b_force_backup
;
obj
->
b_force
=
b_force_backup
;
module_list_free
(
mods
);
free
(
var
);
if
(
p_module
!=
NULL
)
if
(
module
!=
NULL
)
{
msg_Dbg
(
p_this
,
"using %s module
\"
%s
\"
"
,
psz_capability
,
module_get_object
(
p_module
)
);
vlc_object_set_name
(
p_this
,
module_get_object
(
p_module
)
);
msg_Dbg
(
obj
,
"using %s module
\"
%s
\"
"
,
capability
,
module_get_object
(
module
)
);
vlc_object_set_name
(
obj
,
module_get_object
(
module
)
);
}
else
msg_Dbg
(
p_this
,
"no %s module matching
\"
%s
\"
could be loaded"
,
psz_capability
,
(
psz_name
&&
*
psz_name
)
?
psz_name
:
"any"
);
free
(
psz_shortcuts
);
free
(
psz_var
);
/* Don't forget that the module is still locked */
return
p_module
;
msg_Dbg
(
obj
,
"no %s modules matched"
,
capability
);
return
module
;
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment