checkAPIs.pl: check value_string termination
[metze/wireshark/wip.git] / tools / checkAPIs.pl
1 #!/usr/bin/env perl
2
3 #
4 # Copyright 2006, Jeff Morriss <jeff.morriss.ws[AT]gmail.com>
5 #
6 # A simple tool to check source code for function calls that should not
7 # be called by Wireshark code and to perform certain other checks.
8 #
9 # Usage:
10 # checkAPIs.pl [-M] [-g group1] [-g group2] ...
11 #              [-s summary-group1] [-s summary-group2] ...
12 #              [--nocheck-value-string-array]
13 #              [--nocheck-addtext] [--nocheck-hf] [--debug] file1 file2 ...
14 #
15 # Wireshark - Network traffic analyzer
16 # By Gerald Combs <gerald@wireshark.org>
17 # Copyright 1998 Gerald Combs
18 #
19 # This program is free software; you can redistribute it and/or
20 # modify it under the terms of the GNU General Public License
21 # as published by the Free Software Foundation; either version 2
22 # of the License, or (at your option) any later version.
23 #
24 # This program is distributed in the hope that it will be useful,
25 # but WITHOUT ANY WARRANTY; without even the implied warranty of
26 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
27 # GNU General Public License for more details.
28 #
29 # You should have received a copy of the GNU General Public License
30 # along with this program; if not, write to the Free Software
31 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
32 #
33
34 use strict;
35 use Getopt::Long;
36
37 my %APIs = (
38         # API groups.
39         # Group name, e.g. 'prohibited'
40         # '<name>' => {
41         #   'count_errors'      => 1,                     # 1 if these are errors, 0 if warnings
42         #   'functions'         => [ 'f1', 'f2', ...],    # Function array
43         #   'function-counts'   => {'f1',0, 'f2',0, ...}, # Function Counts hash (initialized in the code)
44         # }
45         #
46         # APIs that MUST NOT be used in Wireshark
47         'prohibited' => { 'count_errors' => 1, 'functions' => [
48                 # Memory-unsafe APIs
49                 # Use something that won't overwrite the end of your buffer instead
50                 # of these.
51                 #
52                 # Microsoft provides lists of unsafe functions and their
53                 # recommended replacements in "Security Development Lifecycle
54                 # (SDL) Banned Function Calls"
55                 # https://msdn.microsoft.com/en-us/library/bb288454.aspx
56                 # and "Deprecated CRT Functions"
57                 # https://msdn.microsoft.com/en-us/library/ms235384.aspx
58                 #
59                 'atoi', # use wsutil/strtoi.h functions
60                 'gets',
61                 'sprintf',
62                 'g_sprintf',
63                 'vsprintf',
64                 'g_vsprintf',
65                 'strcpy',
66                 'strncpy',
67                 'strcat',
68                 'strncat',
69                 'cftime',
70                 'ascftime',
71                 ### non-portable APIs
72                 # use glib (g_*) versions instead of these:
73                 'ntohl',
74                 'ntohs',
75                 'htonl',
76                 'htons',
77                 'strdup',
78                 'strndup',
79                 # Windows doesn't have this; use g_ascii_strtoull() instead
80                 'strtoull',
81                 ### non-portable: fails on Windows Wireshark built with VC newer than VC6
82                 # See https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=6695#c2
83                 'g_fprintf',
84                 'g_vfprintf',
85                 ### non-ANSI C
86                 # use memset, memcpy, memcmp instead of these:
87                 'bzero',
88                 'bcopy',
89                 'bcmp',
90                 # The MSDN page for ZeroMemory recommends SecureZeroMemory
91                 # instead.
92                 'ZeroMemory',
93                 # use wmem_*, ep_*, or g_* functions instead of these:
94                 # (One thing to be aware of is that space allocated with malloc()
95                 # may not be freeable--at least on Windows--with g_free() and
96                 # vice-versa.)
97                 'malloc',
98                 'calloc',
99                 'realloc',
100                 'valloc',
101                 'free',
102                 'cfree',
103                 # Locale-unsafe APIs
104                 # These may have unexpected behaviors in some locales (e.g.,
105                 # "I" isn't always the upper-case form of "i", and "i" isn't
106                 # always the lower-case form of "I").  Use the g_ascii_* version
107                 # instead.
108                 'isalnum',
109                 'isascii',
110                 'isalpha',
111                 'iscntrl',
112                 'isdigit',
113                 'islower',
114                 'isgraph',
115                 'isprint',
116                 'ispunct',
117                 'isspace',
118                 'isupper',
119                 'isxdigit',
120                 'tolower',
121                 'atof',
122                 'strtod',
123                 'strcasecmp',
124                 'strncasecmp',
125                 'g_strcasecmp',
126                 'g_strncasecmp',
127                 'g_strup',
128                 'g_strdown',
129                 'g_string_up',
130                 'g_string_down',
131                 'strerror',     # use g_strerror
132                 # Use the ws_* version of these:
133                 # (Necessary because on Windows we use UTF8 for throughout the code
134                 # so we must tweak that to UTF16 before operating on the file.  Code
135                 # using these functions will work unless the file/path name contains
136                 # non-ASCII chars.)
137                 'open',
138                 'rename',
139                 'mkdir',
140                 'stat',
141                 'unlink',
142                 'remove',
143                 'fopen',
144                 'freopen',
145                 'fstat',
146                 'lseek',
147                 # Misc
148                 'tmpnam',       # use mkstemp
149                 '_snwprintf'    # use StringCchPrintf
150                 ] },
151
152         ### Soft-Deprecated functions that should not be used in new code but
153         # have not been entirely removed from old code. These will become errors
154         # once they've been removed from all existing code.
155         'soft-deprecated' => { 'count_errors' => 0, 'functions' => [
156                 'tvb_length_remaining', # replaced with tvb_captured_length_remaining
157
158                 # Locale-unsafe APIs
159                 # These may have unexpected behaviors in some locales (e.g.,
160                 # "I" isn't always the upper-case form of "i", and "i" isn't
161                 # always the lower-case form of "I").  Use the g_ascii_* version
162                 # instead.
163                 'toupper'
164             ] },
165
166         # APIs that SHOULD NOT be used in Wireshark (any more)
167         'deprecated' => { 'count_errors' => 1, 'functions' => [
168                 'perror',                                       # Use g_strerror() and report messages in whatever
169                                                                 #  fashion is appropriate for the code in question.
170                 'ctime',                                        # Use abs_time_secs_to_str()
171                 'next_tvb_add_port',                            # Use next_tvb_add_uint() (and a matching change
172                                                                 #  of NTVB_PORT -> NTVB_UINT)
173
174                 ### Deprecated GLib/GObject functions/macros
175                 # (The list is based upon the GLib 2.30.2 & GObject 2.30.2 documentation;
176                 #  An entry may be commented out if it is currently
177                 #  being used in Wireshark and if the replacement functionality
178                 #  is not available in all the GLib versions that Wireshark
179                 #  currently supports.
180                 # Note: Wireshark currently (Jan 2012) requires GLib 2.14 or newer.
181                 #  The Wireshark build currently (Jan 2012) defines G_DISABLE_DEPRECATED
182                 #  so use of any of the following should cause the Wireshark build to fail and
183                 #  therefore the tests for obsolete GLib function usage in checkAPIs should not be needed.
184                 'G_ALLOC_AND_FREE',
185                 'G_ALLOC_ONLY',
186                 'g_allocator_free',                             # "use slice allocator" (avail since 2.10,2.14)
187                 'g_allocator_new',                              # "use slice allocator" (avail since 2.10,2.14)
188                 'g_async_queue_ref_unlocked',                   # g_async_queue_ref()   (OK since 2.8)
189                 'g_async_queue_unref_and_unlock',               # g_async_queue_unref() (OK since 2.8)
190                 'g_atomic_int_exchange_and_add',                # since 2.30
191                 'g_basename',
192                 'g_blow_chunks',                                # "use slice allocator" (avail since 2.10,2.14)
193                 'g_cache_value_foreach',                        # g_cache_key_foreach()
194                 'g_chunk_free',                                 # g_slice_free (avail since 2.10)
195                 'g_chunk_new',                                  # g_slice_new  (avail since 2.10)
196                 'g_chunk_new0',                                 # g_slice_new0 (avail since 2.10)
197                 'g_completion_add_items',                       # since 2.26
198                 'g_completion_clear_items',                     # since 2.26
199                 'g_completion_complete',                        # since 2.26
200                 'g_completion_complete_utf8',                   # since 2.26
201                 'g_completion_free',                            # since 2.26
202                 'g_completion_new',                             # since 2.26
203                 'g_completion_remove_items',                    # since 2.26
204                 'g_completion_set_compare',                     # since 2.26
205                 'G_CONST_RETURN',                               # since 2.26
206                 'g_date_set_time',                              # g_date_set_time_t (avail since 2.10)
207                 'g_dirname',
208                 'g_format_size_for_display',                    # since 2.30: use g_format_size()
209                 'G_GNUC_FUNCTION',
210                 'G_GNUC_PRETTY_FUNCTION',
211                 'g_hash_table_freeze',
212                 'g_hash_table_thaw',
213                 'G_HAVE_GINT64',
214                 'g_io_channel_close',
215                 'g_io_channel_read',
216                 'g_io_channel_seek',
217                 'g_io_channel_write',
218                 'g_list_pop_allocator',                         # "does nothing since 2.10"
219                 'g_list_push_allocator',                        # "does nothing since 2.10"
220                 'g_main_destroy',
221                 'g_main_is_running',
222                 'g_main_iteration',
223                 'g_main_new',
224                 'g_main_pending',
225                 'g_main_quit',
226                 'g_main_run',
227                 'g_main_set_poll_func',
228                 'g_mapped_file_free',                           # [as of 2.22: use g_map_file_unref]
229                 'g_mem_chunk_alloc',                            # "use slice allocator" (avail since 2.10)
230                 'g_mem_chunk_alloc0',                           # "use slice allocator" (avail since 2.10)
231                 'g_mem_chunk_clean',                            # "use slice allocator" (avail since 2.10)
232                 'g_mem_chunk_create',                           # "use slice allocator" (avail since 2.10)
233                 'g_mem_chunk_destroy',                          # "use slice allocator" (avail since 2.10)
234                 'g_mem_chunk_free',                             # "use slice allocator" (avail since 2.10)
235                 'g_mem_chunk_info',                             # "use slice allocator" (avail since 2.10)
236                 'g_mem_chunk_new',                              # "use slice allocator" (avail since 2.10)
237                 'g_mem_chunk_print',                            # "use slice allocator" (avail since 2.10)
238                 'g_mem_chunk_reset',                            # "use slice allocator" (avail since 2.10)
239                 'g_node_pop_allocator',                         # "does nothing since 2.10"
240                 'g_node_push_allocator',                        # "does nothing since 2.10"
241                 'g_relation_count',                             # since 2.26
242                 'g_relation_delete',                            # since 2.26
243                 'g_relation_destroy',                           # since 2.26
244                 'g_relation_exists',                            # since 2.26
245                 'g_relation_index',                             # since 2.26
246                 'g_relation_insert',                            # since 2.26
247                 'g_relation_new',                               # since 2.26
248                 'g_relation_print',                             # since 2.26
249                 'g_relation_select',                            # since 2.26
250                 'g_scanner_add_symbol',
251                 'g_scanner_remove_symbol',
252                 'g_scanner_foreach_symbol',
253                 'g_scanner_freeze_symbol_table',
254                 'g_scanner_thaw_symbol_table',
255                 'g_slist_pop_allocator',                        # "does nothing since 2.10"
256                 'g_slist_push_allocator',                       # "does nothing since 2.10"
257                 'g_source_get_current_time',                    # since 2.28: use g_source_get_time()
258                 'g_strcasecmp',                                 #
259                 'g_strdown',                                    #
260                 'g_string_down',                                #
261                 'g_string_sprintf',                             # use g_string_printf() instead
262                 'g_string_sprintfa',                            # use g_string_append_printf instead
263                 'g_string_up',                                  #
264                 'g_strncasecmp',                                #
265                 'g_strup',                                      #
266                 'g_tree_traverse',
267                 'g_tuples_destroy',                             # since 2.26
268                 'g_tuples_index',                               # since 2.26
269                 'g_unicode_canonical_decomposition',            # since 2.30: use g_unichar_fully_decompose()
270                 'G_UNICODE_COMBINING_MARK',                     # since 2.30:use G_UNICODE_SPACING_MARK
271                 'g_value_set_boxed_take_ownership',             # GObject
272                 'g_value_set_object_take_ownership',            # GObject
273                 'g_value_set_param_take_ownership',             # GObject
274                 'g_value_set_string_take_ownership',            # Gobject
275                 'G_WIN32_DLLMAIN_FOR_DLL_NAME',
276                 'g_win32_get_package_installation_directory',
277                 'g_win32_get_package_installation_subdirectory',
278                 ] },
279
280         # APIs that make the program exit. Dissectors shouldn't call these
281         'abort' => { 'count_errors' => 1, 'functions' => [
282                 'abort',
283                 'assert',
284                 'assert_perror',
285                 'exit',
286                 'g_assert',
287                 'g_error',
288                 ] },
289
290         # APIs that print to the terminal. Dissectors shouldn't call these
291         'termoutput' => { 'count_errors' => 0, 'functions' => [
292                 'printf',
293                 'g_warning',
294                 ] },
295
296         # Deprecated GTK APIs
297         #  which SHOULD NOT be used in Wireshark (any more).
298         #  (Filled in from 'E' entries in %deprecatedGtkFunctions below)
299         'deprecated-gtk' => { 'count_errors' => 1, 'functions' => [
300                 ] },
301
302         # Deprecated GTK APIs yet to be replaced
303         #  (Filled in from 'W' entries in %deprecatedGtkFunctions below)
304         'deprecated-gtk-todo' => { 'count_errors' => 0, 'functions' => [
305                 ] },
306
307 );
308
309 my @apiGroups = qw(prohibited deprecated soft-deprecated);
310
311
312 # Deprecated GTK+ (and GDK) functions/macros with (E)rror or (W)arning flag:
313 # (The list is based upon the GTK+ 2.24.8 documentation;
314 # E: There should be no current Wireshark use so Error if seen;
315 # W: Not all Wireshark use yet fixed so Warn if seen; (Change to E as fixed)
316
317 # Note: Wireshark currently (Jan 2012) requires GTK 2.12 or newer.
318 #       The Wireshark build currently (Jan 2012) defines GTK_DISABLE_DEPRECATED.
319 #       However: Wireshark source still has a few uses of deprecated GTK functions
320 #                (which either are ifdef'd out or GTK_DISABLE_DEPRECATED is undef'd).
321 #                Thus: there a few GTK functions still marked as 'W' below.
322 #       Deprecated GDK functions are included in the list of deprecated GTK functions.
323 #       The Wireshark build currently (Jan 2012) does not define GDK_DISABLE_DEPRECATED
324 #         since there are still some uses of deprecated GDK functions.
325 #         They are marked with 'W' below.
326
327 my %deprecatedGtkFunctions = (
328                 'gtk_about_dialog_get_name',                    'E',
329                 'gtk_about_dialog_set_name',                    'E',
330                 'gtk_about_dialog_set_email_hook',              'E', # since 2.24
331                 'gtk_about_dialog_set_url_hook',                'E', # since 2.24
332                 'gtk_accel_group_ref',                          'E',
333                 'gtk_accel_group_unref',                        'E',
334                 'gtk_action_block_activate_from',               'E', # since 2.16
335                 'gtk_action_connect_proxy',                     'E', # since 2.16: use gtk_activatable_set_related_action() (as of 2.16)
336                 'gtk_action_disconnect_proxy',                  'E', # since 2.16: use gtk_activatable_set_related_action() (as of 2.16)
337                 'gtk_action_unblock_activate_from',             'E', # since 2.16
338                 'gtk_binding_entry_add',                        'E',
339                 'gtk_binding_entry_add_signal',                 'E',
340                 'gtk_binding_entry_clear',                      'E',
341                 'gtk_binding_parse_binding',                    'E',
342                 'gtk_box_pack_end_defaults',                    'E',
343                 'gtk_box_pack_start_defaults',                  'E',
344                 'gtk_button_box_get_child_ipadding',            'E',
345                 'gtk_button_box_get_child_size',                'E',
346                 'gtk_button_box_get_spacing',                   'E',
347                 'gtk_button_box_set_child_ipadding',            'E', # style properties child-internal-pad-x/-y
348                 'gtk_button_box_set_child_size',                'E', # style properties child-min-width/-height
349                 'gtk_button_box_set_spacing',                   'E', # gtk_box_set_spacing [==]
350                 'gtk_button_enter',                             'E', # since 2.20
351                 'gtk_button_leave',                             'E', # since 2.20
352                 'gtk_button_pressed',                           'E', # since 2.20
353                 'gtk_button_released',                          'E', # since 2.20
354                 'gtk_calendar_display_options',                 'E',
355                 'gtk_calendar_freeze',                          'E',
356                 'gtk_calendar_thaw',                            'E',
357                 'GTK_CELL_PIXMAP',                              'E', # GtkTreeView (& related) ...
358                 'GTK_CELL_PIXTEXT',                             'E',
359                 'gtk_cell_renderer_editing_canceled',           'E',
360                 'GTK_CELL_TEXT',                                'E',
361                 'gtk_cell_view_get_cell_renderers',             'E', # gtk_cell_layout_get_cells ()             (avail since 2.12)
362                 'GTK_CELL_WIDGET',                              'E',
363                 'GTK_CHECK_CAST',                               'E', # G_TYPE_CHECK_INSTANCE_CAST [==]
364                 'GTK_CHECK_CLASS_CAST',                         'E', # G_TYPE_CHECK_CLASS_CAST [==]
365                 'GTK_CHECK_CLASS_TYPE',                         'E', # G_TYPE_CHECK_CLASS_TYPE [==]
366                 'GTK_CHECK_GET_CLASS',                          'E', # G_TYPE_INSTANCE_GET_CLASS [==]
367                 'gtk_check_menu_item_set_show_toggle',          'E', # Does nothing; remove; [show_toggle is always TRUE]
368                 'gtk_check_menu_item_set_state',                'E',
369                 'GTK_CHECK_TYPE',                               'E', # G_TYPE_CHECK_INSTANCE_TYPE [==]
370                 'GTK_CLASS_NAME',                               'E',
371                 'GTK_CLASS_TYPE',                               'E',
372                 'GTK_CLIST_ADD_MODE',                           'E', # GtkTreeView (& related) ...
373                 'gtk_clist_append',                             'E',
374                 'GTK_CLIST_AUTO_RESIZE_BLOCKED',                'E',
375                 'GTK_CLIST_AUTO_SORT',                          'E',
376                 'gtk_clist_clear',                              'E',
377                 'gtk_clist_column_title_active',                'E',
378                 'gtk_clist_column_title_passive',               'E',
379                 'gtk_clist_column_titles_active',               'E',
380                 'gtk_clist_column_titles_hide',                 'E',
381                 'gtk_clist_column_titles_passive',              'E',
382                 'gtk_clist_column_titles_show',                 'E',
383                 'gtk_clist_columns_autosize',                   'E',
384                 'GTK_CLIST_DRAW_DRAG_LINE',                     'E',
385                 'GTK_CLIST_DRAW_DRAG_RECT',                     'E',
386                 'gtk_clist_find_row_from_data',                 'E',
387                 'GTK_CLIST_FLAGS',                              'E',
388                 'gtk_clist_freeze',                             'E',
389                 'gtk_clist_get_cell_style',                     'E',
390                 'gtk_clist_get_cell_type',                      'E',
391                 'gtk_clist_get_column_title',                   'E',
392                 'gtk_clist_get_column_widget',                  'E',
393                 'gtk_clist_get_hadjustment',                    'E',
394                 'gtk_clist_get_pixmap',                         'E',
395                 'gtk_clist_get_pixtext',                        'E',
396                 'gtk_clist_get_row_data',                       'E',
397                 'gtk_clist_get_row_style',                      'E',
398                 'gtk_clist_get_selectable',                     'E',
399                 'gtk_clist_get_selection_info',                 'E',
400                 'gtk_clist_get_text',                           'E',
401                 'gtk_clist_get_vadjustment',                    'E',
402                 'GTK_CLIST_IN_DRAG',                            'E',
403                 'gtk_clist_insert',                             'E',
404                 'gtk_clist_moveto',                             'E',
405                 'gtk_clist_new',                                'E',
406                 'gtk_clist_new_with_titles',                    'E',
407                 'gtk_clist_optimal_column_width',               'E',
408                 'gtk_clist_prepend',                            'E',
409                 'gtk_clist_remove',                             'E',
410                 'GTK_CLIST_REORDERABLE',                        'E',
411                 'GTK_CLIST_ROW',                                'E',
412                 'GTK_CLIST_ROW_HEIGHT_SET',                     'E',
413                 'gtk_clist_row_is_visible',                     'E',
414                 'gtk_clist_row_move',                           'E',
415                 'gtk_clist_select_all',                         'E',
416                 'gtk_clist_select_row',                         'E',
417                 'gtk_clist_set_auto_sort',                      'E',
418                 'gtk_clist_set_background',                     'E',
419                 'gtk_clist_set_button_actions',                 'E',
420                 'gtk_clist_set_cell_style',                     'E',
421                 'gtk_clist_set_column_auto_resize',             'E',
422                 'gtk_clist_set_column_justification',           'E',
423                 'gtk_clist_set_column_max_width',               'E',
424                 'gtk_clist_set_column_min_width',               'E',
425                 'gtk_clist_set_column_resizeable',              'E',
426                 'gtk_clist_set_column_title',                   'E',
427                 'gtk_clist_set_column_visibility',              'E',
428                 'gtk_clist_set_column_widget',                  'E',
429                 'gtk_clist_set_column_width',                   'E',
430                 'gtk_clist_set_compare_func',                   'E',
431                 'GTK_CLIST_SET_FLAG',                           'E',
432                 'gtk_clist_set_foreground',                     'E',
433                 'gtk_clist_set_hadjustment',                    'E',
434                 'gtk_clist_set_pixmap',                         'E',
435                 'gtk_clist_set_pixtext',                        'E',
436                 'gtk_clist_set_reorderable',                    'E',
437                 'gtk_clist_set_row_data',                       'E',
438                 'gtk_clist_set_row_data_full',                  'E',
439                 'gtk_clist_set_row_height',                     'E',
440                 'gtk_clist_set_row_style',                      'E',
441                 'gtk_clist_set_selectable',                     'E',
442                 'gtk_clist_set_selection_mode',                 'E',
443                 'gtk_clist_set_shadow_type',                    'E',
444                 'gtk_clist_set_shift',                          'E',
445                 'gtk_clist_set_sort_column',                    'E',
446                 'gtk_clist_set_sort_type',                      'E',
447                 'gtk_clist_set_text',                           'E',
448                 'gtk_clist_set_use_drag_icons',                 'E',
449                 'gtk_clist_set_vadjustment',                    'E',
450                 'GTK_CLIST_SHOW_TITLES',                        'E',
451                 'gtk_clist_sort',                               'E',
452                 'gtk_clist_swap_rows',                          'E',
453                 'gtk_clist_thaw',                               'E',
454                 'gtk_clist_undo_selection',                     'E',
455                 'gtk_clist_unselect_all',                       'E',
456                 'gtk_clist_unselect_row',                       'E',
457                 'GTK_CLIST_UNSET_FLAG',                         'E',
458                 'GTK_CLIST_USE_DRAG_ICONS',                     'E',
459                 'gtk_color_selection_get_color',                'E',
460                 'gtk_color_selection_set_change_palette_hook',  'E',
461                 'gtk_color_selection_set_color',                'E',
462                 'gtk_color_selection_set_update_policy',        'E',
463                 'gtk_combo_box_append_text',                    'E', #
464                 'gtk_combo_box_entry_get_text_column',          'E', #
465                 'gtk_combo_box_entry_new',                      'E', #
466                 'gtk_combo_box_entry_new_text',                 'E', #
467                 'gtk_combo_box_entry_new_with_model',           'E', #
468                 'gtk_combo_box_entry_set_text_column',          'E', #
469                 'gtk_combo_box_get_active_text',                'E', #
470                 'gtk_combo_box_insert_text',                    'E', #
471                 'gtk_combo_box_new_text',                       'E', #
472                 'gtk_combo_box_prepend_text',                   'E', #
473                 'gtk_combo_box_remove_text',                    'E', #
474                 'gtk_combo_disable_activate',                   'E', # GtkComboBoxEntry ... (avail since 2.4/2.6/2.10/2.14)
475                 'gtk_combo_new',                                'E',
476                 'gtk_combo_set_case_sensitive',                 'E',
477                 'gtk_combo_set_item_string',                    'E',
478                 'gtk_combo_set_popdown_strings',                'E',
479                 'gtk_combo_set_use_arrows',                     'E',
480                 'gtk_combo_set_use_arrows_always',              'E',
481                 'gtk_combo_set_value_in_list',                  'E',
482                 'gtk_container_border_width',                   'E', # gtk_container_set_border_width [==]
483                 'gtk_container_children',                       'E', # gtk_container_get_children [==]
484                 'gtk_container_foreach_full',                   'E',
485                 'gtk_ctree_collapse',                           'E',
486                 'gtk_ctree_collapse_recursive',                 'E',
487                 'gtk_ctree_collapse_to_depth',                  'E',
488                 'gtk_ctree_expand',                             'E',
489                 'gtk_ctree_expand_recursive',                   'E',
490                 'gtk_ctree_expand_to_depth',                    'E',
491                 'gtk_ctree_export_to_gnode',                    'E',
492                 'gtk_ctree_find',                               'E',
493                 'gtk_ctree_find_all_by_row_data',               'E',
494                 'gtk_ctree_find_all_by_row_data_custom',        'E',
495                 'gtk_ctree_find_by_row_data',                   'E',
496                 'gtk_ctree_find_by_row_data_custom',            'E',
497                 'gtk_ctree_find_node_ptr',                      'E',
498                 'GTK_CTREE_FUNC',                               'E',
499                 'gtk_ctree_get_node_info',                      'E',
500                 'gtk_ctree_insert_gnode',                       'E',
501                 'gtk_ctree_insert_node',                        'E',
502                 'gtk_ctree_is_ancestor',                        'E',
503                 'gtk_ctree_is_hot_spot',                        'E',
504                 'gtk_ctree_is_viewable',                        'E',
505                 'gtk_ctree_last',                               'E',
506                 'gtk_ctree_move',                               'E',
507                 'gtk_ctree_new',                                'E',
508                 'gtk_ctree_new_with_titles',                    'E',
509                 'GTK_CTREE_NODE',                               'E',
510                 'gtk_ctree_node_get_cell_style',                'E',
511                 'gtk_ctree_node_get_cell_type',                 'E',
512                 'gtk_ctree_node_get_pixmap',                    'E',
513                 'gtk_ctree_node_get_pixtext',                   'E',
514                 'gtk_ctree_node_get_row_data',                  'E',
515                 'gtk_ctree_node_get_row_style',                 'E',
516                 'gtk_ctree_node_get_selectable',                'E',
517                 'gtk_ctree_node_get_text',                      'E',
518                 'gtk_ctree_node_is_visible',                    'E',
519                 'gtk_ctree_node_moveto',                        'E',
520                 'GTK_CTREE_NODE_NEXT',                          'E',
521                 'gtk_ctree_node_nth',                           'E',
522                 'GTK_CTREE_NODE_PREV',                          'E',
523                 'gtk_ctree_node_set_background',                'E',
524                 'gtk_ctree_node_set_cell_style',                'E',
525                 'gtk_ctree_node_set_foreground',                'E',
526                 'gtk_ctree_node_set_pixmap',                    'E',
527                 'gtk_ctree_node_set_pixtext',                   'E',
528                 'gtk_ctree_node_set_row_data',                  'E',
529                 'gtk_ctree_node_set_row_data_full',             'E',
530                 'gtk_ctree_node_set_row_style',                 'E',
531                 'gtk_ctree_node_set_selectable',                'E',
532                 'gtk_ctree_node_set_shift',                     'E',
533                 'gtk_ctree_node_set_text',                      'E',
534                 'gtk_ctree_post_recursive',                     'E',
535                 'gtk_ctree_post_recursive_to_depth',            'E',
536                 'gtk_ctree_pre_recursive',                      'E',
537                 'gtk_ctree_pre_recursive_to_depth',             'E',
538                 'gtk_ctree_real_select_recursive',              'E',
539                 'gtk_ctree_remove_node',                        'E',
540                 'GTK_CTREE_ROW',                                'E',
541                 'gtk_ctree_select',                             'E',
542                 'gtk_ctree_select_recursive',                   'E',
543                 'gtk_ctree_set_drag_compare_func',              'E',
544                 'gtk_ctree_set_expander_style',                 'E',
545                 'gtk_ctree_set_indent',                         'E',
546                 'gtk_ctree_set_line_style',                     'E',
547                 'gtk_ctree_set_node_info',                      'E',
548                 'gtk_ctree_set_reorderable',                    'E',
549                 'gtk_ctree_set_show_stub',                      'E',
550                 'gtk_ctree_set_spacing',                        'E',
551                 'gtk_ctree_sort_node',                          'E',
552                 'gtk_ctree_sort_recursive',                     'E',
553                 'gtk_ctree_toggle_expansion',                   'E',
554                 'gtk_ctree_toggle_expansion_recursive',         'E',
555                 'gtk_ctree_unselect',                           'E',
556                 'gtk_ctree_unselect_recursive',                 'E',
557                 'gtk_curve_get_vector',                         'E', # since 2.20
558                 'gtk_curve_new',                                'E', # since 2.20
559                 'gtk_curve_reset',                              'E', # since 2.20
560                 'gtk_curve_set_curve_type',                     'E', # since 2.20
561                 'gtk_curve_set_gamma',                          'E', # since 2.20
562                 'gtk_curve_set_range',                          'E', # since 2.20
563                 'gtk_curve_set_vector',                         'E', # since 2.20
564                 'gtk_dialog_get_has_separator',                 'E', # This function will be removed in GTK+ 3
565                 'gtk_dialog_set_has_separator',                 'E', # This function will be removed in GTK+ 3
566                 'gtk_drag_set_default_icon',                    'E',
567                 'gtk_draw_arrow',                               'E',
568                 'gtk_draw_box',                                 'E',
569                 'gtk_draw_box_gap',                             'E',
570                 'gtk_draw_check',                               'E',
571                 'gtk_draw_diamond',                             'E',
572                 'gtk_draw_expander',                            'E',
573                 'gtk_draw_extension',                           'E',
574                 'gtk_draw_flat_box',                            'E',
575                 'gtk_draw_focus',                               'E',
576                 'gtk_draw_handle',                              'E',
577                 'gtk_draw_hline',                               'E',
578                 'gtk_draw_layout',                              'E',
579                 'gtk_draw_option',                              'E',
580                 'gtk_draw_polygon',                             'E',
581                 'gtk_draw_resize_grip',                         'E',
582                 'gtk_draw_shadow',                              'E',
583                 'gtk_draw_shadow_gap',                          'E',
584                 'gtk_draw_slider',                              'E',
585                 'gtk_draw_string',                              'E',
586                 'gtk_draw_tab',                                 'E',
587                 'gtk_draw_vline',                               'E',
588                 'gtk_drawing_area_size',                        'E', # >> g_object_set() [==] ?
589                                                                      #    gtk_widget_set_size_request() [==?]
590                 'gtk_entry_append_text',                        'E', # >> gtk_editable_insert_text() [==?]
591                 'gtk_entry_new_with_max_length',                'E', # gtk_entry_new(); gtk_entry_set_max_length()
592                 'gtk_entry_prepend_text',                       'E',
593                 'gtk_entry_select_region',                      'E',
594                 'gtk_entry_set_editable',                       'E', # >> gtk_editable_set_editable() [==?]
595                 'gtk_entry_set_position',                       'E',
596                 'gtk_exit',                                     'E', # exit() [==]
597                 'gtk_file_chooser_button_new_with_backend',     'E',
598                 'gtk_file_chooser_dialog_new_with_backend',     'E',
599                 'gtk_file_chooser_widget_new_with_backend',     'E',
600                 'gtk_file_selection_complete',                  'E',
601                 'gtk_file_selection_get_filename',              'E', # GtkFileChooser ...
602                 'gtk_file_selection_get_select_multiple',       'E',
603                 'gtk_file_selection_get_selections',            'E',
604                 'gtk_file_selection_hide_fileop_buttons',       'E',
605                 'gtk_file_selection_new',                       'E',
606                 'gtk_file_selection_set_filename',              'E',
607                 'gtk_file_selection_set_select_multiple',       'E',
608                 'gtk_file_selection_show_fileop_buttons',       'E',
609                 'gtk_fixed_get_has_window',                     'E', # gtk_widget_get_has_window() (available since 2.18)
610                 'gtk_fixed_set_has_window',                     'E', # gtk_widget_set_has_window() (available since 2.18)
611                 'gtk_font_selection_dialog_get_apply_button',   'E',
612                 'gtk_font_selection_dialog_get_font',           'E',
613                 'gtk_font_selection_get_font',                  'E', # gtk_font_selection_get_font_name() [!=]
614                 'GTK_FUNDAMENTAL_TYPE',                         'E',
615                 'gtk_gamma_curve_new',                          'E', # since 2.20
616                 'gtk_hbox_new',                                 'W', # gtk_box_new
617                 'gtk_hbutton_box_get_layout_default',           'E',
618                 'gtk_hbutton_box_get_spacing_default',          'E',
619                 'gtk_hbutton_box_new',                          'W', # gtk_button_box_new
620                 'gtk_hbutton_box_set_layout_default',           'E',
621                 'gtk_hbutton_box_set_spacing_default',          'E',
622                 'gtk_hruler_new',                               'E', # since 2.24
623                 'gtk_icon_view_get_orientation',                'E', # gtk_icon_view_get_item_orientation()
624                 'gtk_icon_view_set_orientation',                'E', # gtk_icon_view_set_item_orientation()
625                 'gtk_idle_add',                                 'E',
626                 'gtk_idle_add_full',                            'E',
627                 'gtk_idle_add_priority',                        'E',
628                 'gtk_idle_remove',                              'E',
629                 'gtk_idle_remove_by_data',                      'E',
630                 'gtk_image_get',                                'E',
631                 'gtk_image_set',                                'E',
632                 'gtk_init_add',                                 'E', # removed in 3.0
633                 'gtk_input_add_full',                           'E', # >>> g_io_add_watch_full()
634                 'gtk_input_dialog_new',                         'E', # since 2.20
635                 'gtk_input_remove',                             'E', # >>> g_source_remove()
636                 'GTK_IS_ROOT_TREE',                             'E',
637                 'gtk_item_deselect',                            'E', # gtk_menu_item_deselect()
638                 'gtk_item_select',                              'E', # gtk_menu_item_select()
639                 'gtk_item_toggle',                              'E', #
640                 'gtk_item_factories_path_delete',               'E', # GtkUIManager (avail since 2.4) ...
641                 'gtk_item_factory_add_foreign',                 'E',
642                 'gtk_item_factory_construct',                   'E',
643                 'gtk_item_factory_create_item',                 'W',
644                 'gtk_item_factory_create_items',                'E',
645                 'gtk_item_factory_create_items_ac',             'E',
646                 'gtk_item_factory_create_menu_entries',         'E',
647                 'gtk_item_factory_delete_entries',              'E',
648                 'gtk_item_factory_delete_entry',                'E',
649                 'gtk_item_factory_delete_item',                 'E',
650                 'gtk_item_factory_from_path',                   'E',
651                 'gtk_item_factory_from_widget',                 'W',
652                 'gtk_item_factory_get_item',                    'W',
653                 'gtk_item_factory_get_item_by_action',          'E',
654                 'gtk_item_factory_get_widget',                  'W',
655                 'gtk_item_factory_get_widget_by_action',        'E',
656                 'gtk_item_factory_new',                         'E',
657                 'gtk_item_factory_path_from_widget',            'E',
658                 'gtk_item_factory_popup',                       'E',
659                 'gtk_item_factory_popup_data',                  'E',
660                 'gtk_item_factory_popup_data_from_widget',      'E',
661                 'gtk_item_factory_popup_with_data',             'E',
662                 'gtk_item_factory_set_translate_func',          'E',
663                 'gtk_label_get',                                'E', # gtk_label_get_text() [!=]
664                 'gtk_label_parse_uline',                        'E',
665                 'gtk_label_set',                                'E', # gtk_label_set_text() [==]
666                 'gtk_layout_freeze',                            'E',
667                 'gtk_layout_thaw',                              'E',
668                 'gtk_link_button_set_uri_hook',                 'E', # since 2.24
669                 'gtk_list_append_items',                        'E',
670                 'gtk_list_child_position',                      'E',
671                 'gtk_list_clear_items',                         'E',
672                 'gtk_list_end_drag_selection',                  'E',
673                 'gtk_list_end_selection',                       'E',
674                 'gtk_list_extend_selection',                    'E',
675                 'gtk_list_insert_items',                        'E',
676                 'gtk_list_item_deselect',                       'E',
677                 'gtk_list_item_new',                            'E',
678                 'gtk_list_item_new_with_label',                 'E',
679                 'gtk_list_item_select',                         'E',
680                 'gtk_list_new',                                 'E',
681                 'gtk_list_prepend_items',                       'E',
682                 'gtk_list_remove_items',                        'E',
683                 'gtk_list_remove_items_no_unref',               'E',
684                 'gtk_list_scroll_horizontal',                   'E',
685                 'gtk_list_scroll_vertical',                     'E',
686                 'gtk_list_select_all',                          'E',
687                 'gtk_list_select_child',                        'E',
688                 'gtk_list_select_item',                         'E',
689                 'gtk_list_set_selection_mode',                  'E',
690                 'gtk_list_start_selection',                     'E',
691                 'gtk_list_toggle_add_mode',                     'E',
692                 'gtk_list_toggle_focus_row',                    'E',
693                 'gtk_list_toggle_row',                          'E',
694                 'gtk_list_undo_selection',                      'E',
695                 'gtk_list_unselect_all',                        'E',
696                 'gtk_list_unselect_child',                      'E',
697                 'gtk_list_unselect_item',                       'E',
698                 'gtk_menu_append',                              'E', # gtk_menu_shell_append() [==?]
699                 'gtk_menu_bar_append',                          'E',
700                 'gtk_menu_bar_insert',                          'E',
701                 'gtk_menu_bar_prepend',                         'E',
702                 'gtk_menu_insert',                              'E',
703                 'gtk_menu_item_remove_submenu',                 'E',
704                 'gtk_menu_item_right_justify',                  'E',
705                 'gtk_menu_prepend',                             'E', # gtk_menu_shell_prepend() [==?]
706                 'gtk_menu_tool_button_set_arrow_tooltip',       'E',
707                 'gtk_notebook_current_page',                    'E',
708                 'gtk_notebook_get_group',                       'E', # since 2.24
709                 'gtk_notebook_get_group_id',                    'E',
710                 'gtk_notebook_query_tab_label_packing',         'E', # since 2.20
711                 'gtk_nitebook_set_group',                       'E', # since 2.24
712                 'gtk_notebook_set_group_id',                    'E',
713                 'gtk_notebook_set_homogeneous_tabs',            'E',
714                 'gtk_notebook_set_page',                        'E', # gtk_notebook_set_current_page() [==]
715                 'gtk_notebook_set_tab_border',                  'E',
716                 'gtk_notebook_set_tab_hborder',                 'E',
717                 'gtk_notebook_set_tab_label_packing',           'E', # since 2.20
718                 'gtk_notebook_set_tab_vborder',                 'E',
719                 'gtk_notebook_set_window_creation_hook',        'E', # since 2.24
720                 'gtk_object_add_arg_type',                      'E',
721                 'gtk_object_data_force_id',                     'E',
722                 'gtk_object_data_try_key',                      'E',
723                 'gtk_object_destroy',                           'E', # since 2.24
724                 'GTK_OBJECT_FLAGS',                             'E', # since 2.22
725                 'GTK_OBJECT_FLOATING',                          'E',
726                 'gtk_object_get',                               'E',
727                 'gtk_object_get_data',                          'E',
728                 'gtk_object_get_data_by_id',                    'E',
729                 'gtk_object_get_user_data',                     'E',
730                 'gtk_object_new',                               'E',
731                 'gtk_object_ref',                               'E',
732                 'gtk_object_remove_data',                       'E',
733                 'gtk_object_remove_data_by_id',                 'E',
734                 'gtk_object_remove_no_notify',                  'E',
735                 'gtk_object_remove_no_notify_by_id',            'E',
736                 'gtk_object_set',                               'E',
737                 'gtk_object_set_data',                          'E',
738                 'gtk_object_set_data_by_id',                    'E',
739                 'gtk_object_set_data_by_id_full',               'E',
740                 'gtk_object_set_data_full',                     'E',
741                 'gtk_object_set_user_data',                     'E',
742                 'gtk_object_sink',                              'E',
743                 'GTK_OBJECT_TYPE',                              'E', # G_OBJECT_TYPE
744                 'GTK_OBJECT_TYPE_NAME',                         'E', # G_OBJECT_TYPE_NAME
745                 'gtk_object_unref',                             'E',
746                 'gtk_object_weakref',                           'E',
747                 'gtk_object_weakunref',                         'E',
748                 'gtk_old_editable_changed',                     'E',
749                 'gtk_old_editable_claim_selection',             'E',
750                 'gtk_option_menu_get_history',                  'E', # GtkComboBox ... (avail since 2.4/2.6/2.10/2.14)
751                 'gtk_option_menu_get_menu',                     'E',
752                 'gtk_option_menu_new',                          'E',
753                 'gtk_option_menu_remove_menu',                  'E',
754                 'gtk_option_menu_set_history',                  'E',
755                 'gtk_option_menu_set_menu',                     'E',
756                 'gtk_paint_string',                             'E',
757                 'gtk_paned_gutter_size',                        'E', # gtk_paned_set_gutter_size()
758                 'gtk_paned_set_gutter_size',                    'E', # "does nothing"
759                 'gtk_pixmap_get',                               'E', # GtkImage ...
760                 'gtk_pixmap_new',                               'E',
761                 'gtk_pixmap_set',                               'E',
762                 'gtk_pixmap_set_build_insensitive',             'E',
763                 'gtk_preview_draw_row',                         'E',
764                 'gtk_preview_get_cmap',                         'E',
765                 'gtk_preview_get_info',                         'E',
766                 'gtk_preview_get_visual',                       'E',
767                 'gtk_preview_new',                              'E',
768                 'gtk_preview_put',                              'E',
769                 'gtk_preview_reset',                            'E',
770                 'gtk_preview_set_color_cube',                   'E',
771                 'gtk_preview_set_dither',                       'E',
772                 'gtk_preview_set_expand',                       'E',
773                 'gtk_preview_set_gamma',                        'E',
774                 'gtk_preview_set_install_cmap',                 'E',
775                 'gtk_preview_set_reserved',                     'E',
776                 'gtk_preview_size',                             'E',
777                 'gtk_preview_uninit',                           'E',
778                 'GTK_PRIORITY_DEFAULT',                         'E',
779                 'GTK_PRIORITY_HIGH',                            'E',
780                 'GTK_PRIORITY_INTERNAL',                        'E',
781                 'GTK_PRIORITY_LOW',                             'E',
782                 'GTK_PRIORITY_REDRAW',                          'E',
783                 'gtk_progress_bar_new_with_adjustment',         'E',
784                 'gtk_progress_bar_set_activity_blocks',         'E',
785                 'gtk_progress_bar_set_activity_step',           'E',
786                 'gtk_progress_bar_set_bar_style',               'E',
787                 'gtk_progress_bar_set_discrete_blocks',         'E',
788                 'gtk_progress_bar_update',                      'E', # >>> "gtk_progress_set_value() or
789                                                                      #    gtk_progress_set_percentage()"
790                                                                      ##  Actually: GtkProgress is deprecated so the
791                                                                      ##  right answer appears to be to use
792                                                                      ##  gtk_progress_bar_set_fraction()
793                 'gtk_progress_configure',                       'E',
794                 'gtk_progress_get_current_percentage',          'E',
795                 'gtk_progress_get_current_text',                'E',
796                 'gtk_progress_get_percentage_from_value',       'E',
797                 'gtk_progress_get_text_from_value',             'E',
798                 'gtk_progress_get_value',                       'E',
799                 'gtk_progress_set_activity_mode',               'E',
800                 'gtk_progress_set_adjustment',                  'E',
801                 'gtk_progress_set_format_string',               'E',
802                 'gtk_progress_set_percentage',                  'E',
803                 'gtk_progress_set_show_text',                   'E',
804                 'gtk_progress_set_text_alignment',              'E',
805                 'gtk_progress_set_value',                       'E',
806                 'gtk_quit_add',                                 'E', # removed in 3.0
807                 'gtk_quit_add_destroy',                         'E',
808                 'gtk_quit_add_full',                            'E',
809                 'gtk_quit_remove',                              'E',
810                 'gtk_quit_remove_by_data',                      'E',
811                 'gtk_radio_button_group',                       'E', # gtk_radio_button_get_group() [==]
812                 'gtk_radio_menu_item_group',                    'E',
813                 'gtk_range_get_update_policy',                  'E',
814                 'gtk_range_set_update_policy',                  'E',
815                 'gtk_rc_add_class_style',                       'E',
816                 'gtk_rc_add_widget_class_style',                'E',
817                 'gtk_rc_add_widget_name_style',                 'E',
818                 'gtk_rc_style_ref',                             'E',
819                 'gtk_rc_style_unref',                           'E',
820                 'gtk_recent_chooser_get_show_numbers',          'E',
821                 'gtk_recent_chooser_set_show_numbers',          'E',
822                 'gtk_recent_manager_get_for_screen',            'E',
823                 'gtk_recent_manager_get_limit',                 'E', # Use GtkRecentChooser
824                 'gtk_recent_manager_set_limit',                 'E', #
825                 'gtk_recent_manager_set_screen',                'E',
826                 'GTK_RETLOC_BOOL',                              'E',
827                 'GTK_RETLOC_BOXED',                             'E',
828                 'GTK_RETLOC_CHAR',                              'E',
829                 'GTK_RETLOC_DOUBLE',                            'E',
830                 'GTK_RETLOC_ENUM',                              'E',
831                 'GTK_RETLOC_FLAGS',                             'E',
832                 'GTK_RETLOC_FLOAT',                             'E',
833                 'GTK_RETLOC_INT',                               'E',
834                 'GTK_RETLOC_LONG',                              'E',
835                 'GTK_RETLOC_OBJECT',                            'E',
836                 'GTK_RETLOC_POINTER',                           'E',
837                 'GTK_RETLOC_STRING',                            'E',
838                 'GTK_RETLOC_UCHAR',                             'E',
839                 'GTK_RETLOC_UINT',                              'E',
840                 'GTK_RETLOC_ULONG',                             'E',
841                 'gtk_ruler_get_metric',                         'E',
842                 'gtk_ruler_get_range',                          'E',
843                 'gtk_ruler_set_metric',                         'E',
844                 'gtk_ruler_set_range',                          'E',
845                 'gtk_scale_button_get_orientation',             'E', # gtk_orientable_get_orientation()         (avail since 2.16)
846                 'gtk_scale_button_set_orientation',             'E', # gtk_orientable_set_orientation()         (avail since 2.16)
847                 'gtk_status_icon_set_tooltip',                  'E', # gtk_status_icon_set_tooltip_text()       (avail since 2.16)
848                 'gtk_selection_clear',                          'E',
849                 'gtk_set_locale',                               'E',
850                 'gtk_signal_connect',                           'E', # GSignal ...
851                 'gtk_signal_connect_after',                     'E',
852                 'gtk_signal_connect_full',                      'E',
853                 'gtk_signal_connect_object',                    'E',
854                 'gtk_signal_connect_object_after',              'E',
855                 'gtk_signal_connect_object_while_alive',        'E',
856                 'gtk_signal_connect_while_alive',               'E',
857                 'gtk_signal_default_marshaller',                'E',
858                 'gtk_signal_disconnect',                        'E',
859                 'gtk_signal_disconnect_by_data',                'E',
860                 'gtk_signal_disconnect_by_func',                'E',
861                 'gtk_signal_emit',                              'E',
862                 'gtk_signal_emit_by_name',                      'E',
863                 'gtk_signal_emit_stop',                         'E',
864                 'gtk_signal_emit_stop_by_name',                 'E',
865                 'gtk_signal_emitv',                             'E',
866                 'gtk_signal_emitv_by_name',                     'E',
867                 'GTK_SIGNAL_FUNC',                              'E',
868                 'gtk_signal_handler_block',                     'E',
869                 'gtk_signal_handler_block_by_data',             'E',
870                 'gtk_signal_handler_block_by_func',             'E',
871                 'gtk_signal_handler_pending',                   'E',
872                 'gtk_signal_handler_pending_by_func',           'E',
873                 'gtk_signal_handler_unblock',                   'E',
874                 'gtk_signal_handler_unblock_by_data',           'E',
875                 'gtk_signal_handler_unblock_by_func',           'E',
876                 'gtk_signal_lookup',                            'E',
877                 'gtk_signal_name',                              'E',
878                 'gtk_signal_new',                               'E',
879                 'gtk_signal_newv',                              'E',
880                 'GTK_SIGNAL_OFFSET',                            'E',
881                 'gtk_socket_steal',                             'E',
882                 'gtk_spin_button_get_value_as_float',           'E', # gtk_spin_button_get_value() [==]
883                 'gtk_status_icon_get_blinking',                 'E',
884                 'gtk_status_icon_set_blinking',                 'E',
885                 'GTK_STRUCT_OFFSET',                            'E',
886                 'gtk_style_apply_default_pixmap',               'E',
887                 'gtk_style_get_font',                           'E',
888                 'gtk_style_ref',                                'E',
889                 'gtk_style_set_font',                           'E',
890                 'gtk_style_unref',                              'E', # g_object_unref() [==?]
891                 'gtk_text_backward_delete',                     'E',
892                 'gtk_text_forward_delete',                      'E',
893                 'gtk_text_freeze',                              'E',
894                 'gtk_text_get_length',                          'E',
895                 'gtk_text_get_point',                           'E',
896                 'GTK_TEXT_INDEX',                               'E',
897                 'gtk_text_insert',                              'E', # GtkTextView (GtkText "known to be buggy" !)
898                 'gtk_text_new',                                 'E',
899                 'gtk_text_set_adjustments',                     'E',
900                 'gtk_text_set_editable',                        'E',
901                 'gtk_text_set_line_wrap',                       'E',
902                 'gtk_text_set_point',                           'E',
903                 'gtk_text_set_word_wrap',                       'E',
904                 'gtk_text_thaw',                                'E',
905                 'gtk_timeout_add',                              'E', # g_timeout_add()
906                 'gtk_timeout_add_full',                         'E',
907                 'gtk_timeout_remove',                           'E', # g_source_remove()
908                 'gtk_tips_query_new',                           'E',
909                 'gtk_tips_query_set_caller',                    'E',
910                 'gtk_tips_query_set_labels',                    'E',
911                 'gtk_tips_query_start_query',                   'E',
912                 'gtk_tips_query_stop_query',                    'E',
913                 'gtk_toggle_button_set_state',                  'E', # gtk_toggle_button_set_active [==]
914                 'gtk_toolbar_append_element',                   'E',
915                 'gtk_toolbar_append_item',                      'E',
916                 'gtk_toolbar_append_space',                     'E', # Use gtk_toolbar_insert() instead
917                 'gtk_toolbar_append_widget',                    'E', # ??
918                 'gtk_toolbar_get_orientation',                  'E', # gtk_orientable_get_orientation()         (avail since 2.16)
919                 'gtk_toolbar_get_tooltips',                     'E',
920                 'gtk_toolbar_insert_element',                   'E',
921                 'gtk_toolbar_insert_item',                      'E',
922                 'gtk_toolbar_insert_space',                     'E',
923                 'gtk_toolbar_insert_stock',                     'E',
924                 'gtk_toolbar_insert_widget',                    'E',
925                 'gtk_toolbar_prepend_element',                  'E',
926                 'gtk_toolbar_prepend_item',                     'E',
927                 'gtk_toolbar_prepend_space',                    'E',
928                 'gtk_toolbar_prepend_widget',                   'E',
929                 'gtk_toolbar_remove_space',                     'E',
930                 'gtk_toolbar_set_orientation',                  'E', # gtk_orientable_set_orientation()         (avail since 2.16)
931                 'gtk_toolbar_set_tooltips',                     'E',
932                 'gtk_tooltips_data_get',                        'E', # new API: GtkToolTip (avail since 2.12) ...
933                 'gtk_tooltips_disable',                         'E',
934                 'gtk_tooltips_enable',                          'E',
935                 'gtk_tooltips_force_window',                    'E',
936                 'gtk_tooltips_get_info_from_tip_window',        'E',
937                 'gtk_tooltips_new',                             'E',
938                 'gtk_tooltips_set_delay',                       'E',
939                 'gtk_tooltips_set_tip',                         'E',
940                 'gtk_tool_item_set_tooltip',                    'E', # gtk_tool_item_set_tooltip_text() (avail since 2.12)
941                 'gtk_tree_append',                              'E',
942                 'gtk_tree_child_position',                      'E',
943                 'gtk_tree_clear_items',                         'E',
944                 'gtk_tree_insert',                              'E',
945                 'gtk_tree_item_collapse',                       'E',
946                 'gtk_tree_item_deselect',                       'E',
947                 'gtk_tree_item_expand',                         'E',
948                 'gtk_tree_item_new',                            'E',
949                 'gtk_tree_item_new_with_label',                 'E',
950                 'gtk_tree_item_remove_subtree',                 'E',
951                 'gtk_tree_item_select',                         'E',
952                 'gtk_tree_item_set_subtree',                    'E',
953                 'GTK_TREE_ITEM_SUBTREE',                        'E',
954                 'gtk_tree_model_get_iter_root',                 'E',
955                 'gtk_tree_new',                                 'E',
956                 'gtk_tree_path_new_root',                       'E',
957                 'gtk_tree_prepend',                             'E',
958                 'gtk_tree_remove_item',                         'E',
959                 'gtk_tree_remove_items',                        'E',
960                 'GTK_TREE_ROOT_TREE',                           'E',
961                 'gtk_tree_select_child',                        'E',
962                 'gtk_tree_select_item',                         'E',
963                 'GTK_TREE_SELECTION_OLD',                       'E',
964                 'gtk_tree_set_selection_mode',                  'E',
965                 'gtk_tree_set_view_lines',                      'E',
966                 'gtk_tree_set_view_mode',                       'E',
967                 'gtk_tree_unselect_child',                      'E',
968                 'gtk_tree_unselect_item',                       'E',
969                 'gtk_tree_view_column_get_cell_renderers',      'E', # gtk_cell_layout_get_cells ()             (avail since 2.12)
970                 'gtk_tree_view_tree_to_widget_coords',          'E',
971                 'gtk_tree_view_widget_to_tree_coords',          'E',
972                 'gtk_type_class',                               'E', # g_type_class_peek() or g_type_class_ref()
973                 'GTK_TYPE_CTREE_NODE',                          'E',
974                 'gtk_type_enum_find_value',                     'E',
975                 'gtk_type_enum_get_values',                     'E',
976                 'gtk_type_flags_find_value',                    'E',
977                 'gtk_type_flags_get_values',                    'E',
978                 'gtk_type_from_name',                           'E',
979                 'gtk_type_init',                                'E',
980                 'gtk_type_is_a',                                'E',
981                 'GTK_TYPE_FUNDAMENTAL_LAST',                    'E',
982                 'GTK_TYPE_FUNDAMENTAL_MAX',                     'E',
983                 'GTK_TYPE_IS_OBJECT',                           'E',
984                 'gtk_type_name',                                'E',
985                 'gtk_type_new',                                 'E',
986                 'gtk_type_parent',                              'E',
987                 'gtk_type_unique',                              'E',
988                 'GTK_VALUE_BOOL',                               'E',
989                 'GTK_VALUE_BOXED',                              'E',
990                 'GTK_VALUE_CHAR',                               'E',
991                 'GTK_VALUE_DOUBLE',                             'E',
992                 'GTK_VALUE_ENUM',                               'E',
993                 'GTK_VALUE_FLAGS',                              'E',
994                 'GTK_VALUE_FLOAT',                              'E',
995                 'GTK_VALUE_INT',                                'E',
996                 'GTK_VALUE_LONG',                               'E',
997                 'GTK_VALUE_OBJECT',                             'E',
998                 'GTK_VALUE_POINTER',                            'E',
999                 'GTK_VALUE_SIGNAL',                             'E',
1000                 'GTK_VALUE_STRING',                             'E',
1001                 'GTK_VALUE_UCHAR',                              'E',
1002                 'GTK_VALUE_UINT',                               'E',
1003                 'GTK_VALUE_ULONG',                              'E',
1004                 'gtk_vbox_new',                                 'W', # ws_gtk_box_new
1005                 'gtk_vbutton_box_get_layout_default',           'E',
1006                 'gtk_vbutton_box_get_spacing_default',          'E',
1007                 'gtk_vbutton_box_set_layout_default',           'E',
1008                 'gtk_vbutton_box_set_spacing_default',          'E',
1009                 'gtk_vruler_new',                               'E',
1010                 'GTK_WIDGET_APP_PAINTABLE',                     'E', # gtk_widget_get_app_paintable()    (avail since 2.18)
1011                 'GTK_WIDGET_CAN_DEFAULT',                       'E', # gtk_widget_get_can_default()      (avail since 2.18)
1012                 'GTK_WIDGET_CAN_FOCUS',                         'E', # gtk_widget_get_can_focus()        (avail since 2.18)
1013                 'GTK_WIDGET_COMPOSITE_CHILD',                   'E', # gtk_widget_get_composite_child()  (avail since 2.18)
1014                 'GTK_WIDGET_DOUBLE_BUFFERED',                   'E', # gtk_widget_get_double_buffered()  (avail since 2.18)
1015                 'GTK_WIDGET_DRAWABLE',                          'E', # gtk_widget_get_drawable()         (avail since 2.18)
1016                 'GTK_WIDGET_FLAGS',                             'E', # gtk_widget_get_flags()            (avail since 2.18)
1017                 'GTK_WIDGET_HAS_DEFAULT',                       'E', # gtk_widget_get_has_default()      (avail since 2.18)
1018                 'GTK_WIDGET_HAS_FOCUS',                         'E', # gtk_widget_get_has_focus()        (avail since 2.18)
1019                 'GTK_WIDGET_HAS_GRAB',                          'E', # gtk_widget_get_has_grab()         (avail since 2.18)
1020                 'GTK_WIDGET_IS_SENSITIVE',                      'E', # gtk_widget_get_is_sensitive()     (avail since 2.18)
1021                 'GTK_WIDGET_MAPPED',                            'E', # gtk_widget_get_mapped()           (avail since 2.18)
1022                 'GTK_WIDGET_NO_WINDOW',                         'E', # gtk_widget_get_no_window()        (avail since 2.18)
1023                 'GTK_WIDGET_PARENT_SENSITIVE',                  'E', # gtk_widget_get_parent_sensitive() (avail since 2.18)
1024                 'GTK_WIDGET_RC_STYLE',                          'E', # gtk_widget_get_rc_style()         (avail since 2.18)
1025                 'GTK_WIDGET_REALIZED',                          'E', # gtk_widget_get_realized()         (avail since 2.18)
1026                 'GTK_WIDGET_RECEIVES_DEFAULT',                  'E', # gtk_widget_get_receives_default() (avail since 2.18)
1027                 'GTK_WIDGET_SAVED_STATE',                       'E', # gtk_widget_get_saved_state()      (avail since 2.18)
1028                 'GTK_WIDGET_SENSITIVE',                         'E', # gtk_widget_get_sensitive()        (avail since 2.18)
1029                 'GTK_WIDGET_SET_FLAGS',                         'W', # since GTK 2.22
1030                 'GTK_WIDGET_STATE',                             'E', # gtk_widget_get_state()            (avail since 2.18)
1031                 'GTK_WIDGET_TOPLEVEL',                          'E', # gtk_widget_get_toplevel()         (avail since 2.18)
1032                 'GTK_WIDGET_TYPE',                              'E', # gtk_widget_get_type()             (avail since 2.18)
1033                 'GTK_WIDGET_UNSET_FLAGS',                       'E',
1034                 'GTK_WIDGET_VISIBLE',                           'E', # gtk_widget_get_visible()          (avail since 2.18)
1035                 'gtk_widget_draw',                              'E', # gtk_widget_queue_draw_area():
1036                                                                      #  "in general a better choice if you want
1037                                                                      #  to draw a region of a widget."
1038                 'gtk_widget_get_action',                        'E', # gtk_activatable_get_related_action() (avail since 2.16)
1039                 'gtk_widget_hide_all',                          'E',
1040                 'gtk_widget_pop_visual',                        'E',
1041                 'gtk_widget_push_visual',                       'E',
1042                 'gtk_widget_queue_clear',                       'E',
1043                 'gtk_widget_queue_clear_area',                  'E',
1044                 'gtk_widget_ref',                               'E', # g_object_ref() [==]
1045                 'gtk_widget_reset_shapes',                      'E',
1046                 'gtk_widget_restore_default_style',             'E',
1047                 'gtk_widget_set',                               'E', # g_object_set() [==]
1048                 'gtk_widget_set_default_visual',                'E',
1049                 'gtk_widget_set_rc_style',                      'E',
1050                 'gtk_widget_set_uposition',                     'E', # ?? (see GTK documentation)
1051                 'gtk_widget_set_usize',                         'E', # gtk_widget_set_size_request()
1052                 'gtk_widget_set_visual',                        'E',
1053                 'gtk_widget_unref',                             'E',
1054                 'gtk_window_get_frame_dimensions',              'E',
1055                 'gtk_window_get_has_frame',                     'E',
1056                 'gtk_window_set_frame_dimensions',              'E',
1057                 'gtk_window_set_has_frame',                     'E',
1058                 'gtk_window_position',                          'E',
1059                 'gtk_window_set_policy',                        'E', # >>? gtk_window_set_resizable()
1060
1061 ## GDK deprecated functions:
1062                 'gdk_bitmap_create_from_data',                  'E', #
1063                 'gdk_bitmap_ref',                               'E', #
1064                 'gdk_bitmap_unref',                             'E', #
1065                 'gdk_cairo_set_source_pixmap',                  'W', # deprecated since version 2.24.
1066                                                                      # Use gdk_cairo_set_source_window() where appropriate(Since 2.24).
1067                 'gdk_char_height',                              'E', #
1068                 'gdk_char_measure',                             'E', #
1069                 'gdk_char_width',                               'E', #
1070                 'gdk_char_width_wc',                            'E', #
1071                 'gdk_colormap_change',                          'E', #
1072                 'gdk_colormap_get_system_size',                 'E', #
1073                 'gdk_colormap_ref',                             'E', #
1074                 'gdk_colormap_unref',                           'E', #
1075                 'gdk_colors_alloc',                             'E', #
1076                 'gdk_colors_free',                              'E', #
1077                 'gdk_colors_store',                             'E', #
1078                 'gdk_color_alloc',                              'E', #
1079                 'gdk_color_black',                              'E', #
1080                 'gdk_color_change',                             'E', #
1081                 'gdk_color_white',                              'E', #
1082                 'gdk_cursor_destroy',                           'E', #
1083                 'GdkDestroyNotify',                             'E', #
1084                 'gdk_DISPLAY',                                  'E', #
1085                 'gdk_display_set_pointer_hooks',                'E', #
1086                 'gdk_drag_context_new',                         'E', #
1087                 'gdk_drag_context_ref',                         'E', #
1088                 'gdk_drag_context_unref',                       'E', #
1089                 'gdk_drag_find_window',                         'E', #
1090                 'gdk_drag_get_protocol',                        'E', #
1091                 'gdk_drawable_copy_to_image',                   'E', #
1092                 'gdk_drawable_get_data',                        'E', #
1093                 'gdk_drawable_get_display',                     'E', #
1094                 'gdk_drawable_get_image',                       'E', #
1095                 'gdk_drawable_get_screen',                      'E', #
1096                 'gdk_drawable_get_size',                        'W', # deprecated since version 2.24 Use gdk_window_get_width()
1097                                                                      #  and gdk_window_get_height() for GdkWindows.
1098                                                                      # Use gdk_pixmap_get_size() for GdkPixmaps
1099                 'gdk_drawable_get_visual',                      'E', #
1100                 'gdk_drawable_ref',                             'E', #
1101                 'gdk_drawable_set_data',                        'E', #
1102                 'gdk_drawable_unref',                           'E', #
1103                 'gdk_draw_arc',                                 'E', # deprecated since version 2.22. Use cairo_arc() and
1104                                                                      #  cairo_fill() or cairo_stroke() instead.
1105                 'gdk_draw_drawable',                            'E', # deprecated since version 2.22. Use  gdk_cairo_set_source_pixmap(),
1106                                                                      #  cairo_rectangle() and cairo_fill() to draw pixmap
1107                                                                      #  on top of other drawables
1108                 'gdk_draw_glyphs',                              'E', #
1109                 'gdk_draw_glyphs_transformed',                  'E', #
1110                 'gdk_draw_gray_image',                          'E', #
1111                 'gdk_draw_image',                               'E', #
1112                 'gdk_draw_indexed_image',                       'E', #
1113                 'gdk_draw_layout',                              'E', #
1114                 'gdk_draw_layout_line',                         'E', #
1115                 'gdk_draw_layout_line_with_colors',             'E', #
1116                 'gdk_draw_layout_with_colors',                  'E', #
1117                 'gdk_draw_line',                                'W', # deprecated since version 2.22. Use cairo_line_to() and cairo_stroke()
1118                 'gdk_draw_lines',                               'E', # deprecated since version 2.22. Use cairo_line_to() and cairo_stroke()
1119                 'gdk_draw_pixbuf',                              'E', # gdk_cairo_set_source_pixbuf() and cairo_paint() or
1120                                                                      #  cairo_rectangle() and cairo_fill() instead.
1121                 'gdk_draw_pixmap',                              'E', # gdk_draw_drawable() (gdk_draw_drawable has been
1122                                                                      #  deprecated since version 2.22 )
1123                 'gdk_draw_point',                               'E', #
1124                 'gdk_draw_points',                              'E', #
1125                 'gdk_draw_polygon',                             'E', # deprecated since version 2.22. Use cairo_line_to()
1126                                                                      #  or cairo_append_path() and cairo_fill()
1127                                                                      #  or cairo_stroke() instead.
1128                 'gdk_draw_rectangle',                           'E', # deprecated since version 2.22, Use cairo_rectangle()
1129                                                                      #  and cairo_fill() or cairo_stroke()
1130                 'gdk_draw_rgb_32_image',                        'E', #
1131                 'gdk_draw_rgb_32_image_dithalign',              'E', #
1132                 'gdk_draw_rgb_image',                           'E', #
1133                 'gdk_draw_rgb_image_dithalign',                 'E', #
1134                 'gdk_draw_segments',                            'E', #
1135                 'gdk_draw_string',                              'E', #
1136                 'gdk_draw_text',                                'E', #
1137                 'gdk_draw_text_wc',                             'E', #
1138                 'gdk_draw_trapezoids',                          'E', #
1139                 'gdk_event_get_graphics_expose',                'E', #
1140                 'gdk_exit',                                     'E', #
1141                 'GdkFillRule',                                  'E', #
1142                 'GdkFont',                                      'E', #
1143                 'gdk_fontset_load',                             'E', #
1144                 'gdk_fontset_load_for_display',                 'E', #
1145                 'GdkFontType',                                  'E', #
1146                 'gdk_font_equal',                               'E', #
1147                 'gdk_font_from_description',                    'E', #
1148                 'gdk_font_from_description_for_display',        'E', #
1149                 'gdk_font_get_display',                         'E', #
1150                 'gdk_font_id',                                  'E', #
1151                 'gdk_font_load',                                'E', #
1152                 'gdk_font_load_for_display',                    'E', #
1153                 'gdk_font_lookup',                              'E', #
1154                 'gdk_font_lookup_for_display',                  'E', #
1155                 'gdk_font_ref',                                 'E', #
1156                 'gdk_font_unref',                               'E', #
1157                 'gdk_FONT_XDISPLAY',                            'E', #
1158                 'gdk_FONT_XFONT',                               'E', #
1159                 'gdk_free_compound_text',                       'E', #
1160                 'gdk_free_text_list',                           'E', #
1161                 'gdk_gc_copy',                                  'E', #
1162                 'gdk_gc_destroy',                               'E', #
1163                 'gdk_gc_get_colormap',                          'E', #
1164                 'gdk_gc_get_screen',                            'E', #
1165                 'gdk_gc_get_values',                            'E', #
1166                 'gdk_gc_new',                                   'W', # deprecated since version 2.22 and should not be used
1167                                                                      #  in newly-written code. Use Cairo for rendering.
1168                 'gdk_gc_new_with_values',                       'E', # deprecated since version 2.22
1169                 'gdk_gc_offset',                                'E', #
1170                 'gdk_gc_ref',                                   'E', #
1171                 'gdk_gc_set_background',                        'E', #
1172                 'gdk_gc_set_clip_mask',                         'E', #
1173                 'gdk_gc_set_clip_origin',                       'E', #
1174                 'gdk_gc_set_clip_rectangle',                    'E', #
1175                 'gdk_gc_set_clip_region',                       'E', #
1176                 'gdk_gc_set_colormap',                          'E', #
1177                 'gdk_gc_set_dashes',                            'E', #
1178                 'gdk_gc_set_exposures',                         'E', #
1179                 'gdk_gc_set_fill',                              'E', # deprecated since version 2.22. Use cairo_pattern_set_extend()
1180                                                                      #  on the source.
1181                 'gdk_gc_set_font',                              'E', #
1182                 'gdk_gc_set_foreground',                        'W', # deprecated since version 2.22. Use gdk_cairo_set_source_color()
1183                                                                      #  to use a GdkColor as the source in Cairo.
1184                 'gdk_gc_set_function',                          'W', # deprecated since version 2.22. Use cairo_set_operator() with Cairo.
1185                 'gdk_gc_set_line_attributes',                   'E', #
1186                 'gdk_gc_set_rgb_bg_color',                      'E', #
1187                 'gdk_gc_set_rgb_fg_color',                      'E', # deprecated since version 2.22.
1188                                                                      #  Use gdk_cairo_set_source_color() instead.
1189                 'gdk_gc_set_stipple',                           'E', #
1190                 'gdk_gc_set_subwindow',                         'E', #
1191                 'gdk_gc_set_tile',                              'E', # deprecated since version 2.22.
1192                                                                      # The following code snippet sets a tiling GdkPixmap as the
1193                                                                      #   source in Cairo:
1194                                                                      # gdk_cairo_set_source_pixmap (cr, tile, ts_origin_x, ts_origin_y);
1195                                                                      # cairo_pattern_set_extend (cairo_get_source (cr),
1196                                                                      #  CAIRO_EXTEND_REPEAT);
1197                 'gdk_gc_set_ts_origin',                         'E', #
1198                 'gdk_gc_set_values',                            'E', #
1199                 'gdk_gc_unref',                                 'E', # deprecated since version 2.0. Use g_object_unref()
1200                 'gdk_get_use_xshm',                             'E', #
1201                 'gdk_image_destroy',                            'E', #
1202                 'gdk_image_get',                                'E', #
1203                 'gdk_image_get_bits_per_pixel',                 'E', #
1204                 'gdk_image_get_bytes_per_line',                 'E', #
1205                 'gdk_image_get_bytes_per_pixel',                'E', #
1206                 'gdk_image_get_byte_order',                     'E', #
1207                 'gdk_image_get_colormap',                       'E', #
1208                 'gdk_image_get_depth',                          'E', #
1209                 'gdk_image_get_height',                         'E', #
1210                 'gdk_image_get_image_type',                     'E', #
1211                 'gdk_image_get_pixel',                          'E', #
1212                 'gdk_image_get_pixels',                         'E', #
1213                 'gdk_image_get_visual',                         'E', #
1214                 'gdk_image_get_width',                          'E', #
1215                 'gdk_image_new',                                'E', #
1216                 'gdk_image_new_bitmap',                         'E', #
1217                 'gdk_image_put_pixel',                          'E', #
1218                 'gdk_image_ref',                                'E', #
1219                 'gdk_image_set_colormap',                       'E', #
1220                 'gdk_image_unref',                              'E', #
1221                 'gdk_input_add',                                'E', #
1222                 'gdk_input_add_full',                           'E', #
1223                 'gdk_input_remove',                             'E', #
1224                 'gdk_mbstowcs',                                 'E', #
1225                 'gdk_net_wm_supports',                          'E', #
1226                 'gdk_pango_context_set_colormap',               'E', #
1227                 'gdk_pixbuf_render_to_drawable',                'E', #
1228                 'gdk_pixbuf_render_to_drawable_alpha',          'E', #
1229                 'gdk_pixmap_colormap_create_from_xpm',          'E', #
1230                 'gdk_pixmap_colormap_create_from_xpm_d',        'E', #
1231                 'gdk_pixmap_create_from_data',                  'E', #
1232                 'gdk_pixmap_create_from_xpm',                   'E', #
1233                 'gdk_pixmap_create_from_xpm_d',                 'E', # deprecated since version 2.22. Use a GdkPixbuf instead. You can
1234                                                                      #  use gdk_pixbuf_new_from_xpm_data() to create it.
1235                                                                      # If you must use a pixmap, use gdk_pixmap_new() to create it
1236                                                                      #  and Cairo to draw the pixbuf onto it.
1237                 'gdk_pixmap_ref',                               'E', #
1238                 'gdk_pixmap_unref',                             'E', # Deprecated equivalent of g_object_unref().
1239                 'gdk_region_polygon',                           'E', #
1240                 'gdk_region_rect_equal',                        'E', #
1241                 'gdk_region_shrink',                            'E', #
1242                 'gdk_region_spans_intersect_foreach',           'E', #
1243                 'GdkRgbCmap',                                   'E', #
1244                 'gdk_rgb_cmap_free',                            'E', #
1245                 'gdk_rgb_cmap_new',                             'E', #
1246                 'gdk_rgb_colormap_ditherable',                  'E', #
1247                 'gdk_rgb_ditherable',                           'E', #
1248                 'gdk_rgb_find_color',                           'E', #
1249                 'gdk_rgb_gc_set_background',                    'E', #
1250                 'gdk_rgb_gc_set_foreground',                    'E', #
1251                 'gdk_rgb_get_cmap',                             'E', #
1252                 'gdk_rgb_get_colormap',                         'E', #
1253                 'gdk_rgb_get_visual',                           'E', #
1254                 'gdk_rgb_init',                                 'E', #
1255                 'gdk_rgb_set_install',                          'E', #
1256                 'gdk_rgb_set_min_colors',                       'E', #
1257                 'gdk_rgb_set_verbose',                          'E', #
1258                 'gdk_rgb_xpixel_from_rgb',                      'E', #
1259                 'gdk_ROOT_PARENT',                              'E', #
1260                 'gdk_screen_get_rgb_colormap',                  'E', #
1261                 'gdk_screen_get_rgb_visual',                    'E', #
1262                 'GdkSelection',                                 'E', #
1263                 'GdkSelectionType',                             'E', #
1264                 'gdk_set_locale',                               'E', #
1265                 'gdk_set_pointer_hooks',                        'E', #
1266                 'gdk_set_sm_client_id',                         'E', #
1267                 'gdk_set_use_xshm',                             'E', #
1268                 'GdkSpanFunc',                                  'E', #
1269                 'gdk_spawn_command_line_on_screen',             'E', #
1270                 'gdk_spawn_on_screen',                          'E', #
1271                 'gdk_spawn_on_screen_with_pipes',               'E', #
1272                 'gdk_string_extents',                           'E', #
1273                 'gdk_string_height',                            'E', #
1274                 'gdk_string_measure',                           'E', #
1275                 'gdk_string_to_compound_text',                  'E', #
1276                 'gdk_string_to_compound_text_for_display',      'E', #
1277                 'gdk_string_width',                             'E', #
1278                 'GdkTarget',                                    'E', #
1279                 'gdk_text_extents',                             'E', #
1280                 'gdk_text_extents_wc',                          'E', #
1281                 'gdk_text_height',                              'E', #
1282                 'gdk_text_measure',                             'E', #
1283                 'gdk_text_property_to_text_list',               'E', #
1284                 'gdk_text_property_to_text_list_for_display',   'E', #
1285                 'gdk_text_property_to_utf8_list',               'E', #
1286                 'gdk_text_width',                               'E', #
1287                 'gdk_text_width_wc',                            'E', #
1288                 'gdk_threads_mutex',                            'E', #
1289                 'gdk_utf8_to_compound_text',                    'E', #
1290                 'gdk_utf8_to_compound_text_for_display',        'E', #
1291                 'gdk_visual_ref',                               'E', #
1292                 'gdk_visual_unref',                             'E', #
1293                 'gdk_wcstombs',                                 'E', #
1294                 'gdk_window_copy_area',                         'E', #
1295                 'gdk_window_foreign_new',                       'E', #
1296                 'gdk_window_foreign_new_for_display',           'E', #
1297                 'gdk_window_get_colormap',                      'E', # Deprecated equivalent of gdk_drawable_get_colormap().
1298                 'gdk_window_get_deskrelative_origin',           'E', #
1299                 'gdk_window_get_size',                          'E', # Deprecated equivalent of gdk_drawable_get_size().
1300                 'gdk_window_get_toplevels',                     'E', #
1301                 'gdk_window_get_type',                          'E', #
1302                 'gdk_window_lookup',                            'E', #
1303                 'gdk_window_lookup_for_display',                'E', #
1304                 'gdk_window_ref',                               'E', #
1305                 'gdk_window_set_colormap',                      'E', #
1306                 'gdk_window_set_hints',                         'E', #
1307                 'gdk_window_unref',                             'E', #
1308                 'gdk_x11_font_get_name',                        'E', #
1309                 'gdk_x11_font_get_xdisplay',                    'E', #
1310                 'gdk_x11_font_get_xfont',                       'E', #
1311                 'gdk_x11_gc_get_xdisplay',                      'E', #
1312                 'gdk_x11_gc_get_xgc',                           'E', #
1313                 'gdk_xid_table_lookup',                         'E', #
1314                 'gdk_xid_table_lookup_for_display',             'E', #
1315                 'gdkx_colormap_get',                            'E', #
1316                 'gdkx_visual_get',                              'E', #
1317
1318 );
1319
1320 @{$APIs{'deprecated-gtk'}->{'functions'}}      = grep {$deprecatedGtkFunctions{$_} eq 'E'} keys %deprecatedGtkFunctions;
1321 @{$APIs{'deprecated-gtk-todo'}->{'functions'}} = grep {$deprecatedGtkFunctions{$_} eq 'W'} keys %deprecatedGtkFunctions;
1322
1323
1324
1325 # Given a ref to a hash containing "functions" and "functions_count" entries:
1326 # Determine if any item of the list of APIs contained in the array referenced by "functions"
1327 # exists in the file.
1328 # For each API which appears in the file:
1329 #     Push the API onto the provided list;
1330 #     Add the number of times the API appears in the file to the total count
1331 #      for the API (stored as the value of the API key in the hash referenced by "function_counts").
1332
1333 sub findAPIinFile($$$)
1334 {
1335         my ($groupHashRef, $fileContentsRef, $foundAPIsRef) = @_;
1336
1337         for my $api ( @{$groupHashRef->{functions}} )
1338         {
1339                 my $cnt = 0;
1340                 while (${$fileContentsRef} =~ m/ \W $api \W* \( /gx)
1341                 {
1342                         $cnt += 1;
1343                 }
1344                 if ($cnt > 0) {
1345                         push @{$foundAPIsRef}, $api;
1346                         $groupHashRef->{function_counts}->{$api} += 1;
1347                 }
1348         }
1349 }
1350
1351 # APIs which (generally) should not be called with an argument of tvb_get_ptr()
1352 my @TvbPtrAPIs = (
1353         # Use NULL for the value_ptr instead of tvb_get_ptr() (only if the
1354         # given offset and length are equal) with these:
1355         'proto_tree_add_bytes_format',
1356         'proto_tree_add_bytes_format_value',
1357         'proto_tree_add_ether',
1358         # Use the tvb_* version of these:
1359         # Use tvb_bytes_to_str[_punct] instead of:
1360         'bytes_to_str',
1361         'bytes_to_str_punct',
1362         'SET_ADDRESS',
1363         'SET_ADDRESS_HF',
1364 );
1365
1366 sub checkAPIsCalledWithTvbGetPtr($$$)
1367 {
1368         my ($APIs, $fileContentsRef, $foundAPIsRef) = @_;
1369
1370         for my $api (@{$APIs}) {
1371                 my @items;
1372                 my $cnt = 0;
1373
1374                 @items = (${$fileContentsRef} =~ m/ ($api [^;]* ; ) /xsg);
1375                 while (@items) {
1376                         my ($item) = @items;
1377                         shift @items;
1378                         if ($item =~ / tvb_get_ptr /xos) {
1379                                 $cnt += 1;
1380                         }
1381                 }
1382
1383                 if ($cnt > 0) {
1384                         push @{$foundAPIsRef}, $api;
1385                 }
1386         }
1387 }
1388
1389 # List of possible shadow variable (Majority coming from Mac OS X..)
1390 my @ShadowVariable = (
1391         'index',
1392         'time',
1393         'strlen',
1394         'system'
1395 );
1396
1397 sub checkShadowVariable($$$)
1398 {
1399         my ($groupHashRef, $fileContentsRef, $foundAPIsRef) = @_;
1400
1401         for my $api ( @{$groupHashRef} )
1402         {
1403                 my $cnt = 0;
1404                 while (${$fileContentsRef} =~ m/ \s $api \s*+ [^\(\w] /gx)
1405                 {
1406                         $cnt += 1;
1407                 }
1408                 if ($cnt > 0) {
1409                         push @{$foundAPIsRef}, $api;
1410                 }
1411         }
1412 }
1413
1414 sub check_snprintf_plus_strlen($$)
1415 {
1416         my ($fileContentsRef, $filename) = @_;
1417         my @items;
1418
1419         # This catches both snprintf() and g_snprint.
1420         # If we need to do more APIs, we can make this function look more like
1421         # checkAPIsCalledWithTvbGetPtr().
1422         @items = (${$fileContentsRef} =~ m/ (snprintf [^;]* ; ) /xsg);
1423         while (@items) {
1424                 my ($item) = @items;
1425                 shift @items;
1426                 if ($item =~ / strlen\s*\( /xos) {
1427                         print STDERR "Warning: ".$filename." uses snprintf + strlen to assemble strings.\n";
1428                         last;
1429                 }
1430         }
1431 }
1432
1433 #### Regex for use when searching for value-string definitions
1434 my $StaticRegex             = qr/ static \s+                                                            /xs;
1435 my $ConstRegex              = qr/ const  \s+                                                            /xs;
1436 my $Static_andor_ConstRegex = qr/ (?: $StaticRegex $ConstRegex | $StaticRegex | $ConstRegex)            /xs;
1437 my $ValueStringVarnameRegex = qr/ (?:value|val64|string|range|bytes)_string                             /xs;
1438 my $ValueStringRegex        = qr/ ^ \s* $Static_andor_ConstRegex $ValueStringVarnameRegex \ + [^;*]+ = [^;]+ [{] .+? [}] \s*? ;  /xms;
1439 my $EnumValRegex            = qr/ $Static_andor_ConstRegex enum_val_t \ + [^;*]+ = [^;]+ [{] .+? [}] \s*? ;  /xs;
1440 my $NewlineStringRegex      = qr/ ["] [^"]* \\n [^"]* ["] /xs;
1441
1442 sub check_value_string_arrays($$$)
1443 {
1444         my ($fileContentsRef, $filename, $debug_flag) = @_;
1445         my $cnt = 0;
1446         # Brute force check for value_string (and string_string or range_string) arrays
1447         # which are missing {0, NULL} as the final (terminating) array entry
1448
1449         #  Assumption: definition is of form (pseudo-Regex):
1450         #    " (static const|static|const) (value|string|range)_string .+ = { .+ ;"
1451         #  (possibly over multiple lines)
1452         while (${$fileContentsRef} =~ / ( $ValueStringRegex ) /xsog) {
1453                 # XXX_string array definition found; check if NULL terminated
1454                 my $vs = my $vsx = $1;
1455                 if ($debug_flag) {
1456                         $vsx =~ / ( .+ $ValueStringVarnameRegex [^=]+ ) = /xo;
1457                         printf STDERR "==> %-35.35s: %s\n", $filename, $1;
1458                         printf STDERR "%s\n", $vs;
1459                 }
1460                 $vs =~ s{ \s } {}xg;
1461                 if ($vs !~ / (0|NULL), NULL [}] ,? [}] ; $/xo) {
1462                         $vsx =~ /( $ValueStringVarnameRegex [^=]+ ) = /xo;
1463                         printf STDERR "Error: %-35.35s: {0, NULL} is required as the last XXX_string array entry: %s\n", $filename, $1;
1464                         $cnt++;
1465                 }
1466                 if ($vs !~ / (static)? const $ValueStringVarnameRegex /xo)  {
1467                         $vsx =~ /( $ValueStringVarnameRegex [^=]+ ) = /xo;
1468                         printf STDERR "Error: %-35.35s: Missing 'const': %s\n", $filename, $1;
1469                         $cnt++;
1470                 }
1471                 if ($vs =~ / $NewlineStringRegex /xo && $vs !~ / bytes_string /xo)  {
1472                         $vsx =~ /( $ValueStringVarnameRegex [^=]+ ) = /xo;
1473                         printf STDERR "Error: %-35.35s: XXX_string contains a newline: %s\n", $filename, $1;
1474                         $cnt++;
1475                 }
1476         }
1477
1478         # Brute force check for enum_val_t arrays which are missing {NULL, NULL, ...}
1479         # as the final (terminating) array entry
1480         # For now use the same option to turn this and value_string checking on and off.
1481         # (Is the option even necessary?)
1482
1483         #  Assumption: definition is of form (pseudo-Regex):
1484         #    " (static const|static|const) enum_val_t .+ = { .+ ;"
1485         #  (possibly over multiple lines)
1486         while (${$fileContentsRef} =~ / ( $EnumValRegex ) /xsog) {
1487                 # enum_val_t array definition found; check if NULL terminated
1488                 my $vs = my $vsx = $1;
1489                 if ($debug_flag) {
1490                         $vsx =~ / ( .+ enum_val_t [^=]+ ) = /xo;
1491                         printf STDERR "==> %-35.35s: %s\n", $filename, $1;
1492                         printf STDERR "%s\n", $vs;
1493                 }
1494                 $vs =~ s{ \s } {}xg;
1495                 # README.developer says
1496                 #  "Don't put a comma after the last tuple of an initializer of an array"
1497                 # However: since this usage is present in some number of cases, we'll allow for now
1498                 if ($vs !~ / NULL, NULL, -?[0-9] [}] ,? [}] ; $/xo) {
1499                         $vsx =~ /( enum_val_t [^=]+ ) = /xo;
1500                         printf STDERR "Error: %-35.35s: {NULL, NULL, ...} is required as the last enum_val_t array entry: %s\n", $filename, $1;
1501                         $cnt++;
1502                 }
1503                 if ($vs !~ / (static)? const enum_val_t /xo)  {
1504                         $vsx =~ /( enum_val_t [^=]+ ) = /xo;
1505                         printf STDERR "Error: %-35.35s: Missing 'const': %s\n", $filename, $1;
1506                         $cnt++;
1507                 }
1508                 if ($vs =~ / $NewlineStringRegex /xo)  {
1509                         $vsx =~ /( (?:value|string|range)_string [^=]+ ) = /xo;
1510                         printf STDERR "Error: %-35.35s: enum_val_t contains a newline: %s\n", $filename, $1;
1511                         $cnt++;
1512                 }
1513         }
1514
1515         return $cnt;
1516 }
1517
1518
1519 sub check_included_files($$)
1520 {
1521         my ($fileContentsRef, $filename) = @_;
1522         my @incFiles;
1523
1524         @incFiles = (${$fileContentsRef} =~ m/\#include \s* ([<"].+[>"])/gox);
1525
1526         # only our wrapper file wsutils/wsgcrypt.h may include gcrypt.h
1527         # all other files should include the wrapper
1528         if ($filename !~ /wsgcrypt\.h/) {
1529                 foreach (@incFiles) {
1530                         if ( m#([<"]|/+)gcrypt\.h[>"]$# ) {
1531                                 print STDERR "Warning: ".$filename.
1532                                         " includes gcrypt.h directly. ".
1533                                         "Include wsutil/wsgrypt.h instead.\n";
1534                                 last;
1535                         }
1536                 }
1537         }
1538
1539         # files in the ui/qt directory should include the ui class includes
1540         # by using #include <>
1541         # this ensures that Visual Studio picks up these files from the
1542         # build directory if we're compiling with cmake
1543         if ($filename =~ m#ui/qt/# ) {
1544                 foreach (@incFiles) {
1545                         if ( m#"ui_.*\.h"$# ) {
1546                                 # strip the quotes to get the base name
1547                                 # for the error message
1548                                 s/\"//g;
1549
1550                                 print STDERR "$filename: ".
1551                                         "Please use #include <$_> ".
1552                                         "instead of #include \"$_\".\n";
1553                         }
1554                 }
1555         }
1556 }
1557
1558
1559 sub check_proto_tree_add_XXX_encoding($$)
1560 {
1561         my ($fileContentsRef, $filename) = @_;
1562         my @items;
1563         my $errorCount = 0;
1564
1565         @items = (${$fileContentsRef} =~ m/ (proto_tree_add_[_a-z0-9]+) \( ([^;]*) \) \s* ; /xsg);
1566
1567         while (@items) {
1568                 my ($func) = @items;
1569                 shift @items;
1570                 my ($args) = @items;
1571                 shift @items;
1572
1573                 # Remove anything inside parenthesis in the arguments so we
1574                 # don't get false positives when someone calls
1575                 # proto_tree_add_XXX(..., tvb_YYY(..., ENC_ZZZ))
1576                 # and allow there to be newlines inside
1577                 $args =~ s/\(.*\)//sg;
1578
1579                 if ($args =~ /,\s*ENC_/xos) {
1580                         if (!($func =~ /proto_tree_add_(time|item|bitmask|bits_item|bits_ret_val|item_ret_int|item_ret_uint|bytes_item|checksum)/xos)
1581                            ) {
1582                                 print STDERR "Error: ".$filename." uses $func with ENC_*.\n";
1583                                 $errorCount++;
1584
1585                                 # Print out the function args to make it easier
1586                                 # to find the offending code.  But first make
1587                                 # it readable by eliminating extra white space.
1588                                 $args =~ s/\s+/ /g;
1589                                 print STDERR "\tArgs: " . $args . "\n";
1590                         }
1591                 }
1592         }
1593
1594         return $errorCount;
1595 }
1596
1597
1598 # Verify that all declared ett_ variables are registered.
1599 # Don't bother trying to check usage (for now)...
1600 sub check_ett_registration($$)
1601 {
1602         my ($fileContentsRef, $filename) = @_;
1603         my @ett_declarations;
1604         my %ett_registrations;
1605         my @unRegisteredEtts;
1606         my $errorCount = 0;
1607
1608         # A pattern to match ett variable names.  Obviously this assumes that
1609         # they start with ett_
1610         my $EttVarName = qr{ (?: ett_[a-z0-9_]+ (?:\[[0-9]+\])? ) }xi;
1611
1612         # Remove macro lines
1613         my $fileContents = ${$fileContentsRef};
1614         $fileContents =~ s { ^\s*\#.*$} []xogm;
1615
1616         # Find all the ett_ variables declared in the file
1617         @ett_declarations = ($fileContents =~ m{
1618                 ^\s*static              # assume declarations are on their own line
1619                 \s+
1620                 g?int                   # could be int or gint
1621                 \s+
1622                 ($EttVarName)           # variable name
1623                 \s*=\s*
1624                 -1\s*;
1625         }xgiom);
1626
1627         if (!@ett_declarations) {
1628                 print STDERR "Found no etts in ".$filename."\n";
1629                 return;
1630         }
1631
1632         #print "Found these etts in ".$filename.": ".join(',', @ett_declarations)."\n\n";
1633
1634         # Find the array used for registering the etts
1635         # Save off the block of code containing just the variables
1636         my @reg_blocks;
1637         @reg_blocks = ($fileContents =~ m{
1638                 static
1639                 \s+
1640                 g?int
1641                 \s*\*\s*                # it's an array of pointers
1642                 [a-z0-9_]+              # array name; usually (always?) "ett"
1643                 \s*\[\s*\]\s*           # array brackets
1644                 =
1645                 \s*\{
1646                 ((?:\s*&\s*             # address of the following variable
1647                 $EttVarName             # variable name
1648                 \s*,?                   # the comma is optional (for the last entry)
1649                 \s*)+)                  # match one or more variable names
1650                 \}
1651                 \s*
1652                 ;
1653         }xgios);
1654         #print "Found this ett registration block in ".$filename.": ".join(',', @reg_blocks)."\n";
1655
1656         if (@reg_blocks == 0) {
1657                 print STDERR "Hmm, found ".@reg_blocks." ett registration blocks in ".$filename."\n";
1658                 # For now...
1659                 return;
1660         }
1661
1662         while (@reg_blocks) {
1663                 my ($block) = @reg_blocks;
1664                 shift @reg_blocks;
1665
1666                 # Convert the list returned by the match into a hash of the
1667                 # form ett_variable_name -> 1.  Then combine this new hash with
1668                 # the hash from the last registration block.
1669                 # (Of course) using hashes makes the lookups much faster.
1670                 %ett_registrations = map { $_ => 1 } ($block =~ m{
1671                         \s*&\s*                 # address of the following variable
1672                         ($EttVarName)           # variable name
1673                         \s*,?                   # the comma is optional (for the last entry)
1674                 }xgios, %ett_registrations);
1675         }
1676         #print "Found these ett registrations in ".$filename.": ";
1677         #while( my ($k, $v) = each %ett_registrations ) {
1678         #          print "$k\n";
1679         #}
1680
1681         # Find which declared etts are not registered.
1682         # XXX - using <@ett_declarations> and $_ instead of $ett_var makes this
1683         # MUCH slower...  Why?
1684         while (@ett_declarations) {
1685                 my ($ett_var) = @ett_declarations;
1686                 shift @ett_declarations;
1687
1688                 push(@unRegisteredEtts, $ett_var) if (!$ett_registrations{$ett_var});
1689         }
1690
1691         if (@unRegisteredEtts) {
1692                 print STDERR "Error: found these unregistered ett variables in ".$filename.": ".join(',', @unRegisteredEtts)."\n";
1693                 $errorCount++;
1694         }
1695
1696         return $errorCount;
1697 }
1698
1699 # Given the file contents and a file name, check all of the hf entries for
1700 # various problems (such as those checked for in proto.c).
1701 sub check_hf_entries($$)
1702 {
1703         my ($fileContentsRef, $filename) = @_;
1704         my $errorCount = 0;
1705
1706         my @items;
1707         @items = (${$fileContentsRef} =~ m{
1708                                   \{
1709                                   \s*
1710                                   &\s*([A-Z0-9_\[\]-]+)         # &hf
1711                                   \s*,\s*
1712                                   \{\s*
1713                                   ("[A-Z0-9 '\./\(\)_:-]+")     # name
1714                                   \s*,\s*
1715                                   (NULL|"[A-Z0-9_\.-]*")        # abbrev
1716                                   \s*,\s*
1717                                   (FT_[A-Z0-9_]+)               # field type
1718                                   \s*,\s*
1719                                   ([A-Z0-9x\|_]+)               # display
1720                                   \s*,\s*
1721                                   ([^,]+?)                      # convert
1722                                   \s*,\s*
1723                                   ([A-Z0-9_]+)                  # bitmask
1724                                   \s*,\s*
1725                                   (NULL|"[A-Z0-9 '\./\(\)\?_:-]+")      # blurb (NULL or a string)
1726                                   \s*,\s*
1727                                   HFILL                         # HFILL
1728         }xgios);
1729
1730         #print "Found @items items\n";
1731         while (@items) {
1732                 ##my $errorCount_save = $errorCount;
1733                 my ($hf, $name, $abbrev, $ft, $display, $convert, $bitmask, $blurb) = @items;
1734                 shift @items; shift @items; shift @items; shift @items; shift @items; shift @items; shift @items; shift @items;
1735
1736                 #print "name=$name, abbrev=$abbrev, ft=$ft, display=$display, convert=>$convert<, bitmask=$bitmask, blurb=$blurb\n";
1737
1738                 if ($abbrev eq '""' || $abbrev eq "NULL") {
1739                         print STDERR "Error: $hf does not have an abbreviation in $filename\n";
1740                         $errorCount++;
1741                 }
1742                 if ($abbrev =~ m/\.\.+/) {
1743                         print STDERR "Error: the abbreviation for $hf ($abbrev) contains two or more sequential periods in $filename\n";
1744                         $errorCount++;
1745                 }
1746                 if ($name eq $abbrev) {
1747                         print STDERR "Error: the abbreviation for $hf ($abbrev) matches the field name ($name) in $filename\n";
1748                         $errorCount++;
1749                 }
1750                 if (lc($name) eq lc($blurb)) {
1751                         print STDERR "Error: the blurb for $hf ($blurb) matches the field name ($name) in $filename\n";
1752                         $errorCount++;
1753                 }
1754                 if ($name =~ m/"\s+/) {
1755                         print STDERR "Error: the name for $hf ($name) has leading space in $filename\n";
1756                         $errorCount++;
1757                 }
1758                 if ($name =~ m/\s+"/) {
1759                         print STDERR "Error: the name for $hf ($name) has trailing space in $filename\n";
1760                         $errorCount++;
1761                 }
1762                 if ($blurb =~ m/"\s+/) {
1763                         print STDERR "Error: the blurb for $hf ($blurb) has leading space in $filename\n";
1764                         $errorCount++;
1765                 }
1766                 if ($blurb =~ m/\s+"/) {
1767                         print STDERR "Error: the blurb for $hf ($blurb) has trailing space in $filename\n";
1768                         $errorCount++;
1769                 }
1770                 if ($abbrev =~ m/\s+/) {
1771                         print STDERR "Error: the abbreviation for $hf ($abbrev) has white space in $filename\n";
1772                         $errorCount++;
1773                 }
1774                 if ("\"".$hf ."\"" eq $name) {
1775                         print STDERR "Error: name is the hf_variable_name in field $name ($abbrev) in $filename\n";
1776                         $errorCount++;
1777                 }
1778                 if ("\"".$hf ."\"" eq $abbrev) {
1779                         print STDERR "Error: abbreviation is the hf_variable_name in field $name ($abbrev) in $filename\n";
1780                         $errorCount++;
1781                 }
1782                 if ($ft ne "FT_BOOLEAN" && $convert =~ m/^TFS\(.*\)/) {
1783                         print STDERR "Error: $hf uses a true/false string but is an $ft instead of FT_BOOLEAN in $filename\n";
1784                         $errorCount++;
1785                 }
1786                 if ($ft eq "FT_BOOLEAN" && $convert =~ m/^VALS\(.*\)/) {
1787                         print STDERR "Error: $hf uses a value_string but is an FT_BOOLEAN in $filename\n";
1788                         $errorCount++;
1789                 }
1790                 if (($ft eq "FT_BOOLEAN") && ($bitmask !~ /^(0x)?0+$/) && ($display =~ /^BASE_/)) {
1791                         print STDERR "Error: $hf: FT_BOOLEAN with a bitmask must specify a 'parent field width' for 'display' in $filename\n";
1792                         $errorCount++;
1793                 }
1794                 if (($ft eq "FT_BOOLEAN") && ($convert !~ m/^((0[xX]0?)?0$|NULL$|TFS)/)) {
1795                         print STDERR "Error: $hf: FT_BOOLEAN with non-null 'convert' field missing TFS in $filename\n";
1796                         $errorCount++;
1797                 }
1798                 if ($convert =~ m/RVALS/ && $display !~ m/BASE_RANGE_STRING/) {
1799                         print STDERR "Error: $hf uses RVALS but 'display' does not include BASE_RANGE_STRING in $filename\n";
1800                         $errorCount++;
1801                 }
1802                 if ($convert =~ m/^VALS\(&.*\)/) {
1803                         print STDERR "Error: $hf is passing the address of a pointer to VALS in $filename\n";
1804                         $errorCount++;
1805                 }
1806                 if ($convert =~ m/^RVALS\(&.*\)/) {
1807                         print STDERR "Error: $hf is passing the address of a pointer to RVALS in $filename\n";
1808                         $errorCount++;
1809                 }
1810                 if ($convert !~ m/^((0[xX]0?)?0$|NULL$|VALS|VALS64|VALS_EXT_PTR|RVALS|TFS|CF_FUNC|FRAMENUM_TYPE|&)/ && $display !~ /BASE_CUSTOM/) {
1811                         print STDERR "Error: non-null $hf 'convert' field missing 'VALS|VALS64|RVALS|TFS|CF_FUNC|FRAMENUM_TYPE|&' in $filename ?\n";
1812                         $errorCount++;
1813                 }
1814 ## Benign...
1815 ##              if (($ft eq "FT_BOOLEAN") && ($bitmask =~ /^(0x)?0+$/) && ($display ne "BASE_NONE")) {
1816 ##                      print STDERR "Error: $abbrev: FT_BOOLEAN with no bitmask must use BASE_NONE for 'display' in $filename\n";
1817 ##                      $errorCount++;
1818 ##              }
1819                 ##if ($errorCount != $errorCount_save) {
1820                 ##        print STDERR "name=$name, abbrev=$abbrev, ft=$ft, display=$display, convert=>$convert<, bitmask=$bitmask, blurb=$blurb\n";
1821                 ##}
1822
1823         }
1824
1825         return $errorCount;
1826 }
1827
1828 sub print_usage
1829 {
1830         print "Usage: checkAPIs.pl [-M] [-h] [-g group1] [-g group2] ... \n";
1831         print "                    [--build] [-s group1] [-s group2] ... \n";
1832         print "                    [--sourcedir=srcdir] \n";
1833         print "                    [--nocheck-value-string-array] \n";
1834         print "                    [--nocheck-addtext] [--nocheck-hf] [--debug]\n";
1835         print "                    [--file=/path/to/file_list]\n";
1836         print "                    file1 file2 ...\n";
1837         print "\n";
1838         print "       -M: Generate output for -g in 'machine-readable' format\n";
1839         print "       -p: used by the git pre-commit hook\n";
1840         print "       -h: help, print usage message\n";
1841         print "       -g <group>:  Check input files for use of APIs in <group>\n";
1842         print "                    (in addition to the default groups)\n";
1843         print "       -s <group>:  Output summary (count) for each API in <group>\n";
1844         print "                    (-g <group> also req'd)\n";
1845         print "       ---nocheck-value-string-array: UNDOCUMENTED\n";
1846         print "       ---nocheck-addtext: UNDOCUMENTED\n";
1847         print "       ---nocheck-hf: UNDOCUMENTED\n";
1848         print "       ---debug: UNDOCUMENTED\n";
1849         print "       ---build: UNDOCUMENTED\n";
1850         print "\n";
1851         print "   Default Groups[-g]: ", join (", ", sort @apiGroups), "\n";
1852         print "   Available Groups:   ", join (", ", sort keys %APIs), "\n";
1853 }
1854
1855 # -------------
1856 # action:  remove '#if 0'd code from the input string
1857 # args     codeRef, fileName
1858 # returns: codeRef
1859 #
1860 # Essentially: Use s//patsub/meg to pass each line to patsub.
1861 #              patsub monitors #if/#if 0/etc and determines
1862 #               if a particular code line should be removed.
1863 # XXX: This is probably pretty inefficient;
1864 #      I could imagine using another approach such as converting
1865 #       the input string to an array of lines and then making
1866 #       a pass through the array deleting lines as needed.
1867
1868 {  # block begin
1869 my ($if_lvl, $if0_lvl, $if0); # shared vars
1870 my $debug = 0;
1871
1872     sub remove_if0_code {
1873         my ($codeRef, $fileName)  = @_;
1874
1875         my ($preprocRegEx) = qr {
1876                                     (                                    # $1 [complete line)
1877                                         ^
1878                                         (?:                              # non-capturing
1879                                             \s* \# \s*
1880                                             (if \s 0| if | else | endif) # $2 (only if #...)
1881                                         ) ?
1882                                         .*
1883                                         $
1884                                     )
1885                             }xom;
1886
1887         ($if_lvl, $if0_lvl, $if0) = (0,0,0);
1888         $$codeRef =~ s{ $preprocRegEx }{patsub($1,$2)}xegm;
1889
1890         ($debug == 2) && print "==> After Remove if0: code: [$fileName]\n$$codeRef\n===<\n";
1891         return $codeRef;
1892     }
1893
1894     sub patsub {
1895         if ($debug == 99) {
1896             print "-->$_[0]\n";
1897             (defined $_[1]) && print "  >$_[1]<\n";
1898         }
1899
1900         # #if/#if 0/#else/#endif processing
1901         if (defined $_[1]) {
1902             my ($if) = $_[1];
1903             if ($if eq 'if') {
1904                 $if_lvl += 1;
1905             } elsif ($if eq 'if 0') {
1906                 $if_lvl += 1;
1907                 if ($if0_lvl == 0) {
1908                     $if0_lvl = $if_lvl;
1909                     $if0     = 1;  # inside #if 0
1910                 }
1911             } elsif ($if eq 'else') {
1912                 if ($if0_lvl == $if_lvl) {
1913                     $if0 = 0;
1914                 }
1915             } elsif ($if eq 'endif') {
1916                 if ($if0_lvl == $if_lvl) {
1917                     $if0     = 0;
1918                     $if0_lvl = 0;
1919                 }
1920                 $if_lvl -= 1;
1921                 if ($if_lvl < 0) {
1922                     die "patsub: #if/#endif mismatch"
1923                 }
1924             }
1925             return $_[0];  # don't remove preprocessor lines themselves
1926         }
1927
1928         # not preprocessor line: See if under #if 0: If so, remove
1929         if ($if0 == 1) {
1930             return '';  # remove
1931         }
1932         return $_[0];
1933     }
1934 }  # block end
1935
1936 # The below Regexp are based on those from:
1937 # http://aspn.activestate.com/ASPN/Cookbook/Rx/Recipe/59811
1938 # They are in the public domain.
1939
1940 # 1. A complicated regex which matches C-style comments.
1941 my $CComment = qr{ / [*] [^*]* [*]+ (?: [^/*] [^*]* [*]+ )* / }x;
1942
1943 # 1.a A regex that matches C++-style comments.
1944 #my $CppComment = qr{ // (.*?) \n }x;
1945
1946 # 2. A regex which matches double-quoted strings.
1947 #    ?s added so that strings containing a 'line continuation'
1948 #    ( \ followed by a new-line) will match.
1949 my $DoubleQuotedStr = qr{ (?: ["] (?s: \\. | [^\"\\])* ["]) }x;
1950
1951 # 3. A regex which matches single-quoted strings.
1952 my $SingleQuotedStr = qr{ (?: \' (?: \\. | [^\'\\])* [']) }x;
1953
1954 # 4. Now combine 1 through 3 to produce a regex which
1955 #    matches _either_ double or single quoted strings
1956 #    OR comments. We surround the comment-matching
1957 #    regex in capturing parenthesis to store the contents
1958 #    of the comment in $1.
1959 #    my $commentAndStringRegex = qr{(?:$DoubleQuotedStr|$SingleQuotedStr)|($CComment)|($CppComment)};
1960
1961 # 4. Wireshark is strictly a C program so don't take out C++ style comments
1962 #    since they shouldn't be there anyway...
1963 #    Also: capturing the comment isn't necessary.
1964 ## my $commentAndStringRegex = qr{ (?: $DoubleQuotedStr | $SingleQuotedStr | $CComment) }x;
1965
1966 #
1967 # MAIN
1968 #
1969 my $errorCount = 0;
1970
1971 # The default list, which can be expanded.
1972 my @apiSummaryGroups = ();
1973 my $check_value_string_array= 1;                        # default: enabled
1974 my $machine_readable_output = 0;                        # default: disabled
1975 my $check_hf = 1;                                       # default: enabled
1976 my $check_addtext = 1;                                  # default: enabled
1977 my $debug_flag = 0;                                     # default: disabled
1978 my $buildbot_flag = 0;
1979 my $source_dir = "";
1980 my $filenamelist = "";
1981 my $help_flag = 0;
1982 my $pre_commit = 0;
1983
1984 my $result = GetOptions(
1985                         'group=s' => \@apiGroups,
1986                         'summary-group=s' => \@apiSummaryGroups,
1987                         'check-value-string-array!' => \$check_value_string_array,
1988                         'Machine-readable' => \$machine_readable_output,
1989                         'check-hf!' => \$check_hf,
1990                         'check-addtext!' => \$check_addtext,
1991                         'build' => \$buildbot_flag,
1992                         'sourcedir=s' => \$source_dir,
1993                         'debug' => \$debug_flag,
1994                         'pre-commit' => \$pre_commit,
1995                         'file=s' => \$filenamelist,
1996                         'help' => \$help_flag
1997                         );
1998 if (!$result || $help_flag) {
1999         print_usage();
2000         exit(1);
2001 }
2002
2003 # the pre-commit hook only calls checkAPIs one file at a time, so this
2004 # is safe to do globally (and easier)
2005 if ($pre_commit) {
2006     my $filename = $ARGV[0];
2007     # if the filename is packet-*.c or packet-*.h, then we set the abort and termoutput groups.
2008     if ($filename =~ /\bpacket-[^\/\\]+\.[ch]$/) {
2009         push @apiGroups, "abort";
2010         push @apiGroups, "termoutput";
2011     }
2012 }
2013
2014 # Add a 'function_count' anonymous hash to each of the 'apiGroup' entries in the %APIs hash.
2015 for my $apiGroup (keys %APIs) {
2016         my @functions = @{$APIs{$apiGroup}{functions}};
2017
2018         $APIs{$apiGroup}->{function_counts}   = {};
2019         @{$APIs{$apiGroup}->{function_counts}}{@functions} = ();  # Add fcn names as keys to the anonymous hash
2020 }
2021
2022 my @filelist;
2023 push @filelist, @ARGV;
2024 if ("$filenamelist" ne "") {
2025         # We have a file containing a list of files to check (possibly in
2026         # addition to those on the command line).
2027         open(FC, $filenamelist) || die("Couldn't open $filenamelist");
2028
2029         while (<FC>) {
2030                 # file names can be separated by ;
2031                 push @filelist, split(';');
2032         }
2033         close(FC);
2034 }
2035
2036 # Read through the files; do various checks
2037 while ($_ = pop @filelist)
2038 {
2039         my $filename = $_;
2040         my $fileContents = '';
2041         my @foundAPIs = ();
2042         my $line;
2043
2044         if ($source_dir and ! -e $filename) {
2045                 $filename = $source_dir . '/' . $filename;
2046         }
2047         if (! -e $filename) {
2048                 warn "No such file: \"$filename\"";
2049                 next;
2050         }
2051
2052         # delete leading './'
2053         $filename =~ s{ ^ \. / } {}xo;
2054         unless (-f $filename) {
2055                 print STDERR "Warning: $filename is not of type file - skipping.\n";
2056                 next;
2057         }
2058
2059         # Read in the file (ouch, but it's easier that way)
2060         open(FC, $filename) || die("Couldn't open $filename");
2061         $line = 1;
2062         while (<FC>) {
2063                 $fileContents .= $_;
2064                 if ($_ =~ m{ [\x80-\xFF] }xo) {
2065                         print STDERR "Error: Found non-ASCII characters on line " .$line. " of " .$filename."\n";
2066                         $errorCount++;
2067                 }
2068                 $line++;
2069         }
2070         close(FC);
2071
2072         if (($fileContents =~ m{ \$Id .* \$ }xo))
2073         {
2074                 print STDERR "Warning: ".$filename." has an SVN Id tag. Please remove it!\n";
2075         }
2076
2077         if (($fileContents =~ m{ tab-width:\s*[0-7|9]+ | tabstop=[0-7|9]+ | tabSize=[0-7|9]+ }xo))
2078         {
2079                 # To quote Icf0831717de10fc615971fa1cf75af2f1ea2d03d :
2080                 # HT tab stops are set every 8 spaces on UN*X; UN*X tools that treat an HT character
2081                 # as tabbing to 4-space tab stops, or that even are configurable but *default* to
2082                 # 4-space tab stops (I'm looking at *you*, Xcode!) are broken. tab-width: 4,
2083                 # tabstop=4, and tabSize=4 are errors if you ever expect anybody to look at your file
2084                 # with a UN*X tool, and every text file will probably be looked at by a UN*X tool at
2085                 # some point, so Don't Do That.
2086                 #
2087                 # Can I get an "amen!"?
2088                 print STDERR "Error: Found modelines with tabstops set to something other than 8 in " .$filename."\n";
2089                 $errorCount++;
2090         }
2091
2092         # Remove all the C-comments
2093         $fileContents =~ s{ $CComment } []xog;
2094
2095         # optionally check the hf entries (including those under #if 0)
2096         if ($check_hf) {
2097             $errorCount += check_hf_entries(\$fileContents, $filename);
2098         }
2099
2100         if ($fileContents =~ m{ __func__ }xo)
2101         {
2102                 print STDERR "Error: Found __func__ (which is not portable, use G_STRFUNC) in " .$filename."\n";
2103                 $errorCount++;
2104         }
2105         if ($fileContents =~ m{ %ll }xo)
2106         {
2107                 # use G_GINT64_MODIFIER instead of ll
2108                 print STDERR "Error: Found %ll in " .$filename."\n";
2109                 $errorCount++;
2110         }
2111         if ($fileContents =~ m{ %hh }xo)
2112         {
2113                 # %hh is C99 and Windows doesn't like it:
2114                 # http://connect.microsoft.com/VisualStudio/feedback/details/416843/sscanf-cannot-not-handle-hhd-format
2115                 # Need to use temporary variables instead.
2116                 print STDERR "Error: Found %hh in " .$filename."\n";
2117                 $errorCount++;
2118         }
2119
2120         # check for files that we should not include directly
2121         # this must be done before quoted strings (#include "file.h") are removed
2122         check_included_files(\$fileContents, $filename);
2123
2124         # Check for value_string and enum_val_t errors: NULL termination,
2125         # const-nes, and newlines within strings
2126         if ($check_value_string_array) {
2127                 $errorCount += check_value_string_arrays(\$fileContents, $filename, $debug_flag);
2128         }
2129
2130         # Remove all the quoted strings
2131         $fileContents =~ s{ $DoubleQuotedStr | $SingleQuotedStr } []xog;
2132
2133         #$errorCount += check_ett_registration(\$fileContents, $filename);
2134
2135         # Remove all blank lines
2136         $fileContents =~ s{ ^ \s* $ } []xog;
2137
2138         # Remove all '#if 0'd' code
2139         remove_if0_code(\$fileContents, $filename);
2140
2141         #checkAPIsCalledWithTvbGetPtr(\@TvbPtrAPIs, \$fileContents, \@foundAPIs);
2142         #if (@foundAPIs) {
2143         #       print STDERR "Found APIs with embedded tvb_get_ptr() calls in ".$filename." : ".join(',', @foundAPIs)."\n"
2144         #}
2145
2146         checkShadowVariable(\@ShadowVariable, \$fileContents, \@foundAPIs);
2147         if (@foundAPIs) {
2148                print STDERR "Warning: Found shadow variable(s) in ".$filename." : ".join(',', @foundAPIs)."\n"
2149         }
2150
2151
2152         check_snprintf_plus_strlen(\$fileContents, $filename);
2153
2154         $errorCount += check_proto_tree_add_XXX_encoding(\$fileContents, $filename);
2155
2156
2157         # Check and count APIs
2158         for my $apiGroup (@apiGroups) {
2159                 my $pfx = "Warning";
2160                 @foundAPIs = ();
2161
2162                 findAPIinFile($APIs{$apiGroup}, \$fileContents, \@foundAPIs);
2163
2164                 if ($APIs{$apiGroup}->{count_errors}) {
2165                         # the use of "prohibited" APIs is an error, increment the error count
2166                         $errorCount += @foundAPIs;
2167                         $pfx = "Error";
2168                 }
2169
2170                 if (@foundAPIs && ! $machine_readable_output) {
2171                         print STDERR $pfx . ": Found " . $apiGroup . " APIs in ".$filename.": ".join(',', @foundAPIs)."\n";
2172                 }
2173                 if (@foundAPIs && $machine_readable_output) {
2174                         for my $api (@foundAPIs) {
2175                                 printf STDERR "%-8.8s %-20.20s %-30.30s %-45.45s\n", $pfx, $apiGroup, $filename, $api;
2176                         }
2177                 }
2178         }
2179 }
2180
2181 # Summary: Print Use Counts of each API in each requested summary group
2182
2183 for my $apiGroup (@apiSummaryGroups) {
2184         printf "\n\nUse Counts\n";
2185         for my $api (sort {"\L$a" cmp "\L$b"} (keys %{$APIs{$apiGroup}->{function_counts}}   )) {
2186                 printf "%-20.20s %5d  %-40.40s\n", $apiGroup . ':', $APIs{$apiGroup}{function_counts}{$api}, $api;
2187         }
2188 }
2189
2190 exit($errorCount);
2191
2192 #
2193 # Editor modelines  -  http://www.wireshark.org/tools/modelines.html
2194 #
2195 # Local variables:
2196 # c-basic-offset: 8
2197 # tab-width: 8
2198 # indent-tabs-mode: nil
2199 # End:
2200 #
2201 # vi: set shiftwidth=8 tabstop=8 expandtab:
2202 # :indentSize=8:tabSize=8:noTabs=true:
2203 #