There are frequently patches submitted for merge which use symbols only defined by newer glib versions that the max version currently permitted by QEMU (ie glib==2.22). The glib 2.32 release introduced GLIB_VERSION_MIN_REQUIRED and GLIB_VERSION_MAX_ALLOWED macros to allow apps to declare what they want. Unfortunately QEMU has a glib-compat.h file which backports certain functions from newer glib which confuses the glib version checking macros. This is effectively preventing their use in QEMU. The version check macros also don't cover all versions back to 2.22 so any checks are incomplete.
This patch takes a different approach, by providing a script that can validate that source files are only using glib functions & macros present in the minimum declared glib version, by doing static analysis of the source and comparing to a previously defined list of permitted symbols. The list of functions/macros was extracted from the glib 2.22 HTML docs symbol index using $ grep '<dt>' /usr/share/gtk-doc/html/glib/ix01.html | \ awk {'print $1}' | \ sed -e 's/<dt>//' -e 's/,//' | \ grep -E -i '^g_' | \ sort > scripts/glib-syms.txt The script works by simply searching through the .c and .h files looking for anything that looks like a function or macro call, starting with a 'G_' or 'g_' prefix. This is not a 100% exact science, but with a few override lists it provides a practical/usable level of detection of mistakes. This patch creates a 'scripts/Makefile' file which is intended to accumulate various other style checks, similar to those done by 'checkpatch.pl', but operating against the entire source tree rather than just new patches. The check can be invoked using 'make check-style' in the top level directory. Example output when the check fails would look like: $ make check-style tests/test-io-task.c:151: 'g_thread_ref' symbol not provided in min glib version tests/test-io-task.c:172: 'g_thread_ref' symbol not provided in min glib version tests/test-io-task.c:216: 'g_thread_unref' symbol not provided in min glib version tests/test-io-task.c:217: 'g_thread_unref' symbol not provided in min glib version tests/test-io-task.c:260: 'g_thread_unref' symbol not provided in min glib version tests/test-io-task.c:261: 'g_thread_unref' symbol not provided in min glib version Signed-off-by: Daniel P. Berrange <berra...@redhat.com> --- Makefile | 1 + scripts/Makefile | 24 + scripts/glib-syms.pl | 131 +++++ scripts/glib-syms.txt | 1513 +++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 1669 insertions(+) create mode 100644 scripts/Makefile create mode 100644 scripts/glib-syms.pl create mode 100644 scripts/glib-syms.txt diff --git a/Makefile b/Makefile index af3e5f1..88a7649 100644 --- a/Makefile +++ b/Makefile @@ -165,6 +165,7 @@ dummy := $(call unnest-vars,, \ ifneq ($(wildcard config-host.mak),) include $(SRC_PATH)/tests/Makefile +include $(SRC_PATH)/scripts/Makefile endif all: $(DOCS) $(TOOLS) $(HELPERS-y) recurse-all modules diff --git a/scripts/Makefile b/scripts/Makefile new file mode 100644 index 0000000..162e7e9 --- /dev/null +++ b/scripts/Makefile @@ -0,0 +1,24 @@ +# +# This makefile runs various style checks across the entire +# source tree. +# +# This is similar in concept of checkpatch.pl, but enforces +# rules across the entire codebase, not just new patches +# + +STYLE_CHECKS = \ + cs-glib-syms + +ALL_FILES = \ + $(shell git ls-tree -r HEAD . | awk '{print $$4}') + +C_CODE_FILES = $(filter %.c %.h, $(ALL_FILES)) + +check-style: $(STYLE_CHECKS) + +# Check that we only use glib symbols present in our +# minimum declared glib version +GLIB_SYMS_LIST = scripts/glib-syms.txt + +cs-glib-syms: + @perl scripts/glib-syms.pl $(GLIB_SYMS_LIST) $(C_CODE_FILES) diff --git a/scripts/glib-syms.pl b/scripts/glib-syms.pl new file mode 100644 index 0000000..e4b50c1 --- /dev/null +++ b/scripts/glib-syms.pl @@ -0,0 +1,131 @@ +#!/usr/bin/perl +# +# Copyright (C) 2015 Red Hat Inc. +# +# This work is licensed under the terms of the GNU GPL, version 2 +# or later. See the COPYING file in the top-level directory. +# +# This parses *.c and *.h files in QEMU source tree to +# extract a list of functions used from the glib +# library and compares them to the list of symbols +# present in the minimum required glib version. + +use strict; +use warnings; + +# The file containing the list of glib symbols +# Generated by from the glib 2.22 HTML docs index +# of symbols file using +# +# $ grep '<dt>' /usr/share/gtk-doc/html/glib/ix01.html | \ +# awk {'print $1}' | \ +# sed -e 's/<dt>//' -e 's/,//' | \ +# grep -E -i '^g_' | \ +# sort > scripts/glib-syms.txt +# +# Newer versions might need different grep/awk/sed rules +my $syms = shift @ARGV; + + +# Symbols not present in the release that we depend +# on, but which have wrappers in include/glib-compat.h +my @compatsyms = qw( + g_get_monotonic_time + + g_assert_true + g_assert_false + g_assert_null + g_assert_nonnull + g_assert_cmpmem + + g_hash_table_add + + g_cond_clear + g_cond_init + g_cond_wait_until + + g_mutex_init + g_mutex_clear + + g_thread_new + + g_private_replace + G_PRIVATE_INIT + + G_TIME_SPAN_SECOND +); + + +# Functions defined inside QEMU which are using the +# the same "g_" function name prefix as glib, so +# get mis-detected as glib symbols +my @blacklist = qw( + g_to_float64 + g_assert_no_errno + g_cclosure_new_swap + g_free_rcu + g_test_trap_subprocess + g_poll_fixed + g_list_insert_sorted_merged + G_BYTE +); + +# GObject stuff used by gtk frontend +my @gobjectsums = qw( + g_object_ref + g_object_unref + g_object_set_data + g_signal_connect + G_CALLBACK +); + +# Functions defined by glib which are strangely +# missing from their docs header index +my @missingindex = qw( + g_assertion_message + g_assertion_message_expr + g_assertion_message_cmpstr + g_assertion_message_cmpnum + g_assertion_message_error +); + +my %allowedsyms; + +# Read the master list of permitted syms +open SYMS, "<", $syms or die "cannot read permitted syms $syms: $!"; +while (<SYMS>) { + chomp; + $allowedsyms{$_} = 1; +} +close SYMS; + +# And now the various hacks / fixes +foreach (@compatsyms, @missingindex, @blacklist, @gobjectsums) { + $allowedsyms{$_} = 1; +} + + +my $incomment = 0; +while (<>) { + # Kill single line comments + s,/\*.*\*/,,; + s,//.*$,,; + # Kill multi-line comments + $incomment = 1 if m,/\*,; + $incomment = 0 if m,\*/,; + next if $incomment; + + # Try to detect function calls... + if (/\b(g_[a-zA-Z0-9_]+)\b\s*\(/i) { + next if exists $allowedsyms{$1}; + # Many G_* macros defined in this file so just skip it + next if $ARGV eq "hw/timer/exynos4210_mct.c"; + # Not relevant to linked program + next if $ARGV eq "scripts/coverity-model.c"; + + print "$ARGV:$.: '$1' symbol not provided in min glib version\n"; + } +} continue { + # Hack to reset line number for each file + close ARGV if eof; # Not eof()! +} diff --git a/scripts/glib-syms.txt b/scripts/glib-syms.txt new file mode 100644 index 0000000..8420cab --- /dev/null +++ b/scripts/glib-syms.txt @@ -0,0 +1,1513 @@ +g_access +g_alloca +G_ALLOC_AND_FREE +g_allocator_free +g_allocator_new +G_ALLOC_ONLY +g_array_append_val +g_array_append_vals +g_array_free +g_array_get_element_size +g_array_index +g_array_insert_val +g_array_insert_vals +g_array_new +g_array_prepend_val +g_array_prepend_vals +g_array_ref +g_array_remove_index +g_array_remove_index_fast +g_array_remove_range +g_array_set_size +g_array_sized_new +g_array_sort +g_array_sort_with_data +g_array_unref +g_ascii_digit_value +g_ascii_dtostr +G_ASCII_DTOSTR_BUF_SIZE +g_ascii_formatd +g_ascii_isalnum +g_ascii_isalpha +g_ascii_iscntrl +g_ascii_isdigit +g_ascii_isgraph +g_ascii_islower +g_ascii_isprint +g_ascii_ispunct +g_ascii_isspace +g_ascii_isupper +g_ascii_isxdigit +g_ascii_strcasecmp +g_ascii_strdown +g_ascii_strncasecmp +g_ascii_strtod +g_ascii_strtoll +g_ascii_strtoull +g_ascii_strup +g_ascii_tolower +g_ascii_toupper +g_ascii_xdigit_value +g_assert +g_assert_cmpfloat +g_assert_cmphex +g_assert_cmpint +g_assert_cmpstr +g_assert_cmpuint +g_assert_error +g_assert_no_error +g_assert_not_reached +g_async_queue_length +g_async_queue_length_unlocked +g_async_queue_lock +g_async_queue_new +g_async_queue_new_full +g_async_queue_pop +g_async_queue_pop_unlocked +g_async_queue_push +g_async_queue_push_sorted +g_async_queue_push_sorted_unlocked +g_async_queue_push_unlocked +g_async_queue_ref +g_async_queue_ref_unlocked +g_async_queue_sort +g_async_queue_sort_unlocked +g_async_queue_timed_pop +g_async_queue_timed_pop_unlocked +g_async_queue_try_pop +g_async_queue_try_pop_unlocked +g_async_queue_unlock +g_async_queue_unref +g_async_queue_unref_and_unlock +g_atexit +g_atomic_int_add +g_atomic_int_compare_and_exchange +g_atomic_int_dec_and_test +g_atomic_int_exchange_and_add +g_atomic_int_get +g_atomic_int_inc +g_atomic_int_set +g_atomic_pointer_compare_and_exchange +g_atomic_pointer_get +g_atomic_pointer_set +g_base64_decode +g_base64_decode_inplace +g_base64_decode_step +g_base64_encode +g_base64_encode_close +g_base64_encode_step +g_basename +G_BEGIN_DECLS +G_BIG_ENDIAN +g_bit_nth_lsf +g_bit_nth_msf +g_bit_storage +g_blow_chunks +g_bookmark_file_add_application +g_bookmark_file_add_group +G_BOOKMARK_FILE_ERROR +g_bookmark_file_free +g_bookmark_file_get_added +g_bookmark_file_get_app_info +g_bookmark_file_get_applications +g_bookmark_file_get_description +g_bookmark_file_get_groups +g_bookmark_file_get_icon +g_bookmark_file_get_is_private +g_bookmark_file_get_mime_type +g_bookmark_file_get_modified +g_bookmark_file_get_size +g_bookmark_file_get_title +g_bookmark_file_get_uris +g_bookmark_file_get_visited +g_bookmark_file_has_application +g_bookmark_file_has_group +g_bookmark_file_has_item +g_bookmark_file_load_from_data +g_bookmark_file_load_from_data_dirs +g_bookmark_file_load_from_file +g_bookmark_file_move_item +g_bookmark_file_new +g_bookmark_file_remove_application +g_bookmark_file_remove_group +g_bookmark_file_remove_item +g_bookmark_file_set_added +g_bookmark_file_set_app_info +g_bookmark_file_set_description +g_bookmark_file_set_groups +g_bookmark_file_set_icon +g_bookmark_file_set_is_private +g_bookmark_file_set_mime_type +g_bookmark_file_set_modified +g_bookmark_file_set_title +g_bookmark_file_set_visited +g_bookmark_file_to_data +g_bookmark_file_to_file +G_BREAKPOINT +g_build_filename +g_build_filenamev +g_build_path +g_build_pathv +g_byte_array_append +g_byte_array_free +g_byte_array_new +g_byte_array_prepend +g_byte_array_ref +g_byte_array_remove_index +g_byte_array_remove_index_fast +g_byte_array_remove_range +g_byte_array_set_size +g_byte_array_sized_new +g_byte_array_sort +g_byte_array_sort_with_data +g_byte_array_unref +G_BYTE_ORDER +g_cache_destroy +g_cache_insert +g_cache_key_foreach +g_cache_new +g_cache_remove +g_cache_value_foreach +g_chdir +g_checksum_copy +g_checksum_free +g_checksum_get_digest +g_checksum_get_string +g_checksum_new +g_checksum_reset +g_checksum_type_get_length +g_checksum_update +g_child_watch_add +g_child_watch_add_full +g_child_watch_source_new +g_chmod +g_chunk_free +g_chunk_new +g_chunk_new0 +g_clear_error +g_completion_add_items +g_completion_clear_items +g_completion_complete +g_completion_complete_utf8 +g_completion_free +g_completion_new +g_completion_remove_items +g_completion_set_compare +g_compute_checksum_for_data +g_compute_checksum_for_string +g_cond_broadcast +g_cond_free +g_cond_new +g_cond_signal +g_cond_timed_wait +g_cond_wait +G_CONST_RETURN +g_convert +G_CONVERT_ERROR +g_convert_with_fallback +g_convert_with_iconv +g_creat +g_critical +G_CSET_a_2_z +G_CSET_A_2_Z +G_CSET_DIGITS +G_CSET_LATINC +G_CSET_LATINS +g_datalist_clear +G_DATALIST_FLAGS_MASK +g_datalist_foreach +g_datalist_get_data +g_datalist_get_flags +g_datalist_id_get_data +g_datalist_id_remove_data +g_datalist_id_remove_no_notify +g_datalist_id_set_data +g_datalist_id_set_data_full +g_datalist_init +g_datalist_remove_data +g_datalist_remove_no_notify +g_datalist_set_data +g_datalist_set_data_full +g_datalist_set_flags +g_datalist_unset_flags +g_dataset_destroy +g_dataset_foreach +g_dataset_get_data +g_dataset_id_get_data +g_dataset_id_remove_data +g_dataset_id_remove_no_notify +g_dataset_id_set_data +g_dataset_id_set_data_full +g_dataset_remove_data +g_dataset_remove_no_notify +g_dataset_set_data +g_dataset_set_data_full +g_date_add_days +g_date_add_months +g_date_add_years +G_DATE_BAD_DAY +G_DATE_BAD_JULIAN +G_DATE_BAD_YEAR +g_date_clamp +g_date_clear +g_date_compare +g_date_days_between +g_date_free +g_date_get_day +g_date_get_day_of_year +g_date_get_days_in_month +g_date_get_iso8601_week_of_year +g_date_get_julian +g_date_get_monday_week_of_year +g_date_get_monday_weeks_in_year +g_date_get_month +g_date_get_sunday_week_of_year +g_date_get_sunday_weeks_in_year +g_date_get_weekday +g_date_get_year +g_date_is_first_of_month +g_date_is_last_of_month +g_date_is_leap_year +g_date_new +g_date_new_dmy +g_date_new_julian +g_date_order +g_date_set_day +g_date_set_dmy +g_date_set_julian +g_date_set_month +g_date_set_parse +g_date_set_time +g_date_set_time_t +g_date_set_time_val +g_date_set_year +g_date_strftime +g_date_subtract_days +g_date_subtract_months +g_date_subtract_years +g_date_to_struct_tm +g_date_valid +g_date_valid_day +g_date_valid_dmy +g_date_valid_julian +g_date_valid_month +g_date_valid_weekday +g_date_valid_year +g_debug +g_dgettext +g_dir_close +g_direct_equal +g_direct_hash +g_dirname +g_dir_open +g_dir_read_name +g_dir_rewind +G_DIR_SEPARATOR +G_DIR_SEPARATOR_S +g_dngettext +g_double_equal +g_double_hash +g_dpgettext +g_dpgettext2 +G_E +G_END_DECLS +g_error +g_error_copy +g_error_free +g_error_matches +g_error_new +g_error_new_literal +g_error_new_valist +G_FILE_ERROR +g_file_error_from_errno +g_file_get_contents +g_filename_display_basename +g_filename_display_name +g_filename_from_uri +g_filename_from_utf8 +g_filename_to_uri +g_filename_to_utf8 +g_file_open_tmp +g_file_read_link +g_file_set_contents +g_file_test +g_find_program_in_path +g_fopen +g_format_size_for_display +g_fprintf +g_free +g_freopen +g_get_application_name +g_get_charset +g_get_current_dir +g_get_current_time +g_getenv +g_get_filename_charsets +g_get_home_dir +g_get_host_name +g_get_language_names +g_get_prgname +g_get_real_name +g_get_system_config_dirs +g_get_system_data_dirs +g_get_tmp_dir +g_get_user_cache_dir +g_get_user_config_dir +g_get_user_data_dir +g_get_user_name +g_get_user_special_dir +G_GINT16_FORMAT +G_GINT16_MODIFIER +G_GINT32_FORMAT +G_GINT32_MODIFIER +G_GINT64_CONSTANT +G_GINT64_FORMAT +G_GINT64_MODIFIER +G_GINTPTR_FORMAT +G_GINTPTR_MODIFIER +G_GNUC_ALLOC_SIZE +G_GNUC_ALLOC_SIZE2 +G_GNUC_CONST +G_GNUC_DEPRECATED +G_GNUC_EXTENSION +G_GNUC_FORMAT +G_GNUC_FUNCTION +G_GNUC_INTERNAL +G_GNUC_MALLOC +G_GNUC_MAY_ALIAS +G_GNUC_NO_INSTRUMENT +G_GNUC_NORETURN +G_GNUC_NULL_TERMINATED +G_GNUC_PRETTY_FUNCTION +G_GNUC_PRINTF +G_GNUC_PURE +G_GNUC_SCANF +G_GNUC_UNUSED +G_GNUC_WARN_UNUSED_RESULT +G_GOFFSET_CONSTANT +G_GOFFSET_FORMAT +G_GOFFSET_MODIFIER +G_GSIZE_FORMAT +G_GSIZE_MODIFIER +G_GSSIZE_FORMAT +G_GUINT16_FORMAT +G_GUINT32_FORMAT +G_GUINT64_CONSTANT +G_GUINT64_FORMAT +G_GUINTPTR_FORMAT +g_hash_table_destroy +g_hash_table_find +g_hash_table_foreach +g_hash_table_foreach_remove +g_hash_table_foreach_steal +g_hash_table_freeze +g_hash_table_get_keys +g_hash_table_get_values +g_hash_table_insert +g_hash_table_iter_get_hash_table +g_hash_table_iter_init +g_hash_table_iter_next +g_hash_table_iter_remove +g_hash_table_iter_steal +g_hash_table_lookup +g_hash_table_lookup_extended +g_hash_table_new +g_hash_table_new_full +g_hash_table_ref +g_hash_table_remove +g_hash_table_remove_all +g_hash_table_replace +g_hash_table_size +g_hash_table_steal +g_hash_table_steal_all +g_hash_table_thaw +g_hash_table_unref +G_HAVE_GINT64 +G_HAVE_GNUC_VISIBILITY +G_HOOK +G_HOOK_ACTIVE +g_hook_alloc +g_hook_append +g_hook_compare_ids +g_hook_destroy +g_hook_destroy_link +g_hook_find +g_hook_find_data +g_hook_find_func +g_hook_find_func_data +g_hook_first_valid +G_HOOK_FLAGS +G_HOOK_FLAG_USER_SHIFT +g_hook_free +g_hook_get +G_HOOK_IN_CALL +g_hook_insert_before +g_hook_insert_sorted +G_HOOK_IS_UNLINKED +G_HOOK_IS_VALID +g_hook_list_clear +g_hook_list_init +g_hook_list_invoke +g_hook_list_invoke_check +g_hook_list_marshal +g_hook_list_marshal_check +g_hook_next_valid +g_hook_prepend +g_hook_ref +g_hook_unref +g_hostname_is_ascii_encoded +g_hostname_is_ip_address +g_hostname_is_non_ascii +g_hostname_to_ascii +g_hostname_to_unicode +g_htonl +g_htons +g_iconv +g_iconv_close +g_iconv_open +g_idle_add +g_idle_add_full +g_idle_remove_by_data +g_idle_source_new +G_IEEE754_DOUBLE_BIAS +G_IEEE754_FLOAT_BIAS +G_INLINE_FUNC +g_int64_equal +g_int64_hash +g_int_equal +g_intern_static_string +g_intern_string +g_int_hash +g_io_add_watch +g_io_add_watch_full +g_io_channel_close +G_IO_CHANNEL_ERROR +g_io_channel_error_from_errno +g_io_channel_flush +g_io_channel_get_buffer_condition +g_io_channel_get_buffered +g_io_channel_get_buffer_size +g_io_channel_get_close_on_unref +g_io_channel_get_encoding +g_io_channel_get_flags +g_io_channel_get_line_term +g_io_channel_init +g_io_channel_new_file +g_io_channel_read +g_io_channel_read_chars +g_io_channel_read_line +g_io_channel_read_line_string +g_io_channel_read_to_end +g_io_channel_read_unichar +g_io_channel_ref +g_io_channel_seek +g_io_channel_seek_position +g_io_channel_set_buffered +g_io_channel_set_buffer_size +g_io_channel_set_close_on_unref +g_io_channel_set_encoding +g_io_channel_set_flags +g_io_channel_set_line_term +g_io_channel_shutdown +g_io_channel_unix_get_fd +g_io_channel_unix_new +g_io_channel_unref +g_io_channel_win32_new_fd +g_io_channel_win32_new_messages +g_io_channel_win32_new_socket +g_io_channel_write +g_io_channel_write_chars +g_io_channel_write_unichar +g_io_create_watch +G_IS_DIR_SEPARATOR +G_KEY_FILE_DESKTOP_GROUP +G_KEY_FILE_DESKTOP_KEY_CATEGORIES +G_KEY_FILE_DESKTOP_KEY_COMMENT +G_KEY_FILE_DESKTOP_KEY_EXEC +G_KEY_FILE_DESKTOP_KEY_GENERIC_NAME +G_KEY_FILE_DESKTOP_KEY_HIDDEN +G_KEY_FILE_DESKTOP_KEY_ICON +G_KEY_FILE_DESKTOP_KEY_MIME_TYPE +G_KEY_FILE_DESKTOP_KEY_NAME +G_KEY_FILE_DESKTOP_KEY_NO_DISPLAY +G_KEY_FILE_DESKTOP_KEY_NOT_SHOW_IN +G_KEY_FILE_DESKTOP_KEY_ONLY_SHOW_IN +G_KEY_FILE_DESKTOP_KEY_PATH +G_KEY_FILE_DESKTOP_KEY_STARTUP_NOTIFY +G_KEY_FILE_DESKTOP_KEY_STARTUP_WM_CLASS +G_KEY_FILE_DESKTOP_KEY_TERMINAL +G_KEY_FILE_DESKTOP_KEY_TRY_EXEC +G_KEY_FILE_DESKTOP_KEY_TYPE +G_KEY_FILE_DESKTOP_KEY_URL +G_KEY_FILE_DESKTOP_KEY_VERSION +G_KEY_FILE_DESKTOP_TYPE_APPLICATION +G_KEY_FILE_DESKTOP_TYPE_DIRECTORY +G_KEY_FILE_DESKTOP_TYPE_LINK +G_KEY_FILE_ERROR +g_key_file_free +g_key_file_get_boolean +g_key_file_get_boolean_list +g_key_file_get_comment +g_key_file_get_double +g_key_file_get_double_list +g_key_file_get_groups +g_key_file_get_integer +g_key_file_get_integer_list +g_key_file_get_keys +g_key_file_get_locale_string +g_key_file_get_locale_string_list +g_key_file_get_start_group +g_key_file_get_string +g_key_file_get_string_list +g_key_file_get_value +g_key_file_has_group +g_key_file_has_key +g_key_file_load_from_data +g_key_file_load_from_data_dirs +g_key_file_load_from_dirs +g_key_file_load_from_file +g_key_file_new +g_key_file_remove_comment +g_key_file_remove_group +g_key_file_remove_key +g_key_file_set_boolean +g_key_file_set_boolean_list +g_key_file_set_comment +g_key_file_set_double +g_key_file_set_double_list +g_key_file_set_integer +g_key_file_set_integer_list +g_key_file_set_list_separator +g_key_file_set_locale_string +g_key_file_set_locale_string_list +g_key_file_set_string +g_key_file_set_string_list +g_key_file_set_value +g_key_file_to_data +G_LIKELY +g_list_alloc +g_list_append +g_list_concat +g_list_copy +g_list_delete_link +g_listenv +g_list_find +g_list_find_custom +g_list_first +g_list_foreach +g_list_free +g_list_free1 +g_list_free_1 +g_list_index +g_list_insert +g_list_insert_before +g_list_insert_sorted +g_list_insert_sorted_with_data +g_list_last +g_list_length +g_list_next +g_list_nth +g_list_nth_data +g_list_nth_prev +g_list_pop_allocator +g_list_position +g_list_prepend +g_list_previous +g_list_push_allocator +g_list_remove +g_list_remove_all +g_list_remove_link +g_list_reverse +g_list_sort +g_list_sort_with_data +G_LITTLE_ENDIAN +G_LN10 +G_LN2 +g_locale_from_utf8 +g_locale_to_utf8 +G_LOCK +G_LOCK_DEFINE +G_LOCK_DEFINE_STATIC +G_LOCK_EXTERN +g_log +G_LOG_2_BASE_10 +g_log_default_handler +G_LOG_DOMAIN +G_LOG_FATAL_MASK +G_LOG_LEVEL_USER_SHIFT +g_log_remove_handler +g_log_set_always_fatal +g_log_set_default_handler +g_log_set_fatal_mask +g_log_set_handler +g_logv +g_lstat +g_main_context_acquire +g_main_context_add_poll +g_main_context_check +g_main_context_default +g_main_context_dispatch +g_main_context_find_source_by_funcs_user_data +g_main_context_find_source_by_id +g_main_context_find_source_by_user_data +g_main_context_get_poll_func +g_main_context_get_thread_default +g_main_context_is_owner +g_main_context_iteration +g_main_context_new +g_main_context_pending +g_main_context_pop_thread_default +g_main_context_prepare +g_main_context_push_thread_default +g_main_context_query +g_main_context_ref +g_main_context_release +g_main_context_remove_poll +g_main_context_set_poll_func +g_main_context_unref +g_main_context_wait +g_main_context_wakeup +g_main_current_source +g_main_depth +g_main_destroy +g_main_is_running +g_main_iteration +g_main_loop_get_context +g_main_loop_is_running +g_main_loop_new +g_main_loop_quit +g_main_loop_ref +g_main_loop_run +g_main_loop_unref +g_main_new +g_main_pending +g_main_quit +g_main_run +g_main_set_poll_func +g_malloc +g_malloc0 +g_mapped_file_free +g_mapped_file_get_contents +g_mapped_file_get_length +g_mapped_file_new +g_mapped_file_ref +g_mapped_file_unref +g_markup_collect_attributes +G_MARKUP_ERROR +g_markup_escape_text +g_markup_parse_context_end_parse +g_markup_parse_context_free +g_markup_parse_context_get_element +g_markup_parse_context_get_element_stack +g_markup_parse_context_get_position +g_markup_parse_context_get_user_data +g_markup_parse_context_new +g_markup_parse_context_parse +g_markup_parse_context_pop +g_markup_parse_context_push +g_markup_printf_escaped +g_markup_vprintf_escaped +g_match_info_expand_references +g_match_info_fetch +g_match_info_fetch_all +g_match_info_fetch_named +g_match_info_fetch_named_pos +g_match_info_fetch_pos +g_match_info_free +g_match_info_get_match_count +g_match_info_get_regex +g_match_info_get_string +g_match_info_is_partial_match +g_match_info_matches +g_match_info_next +G_MAXDOUBLE +G_MAXFLOAT +G_MAXINT +G_MAXINT16 +G_MAXINT32 +G_MAXINT64 +G_MAXINT8 +G_MAXLONG +G_MAXOFFSET +G_MAXSHORT +G_MAXSIZE +G_MAXSSIZE +G_MAXUINT +G_MAXUINT16 +G_MAXUINT32 +G_MAXUINT64 +G_MAXUINT8 +G_MAXULONG +G_MAXUSHORT +G_MEM_ALIGN +g_mem_chunk_alloc +g_mem_chunk_alloc0 +g_mem_chunk_clean +g_mem_chunk_create +g_mem_chunk_destroy +g_mem_chunk_free +g_mem_chunk_info +g_mem_chunk_new +g_mem_chunk_print +g_mem_chunk_reset +g_memdup +g_mem_gc_friendly +g_mem_is_system_malloc +g_memmove +g_mem_profile +g_mem_set_vtable +g_message +G_MINDOUBLE +G_MINFLOAT +G_MININT +G_MININT16 +G_MININT32 +G_MININT64 +G_MININT8 +G_MINLONG +G_MINOFFSET +G_MINSHORT +G_MINSSIZE +g_mkdir +g_mkdir_with_parents +g_mkstemp +g_mkstemp_full +g_module_build_path +g_module_check_init +g_module_close +g_module_error +G_MODULE_EXPORT +G_MODULE_IMPORT +g_module_make_resident +g_module_name +g_module_open +G_MODULE_SUFFIX +g_module_supported +g_module_symbol +g_module_unload +g_mutex_free +g_mutex_lock +g_mutex_new +g_mutex_trylock +g_mutex_unlock +G_N_ELEMENTS +g_new +g_new0 +g_newa +g_node_append +g_node_append_data +g_node_child_index +g_node_child_position +g_node_children_foreach +g_node_copy +g_node_copy_deep +g_node_depth +g_node_destroy +g_node_find +g_node_find_child +g_node_first_child +g_node_first_sibling +g_node_get_root +g_node_insert +g_node_insert_after +g_node_insert_before +g_node_insert_data +g_node_insert_data_before +g_node_is_ancestor +G_NODE_IS_LEAF +G_NODE_IS_ROOT +g_node_last_child +g_node_last_sibling +g_node_max_height +g_node_n_children +g_node_new +g_node_next_sibling +g_node_n_nodes +g_node_nth_child +g_node_pop_allocator +g_node_prepend +g_node_prepend_data +g_node_prev_sibling +g_node_push_allocator +g_node_reverse_children +g_node_traverse +g_node_unlink +g_ntohl +g_ntohs +g_nullify_pointer +g_once +G_ONCE_INIT +g_once_init_enter +g_once_init_leave +g_on_error_query +g_on_error_stack_trace +g_open +g_option_context_add_group +g_option_context_add_main_entries +g_option_context_free +g_option_context_get_description +g_option_context_get_help +g_option_context_get_help_enabled +g_option_context_get_ignore_unknown_options +g_option_context_get_main_group +g_option_context_get_summary +g_option_context_new +g_option_context_parse +g_option_context_set_description +g_option_context_set_help_enabled +g_option_context_set_ignore_unknown_options +g_option_context_set_main_group +g_option_context_set_summary +g_option_context_set_translate_func +g_option_context_set_translation_domain +G_OPTION_ERROR +g_option_group_add_entries +g_option_group_free +g_option_group_new +g_option_group_set_error_hook +g_option_group_set_parse_hooks +g_option_group_set_translate_func +g_option_group_set_translation_domain +G_OPTION_REMAINING +G_OS_BEOS +G_OS_UNIX +G_OS_WIN32 +g_parse_debug_string +G_PASTE +G_PASTE_ARGS +g_path_get_basename +g_path_get_dirname +g_path_is_absolute +g_path_skip_root +g_pattern_match +g_pattern_match_simple +g_pattern_match_string +g_pattern_spec_equal +g_pattern_spec_free +g_pattern_spec_new +G_PDP_ENDIAN +G_PI +G_PI_2 +G_PI_4 +g_poll +G_POLLFD_FORMAT +g_prefix_error +g_print +g_printerr +g_printf +g_printf_string_upper_bound +G_PRIORITY_DEFAULT +G_PRIORITY_DEFAULT_IDLE +G_PRIORITY_HIGH +G_PRIORITY_HIGH_IDLE +G_PRIORITY_LOW +g_private_get +g_private_new +g_private_set +g_propagate_error +g_propagate_prefixed_error +g_ptr_array_add +g_ptr_array_foreach +g_ptr_array_free +g_ptr_array_index +g_ptr_array_new +g_ptr_array_new_with_free_func +g_ptr_array_ref +g_ptr_array_remove +g_ptr_array_remove_fast +g_ptr_array_remove_index +g_ptr_array_remove_index_fast +g_ptr_array_remove_range +g_ptr_array_set_free_func +g_ptr_array_set_size +g_ptr_array_sized_new +g_ptr_array_sort +g_ptr_array_sort_with_data +g_ptr_array_unref +g_qsort_with_data +g_quark_from_static_string +g_quark_from_string +g_quark_to_string +g_quark_try_string +g_queue_clear +g_queue_copy +g_queue_delete_link +g_queue_find +g_queue_find_custom +g_queue_foreach +g_queue_free +g_queue_get_length +g_queue_index +g_queue_init +G_QUEUE_INIT +g_queue_insert_after +g_queue_insert_before +g_queue_insert_sorted +g_queue_is_empty +g_queue_link_index +g_queue_new +g_queue_peek_head +g_queue_peek_head_link +g_queue_peek_nth +g_queue_peek_nth_link +g_queue_peek_tail +g_queue_peek_tail_link +g_queue_pop_head +g_queue_pop_head_link +g_queue_pop_nth +g_queue_pop_nth_link +g_queue_pop_tail +g_queue_pop_tail_link +g_queue_push_head +g_queue_push_head_link +g_queue_push_nth +g_queue_push_nth_link +g_queue_push_tail +g_queue_push_tail_link +g_queue_remove +g_queue_remove_all +g_queue_reverse +g_queue_sort +g_queue_unlink +g_rand_boolean +g_rand_copy +g_rand_double +g_rand_double_range +g_rand_free +g_rand_int +g_rand_int_range +g_rand_new +g_rand_new_with_seed +g_rand_new_with_seed_array +g_random_boolean +g_random_double +g_random_double_range +g_random_int +g_random_int_range +g_random_set_seed +g_rand_set_seed +g_rand_set_seed_array +g_realloc +g_regex_check_replacement +G_REGEX_ERROR +g_regex_escape_string +g_regex_get_capture_count +g_regex_get_max_backref +g_regex_get_pattern +g_regex_get_string_number +g_regex_match +g_regex_match_all +g_regex_match_all_full +g_regex_match_full +g_regex_match_simple +g_regex_new +g_regex_ref +g_regex_replace +g_regex_replace_eval +g_regex_replace_literal +g_regex_split +g_regex_split_full +g_regex_split_simple +g_regex_unref +g_relation_count +g_relation_delete +g_relation_destroy +g_relation_exists +g_relation_index +g_relation_insert +g_relation_new +g_relation_print +g_relation_select +g_reload_user_special_dirs_cache +g_remove +g_rename +g_renew +g_return_if_fail +g_return_if_reached +g_return_val_if_fail +g_return_val_if_reached +g_rmdir +g_scanner_add_symbol +g_scanner_cur_line +g_scanner_cur_position +g_scanner_cur_token +g_scanner_cur_value +g_scanner_destroy +g_scanner_eof +g_scanner_error +g_scanner_foreach_symbol +g_scanner_freeze_symbol_table +g_scanner_get_next_token +g_scanner_input_file +g_scanner_input_text +g_scanner_lookup_symbol +g_scanner_new +g_scanner_peek_next_token +g_scanner_remove_symbol +g_scanner_scope_add_symbol +g_scanner_scope_foreach_symbol +g_scanner_scope_lookup_symbol +g_scanner_scope_remove_symbol +g_scanner_set_scope +g_scanner_sync_file_offset +g_scanner_thaw_symbol_table +g_scanner_unexp_token +g_scanner_warn +G_SEARCHPATH_SEPARATOR +G_SEARCHPATH_SEPARATOR_S +g_sequence_append +g_sequence_foreach +g_sequence_foreach_range +g_sequence_free +g_sequence_get +g_sequence_get_begin_iter +g_sequence_get_end_iter +g_sequence_get_iter_at_pos +g_sequence_get_length +g_sequence_insert_before +g_sequence_insert_sorted +g_sequence_insert_sorted_iter +g_sequence_iter_compare +g_sequence_iter_get_position +g_sequence_iter_get_sequence +g_sequence_iter_is_begin +g_sequence_iter_is_end +g_sequence_iter_move +g_sequence_iter_next +g_sequence_iter_prev +g_sequence_move +g_sequence_move_range +g_sequence_new +g_sequence_prepend +g_sequence_range_get_midpoint +g_sequence_remove +g_sequence_remove_range +g_sequence_search +g_sequence_search_iter +g_sequence_set +g_sequence_sort +g_sequence_sort_changed +g_sequence_sort_changed_iter +g_sequence_sort_iter +g_sequence_swap +g_set_application_name +g_setenv +g_set_error +g_set_error_literal +g_set_prgname +g_set_printerr_handler +g_set_print_handler +G_SHELL_ERROR +g_shell_parse_argv +g_shell_quote +g_shell_unquote +g_slice_alloc +g_slice_alloc0 +g_slice_copy +g_slice_dup +g_slice_free +g_slice_free1 +g_slice_free_chain +g_slice_free_chain_with_offset +g_slice_new +g_slice_new0 +g_slist_alloc +g_slist_append +g_slist_concat +g_slist_copy +g_slist_delete_link +g_slist_find +g_slist_find_custom +g_slist_foreach +g_slist_free +g_slist_free1 +g_slist_free_1 +g_slist_index +g_slist_insert +g_slist_insert_before +g_slist_insert_sorted +g_slist_insert_sorted_with_data +g_slist_last +g_slist_length +g_slist_next +g_slist_nth +g_slist_nth_data +g_slist_pop_allocator +g_slist_position +g_slist_prepend +g_slist_push_allocator +g_slist_remove +g_slist_remove_all +g_slist_remove_link +g_slist_reverse +g_slist_sort +g_slist_sort_with_data +g_snprintf +g_source_add_poll +g_source_attach +g_source_destroy +g_source_get_can_recurse +g_source_get_context +g_source_get_current_time +g_source_get_id +g_source_get_priority +g_source_is_destroyed +g_source_new +g_source_ref +g_source_remove +g_source_remove_by_funcs_user_data +g_source_remove_by_user_data +g_source_remove_poll +g_source_set_callback +g_source_set_callback_indirect +g_source_set_can_recurse +g_source_set_funcs +g_source_set_priority +g_source_unref +g_spaced_primes_closest +g_spawn_async +g_spawn_async_with_pipes +g_spawn_close_pid +g_spawn_command_line_async +g_spawn_command_line_sync +G_SPAWN_ERROR +g_spawn_sync +g_sprintf +G_SQRT2 +g_stat +G_STATIC_ASSERT +g_static_mutex_free +g_static_mutex_get_mutex +g_static_mutex_init +G_STATIC_MUTEX_INIT +g_static_mutex_lock +g_static_mutex_trylock +g_static_mutex_unlock +g_static_private_free +g_static_private_get +g_static_private_init +G_STATIC_PRIVATE_INIT +g_static_private_set +g_static_rec_mutex_free +g_static_rec_mutex_init +G_STATIC_REC_MUTEX_INIT +g_static_rec_mutex_lock +g_static_rec_mutex_lock_full +g_static_rec_mutex_trylock +g_static_rec_mutex_unlock +g_static_rec_mutex_unlock_full +g_static_rw_lock_free +g_static_rw_lock_init +G_STATIC_RW_LOCK_INIT +g_static_rw_lock_reader_lock +g_static_rw_lock_reader_trylock +g_static_rw_lock_reader_unlock +g_static_rw_lock_writer_lock +g_static_rw_lock_writer_trylock +g_static_rw_lock_writer_unlock +G_STMT_END +G_STMT_START +g_stpcpy +g_strcanon +g_strcasecmp +g_strchomp +g_strchug +g_strcmp0 +g_strcompress +g_strconcat +g_strdelimit +G_STR_DELIMITERS +g_strdown +g_strdup +g_strdup_printf +g_strdupv +g_strdup_vprintf +g_str_equal +g_strerror +g_strescape +g_strfreev +G_STRFUNC +g_str_hash +g_str_has_prefix +g_str_has_suffix +g_string_append +g_string_append_c +g_string_append_len +g_string_append_printf +g_string_append_unichar +g_string_append_uri_escaped +g_string_append_vprintf +g_string_ascii_down +g_string_ascii_up +g_string_assign +g_string_chunk_clear +g_string_chunk_free +g_string_chunk_insert +g_string_chunk_insert_const +g_string_chunk_insert_len +g_string_chunk_new +g_string_down +g_string_equal +g_string_erase +g_string_free +g_string_hash +G_STRINGIFY +g_string_insert +g_string_insert_c +g_string_insert_len +g_string_insert_unichar +g_string_new +g_string_new_len +g_string_overwrite +g_string_overwrite_len +g_string_prepend +g_string_prepend_c +g_string_prepend_len +g_string_prepend_unichar +g_string_printf +g_string_set_size +g_string_sized_new +g_string_sprintf +g_string_sprintfa +g_string_truncate +g_string_up +g_string_vprintf +g_strip_context +g_strjoin +g_strjoinv +g_strlcat +g_strlcpy +G_STRLOC +g_strncasecmp +g_strndup +g_strnfill +g_strreverse +g_strrstr +g_strrstr_len +g_strsignal +g_strsplit +g_strsplit_set +g_strstrip +g_strstr_len +g_strtod +G_STRUCT_MEMBER +G_STRUCT_MEMBER_P +G_STRUCT_OFFSET +g_strup +g_strv_length +g_test_add +g_test_add_data_func +g_test_add_func +g_test_bug +g_test_bug_base +g_test_create_case +g_test_create_suite +g_test_get_root +g_test_init +g_test_log_set_fatal_handler +g_test_maximized_result +g_test_message +g_test_minimized_result +g_test_perf +g_test_queue_destroy +g_test_queue_free +g_test_queue_unref +g_test_quick +g_test_quiet +g_test_rand_bit +g_test_rand_double +g_test_rand_double_range +g_test_rand_int +g_test_rand_int_range +g_test_run +g_test_run_suite +g_test_slow +g_test_suite_add +g_test_suite_add_suite +g_test_thorough +g_test_timer_elapsed +g_test_timer_last +g_test_timer_start +g_test_trap_assert_failed +g_test_trap_assert_passed +g_test_trap_assert_stderr +g_test_trap_assert_stderr_unmatched +g_test_trap_assert_stdout +g_test_trap_assert_stdout_unmatched +g_test_trap_fork +g_test_trap_has_passed +g_test_trap_reached_timeout +g_test_verbose +g_thread_create +g_thread_create_full +G_THREAD_ERROR +g_thread_exit +g_thread_foreach +g_thread_get_initialized +g_thread_init +g_thread_join +g_thread_pool_free +g_thread_pool_get_max_idle_time +g_thread_pool_get_max_threads +g_thread_pool_get_max_unused_threads +g_thread_pool_get_num_threads +g_thread_pool_get_num_unused_threads +g_thread_pool_new +g_thread_pool_push +g_thread_pool_set_max_idle_time +g_thread_pool_set_max_threads +g_thread_pool_set_max_unused_threads +g_thread_pool_set_sort_function +g_thread_pool_stop_unused_threads +g_thread_pool_unprocessed +g_thread_self +G_THREADS_ENABLED +g_thread_set_priority +G_THREADS_IMPL_NONE +G_THREADS_IMPL_POSIX +g_thread_supported +g_thread_yield +g_timeout_add +g_timeout_add_full +g_timeout_add_seconds +g_timeout_add_seconds_full +g_timeout_source_new +g_timeout_source_new_seconds +g_timer_continue +g_timer_destroy +g_timer_elapsed +g_timer_new +g_timer_reset +g_timer_start +g_timer_stop +g_time_val_add +g_time_val_from_iso8601 +g_time_val_to_iso8601 +g_trap_free_size +g_trap_malloc_size +g_trap_realloc_size +g_trash_stack_height +g_trash_stack_peek +g_trash_stack_pop +g_trash_stack_push +g_tree_destroy +g_tree_foreach +g_tree_height +g_tree_insert +g_tree_lookup +g_tree_lookup_extended +g_tree_new +g_tree_new_full +g_tree_new_with_data +g_tree_nnodes +g_tree_ref +g_tree_remove +g_tree_replace +g_tree_search +g_tree_steal +g_tree_traverse +g_tree_unref +G_TRYLOCK +g_try_malloc +g_try_malloc0 +g_try_new +g_try_new0 +g_try_realloc +g_try_renew +g_tuples_destroy +g_tuples_index +g_ucs4_to_utf16 +g_ucs4_to_utf8 +g_unichar_break_type +g_unichar_combining_class +g_unichar_digit_value +g_unichar_get_mirror_char +g_unichar_get_script +g_unichar_isalnum +g_unichar_isalpha +g_unichar_iscntrl +g_unichar_isdefined +g_unichar_isdigit +g_unichar_isgraph +g_unichar_islower +g_unichar_ismark +g_unichar_isprint +g_unichar_ispunct +g_unichar_isspace +g_unichar_istitle +g_unichar_isupper +g_unichar_iswide +g_unichar_iswide_cjk +g_unichar_isxdigit +g_unichar_iszerowidth +g_unichar_tolower +g_unichar_totitle +g_unichar_toupper +g_unichar_to_utf8 +g_unichar_type +g_unichar_validate +g_unichar_xdigit_value +g_unicode_canonical_decomposition +g_unicode_canonical_ordering +G_UNLIKELY +g_unlink +G_UNLOCK +g_unsetenv +g_uri_escape_string +g_uri_list_extract_uris +g_uri_parse_scheme +G_URI_RESERVED_CHARS_ALLOWED_IN_PATH +G_URI_RESERVED_CHARS_ALLOWED_IN_PATH_ELEMENT +G_URI_RESERVED_CHARS_ALLOWED_IN_USERINFO +G_URI_RESERVED_CHARS_GENERIC_DELIMITERS +G_URI_RESERVED_CHARS_SUBCOMPONENT_DELIMITERS +g_uri_unescape_segment +g_uri_unescape_string +G_USEC_PER_SEC +g_usleep +g_utf16_to_ucs4 +g_utf16_to_utf8 +g_utf8_casefold +g_utf8_collate +g_utf8_collate_key +g_utf8_collate_key_for_filename +g_utf8_find_next_char +g_utf8_find_prev_char +g_utf8_get_char +g_utf8_get_char_validated +g_utf8_next_char +g_utf8_normalize +g_utf8_offset_to_pointer +g_utf8_pointer_to_offset +g_utf8_prev_char +g_utf8_strchr +g_utf8_strdown +g_utf8_strlen +g_utf8_strncpy +g_utf8_strrchr +g_utf8_strreverse +g_utf8_strup +g_utf8_to_ucs4 +g_utf8_to_ucs4_fast +g_utf8_to_utf16 +g_utf8_validate +g_utime +G_VA_COPY +g_vasprintf +g_vfprintf +g_vprintf +g_vsnprintf +g_vsprintf +g_warn_if_fail +g_warn_if_reached +g_warning +G_WIN32_DLLMAIN_FOR_DLL_NAME +g_win32_error_message +g_win32_getlocale +g_win32_get_package_installation_directory +g_win32_get_package_installation_directory_of_module +g_win32_get_package_installation_subdirectory +g_win32_get_windows_version +G_WIN32_HAVE_WIDECHAR_API +G_WIN32_IS_NT_BASED +g_win32_locale_filename_from_utf8 -- 2.5.0