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