Bug Summary

File:ctk/ctkrecentchooserutils.c
Warning:line 327, column 27
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name ctkrecentchooserutils.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/ctk -resource-dir /usr/lib/llvm-16/lib/clang/16 -D HAVE_CONFIG_H -I . -I .. -D G_LOG_DOMAIN="Ctk" -D G_LOG_USE_STRUCTURED=1 -D CTK_VERSION="3.25.5" -D CTK_BINARY_VERSION="3.0.0" -D CTK_COMPILATION -D CTK_PRINT_BACKEND_ENABLE_UNSUPPORTED -D CTK_LIBDIR="/usr/lib" -D CTK_LOCALEDIR="/usr/share/locale" -D CTK_DATADIR="/usr/share" -D CTK_DATA_PREFIX="/usr" -D CTK_SYSCONFDIR="/usr/etc" -D CTK_HOST="x86_64-pc-linux-gnu" -D CTK_PRINT_BACKENDS="file,cups" -D X11_DATA_PREFIX="/usr" -D ISO_CODES_PREFIX="" -I .. -I ../ctk -I .. -I ../cdk -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/sysprof-6 -D G_ENABLE_DEBUG -D G_ENABLE_CONSISTENCY_CHECKS -D GLIB_MIN_REQUIRED_VERSION=GLIB_VERSION_2_66 -D GLIB_MAX_ALLOWED_VERSION=GLIB_VERSION_2_66 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/sysprof-6 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/atk-1.0 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/x86_64-linux-gnu -I /usr/include/webp -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib/x86_64-linux-gnu/dbus-1.0/include -I /usr/include/gio-unix-2.0 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/sysprof-6 -I /usr/include/pango-1.0 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/cairo -I /usr/include/pixman-1 -D PIC -internal-isystem /usr/lib/llvm-16/lib/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fdebug-compilation-dir=/rootdir/ctk -ferror-limit 19 -fvisibility=hidden -fgnuc-version=4.2.1 -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2024-09-19-172131-43638-1 -x c ctkrecentchooserutils.c
1/* ctkrecentchooserutils.h - Private utility functions for implementing a
2 * CtkRecentChooser interface
3 *
4 * Copyright (C) 2006 Emmanuele Bassi
5 *
6 * All rights reserved
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
17 *
18 * You should have received a copy of the GNU Library General Public
19 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
20 *
21 * Based on ctkfilechooserutils.c:
22 * Copyright (C) 2003 Red Hat, Inc.
23 */
24
25#include "config.h"
26
27#include "ctkrecentchooserutils.h"
28
29/* Methods */
30static void delegate_set_sort_func (CtkRecentChooser *chooser,
31 CtkRecentSortFunc sort_func,
32 gpointer sort_data,
33 GDestroyNotify data_destroy);
34static void delegate_add_filter (CtkRecentChooser *chooser,
35 CtkRecentFilter *filter);
36static void delegate_remove_filter (CtkRecentChooser *chooser,
37 CtkRecentFilter *filter);
38static GSList *delegate_list_filters (CtkRecentChooser *chooser);
39static gboolean delegate_select_uri (CtkRecentChooser *chooser,
40 const gchar *uri,
41 GError **error);
42static void delegate_unselect_uri (CtkRecentChooser *chooser,
43 const gchar *uri);
44static GList *delegate_get_items (CtkRecentChooser *chooser);
45static CtkRecentManager *delegate_get_recent_manager (CtkRecentChooser *chooser);
46static void delegate_select_all (CtkRecentChooser *chooser);
47static void delegate_unselect_all (CtkRecentChooser *chooser);
48static gboolean delegate_set_current_uri (CtkRecentChooser *chooser,
49 const gchar *uri,
50 GError **error);
51static gchar * delegate_get_current_uri (CtkRecentChooser *chooser);
52
53/* Signals */
54static void delegate_notify (GObject *object,
55 GParamSpec *pspec,
56 gpointer user_data);
57static void delegate_selection_changed (CtkRecentChooser *receiver,
58 gpointer user_data);
59static void delegate_item_activated (CtkRecentChooser *receiver,
60 gpointer user_data);
61
62/**
63 * _ctk_recent_chooser_install_properties:
64 * @klass: the class structure for a type deriving from #GObject
65 *
66 * Installs the necessary properties for a class implementing
67 * #CtkRecentChooser. A #CtkParamSpecOverride property is installed
68 * for each property, using the values from the #CtkRecentChooserProp
69 * enumeration. The caller must make sure itself that the enumeration
70 * values don’t collide with some other property values they
71 * are using.
72 */
73void
74_ctk_recent_chooser_install_properties (GObjectClass *klass)
75{
76 g_object_class_override_property (klass,
77 CTK_RECENT_CHOOSER_PROP_RECENT_MANAGER,
78 "recent-manager");
79 g_object_class_override_property (klass,
80 CTK_RECENT_CHOOSER_PROP_SHOW_PRIVATE,
81 "show-private");
82 g_object_class_override_property (klass,
83 CTK_RECENT_CHOOSER_PROP_SHOW_TIPS,
84 "show-tips");
85 g_object_class_override_property (klass,
86 CTK_RECENT_CHOOSER_PROP_SHOW_ICONS,
87 "show-icons");
88 g_object_class_override_property (klass,
89 CTK_RECENT_CHOOSER_PROP_SHOW_NOT_FOUND,
90 "show-not-found");
91 g_object_class_override_property (klass,
92 CTK_RECENT_CHOOSER_PROP_SELECT_MULTIPLE,
93 "select-multiple");
94 g_object_class_override_property (klass,
95 CTK_RECENT_CHOOSER_PROP_LIMIT,
96 "limit");
97 g_object_class_override_property (klass,
98 CTK_RECENT_CHOOSER_PROP_LOCAL_ONLY,
99 "local-only");
100 g_object_class_override_property (klass,
101 CTK_RECENT_CHOOSER_PROP_SORT_TYPE,
102 "sort-type");
103 g_object_class_override_property (klass,
104 CTK_RECENT_CHOOSER_PROP_FILTER,
105 "filter");
106}
107
108/**
109 * _ctk_recent_chooser_delegate_iface_init:
110 * @iface: a #CtkRecentChooserIface
111 *
112 * An interface-initialization function for use in cases where
113 * an object is simply delegating the methods, signals of
114 * the #CtkRecentChooser interface to another object.
115 * _ctk_recent_chooser_set_delegate() must be called on each
116 * instance of the object so that the delegate object can
117 * be found.
118 */
119void
120_ctk_recent_chooser_delegate_iface_init (CtkRecentChooserIface *iface)
121{
122 iface->set_current_uri = delegate_set_current_uri;
123 iface->get_current_uri = delegate_get_current_uri;
124 iface->select_uri = delegate_select_uri;
125 iface->unselect_uri = delegate_unselect_uri;
126 iface->select_all = delegate_select_all;
127 iface->unselect_all = delegate_unselect_all;
128 iface->get_items = delegate_get_items;
129 iface->get_recent_manager = delegate_get_recent_manager;
130 iface->set_sort_func = delegate_set_sort_func;
131 iface->add_filter = delegate_add_filter;
132 iface->remove_filter = delegate_remove_filter;
133 iface->list_filters = delegate_list_filters;
134}
135
136/**
137 * _ctk_recent_chooser_set_delegate:
138 * @receiver: a #GObject implementing #CtkRecentChooser
139 * @delegate: another #GObject implementing #CtkRecentChooser
140 *
141 * Establishes that calls on @receiver for #CtkRecentChooser
142 * methods should be delegated to @delegate, and that
143 * #CtkRecentChooser signals emitted on @delegate should be
144 * forwarded to @receiver. Must be used in conjunction with
145 * _ctk_recent_chooser_delegate_iface_init().
146 */
147void
148_ctk_recent_chooser_set_delegate (CtkRecentChooser *receiver,
149 CtkRecentChooser *delegate)
150{
151 g_return_if_fail (CTK_IS_RECENT_CHOOSER (receiver))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((receiver)); GType __t = ((ctk_recent_chooser_get_type ()
)); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const
char*) (__func__)), "CTK_IS_RECENT_CHOOSER (receiver)"); return
; } } while (0)
;
152 g_return_if_fail (CTK_IS_RECENT_CHOOSER (delegate))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((delegate)); GType __t = ((ctk_recent_chooser_get_type ()
)); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const
char*) (__func__)), "CTK_IS_RECENT_CHOOSER (delegate)"); return
; } } while (0)
;
153
154 g_object_set_data (G_OBJECT (receiver)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((receiver)), (((GType) ((20) << (2))))))))
,
155 "ctk-recent-chooser-delegate", delegate);
156
157 g_signal_connect (delegate, "notify",g_signal_connect_data ((delegate), ("notify"), (((GCallback) (
delegate_notify))), (receiver), ((void*)0), (GConnectFlags) 0
)
158 G_CALLBACK (delegate_notify), receiver)g_signal_connect_data ((delegate), ("notify"), (((GCallback) (
delegate_notify))), (receiver), ((void*)0), (GConnectFlags) 0
)
;
159 g_signal_connect (delegate, "selection-changed",g_signal_connect_data ((delegate), ("selection-changed"), (((
GCallback) (delegate_selection_changed))), (receiver), ((void
*)0), (GConnectFlags) 0)
160 G_CALLBACK (delegate_selection_changed), receiver)g_signal_connect_data ((delegate), ("selection-changed"), (((
GCallback) (delegate_selection_changed))), (receiver), ((void
*)0), (GConnectFlags) 0)
;
161 g_signal_connect (delegate, "item-activated",g_signal_connect_data ((delegate), ("item-activated"), (((GCallback
) (delegate_item_activated))), (receiver), ((void*)0), (GConnectFlags
) 0)
162 G_CALLBACK (delegate_item_activated), receiver)g_signal_connect_data ((delegate), ("item-activated"), (((GCallback
) (delegate_item_activated))), (receiver), ((void*)0), (GConnectFlags
) 0)
;
163}
164
165GQuark
166_ctk_recent_chooser_delegate_get_quark (void)
167{
168 static GQuark quark = 0;
169
170 if (G_UNLIKELY (quark == 0)(quark == 0))
171 quark = g_quark_from_static_string ("ctk-recent-chooser-delegate");
172
173 return quark;
174}
175
176static CtkRecentChooser *
177get_delegate (CtkRecentChooser *receiver)
178{
179 return g_object_get_qdata (G_OBJECT (receiver)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((receiver)), (((GType) ((20) << (2))))))))
,
180 CTK_RECENT_CHOOSER_DELEGATE_QUARK(_ctk_recent_chooser_delegate_get_quark ()));
181}
182
183static void
184delegate_set_sort_func (CtkRecentChooser *chooser,
185 CtkRecentSortFunc sort_func,
186 gpointer sort_data,
187 GDestroyNotify data_destroy)
188{
189 ctk_recent_chooser_set_sort_func (get_delegate (chooser),
190 sort_func,
191 sort_data,
192 data_destroy);
193}
194
195static void
196delegate_add_filter (CtkRecentChooser *chooser,
197 CtkRecentFilter *filter)
198{
199 ctk_recent_chooser_add_filter (get_delegate (chooser), filter);
200}
201
202static void
203delegate_remove_filter (CtkRecentChooser *chooser,
204 CtkRecentFilter *filter)
205{
206 ctk_recent_chooser_remove_filter (get_delegate (chooser), filter);
207}
208
209static GSList *
210delegate_list_filters (CtkRecentChooser *chooser)
211{
212 return ctk_recent_chooser_list_filters (get_delegate (chooser));
213}
214
215static gboolean
216delegate_select_uri (CtkRecentChooser *chooser,
217 const gchar *uri,
218 GError **error)
219{
220 return ctk_recent_chooser_select_uri (get_delegate (chooser), uri, error);
221}
222
223static void
224delegate_unselect_uri (CtkRecentChooser *chooser,
225 const gchar *uri)
226{
227 ctk_recent_chooser_unselect_uri (get_delegate (chooser), uri);
228}
229
230static GList *
231delegate_get_items (CtkRecentChooser *chooser)
232{
233 return ctk_recent_chooser_get_items (get_delegate (chooser));
234}
235
236static CtkRecentManager *
237delegate_get_recent_manager (CtkRecentChooser *chooser)
238{
239 return _ctk_recent_chooser_get_recent_manager (get_delegate (chooser));
240}
241
242static void
243delegate_select_all (CtkRecentChooser *chooser)
244{
245 ctk_recent_chooser_select_all (get_delegate (chooser));
246}
247
248static void
249delegate_unselect_all (CtkRecentChooser *chooser)
250{
251 ctk_recent_chooser_unselect_all (get_delegate (chooser));
252}
253
254static gboolean
255delegate_set_current_uri (CtkRecentChooser *chooser,
256 const gchar *uri,
257 GError **error)
258{
259 return ctk_recent_chooser_set_current_uri (get_delegate (chooser), uri, error);
260}
261
262static gchar *
263delegate_get_current_uri (CtkRecentChooser *chooser)
264{
265 return ctk_recent_chooser_get_current_uri (get_delegate (chooser));
266}
267
268static void
269delegate_notify (GObject *object,
270 GParamSpec *pspec,
271 gpointer user_data)
272{
273 gpointer iface;
274
275 iface = g_type_interface_peek (g_type_class_peek (G_OBJECT_TYPE (object)(((((GTypeClass*) (((GTypeInstance*) (object))->g_class))->
g_type)))
),
276 ctk_recent_chooser_get_type ());
277 if (g_object_interface_find_property (iface, pspec->name))
278 g_object_notify (user_data, pspec->name);
279}
280
281static void
282delegate_selection_changed (CtkRecentChooser *receiver G_GNUC_UNUSED__attribute__ ((__unused__)),
283 gpointer user_data)
284{
285 _ctk_recent_chooser_selection_changed (CTK_RECENT_CHOOSER (user_data)((((CtkRecentChooser*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((user_data)), ((ctk_recent_chooser_get_type (
)))))))
);
286}
287
288static void
289delegate_item_activated (CtkRecentChooser *receiver G_GNUC_UNUSED__attribute__ ((__unused__)),
290 gpointer user_data)
291{
292 _ctk_recent_chooser_item_activated (CTK_RECENT_CHOOSER (user_data)((((CtkRecentChooser*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((user_data)), ((ctk_recent_chooser_get_type (
)))))))
);
293}
294
295static gint
296sort_recent_items_mru (CtkRecentInfo *a,
297 CtkRecentInfo *b,
298 gpointer unused G_GNUC_UNUSED__attribute__ ((__unused__)))
299{
300 g_assert (a != NULL && b != NULL)do { if (a != ((void*)0) && b != ((void*)0)) ; else g_assertion_message_expr
("Ctk", "ctkrecentchooserutils.c", 300, ((const char*) (__func__
)), "a != NULL && b != NULL"); } while (0)
;
301
302 return g_date_time_to_unix (ctk_recent_info_get_modified (b)) - g_date_time_to_unix (ctk_recent_info_get_modified (a));
303}
304
305static gint
306sort_recent_items_lru (CtkRecentInfo *a,
307 CtkRecentInfo *b,
308 gpointer unused G_GNUC_UNUSED__attribute__ ((__unused__)))
309{
310 g_assert (a != NULL && b != NULL)do { if (a != ((void*)0) && b != ((void*)0)) ; else g_assertion_message_expr
("Ctk", "ctkrecentchooserutils.c", 310, ((const char*) (__func__
)), "a != NULL && b != NULL"); } while (0)
;
311
312 return -1 * (g_date_time_to_unix (ctk_recent_info_get_modified (b)) - g_date_time_to_unix (ctk_recent_info_get_modified (a)));
313}
314
315typedef struct
316{
317 CtkRecentSortFunc func;
318 gpointer data;
319} SortRecentData;
320
321/* our proxy sorting function */
322static gint
323sort_recent_items_proxy (gpointer *a,
324 gpointer *b,
325 gpointer user_data)
326{
327 CtkRecentInfo *info_a = (CtkRecentInfo *) a;
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption
328 CtkRecentInfo *info_b = (CtkRecentInfo *) b;
329 SortRecentData *sort_recent = user_data;
330
331 if (sort_recent->func)
332 return (* sort_recent->func) (info_a, info_b, sort_recent->data);
333
334 /* fallback */
335 return 0;
336}
337
338static gboolean
339get_is_recent_filtered (CtkRecentFilter *filter,
340 CtkRecentInfo *info)
341{
342 CtkRecentFilterInfo filter_info;
343 CtkRecentFilterFlags needed;
344 gboolean retval;
345
346 g_assert (info != NULL)do { if (info != ((void*)0)) ; else g_assertion_message_expr (
"Ctk", "ctkrecentchooserutils.c", 346, ((const char*) (__func__
)), "info != NULL"); } while (0)
;
347
348 needed = ctk_recent_filter_get_needed (filter);
349
350 filter_info.contains = CTK_RECENT_FILTER_URI | CTK_RECENT_FILTER_MIME_TYPE;
351
352 filter_info.uri = ctk_recent_info_get_uri (info);
353 filter_info.mime_type = ctk_recent_info_get_mime_type (info);
354
355 if (needed & CTK_RECENT_FILTER_DISPLAY_NAME)
356 {
357 filter_info.display_name = ctk_recent_info_get_display_name (info);
358 filter_info.contains |= CTK_RECENT_FILTER_DISPLAY_NAME;
359 }
360 else
361 filter_info.uri = NULL((void*)0);
362
363 if (needed & CTK_RECENT_FILTER_APPLICATION)
364 {
365 filter_info.applications = (const gchar **) ctk_recent_info_get_applications (info, NULL((void*)0));
366 filter_info.contains |= CTK_RECENT_FILTER_APPLICATION;
367 }
368 else
369 filter_info.applications = NULL((void*)0);
370
371 if (needed & CTK_RECENT_FILTER_GROUP)
372 {
373 filter_info.groups = (const gchar **) ctk_recent_info_get_groups (info, NULL((void*)0));
374 filter_info.contains |= CTK_RECENT_FILTER_GROUP;
375 }
376 else
377 filter_info.groups = NULL((void*)0);
378
379 if (needed & CTK_RECENT_FILTER_AGE)
380 {
381 filter_info.age = ctk_recent_info_get_age (info);
382 filter_info.contains |= CTK_RECENT_FILTER_AGE;
383 }
384 else
385 filter_info.age = -1;
386
387 retval = ctk_recent_filter_filter (filter, &filter_info);
388
389 /* these we own */
390 if (filter_info.applications)
391 g_strfreev ((gchar **) filter_info.applications);
392 if (filter_info.groups)
393 g_strfreev ((gchar **) filter_info.groups);
394
395 return !retval;
396}
397
398/*
399 * _ctk_recent_chooser_get_items:
400 * @chooser: a #CtkRecentChooser
401 * @filter: a #CtkRecentFilter
402 * @sort_func: (allow-none): sorting function, or %NULL
403 * @sort_data: (allow-none): sorting function data, or %NULL
404 *
405 * Default implementation for getting the filtered, sorted and
406 * clamped list of recently used resources from a #CtkRecentChooser.
407 * This function should be used by implementations of the
408 * #CtkRecentChooser interface inside the CtkRecentChooser::get_items
409 * vfunc.
410 *
411 * Returns: a list of #CtkRecentInfo objects
412 */
413GList *
414_ctk_recent_chooser_get_items (CtkRecentChooser *chooser,
415 CtkRecentFilter *filter,
416 CtkRecentSortFunc sort_func,
417 gpointer sort_data)
418{
419 CtkRecentManager *manager;
420 gint limit;
421 CtkRecentSortType sort_type;
422 GList *items;
423 GCompareDataFunc compare_func;
424 gint length;
425
426 g_return_val_if_fail (CTK_IS_RECENT_CHOOSER (chooser), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((chooser)); GType __t = ((ctk_recent_chooser_get_type ())
); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const
char*) (__func__)), "CTK_IS_RECENT_CHOOSER (chooser)"); return
(((void*)0)); } } while (0)
;
427
428 manager = _ctk_recent_chooser_get_recent_manager (chooser);
429 if (!manager)
430 return NULL((void*)0);
431
432 items = ctk_recent_manager_get_items (manager);
433 if (!items)
434 return NULL((void*)0);
435
436 limit = ctk_recent_chooser_get_limit (chooser);
437 if (limit == 0)
438 return NULL((void*)0);
439
440 if (filter)
441 {
442 GList *filter_items, *l;
443 gboolean local_only = FALSE(0);
444 gboolean show_private = FALSE(0);
445 gboolean show_not_found = FALSE(0);
446
447 g_object_get (G_OBJECT (chooser)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((chooser)), (((GType) ((20) << (2))))))))
,
448 "local-only", &local_only,
449 "show-private", &show_private,
450 "show-not-found", &show_not_found,
451 NULL((void*)0));
452
453 filter_items = NULL((void*)0);
454 for (l = items; l != NULL((void*)0); l = l->next)
455 {
456 CtkRecentInfo *info = l->data;
457 gboolean remove_item = FALSE(0);
458
459 if (get_is_recent_filtered (filter, info))
460 remove_item = TRUE(!(0));
461
462 if (local_only && !ctk_recent_info_is_local (info))
463 remove_item = TRUE(!(0));
464
465 if (!show_private && ctk_recent_info_get_private_hint (info))
466 remove_item = TRUE(!(0));
467
468 if (!show_not_found && !ctk_recent_info_exists (info))
469 remove_item = TRUE(!(0));
470
471 if (!remove_item)
472 filter_items = g_list_prepend (filter_items, info);
473 else
474 ctk_recent_info_unref (info);
475 }
476
477 g_list_free (items);
478 items = filter_items;
479 }
480
481 if (!items)
482 return NULL((void*)0);
483
484 sort_type = ctk_recent_chooser_get_sort_type (chooser);
485 switch (sort_type)
486 {
487 case CTK_RECENT_SORT_NONE:
488 compare_func = NULL((void*)0);
489 break;
490 case CTK_RECENT_SORT_MRU:
491 compare_func = (GCompareDataFunc) sort_recent_items_mru;
492 break;
493 case CTK_RECENT_SORT_LRU:
494 compare_func = (GCompareDataFunc) sort_recent_items_lru;
495 break;
496 case CTK_RECENT_SORT_CUSTOM:
497 compare_func = (GCompareDataFunc) sort_recent_items_proxy;
498 break;
499 default:
500 g_assert_not_reached ()do { g_assertion_message_expr ("Ctk", "ctkrecentchooserutils.c"
, 500, ((const char*) (__func__)), ((void*)0)); } while (0)
;
501 break;
502 }
503
504 if (compare_func)
505 {
506 SortRecentData sort_recent;
507
508 sort_recent.func = sort_func;
509 sort_recent.data = sort_data;
510
511 items = g_list_sort_with_data (items, compare_func, &sort_recent);
512 }
513
514 length = g_list_length (items);
515 if ((limit != -1) && (length > limit))
516 {
517 GList *clamp, *l;
518
519 clamp = g_list_nth (items, limit - 1);
520 if (!clamp)
521 return items;
522
523 l = clamp->next;
524 clamp->next = NULL((void*)0);
525
526 g_list_free_full (l, (GDestroyNotify) ctk_recent_info_unref);
527 }
528
529 return items;
530}