gplugin/gplugin
Clone
Summary
Browse
Changes
Graph
Use g_set_str everywhere
default
tip
24 hours ago, Elliott Sales de Andrade
ed6abba21225
Use g_set_str everywhere
This simplifies some setters.
Testing Done:
Ran `ninja turtles`
Reviewed at https://reviews.imfreedom.org/r/3179/
/*
* Copyright (C) 2011-2023 Gary Kramlich <grim@reaperworld.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see <https://www.gnu.org/licenses/>.
*/
#include
<glib.h>
#include
<glib/gi18n-lib.h>
#include
<gio/gio.h>
#include
<gplugin.h>
#include
<gplugin-native.h>
#include
<girepository.h>
#include
"gplugin-introspection.h"
/******************************************************************************
* Helpers
*****************************************************************************/
static
char
*
gplugin_introspection_get_ir_dump_directory
(
int
*
argc
,
char
***
argv
,
GError
**
error
)
{
GOptionContext
*
ctx
=
NULL
;
char
*
irdump
=
NULL
;
GOptionEntry
entries
[]
=
{
{
.
long_name
=
"introspect-dump"
,
.
short_name
=
'i'
,
.
flags
=
G_OPTION_FLAG_NONE
,
.
arg
=
G_OPTION_ARG_STRING
,
.
arg_data
=
&
irdump
,
},
G_OPTION_ENTRY_NULL
,
};
ctx
=
g_option_context_new
(
""
);
g_option_context_set_summary
(
ctx
,
_
(
"Loads plugins so they can be scanned by g-ir-scanner"
));
g_option_context_set_translation_domain
(
ctx
,
GETTEXT_PACKAGE
);
g_option_context_add_main_entries
(
ctx
,
entries
,
GETTEXT_PACKAGE
);
g_option_context_parse
(
ctx
,
argc
,
argv
,
error
);
g_clear_pointer
(
&
ctx
,
g_option_context_free
);
return
irdump
;
}
static
GPluginPlugin
*
gplugin_introspection_query_and_load_plugin
(
GPluginLoader
*
loader
,
const
char
*
filename
,
GError
**
error
)
{
GPluginPlugin
*
plugin
=
NULL
;
GError
*
local_error
=
NULL
;
gboolean
loaded
=
FALSE
;
plugin
=
gplugin_loader_query_plugin
(
loader
,
filename
,
&
local_error
);
if
(
local_error
!=
NULL
)
{
g_clear_object
(
&
plugin
);
g_propagate_error
(
error
,
local_error
);
return
NULL
;
}
if
(
!
GPLUGIN_IS_PLUGIN
(
plugin
))
{
g_set_error_literal
(
error
,
GPLUGIN_DOMAIN
,
0
,
"plugin unexpectedly is invalid"
);
return
NULL
;
}
loaded
=
gplugin_loader_load_plugin
(
loader
,
plugin
,
&
local_error
);
if
(
local_error
!=
NULL
)
{
g_clear_object
(
&
plugin
);
g_propagate_error
(
error
,
local_error
);
return
NULL
;
}
if
(
!
loaded
)
{
g_set_error
(
error
,
GPLUGIN_DOMAIN
,
0
,
_
(
"Failed to load plugin %s: unknown error"
),
filename
);
g_clear_object
(
&
plugin
);
return
NULL
;
}
return
plugin
;
}
static
void
gplugin_introspection_introspect_unload_plugins
(
GPluginLoader
*
loader
,
GListModel
*
plugins
)
{
for
(
guint
i
=
0
;
i
<
g_list_model_get_n_items
(
plugins
);
i
++
)
{
GPluginPlugin
*
plugin
=
NULL
;
plugin
=
g_list_model_get_item
(
plugins
,
i
);
gplugin_loader_unload_plugin
(
loader
,
plugin
,
TRUE
,
NULL
);
g_clear_object
(
&
plugin
);
}
}
/******************************************************************************
* Public API
*****************************************************************************/
int
gplugin_introspection_introspect_plugin
(
int
*
argc
,
char
***
argv
,
const
char
*
filename
)
{
return
gplugin_introspection_introspect_plugins
(
argc
,
argv
,
filename
,
NULL
);
}
int
gplugin_introspection_introspect_plugins
(
int
*
argc
,
char
***
argv
,
...)
{
GPluginLoader
*
loader
=
NULL
;
GError
*
error
=
NULL
;
GListStore
*
plugins
=
NULL
;
char
*
irdump
=
NULL
;
const
char
*
filename
=
NULL
;
va_list
args
;
irdump
=
gplugin_introspection_get_ir_dump_directory
(
argc
,
argv
,
&
error
);
if
(
error
!=
NULL
)
{
g_print
(
_
(
"Failed to parse command line arguments: %s
\n
"
),
error
->
message
);
g_free
(
irdump
);
return
1
;
}
if
(
irdump
==
NULL
||
irdump
[
0
]
==
'\0'
)
{
g_print
(
_
(
"The introspect-dump option was not provided. This tool is"
"only meant to be called by g-ir-scanner directly."
));
return
1
;
}
/* Create an instance of the native loader to load the plugins. */
loader
=
g_object_new
(
GPLUGIN_TYPE_NATIVE_LOADER
,
NULL
);
/* Load our plugins. We store them in a GListStore so we can easily unload
* and unref them later. We can't use GPLUGIN_TYPE_PLUGIN as it's an
* interface, so just force it down to GObject to make it work.
*/
plugins
=
g_list_store_new
(
G_TYPE_OBJECT
);
va_start
(
args
,
argv
);
while
((
filename
=
va_arg
(
args
,
const
char
*
))
!=
NULL
)
{
GPluginPlugin
*
plugin
=
NULL
;
plugin
=
gplugin_introspection_query_and_load_plugin
(
loader
,
filename
,
&
error
);
if
(
error
!=
NULL
)
{
g_print
(
_
(
"Failed to query or load plugin %s: %s
\n
"
),
filename
,
error
->
message
);
gplugin_introspection_introspect_unload_plugins
(
loader
,
G_LIST_MODEL
(
plugins
));
g_clear_object
(
&
plugins
);
g_free
(
irdump
);
g_clear_object
(
&
plugin
);
g_clear_object
(
&
loader
);
return
1
;
}
g_list_store_append
(
plugins
,
plugin
);
/* Remove our reference to the plugin as we don't need it any more. */
g_clear_object
(
&
plugin
);
}
va_end
(
args
);
/* Now that all of the plugins have been loaded, run the scanner. */
if
(
!
g_irepository_dump
(
irdump
,
&
error
))
{
g_print
(
"g_irepository_dump() failed: %s
\n
"
,
error
->
message
);
g_free
(
irdump
);
gplugin_introspection_introspect_unload_plugins
(
loader
,
G_LIST_MODEL
(
plugins
));
g_clear_object
(
&
plugins
);
g_clear_object
(
&
loader
);
return
1
;
}
gplugin_introspection_introspect_unload_plugins
(
loader
,
G_LIST_MODEL
(
plugins
));
g_clear_object
(
&
plugins
);
g_clear_object
(
&
loader
);
g_free
(
irdump
);
return
0
;
}