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